##// END OF EJS Templates
Add HighlightMagicsPreprocessor...
Pablo de Oliveira -
Show More
@@ -0,0 +1,104 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 # Needed to override preprocessor
25 from .base import (Preprocessor)
26 from IPython.utils.traitlets import Dict
27
28 #-----------------------------------------------------------------------------
29 # Classes
30 #-----------------------------------------------------------------------------
31
32
33 class HighlightMagicsPreprocessor(Preprocessor):
34 """
35 Detects and tags code cells that use a different languages than Python.
36 """
37
38 # list of magic language extensions and their associated pygment lexers
39 languages = Dict(
40 default_value={
41 '%%R': 'r',
42 '%%bash': 'bash',
43 '%%octave': 'octave',
44 '%%perl': 'perl',
45 '%%ruby': 'ruby'},
46 config=True,
47 help=("Syntax highlighting for magic's extension languages. "
48 "Each item associates a language magic extension such as %%R, "
49 "with a pygments lexer such as r."))
50
51 def __init__(self, config=None, **kw):
52 """Public constructor"""
53
54 super(HighlightMagicsPreprocessor, self).__init__(config=config, **kw)
55
56 # build a regular expression to catch language extensions and choose
57 # an adequate pygments lexer
58 any_language = "|".join(self.languages.keys())
59 self.re_magic_language = re.compile(
60 r'^\s*({0})\s+'.format(any_language))
61
62 def which_magic_language(self, source):
63 """
64 When a cell uses another language through a magic extension,
65 the other language is returned.
66 If no language magic is detected, this function returns None.
67
68 Parameters
69 ----------
70 source: str
71 Source code of the cell to highlight
72 """
73
74 m = self.re_magic_language.match(source)
75
76 if m:
77 # By construction of the re, the matched language must be in the
78 # languages dictionnary
79 assert(m.group(1) in self.languages)
80 return self.languages[m.group(1)]
81 else:
82 return None
83
84 def preprocess_cell(self, cell, resources, cell_index):
85 """
86 Tags cells using a magic extension language
87
88 Parameters
89 ----------
90 cell : NotebookNode cell
91 Notebook cell being processed
92 resources : dictionary
93 Additional resources used in the conversion process. Allows
94 preprocessors to pass variables into the Jinja engine.
95 cell_index : int
96 Index of the cell being processed (see base.py)
97 """
98
99 # Only tag code cells
100 if hasattr(cell, "input") and cell.cell_type == "code":
101 magic_language = self.which_magic_language(cell.input)
102 if magic_language:
103 cell['metadata']['magics_language'] = magic_language
104 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 68 nbpreprocessors.CSSHTMLHeaderPreprocessor,
69 69 nbpreprocessors.RevealHelpPreprocessor,
70 70 nbpreprocessors.LatexPreprocessor,
71 nbpreprocessors.SphinxPreprocessor],
71 nbpreprocessors.SphinxPreprocessor,
72 nbpreprocessors.HighlightMagicsPreprocessor],
72 73 config=True,
73 74 help="""List of preprocessors available by default, by name, namespace,
74 75 instance, or type.""")
@@ -46,7 +46,10 b' class HTMLExporter(TemplateExporter):'
46 46 c = Config({
47 47 'CSSHTMLHeaderPreprocessor':{
48 48 'enabled':True
49 }
49 },
50 'HighlightMagicsPreprocessor': {
51 'enabled':True
52 }
50 53 })
51 54 c.merge(super(HTMLExporter,self).default_config)
52 55 return c
@@ -85,6 +85,9 b' class LatexExporter(TemplateExporter):'
85 85 },
86 86 'SphinxPreprocessor': {
87 87 'enabled':True
88 },
89 'HighlightMagicsPreprocessor': {
90 'enabled':True
88 91 }
89 92 })
90 93 c.merge(super(LatexExporter,self).default_config)
@@ -7,6 +7,7 b' from .revealhelp import RevealHelpPreprocessor'
7 7 from .latex import LatexPreprocessor
8 8 from .sphinx import SphinxPreprocessor
9 9 from .csshtmlheader import CSSHTMLHeaderPreprocessor
10 from .highlightmagics import HighlightMagicsPreprocessor
10 11
11 12 # decorated function Preprocessors
12 13 from .coalescestreams import coalesce_streams
General Comments 0
You need to be logged in to leave comments. Login now