##// END OF EJS Templates
nbconvert: don't require mistune unless it's used...
Min RK -
Show More
@@ -0,0 +1,118 b''
1 """Markdown filters with mistune
2
3 Used from markdown.py
4 """
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
7
8 from __future__ import print_function
9
10 import re
11
12 import mistune
13
14 from pygments import highlight
15 from pygments.lexers import get_lexer_by_name
16 from pygments.formatters import HtmlFormatter
17 from pygments.util import ClassNotFound
18
19 from IPython.nbconvert.filters.strings import add_anchor
20 from IPython.nbconvert.utils.exceptions import ConversionException
21 from IPython.utils.decorators import undoc
22
23
24 @undoc
25 class MathBlockGrammar(mistune.BlockGrammar):
26 block_math = re.compile("^\$\$(.*?)\$\$", re.DOTALL)
27 latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}",
28 re.DOTALL)
29
30 @undoc
31 class MathBlockLexer(mistune.BlockLexer):
32 default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules
33
34 def __init__(self, rules=None, **kwargs):
35 if rules is None:
36 rules = MathBlockGrammar()
37 super(MathBlockLexer, self).__init__(rules, **kwargs)
38
39 def parse_block_math(self, m):
40 """Parse a $$math$$ block"""
41 self.tokens.append({
42 'type': 'block_math',
43 'text': m.group(1)
44 })
45
46 def parse_latex_environment(self, m):
47 self.tokens.append({
48 'type': 'latex_environment',
49 'name': m.group(1),
50 'text': m.group(2)
51 })
52
53 @undoc
54 class MathInlineGrammar(mistune.InlineGrammar):
55 math = re.compile("^\$(.+?)\$")
56 text = re.compile(r'^[\s\S]+?(?=[\\<!\[_*`~$]|https?://| {2,}\n|$)')
57
58 @undoc
59 class MathInlineLexer(mistune.InlineLexer):
60 default_rules = ['math'] + mistune.InlineLexer.default_rules
61
62 def __init__(self, renderer, rules=None, **kwargs):
63 if rules is None:
64 rules = MathInlineGrammar()
65 super(MathInlineLexer, self).__init__(renderer, rules, **kwargs)
66
67 def output_math(self, m):
68 return self.renderer.inline_math(m.group(1))
69
70 @undoc
71 class MarkdownWithMath(mistune.Markdown):
72 def __init__(self, renderer, **kwargs):
73 if 'inline' not in kwargs:
74 kwargs['inline'] = MathInlineLexer
75 if 'block' not in kwargs:
76 kwargs['block'] = MathBlockLexer
77 super(MarkdownWithMath, self).__init__(renderer, **kwargs)
78
79 def output_block_math(self):
80 return self.renderer.block_math(self.token['text'])
81
82 def output_latex_environment(self):
83 return self.renderer.latex_environment(self.token['name'], self.token['text'])
84
85 @undoc
86 class IPythonRenderer(mistune.Renderer):
87 def block_code(self, code, lang):
88 if lang:
89 try:
90 lexer = get_lexer_by_name(lang, stripall=True)
91 except ClassNotFound:
92 code = lang + '\n' + code
93 lang = None
94
95 if not lang:
96 return '\n<pre><code>%s</code></pre>\n' % \
97 mistune.escape(code)
98
99 formatter = HtmlFormatter()
100 return highlight(code, lexer, formatter)
101
102 def header(self, text, level, raw=None):
103 html = super(IPythonRenderer, self).header(text, level, raw=raw)
104 return add_anchor(html)
105
106 # Pass math through unaltered - mathjax does the rendering in the browser
107 def block_math(self, text):
108 return '$$%s$$' % text
109
110 def latex_environment(self, name, text):
111 return r'\begin{%s}%s\end{%s}' % (name, text, name)
112
113 def inline_math(self, text):
114 return '$%s$' % text
115
116 def markdown2html_mistune(source):
117 """Convert a markdown string to HTML using mistune"""
118 return MarkdownWithMath(renderer=IPythonRenderer()).render(source)
@@ -8,23 +8,21 b' markdown within Jinja templates.'
8 8
9 9 from __future__ import print_function
10 10
11 # Stdlib imports
12 11 import os
13 12 import subprocess
14 13 from io import TextIOWrapper, BytesIO
15 import re
16 14
17 import mistune
18 from pygments import highlight
19 from pygments.lexers import get_lexer_by_name
20 from pygments.formatters import HtmlFormatter
21 from pygments.util import ClassNotFound
15 try:
16 from .markdown_mistune import markdown2html_mistune
17 except ImportError as e:
18 # store in variable for Python 3
19 _mistune_import_error = e
20 def markdown2html_mistune(source):
21 """mistune is unavailable, raise ImportError"""
22 raise ImportError("markdown2html requires mistune: %s" % _mistune_import_error)
22 23
23 # IPython imports
24 from IPython.nbconvert.filters.strings import add_anchor
25 24 from IPython.nbconvert.utils.pandoc import pandoc
26 25 from IPython.nbconvert.utils.exceptions import ConversionException
27 from IPython.utils.decorators import undoc
28 26 from IPython.utils.process import get_output_error_code
29 27 from IPython.utils.py3compat import cast_bytes
30 28 from IPython.utils.version import check_version
@@ -46,6 +44,7 b' class NodeJSMissing(ConversionException):'
46 44 """Exception raised when node.js is missing."""
47 45 pass
48 46
47
49 48 def markdown2latex(source, markup='markdown', extra_args=None):
50 49 """Convert a markdown string to LaTeX via pandoc.
51 50
@@ -69,107 +68,12 b" def markdown2latex(source, markup='markdown', extra_args=None):"
69 68 return pandoc(source, markup, 'latex', extra_args=extra_args)
70 69
71 70
72 @undoc
73 class MathBlockGrammar(mistune.BlockGrammar):
74 block_math = re.compile("^\$\$(.*?)\$\$", re.DOTALL)
75 latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}",
76 re.DOTALL)
77
78 @undoc
79 class MathBlockLexer(mistune.BlockLexer):
80 default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules
81
82 def __init__(self, rules=None, **kwargs):
83 if rules is None:
84 rules = MathBlockGrammar()
85 super(MathBlockLexer, self).__init__(rules, **kwargs)
86
87 def parse_block_math(self, m):
88 """Parse a $$math$$ block"""
89 self.tokens.append({
90 'type': 'block_math',
91 'text': m.group(1)
92 })
93
94 def parse_latex_environment(self, m):
95 self.tokens.append({
96 'type': 'latex_environment',
97 'name': m.group(1),
98 'text': m.group(2)
99 })
100
101 @undoc
102 class MathInlineGrammar(mistune.InlineGrammar):
103 math = re.compile("^\$(.+?)\$")
104 text = re.compile(r'^[\s\S]+?(?=[\\<!\[_*`~$]|https?://| {2,}\n|$)')
105
106 @undoc
107 class MathInlineLexer(mistune.InlineLexer):
108 default_rules = ['math'] + mistune.InlineLexer.default_rules
109
110 def __init__(self, renderer, rules=None, **kwargs):
111 if rules is None:
112 rules = MathInlineGrammar()
113 super(MathInlineLexer, self).__init__(renderer, rules, **kwargs)
114
115 def output_math(self, m):
116 return self.renderer.inline_math(m.group(1))
117
118 @undoc
119 class MarkdownWithMath(mistune.Markdown):
120 def __init__(self, renderer, **kwargs):
121 if 'inline' not in kwargs:
122 kwargs['inline'] = MathInlineLexer
123 if 'block' not in kwargs:
124 kwargs['block'] = MathBlockLexer
125 super(MarkdownWithMath, self).__init__(renderer, **kwargs)
126
127 def output_block_math(self):
128 return self.renderer.block_math(self.token['text'])
129
130 def output_latex_environment(self):
131 return self.renderer.latex_environment(self.token['name'], self.token['text'])
132
133 @undoc
134 class IPythonRenderer(mistune.Renderer):
135 def block_code(self, code, lang):
136 if lang:
137 try:
138 lexer = get_lexer_by_name(lang, stripall=True)
139 except ClassNotFound:
140 code = lang + '\n' + code
141 lang = None
142
143 if not lang:
144 return '\n<pre><code>%s</code></pre>\n' % \
145 mistune.escape(code)
146
147 formatter = HtmlFormatter()
148 return highlight(code, lexer, formatter)
149
150 def header(self, text, level, raw=None):
151 html = super(IPythonRenderer, self).header(text, level, raw=raw)
152 return add_anchor(html)
153
154 # Pass math through unaltered - mathjax does the rendering in the browser
155 def block_math(self, text):
156 return '$$%s$$' % text
157
158 def latex_environment(self, name, text):
159 return r'\begin{%s}%s\end{%s}' % (name, text, name)
160
161 def inline_math(self, text):
162 return '$%s$' % text
163
164 def markdown2html_mistune(source):
165 """Convert a markdown string to HTML using mistune"""
166 return MarkdownWithMath(renderer=IPythonRenderer()).render(source)
167
168 71 def markdown2html_pandoc(source, extra_args=None):
169 72 """Convert a markdown string to HTML via pandoc"""
170 73 extra_args = extra_args or ['--mathjax']
171 74 return pandoc(source, 'markdown', 'html', extra_args=extra_args)
172 75
76
173 77 def _find_nodejs():
174 78 global _node
175 79 if _node is None:
General Comments 0
You need to be logged in to leave comments. Login now