Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4dd584e

Browse files
committed
Merge pull request #6720 from takluyver/kernelspec-pygments-lexer
Respect kernelspec metadata for syntax highlighting in nbconvert
2 parents 2a8a2c8 + 0d0b44f commit 4dd584e

12 files changed

Lines changed: 89 additions & 29 deletions

File tree

IPython/html/static/notebook/js/notebook.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ define([
208208

209209
this.events.on('spec_changed.Kernel', function(event, data) {
210210
that.set_kernelspec_metadata(data);
211-
if (data.codemirror_mode) {
212-
that.set_codemirror_mode(data.codemirror_mode);
213-
}
211+
// Mode 'null' should be plain, unhighlighted text.
212+
cm_mode = data.codemirror_mode || data.language || 'null'
213+
that.set_codemirror_mode(cm_mode);
214214
});
215215

216216
var collapse_time = function (time) {

IPython/kernel/kernelspec.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,15 @@ class KernelSpec(HasTraits):
3838
display_name = Unicode()
3939
language = Unicode()
4040
codemirror_mode = Any() # can be unicode or dict
41+
pygments_lexer = Unicode()
4142
env = Dict()
4243
resource_dir = Unicode()
4344

4445
def _codemirror_mode_default(self):
4546
return self.language
47+
48+
def _pygments_lexer_default(self):
49+
return self.language
4650

4751
@classmethod
4852
def from_resource_dir(cls, resource_dir):
@@ -56,12 +60,17 @@ def from_resource_dir(cls, resource_dir):
5660
return cls(resource_dir=resource_dir, **kernel_dict)
5761

5862
def to_dict(self):
59-
return dict(argv=self.argv,
60-
env=self.env,
61-
display_name=self.display_name,
62-
language=self.language,
63-
codemirror_mode=self.codemirror_mode,
64-
)
63+
d = dict(argv=self.argv,
64+
env=self.env,
65+
display_name=self.display_name,
66+
language=self.language,
67+
)
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
6574

6675
def to_json(self):
6776
return json.dumps(self.to_dict())
@@ -114,6 +123,7 @@ def _native_kernel_dict(self):
114123
'language': 'python',
115124
'codemirror_mode': {'name': 'ipython',
116125
'version': sys.version_info[0]},
126+
'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
117127
}
118128

119129
@property

IPython/nbconvert/exporters/html.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import os
1616

17-
from IPython.nbconvert import preprocessors
17+
from IPython.nbconvert.filters.highlight import Highlight2HTML
1818
from IPython.config import Config
1919

2020
from .templateexporter import TemplateExporter
@@ -57,3 +57,10 @@ def default_config(self):
5757
})
5858
c.merge(super(HTMLExporter,self).default_config)
5959
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)

IPython/nbconvert/exporters/latex.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from IPython.utils.traitlets import Unicode
2020
from IPython.config import Config
2121

22-
from IPython.nbconvert import filters, preprocessors
22+
from IPython.nbconvert.filters.highlight import Highlight2Latex
2323
from .templateexporter import TemplateExporter
2424

2525
#-----------------------------------------------------------------------------
@@ -87,3 +87,10 @@ def default_config(self):
8787
})
8888
c.merge(super(LatexExporter,self).default_config)
8989
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)

IPython/nbconvert/filters/highlight.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# not import time, when it may not be needed.
1212

1313
from IPython.nbconvert.utils.base import NbConvertBase
14+
from warnings import warn
1415

1516
MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
1617

@@ -20,6 +21,14 @@
2021
]
2122

2223
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
2332

2433
def __call__(self, source, language=None, metadata=None):
2534
"""
@@ -35,8 +44,9 @@ def __call__(self, source, language=None, metadata=None):
3544
metadata of the cell to highlight
3645
"""
3746
from pygments.formatters import HtmlFormatter
47+
3848
if not language:
39-
language=self.default_language
49+
language=self.pygments_lexer
4050

4151
return _pygments_highlight(source if len(source) > 0 else ' ',
4252
# needed to help post processors:
@@ -45,6 +55,14 @@ def __call__(self, source, language=None, metadata=None):
4555

4656

4757
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
4866

4967
def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
5068
"""
@@ -63,7 +81,7 @@ def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
6381
"""
6482
from pygments.formatters import LatexFormatter
6583
if not language:
66-
language=self.default_language
84+
language=self.pygments_lexer
6785

6886
latex = _pygments_highlight(source, LatexFormatter(), language, metadata)
6987
if strip_verbatim:
@@ -90,7 +108,8 @@ def _pygments_highlight(source, output_formatter, language='ipython', metadata=N
90108
"""
91109
from pygments import highlight
92110
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
94113

95114
# If the cell uses a magic extension language,
96115
# use the magic language instead.
@@ -100,9 +119,17 @@ def _pygments_highlight(source, output_formatter, language='ipython', metadata=N
100119

101120
language = metadata['magics_language']
102121

103-
if language == 'ipython':
122+
if language == 'ipython2':
104123
lexer = IPythonLexer()
124+
elif language == 'ipython3':
125+
lexer = IPython3Lexer()
105126
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+
107134

108135
return highlight(source, lexer, output_formatter)

IPython/nbconvert/filters/tests/test_highlight.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525

2626
highlight2html = Highlight2HTML()
2727
highlight2latex = Highlight2Latex()
28-
c = Config()
29-
c.Highlight2HTML.default_language='ruby'
30-
highlight2html_ruby = Highlight2HTML(config=c)
28+
highlight2html_ruby = Highlight2HTML(pygments_lexer='ruby')
3129

3230
class TestHighlight(TestsBase):
3331
"""Contains test functions for highlight.py"""
@@ -37,8 +35,10 @@ class TestHighlight(TestsBase):
3735
"""
3836
#Hello World Example
3937
38+
import foo
39+
4040
def say(text):
41-
print(text)
41+
foo.bar(text)
4242
4343
end
4444
@@ -51,7 +51,7 @@ def say(text):
5151
]
5252

5353
tokens = [
54-
['Hello World Example', 'say', 'text', 'print', 'def'],
54+
['Hello World Example', 'say', 'text', 'import', 'def'],
5555
['pylab', 'plot']]
5656

5757

@@ -72,11 +72,13 @@ def test_parse_html_many_lang(self):
7272
rb = highlight2html_ruby(self.tests[0])
7373

7474
for lang,tkns in [
75-
( ht, ('def','print') ),
75+
( ht, ('def', )),
7676
( rb, ('def','end' ) )
7777
]:
78+
print(tkns)
79+
print(lang)
7880
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))
8082

8183
def _extract_tokens(self, root, cls):
8284
return set(map(lambda x:x.text,root.findall(".//*[@class='"+cls+"']")))

IPython/nbconvert/templates/html/basic.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ In [ ]:
4646
{% block input %}
4747
<div class="inner_cell">
4848
<div class="input_area">
49-
{{ cell.input | highlight2html(language=resources.get('language'), metadata=cell.metadata) }}
49+
{{ cell.input | highlight_code(metadata=cell.metadata) }}
5050
</div>
5151
</div>
5252
{%- endblock input %}

IPython/nbconvert/templates/latex/style_ipython.tplx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
%===============================================================================
2121

2222
((* 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') )))
2424
((* endblock input *))
2525

2626

IPython/nbconvert/templates/latex/style_python.tplx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616

1717
((* block input scoped *))
1818
\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 )))
2020
\end{Verbatim}
2121
((* endblock input *))

IPython/nbconvert/utils/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class NbConvertBase(LoggingConfigurable):
3434
"""
3535
)
3636

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')
3839

3940
def __init__(self, **kw):
4041
super(NbConvertBase, self).__init__(**kw)

0 commit comments

Comments
 (0)