Show More
@@ -1,88 +1,131 b'' | |||
|
1 | 1 | """ |
|
2 | 2 | Module containing filter functions that allow code to be highlighted |
|
3 | 3 | from within Jinja templates. |
|
4 | 4 | """ |
|
5 | 5 | #----------------------------------------------------------------------------- |
|
6 | 6 | # Copyright (c) 2013, the IPython Development Team. |
|
7 | 7 | # |
|
8 | 8 | # Distributed under the terms of the Modified BSD License. |
|
9 | 9 | # |
|
10 | 10 | # The full license is in the file COPYING.txt, distributed with this software. |
|
11 | 11 | #----------------------------------------------------------------------------- |
|
12 | 12 | |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | # Imports |
|
15 | 15 | #----------------------------------------------------------------------------- |
|
16 | 16 | |
|
17 | from pygments import highlight as pygements_highlight | |
|
17 | import re | |
|
18 | ||
|
19 | from pygments import highlight as pygements_highlight | |
|
18 | 20 | from pygments.lexers import get_lexer_by_name |
|
19 | 21 | from pygments.formatters import HtmlFormatter |
|
20 | 22 | from pygments.formatters import LatexFormatter |
|
21 | 23 | |
|
22 | 24 | # Our own imports |
|
23 | 25 | from IPython.nbconvert.utils.lexers import IPythonLexer |
|
24 | 26 | |
|
25 | 27 | #----------------------------------------------------------------------------- |
|
26 | 28 | # Globals and constants |
|
27 | 29 | #----------------------------------------------------------------------------- |
|
28 | 30 | |
|
29 | 31 | MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] |
|
30 | 32 | |
|
33 | # list of magic language extensions and their associated pygment lexers | |
|
34 | magic_languages = {'%%R': 'r', | |
|
35 | '%%bash': 'bash', | |
|
36 | '%%octave': 'octave', | |
|
37 | '%%perl': 'perl', | |
|
38 | '%%ruby': 'ruby' | |
|
39 | } | |
|
40 | ||
|
41 | # build a RE to catch language extensions and choose an adequate | |
|
42 | # pygments lexer | |
|
43 | re_languages = "|".join(magic_languages.keys()) | |
|
44 | re_magic_language = re.compile(r'^\s*({})\s+'.format(re_languages), | |
|
45 | re.MULTILINE) | |
|
46 | ||
|
31 | 47 | #----------------------------------------------------------------------------- |
|
32 | 48 | # Utility functions |
|
33 | 49 | #----------------------------------------------------------------------------- |
|
34 | 50 | |
|
35 | 51 | __all__ = [ |
|
36 | 52 | 'highlight2html', |
|
37 | 53 | 'highlight2latex' |
|
38 | 54 | ] |
|
39 | 55 | |
|
40 | 56 | |
|
41 | 57 | def highlight2html(source, language='ipython'): |
|
42 | 58 | """ |
|
43 | 59 | Return a syntax-highlighted version of the input source as html output. |
|
44 | ||
|
60 | ||
|
45 | 61 | Parameters |
|
46 | 62 | ---------- |
|
47 | 63 | source : str |
|
48 | 64 | Source code to highlight the syntax of. |
|
49 | 65 | language : str |
|
50 | 66 | Language to highlight the syntax of. |
|
51 | 67 | """ |
|
52 | ||
|
68 | ||
|
53 | 69 | return _pygment_highlight(source, HtmlFormatter(), language) |
|
54 | 70 | |
|
55 | 71 | |
|
56 | 72 | def highlight2latex(source, language='ipython'): |
|
57 | 73 | """ |
|
58 | 74 | Return a syntax-highlighted version of the input source as latex output. |
|
59 | ||
|
75 | ||
|
60 | 76 | Parameters |
|
61 | 77 | ---------- |
|
62 | 78 | source : str |
|
63 | 79 | Source code to highlight the syntax of. |
|
64 | 80 | language : str |
|
65 | 81 | Language to highlight the syntax of. |
|
66 | 82 | """ |
|
67 | 83 | return _pygment_highlight(source, LatexFormatter(), language) |
|
68 | 84 | |
|
69 | 85 | |
|
86 | def which_magic_language(source): | |
|
87 | """ | |
|
88 | When a cell uses another language through a magic extension, | |
|
89 | the other language is returned. | |
|
90 | If no language magic is detected, this function returns None. | |
|
91 | ||
|
92 | Parameters | |
|
93 | ---------- | |
|
94 | source: str | |
|
95 | Source code of the cell to highlight | |
|
96 | """ | |
|
97 | ||
|
98 | m = re_magic_language.search(source) | |
|
99 | ||
|
100 | if m: | |
|
101 | # By construction of the re, the matched language must be in the | |
|
102 | # language dictionnary | |
|
103 | assert(m.group(1) in magic_languages) | |
|
104 | return magic_languages[m.group(1)] | |
|
105 | else: | |
|
106 | return None | |
|
107 | ||
|
108 | ||
|
70 | 109 | def _pygment_highlight(source, output_formatter, language='ipython'): |
|
71 | 110 | """ |
|
72 | 111 | Return a syntax-highlighted version of the input source |
|
73 | ||
|
112 | ||
|
74 | 113 | Parameters |
|
75 | 114 | ---------- |
|
76 | 115 | source : str |
|
77 | 116 | Source code to highlight the syntax of. |
|
78 | 117 | output_formatter : Pygments formatter |
|
79 | 118 | language : str |
|
80 | 119 | Language to highlight the syntax of. |
|
81 | 120 | """ |
|
82 | ||
|
121 | ||
|
122 | magic_language = which_magic_language(source) | |
|
123 | if magic_language: | |
|
124 | language = magic_language | |
|
125 | ||
|
83 | 126 | if language == 'ipython': |
|
84 | 127 | lexer = IPythonLexer() |
|
85 | 128 | else: |
|
86 | 129 | lexer = get_lexer_by_name(language, stripall=True) |
|
87 | 130 | |
|
88 |
return pygements_highlight(source, lexer, output_formatter) |
|
|
131 | return pygements_highlight(source, lexer, output_formatter) |
@@ -1,65 +1,97 b'' | |||
|
1 | 1 | """ |
|
2 | 2 | Module with tests for Highlight |
|
3 | 3 | """ |
|
4 | 4 | |
|
5 | 5 | #----------------------------------------------------------------------------- |
|
6 | 6 | # Copyright (c) 2013, the IPython Development Team. |
|
7 | 7 | # |
|
8 | 8 | # Distributed under the terms of the Modified BSD License. |
|
9 | 9 | # |
|
10 | 10 | # The full license is in the file COPYING.txt, distributed with this software. |
|
11 | 11 | #----------------------------------------------------------------------------- |
|
12 | 12 | |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | # Imports |
|
15 | 15 | #----------------------------------------------------------------------------- |
|
16 | 16 | |
|
17 | 17 | from ...tests.base import TestsBase |
|
18 | from ..highlight import highlight2html, highlight2latex | |
|
18 | from ..highlight import highlight2html, highlight2latex, which_magic_language | |
|
19 | 19 | |
|
20 | 20 | |
|
21 | 21 | #----------------------------------------------------------------------------- |
|
22 | 22 | # Class |
|
23 | 23 | #----------------------------------------------------------------------------- |
|
24 | 24 | |
|
25 | 25 | class TestHighlight(TestsBase): |
|
26 | 26 | """Contains test functions for highlight.py""" |
|
27 | 27 | |
|
28 | 28 | #Hello world test, magics test, blank string test |
|
29 | 29 | tests = [ |
|
30 | 30 | """ |
|
31 | 31 | #Hello World Example |
|
32 | 32 | |
|
33 | 33 | def say(text): |
|
34 | 34 | print(text) |
|
35 | 35 | |
|
36 | 36 | say('Hello World!') |
|
37 | 37 | """, |
|
38 | 38 | """ |
|
39 | 39 | %%pylab |
|
40 | 40 | plot(x,y, 'r') |
|
41 | 41 | """ |
|
42 |
] |
|
|
42 | ] | |
|
43 | 43 | |
|
44 | 44 | tokens = [ |
|
45 | 45 | ['Hello World Example', 'say', 'text', 'print', 'def'], |
|
46 | 46 | ['pylab', 'plot']] |
|
47 | 47 | |
|
48 | ||
|
49 | 48 | def test_highlight2html(self): |
|
50 | 49 | """highlight2html test""" |
|
51 | 50 | for index, test in enumerate(self.tests): |
|
52 | 51 | self._try_highlight(highlight2html, test, self.tokens[index]) |
|
53 | 52 | |
|
54 | ||
|
55 | 53 | def test_highlight2latex(self): |
|
56 | 54 | """highlight2latex test""" |
|
57 | 55 | for index, test in enumerate(self.tests): |
|
58 | 56 | self._try_highlight(highlight2latex, test, self.tokens[index]) |
|
59 | 57 | |
|
60 | ||
|
61 | 58 | def _try_highlight(self, method, test, tokens): |
|
62 | 59 | """Try highlighting source, look for key tokens""" |
|
63 | 60 | results = method(test) |
|
64 | 61 | for token in tokens: |
|
65 | 62 | assert token in results |
|
63 | ||
|
64 | magic_tests = { | |
|
65 | 'r': | |
|
66 | """%%R -i x,y -o XYcoef | |
|
67 | lm.fit <- lm(y~x) | |
|
68 | par(mfrow=c(2,2)) | |
|
69 | print(summary(lm.fit)) | |
|
70 | plot(lm.fit) | |
|
71 | XYcoef <- coef(lm.fit) | |
|
72 | """, | |
|
73 | 'bash': | |
|
74 | """# the following code is in bash | |
|
75 | %%bash | |
|
76 | echo "test" > out | |
|
77 | """, | |
|
78 | 'ipython': | |
|
79 | """# this should not be detected | |
|
80 | print("%%R") | |
|
81 | """ | |
|
82 | } | |
|
83 | ||
|
84 | def test_highlight_rmagic(self): | |
|
85 | """Test %%R magic highlighting""" | |
|
86 | language = which_magic_language(self.magic_tests['r']) | |
|
87 | assert language == 'r' | |
|
88 | ||
|
89 | def test_highlight_bashmagic(self): | |
|
90 | """Test %%bash magic highlighting""" | |
|
91 | language = which_magic_language(self.magic_tests['bash']) | |
|
92 | assert language == 'bash' | |
|
93 | ||
|
94 | def test_highlight_interferemagic(self): | |
|
95 | """Test that magic highlighting does not interfere with ipython code""" | |
|
96 | language = which_magic_language(self.magic_tests['ipython']) | |
|
97 | assert language == None No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now