##// END OF EJS Templates
Merge pull request #6720 from takluyver/kernelspec-pygments-lexer...
Matthias Bussonnier -
r18419:4dd584ef merge
parent child Browse files
Show More
@@ -0,0 +1,3
1 - Setting the default highlighting language for nbconvert with the config option
2 ``NbConvertBase.default_language`` is deprecated. Nbconvert now respects
3 metadata stored in the :ref:`kernel spec <kernelspecs>`_.
@@ -208,9 +208,9 define([
208
208
209 this.events.on('spec_changed.Kernel', function(event, data) {
209 this.events.on('spec_changed.Kernel', function(event, data) {
210 that.set_kernelspec_metadata(data);
210 that.set_kernelspec_metadata(data);
211 if (data.codemirror_mode) {
211 // Mode 'null' should be plain, unhighlighted text.
212 that.set_codemirror_mode(data.codemirror_mode);
212 cm_mode = data.codemirror_mode || data.language || 'null'
213 }
213 that.set_codemirror_mode(cm_mode);
214 });
214 });
215
215
216 var collapse_time = function (time) {
216 var collapse_time = function (time) {
@@ -38,11 +38,15 class KernelSpec(HasTraits):
38 display_name = Unicode()
38 display_name = Unicode()
39 language = Unicode()
39 language = Unicode()
40 codemirror_mode = Any() # can be unicode or dict
40 codemirror_mode = Any() # can be unicode or dict
41 pygments_lexer = Unicode()
41 env = Dict()
42 env = Dict()
42 resource_dir = Unicode()
43 resource_dir = Unicode()
43
44
44 def _codemirror_mode_default(self):
45 def _codemirror_mode_default(self):
45 return self.language
46 return self.language
47
48 def _pygments_lexer_default(self):
49 return self.language
46
50
47 @classmethod
51 @classmethod
48 def from_resource_dir(cls, resource_dir):
52 def from_resource_dir(cls, resource_dir):
@@ -56,12 +60,17 class KernelSpec(HasTraits):
56 return cls(resource_dir=resource_dir, **kernel_dict)
60 return cls(resource_dir=resource_dir, **kernel_dict)
57
61
58 def to_dict(self):
62 def to_dict(self):
59 return dict(argv=self.argv,
63 d = dict(argv=self.argv,
60 env=self.env,
64 env=self.env,
61 display_name=self.display_name,
65 display_name=self.display_name,
62 language=self.language,
66 language=self.language,
63 codemirror_mode=self.codemirror_mode,
67 )
64 )
68 if self.codemirror_mode != self.language:
69 d['codemirror_mode'] = self.codemirror_mode
70 if self.pygments_lexer != self.language:
71 d['pygments_lexer'] = self.pygments_lexer
72
73 return d
65
74
66 def to_json(self):
75 def to_json(self):
67 return json.dumps(self.to_dict())
76 return json.dumps(self.to_dict())
@@ -114,6 +123,7 class KernelSpecManager(HasTraits):
114 'language': 'python',
123 'language': 'python',
115 'codemirror_mode': {'name': 'ipython',
124 'codemirror_mode': {'name': 'ipython',
116 'version': sys.version_info[0]},
125 'version': sys.version_info[0]},
126 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
117 }
127 }
118
128
119 @property
129 @property
@@ -14,7 +14,7
14
14
15 import os
15 import os
16
16
17 from IPython.nbconvert import preprocessors
17 from IPython.nbconvert.filters.highlight import Highlight2HTML
18 from IPython.config import Config
18 from IPython.config import Config
19
19
20 from .templateexporter import TemplateExporter
20 from .templateexporter import TemplateExporter
@@ -57,3 +57,10 class HTMLExporter(TemplateExporter):
57 })
57 })
58 c.merge(super(HTMLExporter,self).default_config)
58 c.merge(super(HTMLExporter,self).default_config)
59 return c
59 return c
60
61 def from_notebook_node(self, nb, resources=None, **kw):
62 kernelspec = nb.metadata.get('kernelspec', {})
63 lexer = kernelspec.get('pygments_lexer', kernelspec.get('language', None))
64 self.register_filter('highlight_code',
65 Highlight2HTML(pygments_lexer=lexer, parent=self))
66 return super(HTMLExporter, self).from_notebook_node(nb, resources, **kw)
@@ -19,7 +19,7 import os
19 from IPython.utils.traitlets import Unicode
19 from IPython.utils.traitlets import Unicode
20 from IPython.config import Config
20 from IPython.config import Config
21
21
22 from IPython.nbconvert import filters, preprocessors
22 from IPython.nbconvert.filters.highlight import Highlight2Latex
23 from .templateexporter import TemplateExporter
23 from .templateexporter import TemplateExporter
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
@@ -87,3 +87,10 class LatexExporter(TemplateExporter):
87 })
87 })
88 c.merge(super(LatexExporter,self).default_config)
88 c.merge(super(LatexExporter,self).default_config)
89 return c
89 return c
90
91 def from_notebook_node(self, nb, resources=None, **kw):
92 kernelspec = nb.metadata.get('kernelspec', {})
93 lexer = kernelspec.get('pygments_lexer', kernelspec.get('language', None))
94 self.register_filter('highlight_code',
95 Highlight2Latex(pygments_lexer=lexer, parent=self))
96 return super(LatexExporter, self).from_notebook_node(nb, resources, **kw)
@@ -11,6 +11,7 from within Jinja templates.
11 # not import time, when it may not be needed.
11 # not import time, when it may not be needed.
12
12
13 from IPython.nbconvert.utils.base import NbConvertBase
13 from IPython.nbconvert.utils.base import NbConvertBase
14 from warnings import warn
14
15
15 MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
16 MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
16
17
@@ -20,6 +21,14 __all__ = [
20 ]
21 ]
21
22
22 class Highlight2HTML(NbConvertBase):
23 class Highlight2HTML(NbConvertBase):
24 def __init__(self, pygments_lexer=None, **kwargs):
25 self.pygments_lexer = pygments_lexer or 'ipython3'
26 super(Highlight2HTML, self).__init__(**kwargs)
27
28 def _default_language_changed(self, name, old, new):
29 warn('Setting default_language in config is deprecated, '
30 'please use kernelspecs instead.')
31 self.pygments_lexer = new
23
32
24 def __call__(self, source, language=None, metadata=None):
33 def __call__(self, source, language=None, metadata=None):
25 """
34 """
@@ -35,8 +44,9 class Highlight2HTML(NbConvertBase):
35 metadata of the cell to highlight
44 metadata of the cell to highlight
36 """
45 """
37 from pygments.formatters import HtmlFormatter
46 from pygments.formatters import HtmlFormatter
47
38 if not language:
48 if not language:
39 language=self.default_language
49 language=self.pygments_lexer
40
50
41 return _pygments_highlight(source if len(source) > 0 else ' ',
51 return _pygments_highlight(source if len(source) > 0 else ' ',
42 # needed to help post processors:
52 # needed to help post processors:
@@ -45,6 +55,14 class Highlight2HTML(NbConvertBase):
45
55
46
56
47 class Highlight2Latex(NbConvertBase):
57 class Highlight2Latex(NbConvertBase):
58 def __init__(self, pygments_lexer=None, **kwargs):
59 self.pygments_lexer = pygments_lexer or 'ipython3'
60 super(Highlight2Latex, self).__init__(**kwargs)
61
62 def _default_language_changed(self, name, old, new):
63 warn('Setting default_language in config is deprecated, '
64 'please use kernelspecs instead.')
65 self.pygments_lexer = new
48
66
49 def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
67 def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
50 """
68 """
@@ -63,7 +81,7 class Highlight2Latex(NbConvertBase):
63 """
81 """
64 from pygments.formatters import LatexFormatter
82 from pygments.formatters import LatexFormatter
65 if not language:
83 if not language:
66 language=self.default_language
84 language=self.pygments_lexer
67
85
68 latex = _pygments_highlight(source, LatexFormatter(), language, metadata)
86 latex = _pygments_highlight(source, LatexFormatter(), language, metadata)
69 if strip_verbatim:
87 if strip_verbatim:
@@ -90,7 +108,8 def _pygments_highlight(source, output_formatter, language='ipython', metadata=N
90 """
108 """
91 from pygments import highlight
109 from pygments import highlight
92 from pygments.lexers import get_lexer_by_name
110 from pygments.lexers import get_lexer_by_name
93 from IPython.nbconvert.utils.lexers import IPythonLexer
111 from pygments.util import ClassNotFound
112 from IPython.nbconvert.utils.lexers import IPythonLexer, IPython3Lexer
94
113
95 # If the cell uses a magic extension language,
114 # If the cell uses a magic extension language,
96 # use the magic language instead.
115 # use the magic language instead.
@@ -100,9 +119,17 def _pygments_highlight(source, output_formatter, language='ipython', metadata=N
100
119
101 language = metadata['magics_language']
120 language = metadata['magics_language']
102
121
103 if language == 'ipython':
122 if language == 'ipython2':
104 lexer = IPythonLexer()
123 lexer = IPythonLexer()
124 elif language == 'ipython3':
125 lexer = IPython3Lexer()
105 else:
126 else:
106 lexer = get_lexer_by_name(language, stripall=True)
127 try:
128 lexer = get_lexer_by_name(language, stripall=True)
129 except ClassNotFound:
130 warn("No lexer found for language %r. Treating as plain text." % language)
131 from pygments.lexers.special import TextLexer
132 lexer = TextLexer()
133
107
134
108 return highlight(source, lexer, output_formatter)
135 return highlight(source, lexer, output_formatter)
@@ -25,9 +25,7 import xml
25
25
26 highlight2html = Highlight2HTML()
26 highlight2html = Highlight2HTML()
27 highlight2latex = Highlight2Latex()
27 highlight2latex = Highlight2Latex()
28 c = Config()
28 highlight2html_ruby = Highlight2HTML(pygments_lexer='ruby')
29 c.Highlight2HTML.default_language='ruby'
30 highlight2html_ruby = Highlight2HTML(config=c)
31
29
32 class TestHighlight(TestsBase):
30 class TestHighlight(TestsBase):
33 """Contains test functions for highlight.py"""
31 """Contains test functions for highlight.py"""
@@ -37,8 +35,10 class TestHighlight(TestsBase):
37 """
35 """
38 #Hello World Example
36 #Hello World Example
39
37
38 import foo
39
40 def say(text):
40 def say(text):
41 print(text)
41 foo.bar(text)
42
42
43 end
43 end
44
44
@@ -51,7 +51,7 class TestHighlight(TestsBase):
51 ]
51 ]
52
52
53 tokens = [
53 tokens = [
54 ['Hello World Example', 'say', 'text', 'print', 'def'],
54 ['Hello World Example', 'say', 'text', 'import', 'def'],
55 ['pylab', 'plot']]
55 ['pylab', 'plot']]
56
56
57
57
@@ -72,11 +72,13 class TestHighlight(TestsBase):
72 rb = highlight2html_ruby(self.tests[0])
72 rb = highlight2html_ruby(self.tests[0])
73
73
74 for lang,tkns in [
74 for lang,tkns in [
75 ( ht, ('def','print') ),
75 ( ht, ('def', )),
76 ( rb, ('def','end' ) )
76 ( rb, ('def','end' ) )
77 ]:
77 ]:
78 print(tkns)
79 print(lang)
78 root = xml.etree.ElementTree.fromstring(lang)
80 root = xml.etree.ElementTree.fromstring(lang)
79 assert self._extract_tokens(root,'k') == set(tkns)
81 self.assertEqual(self._extract_tokens(root,'k'), set(tkns))
80
82
81 def _extract_tokens(self, root, cls):
83 def _extract_tokens(self, root, cls):
82 return set(map(lambda x:x.text,root.findall(".//*[@class='"+cls+"']")))
84 return set(map(lambda x:x.text,root.findall(".//*[@class='"+cls+"']")))
@@ -46,7 +46,7 In&nbsp;[&nbsp;]:
46 {% block input %}
46 {% block input %}
47 <div class="inner_cell">
47 <div class="inner_cell">
48 <div class="input_area">
48 <div class="input_area">
49 {{ cell.input | highlight2html(language=resources.get('language'), metadata=cell.metadata) }}
49 {{ cell.input | highlight_code(metadata=cell.metadata) }}
50 </div>
50 </div>
51 </div>
51 </div>
52 {%- endblock input %}
52 {%- endblock input %}
@@ -20,7 +20,7
20 %===============================================================================
20 %===============================================================================
21
21
22 ((* block input scoped *))
22 ((* block input scoped *))
23 ((( add_prompt(cell.input | highlight2latex(strip_verbatim=True), cell, 'In ', 'incolor') )))
23 ((( add_prompt(cell.input | highlight_code(strip_verbatim=True), cell, 'In ', 'incolor') )))
24 ((* endblock input *))
24 ((* endblock input *))
25
25
26
26
@@ -16,6 +16,6
16
16
17 ((* block input scoped *))
17 ((* block input scoped *))
18 \begin{Verbatim}[commandchars=\\\{\}]
18 \begin{Verbatim}[commandchars=\\\{\}]
19 ((( cell.input | highlight2latex(language=resources.get('language'), strip_verbatim=True) | add_prompts )))
19 ((( cell.input | highlight_code(strip_verbatim=True) | add_prompts )))
20 \end{Verbatim}
20 \end{Verbatim}
21 ((* endblock input *))
21 ((* endblock input *))
@@ -34,7 +34,8 class NbConvertBase(LoggingConfigurable):
34 """
34 """
35 )
35 )
36
36
37 default_language = Unicode('ipython', config=True, help='default highlight language')
37 default_language = Unicode('ipython', config=True,
38 help='DEPRECATED default highlight language, please use kernelspecs instead')
38
39
39 def __init__(self, **kw):
40 def __init__(self, **kw):
40 super(NbConvertBase, self).__init__(**kw)
41 super(NbConvertBase, self).__init__(**kw)
@@ -118,8 +118,11 JSON serialised dictionary containing the following keys and values:
118 identify alternative kernels that can run some code.
118 identify alternative kernels that can run some code.
119 - **codemirror_mode** (optional): The `codemirror mode <http://codemirror.net/mode/index.html>`_
119 - **codemirror_mode** (optional): The `codemirror mode <http://codemirror.net/mode/index.html>`_
120 to use for code in this language. This can be a string or a dictionary, as
120 to use for code in this language. This can be a string or a dictionary, as
121 passed to codemirror config. The string from *language* will be used if this is
121 passed to codemirror config. This only needs to be specified if it does not
122 not provided.
122 match the value in *language*.
123 - **pygments_lexer** (optional): The name of a `Pygments lexer <http://pygments.org/docs/lexers/>`_
124 to use for code in this language, as a string. This only needs to be specified
125 if it does not match the value in *language*.
123 - **env** (optional): A dictionary of environment variables to set for the kernel.
126 - **env** (optional): A dictionary of environment variables to set for the kernel.
124 These will be added to the current environment variables before the kernel is
127 These will be added to the current environment variables before the kernel is
125 started.
128 started.
General Comments 0
You need to be logged in to leave comments. Login now