##// END OF EJS Templates
Merge pull request #4187 from pablooliveira/pr-4184...
Min RK -
r12588:9fde9a83 merge
parent child Browse files
Show More
@@ -0,0 +1,113 b''
1 """This preprocessor detect cells using a different language through
2 magic extensions such as `%%R` or `%%octave`. Cell's metadata is marked
3 so that the appropriate highlighter can be used in the `highlight`
4 filter.
5 """
6
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from __future__ import print_function, absolute_import
20
21 import re
22
23 # Our own imports
24 from .base import Preprocessor
25 from IPython.utils.traitlets import Dict
26
27 #-----------------------------------------------------------------------------
28 # Classes
29 #-----------------------------------------------------------------------------
30
31
32 class HighlightMagicsPreprocessor(Preprocessor):
33 """
34 Detects and tags code cells that use a different languages than Python.
35 """
36
37 # list of magic language extensions and their associated pygment lexers
38 default_languages = Dict(
39 default_value={
40 '%%R': 'r',
41 '%%bash': 'bash',
42 '%%cython': 'cython',
43 '%%javascript': 'javascript',
44 '%%julia': 'julia',
45 '%%latex': 'latex',
46 '%%octave': 'octave',
47 '%%perl': 'perl',
48 '%%ruby': 'ruby',
49 '%%sh': 'sh'})
50
51 # user defined language extensions
52 languages = Dict(
53 config=True,
54 help=("Syntax highlighting for magic's extension languages. "
55 "Each item associates a language magic extension such as %%R, "
56 "with a pygments lexer such as r."))
57
58 def __init__(self, config=None, **kw):
59 """Public constructor"""
60
61 super(HighlightMagicsPreprocessor, self).__init__(config=config, **kw)
62
63 # Update the default languages dict with the user configured ones
64 self.default_languages.update(self.languages)
65
66 # build a regular expression to catch language extensions and choose
67 # an adequate pygments lexer
68 any_language = "|".join(self.default_languages.keys())
69 self.re_magic_language = re.compile(
70 r'^\s*({0})\s+'.format(any_language))
71
72 def which_magic_language(self, source):
73 """
74 When a cell uses another language through a magic extension,
75 the other language is returned.
76 If no language magic is detected, this function returns None.
77
78 Parameters
79 ----------
80 source: str
81 Source code of the cell to highlight
82 """
83
84 m = self.re_magic_language.match(source)
85
86 if m:
87 # By construction of the re, the matched language must be in the
88 # languages dictionary
89 return self.default_languages[m.group(1)]
90 else:
91 return None
92
93 def preprocess_cell(self, cell, resources, cell_index):
94 """
95 Tags cells using a magic extension language
96
97 Parameters
98 ----------
99 cell : NotebookNode cell
100 Notebook cell being processed
101 resources : dictionary
102 Additional resources used in the conversion process. Allows
103 preprocessors to pass variables into the Jinja engine.
104 cell_index : int
105 Index of the cell being processed (see base.py)
106 """
107
108 # Only tag code cells
109 if hasattr(cell, "input") and cell.cell_type == "code":
110 magic_language = self.which_magic_language(cell.input)
111 if magic_language:
112 cell['metadata']['magics_language'] = magic_language
113 return cell, resources
@@ -0,0 +1,68 b''
1 """
2 Module with tests for the HighlightMagics preprocessor
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import PreprocessorTestsBase
18 from ..highlightmagics import HighlightMagicsPreprocessor
19
20
21 #-----------------------------------------------------------------------------
22 # Class
23 #-----------------------------------------------------------------------------
24
25 class TestHighlightMagics(PreprocessorTestsBase):
26 """Contains test functions for highlightmagics.py"""
27
28
29 def build_preprocessor(self):
30 """Make an instance of a preprocessor"""
31 preprocessor = HighlightMagicsPreprocessor()
32 preprocessor.enabled = True
33 return preprocessor
34
35 def test_constructor(self):
36 """Can a HighlightMagicsPreprocessor be constructed?"""
37 self.build_preprocessor()
38
39 def test_tagging(self):
40 """Test the HighlightMagicsPreprocessor tagging"""
41 nb = self.build_notebook()
42 res = self.build_resources()
43 preprocessor = self.build_preprocessor()
44 nb.worksheets[0].cells[0].input = """%%R -i x,y -o XYcoef
45 lm.fit <- lm(y~x)
46 par(mfrow=c(2,2))
47 print(summary(lm.fit))
48 plot(lm.fit)
49 XYcoef <- coef(lm.fit)"""
50
51 nb, res = preprocessor(nb, res)
52
53 assert('magics_language' in nb.worksheets[0].cells[0]['metadata'])
54
55 self.assertEqual(nb.worksheets[0].cells[0]['metadata']['magics_language'], 'r')
56
57 def test_no_false_positive(self):
58 """Test that HighlightMagicsPreprocessor does not tag false positives"""
59 nb = self.build_notebook()
60 res = self.build_resources()
61 preprocessor = self.build_preprocessor()
62 nb.worksheets[0].cells[0].input = """# this should not be detected
63 print(\"""
64 %%R -i x, y
65 \""")"""
66 nb, res = preprocessor(nb, res)
67
68 assert('magics_language' not in nb.worksheets[0].cells[0]['metadata']) No newline at end of file
@@ -68,7 +68,8 b' class Exporter(LoggingConfigurable):'
68 nbpreprocessors.CSSHTMLHeaderPreprocessor,
68 nbpreprocessors.CSSHTMLHeaderPreprocessor,
69 nbpreprocessors.RevealHelpPreprocessor,
69 nbpreprocessors.RevealHelpPreprocessor,
70 nbpreprocessors.LatexPreprocessor,
70 nbpreprocessors.LatexPreprocessor,
71 nbpreprocessors.SphinxPreprocessor],
71 nbpreprocessors.SphinxPreprocessor,
72 nbpreprocessors.HighlightMagicsPreprocessor],
72 config=True,
73 config=True,
73 help="""List of preprocessors available by default, by name, namespace,
74 help="""List of preprocessors available by default, by name, namespace,
74 instance, or type.""")
75 instance, or type.""")
@@ -46,7 +46,10 b' class HTMLExporter(TemplateExporter):'
46 c = Config({
46 c = Config({
47 'CSSHTMLHeaderPreprocessor':{
47 'CSSHTMLHeaderPreprocessor':{
48 'enabled':True
48 'enabled':True
49 }
49 },
50 'HighlightMagicsPreprocessor': {
51 'enabled':True
52 }
50 })
53 })
51 c.merge(super(HTMLExporter,self).default_config)
54 c.merge(super(HTMLExporter,self).default_config)
52 return c
55 return c
@@ -85,6 +85,9 b' class LatexExporter(TemplateExporter):'
85 },
85 },
86 'SphinxPreprocessor': {
86 'SphinxPreprocessor': {
87 'enabled':True
87 'enabled':True
88 },
89 'HighlightMagicsPreprocessor': {
90 'enabled':True
88 }
91 }
89 })
92 })
90 c.merge(super(LatexExporter,self).default_config)
93 c.merge(super(LatexExporter,self).default_config)
@@ -47,6 +47,9 b' class SlidesExporter(TemplateExporter):'
47 'RevealHelpPreprocessor':{
47 'RevealHelpPreprocessor':{
48 'enabled':True,
48 'enabled':True,
49 },
49 },
50 'HighlightMagicsPreprocessor': {
51 'enabled':True
52 }
50 })
53 })
51 c.merge(super(SlidesExporter,self).default_config)
54 c.merge(super(SlidesExporter,self).default_config)
52 return c
55 return c
@@ -14,7 +14,7 b' from within Jinja templates.'
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from pygments import highlight as pygements_highlight
17 from pygments import highlight as pygements_highlight
18 from pygments.lexers import get_lexer_by_name
18 from pygments.lexers import get_lexer_by_name
19 from pygments.formatters import HtmlFormatter
19 from pygments.formatters import HtmlFormatter
20 from pygments.formatters import LatexFormatter
20 from pygments.formatters import LatexFormatter
@@ -37,52 +37,66 b' __all__ = ['
37 'highlight2latex'
37 'highlight2latex'
38 ]
38 ]
39
39
40
40 def highlight2html(source, language='ipython', metadata=None):
41 def highlight2html(source, language='ipython'):
42 """
41 """
43 Return a syntax-highlighted version of the input source as html output.
42 Return a syntax-highlighted version of the input source as html output.
44
43
45 Parameters
44 Parameters
46 ----------
45 ----------
47 source : str
46 source : str
48 Source code to highlight the syntax of.
47 source of the cell to highlight.
49 language : str
48 language : str
50 Language to highlight the syntax of.
49 Language to highlight the syntax of.
50 metadata : NotebookNode cell metadata
51 metadata of the cell to highlight.
51 """
52 """
52
53
53 return _pygment_highlight(source, HtmlFormatter(), language)
54 return _pygment_highlight(source, HtmlFormatter(), language, metadata)
54
55
55
56
56 def highlight2latex(source, language='ipython'):
57 def highlight2latex(source, language='ipython', metadata=None):
57 """
58 """
58 Return a syntax-highlighted version of the input source as latex output.
59 Return a syntax-highlighted version of the input source as latex output.
59
60
60 Parameters
61 Parameters
61 ----------
62 ----------
62 source : str
63 source : str
63 Source code to highlight the syntax of.
64 source of the cell to highlight.
64 language : str
65 language : str
65 Language to highlight the syntax of.
66 Language to highlight the syntax of.
67 metadata : NotebookNode cell metadata
68 metadata of the cell to highlight.
66 """
69 """
67 return _pygment_highlight(source, LatexFormatter(), language)
70 return _pygment_highlight(source, LatexFormatter(), language, metadata)
71
68
72
69
73
70 def _pygment_highlight(source, output_formatter, language='ipython'):
74 def _pygment_highlight(source, output_formatter, language='ipython', metadata=None):
71 """
75 """
72 Return a syntax-highlighted version of the input source
76 Return a syntax-highlighted version of the input source
73
77
74 Parameters
78 Parameters
75 ----------
79 ----------
76 source : str
80 source : str
77 Source code to highlight the syntax of.
81 source of the cell to highlight.
78 output_formatter : Pygments formatter
82 output_formatter : Pygments formatter
79 language : str
83 language : str
80 Language to highlight the syntax of.
84 Language to highlight the syntax of.
85 metadata : NotebookNode cell metadata
86 metadata of the cell to highlight.
81 """
87 """
82
88
89 # If the cell uses a magic extension language,
90 # use the magic language instead.
91 if language == 'ipython' \
92 and metadata \
93 and 'magics_language' in metadata:
94
95 language = metadata['magics_language']
96
83 if language == 'ipython':
97 if language == 'ipython':
84 lexer = IPythonLexer()
98 lexer = IPythonLexer()
85 else:
99 else:
86 lexer = get_lexer_by_name(language, stripall=True)
100 lexer = get_lexer_by_name(language, stripall=True)
87
101
88 return pygements_highlight(source, lexer, output_formatter)
102 return pygements_highlight(source, lexer, output_formatter)
@@ -7,6 +7,7 b' from .revealhelp import RevealHelpPreprocessor'
7 from .latex import LatexPreprocessor
7 from .latex import LatexPreprocessor
8 from .sphinx import SphinxPreprocessor
8 from .sphinx import SphinxPreprocessor
9 from .csshtmlheader import CSSHTMLHeaderPreprocessor
9 from .csshtmlheader import CSSHTMLHeaderPreprocessor
10 from .highlightmagics import HighlightMagicsPreprocessor
10
11
11 # decorated function Preprocessors
12 # decorated function Preprocessors
12 from .coalescestreams import coalesce_streams
13 from .coalescestreams import coalesce_streams
@@ -36,7 +36,7 b' In&nbsp;[{{ cell.prompt_number }}]:'
36
36
37 {% block input %}
37 {% block input %}
38 <div class="input_area box-flex1">
38 <div class="input_area box-flex1">
39 {{ cell.input | highlight2html }}
39 {{ cell.input | highlight2html(metadata=cell.metadata) }}
40 </div>
40 </div>
41 {%- endblock input %}
41 {%- endblock input %}
42
42
@@ -284,7 +284,7 b' Note: For best display, use latex syntax highlighting. =))'
284 \vspace{-25pt}
284 \vspace{-25pt}
285
285
286 % Add contents below.
286 % Add contents below.
287 ((( cell.input | highlight2latex )))
287 ((( cell.input | highlight2latex(metadata=cell.metadata) )))
288
288
289 ((* elif resources.sphinx.outputstyle == 'notebook' *))
289 ((* elif resources.sphinx.outputstyle == 'notebook' *))
290 \vspace{6pt}
290 \vspace{6pt}
@@ -292,7 +292,7 b' Note: For best display, use latex syntax highlighting. =))'
292 \vspace{-2.65\baselineskip}
292 \vspace{-2.65\baselineskip}
293 \begin{ColorVerbatim}
293 \begin{ColorVerbatim}
294 \vspace{-0.7\baselineskip}
294 \vspace{-0.7\baselineskip}
295 ((( cell.input | highlight2latex )))
295 ((( cell.input | highlight2latex(metadata=cell.metadata) )))
296 ((* if cell.input == None or cell.input == '' *))
296 ((* if cell.input == None or cell.input == '' *))
297 \vspace{0.3\baselineskip}
297 \vspace{0.3\baselineskip}
298 ((* else *))
298 ((* else *))
General Comments 0
You need to be logged in to leave comments. Login now