diff --git a/IPython/nbconvert/filters/markdown.py b/IPython/nbconvert/filters/markdown.py
index cace686..2937045 100755
--- a/IPython/nbconvert/filters/markdown.py
+++ b/IPython/nbconvert/filters/markdown.py
@@ -8,23 +8,21 @@ markdown within Jinja templates.
from __future__ import print_function
-# Stdlib imports
import os
import subprocess
from io import TextIOWrapper, BytesIO
-import re
-import mistune
-from pygments import highlight
-from pygments.lexers import get_lexer_by_name
-from pygments.formatters import HtmlFormatter
-from pygments.util import ClassNotFound
+try:
+ from .markdown_mistune import markdown2html_mistune
+except ImportError as e:
+ # store in variable for Python 3
+ _mistune_import_error = e
+ def markdown2html_mistune(source):
+ """mistune is unavailable, raise ImportError"""
+ raise ImportError("markdown2html requires mistune: %s" % _mistune_import_error)
-# IPython imports
-from IPython.nbconvert.filters.strings import add_anchor
from IPython.nbconvert.utils.pandoc import pandoc
from IPython.nbconvert.utils.exceptions import ConversionException
-from IPython.utils.decorators import undoc
from IPython.utils.process import get_output_error_code
from IPython.utils.py3compat import cast_bytes
from IPython.utils.version import check_version
@@ -46,6 +44,7 @@ class NodeJSMissing(ConversionException):
"""Exception raised when node.js is missing."""
pass
+
def markdown2latex(source, markup='markdown', extra_args=None):
"""Convert a markdown string to LaTeX via pandoc.
@@ -69,107 +68,12 @@ def markdown2latex(source, markup='markdown', extra_args=None):
return pandoc(source, markup, 'latex', extra_args=extra_args)
-@undoc
-class MathBlockGrammar(mistune.BlockGrammar):
- block_math = re.compile("^\$\$(.*?)\$\$", re.DOTALL)
- latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}",
- re.DOTALL)
-
-@undoc
-class MathBlockLexer(mistune.BlockLexer):
- default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules
-
- def __init__(self, rules=None, **kwargs):
- if rules is None:
- rules = MathBlockGrammar()
- super(MathBlockLexer, self).__init__(rules, **kwargs)
-
- def parse_block_math(self, m):
- """Parse a $$math$$ block"""
- self.tokens.append({
- 'type': 'block_math',
- 'text': m.group(1)
- })
-
- def parse_latex_environment(self, m):
- self.tokens.append({
- 'type': 'latex_environment',
- 'name': m.group(1),
- 'text': m.group(2)
- })
-
-@undoc
-class MathInlineGrammar(mistune.InlineGrammar):
- math = re.compile("^\$(.+?)\$")
- text = re.compile(r'^[\s\S]+?(?=[\\%s
\n' % \
- mistune.escape(code)
-
- formatter = HtmlFormatter()
- return highlight(code, lexer, formatter)
-
- def header(self, text, level, raw=None):
- html = super(IPythonRenderer, self).header(text, level, raw=raw)
- return add_anchor(html)
-
- # Pass math through unaltered - mathjax does the rendering in the browser
- def block_math(self, text):
- return '$$%s$$' % text
-
- def latex_environment(self, name, text):
- return r'\begin{%s}%s\end{%s}' % (name, text, name)
-
- def inline_math(self, text):
- return '$%s$' % text
-
-def markdown2html_mistune(source):
- """Convert a markdown string to HTML using mistune"""
- return MarkdownWithMath(renderer=IPythonRenderer()).render(source)
-
def markdown2html_pandoc(source, extra_args=None):
"""Convert a markdown string to HTML via pandoc"""
extra_args = extra_args or ['--mathjax']
return pandoc(source, 'markdown', 'html', extra_args=extra_args)
+
def _find_nodejs():
global _node
if _node is None:
diff --git a/IPython/nbconvert/filters/markdown_mistune.py b/IPython/nbconvert/filters/markdown_mistune.py
new file mode 100644
index 0000000..18a1f8a
--- /dev/null
+++ b/IPython/nbconvert/filters/markdown_mistune.py
@@ -0,0 +1,118 @@
+"""Markdown filters with mistune
+
+Used from markdown.py
+"""
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
+
+from __future__ import print_function
+
+import re
+
+import mistune
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name
+from pygments.formatters import HtmlFormatter
+from pygments.util import ClassNotFound
+
+from IPython.nbconvert.filters.strings import add_anchor
+from IPython.nbconvert.utils.exceptions import ConversionException
+from IPython.utils.decorators import undoc
+
+
+@undoc
+class MathBlockGrammar(mistune.BlockGrammar):
+ block_math = re.compile("^\$\$(.*?)\$\$", re.DOTALL)
+ latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}",
+ re.DOTALL)
+
+@undoc
+class MathBlockLexer(mistune.BlockLexer):
+ default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules
+
+ def __init__(self, rules=None, **kwargs):
+ if rules is None:
+ rules = MathBlockGrammar()
+ super(MathBlockLexer, self).__init__(rules, **kwargs)
+
+ def parse_block_math(self, m):
+ """Parse a $$math$$ block"""
+ self.tokens.append({
+ 'type': 'block_math',
+ 'text': m.group(1)
+ })
+
+ def parse_latex_environment(self, m):
+ self.tokens.append({
+ 'type': 'latex_environment',
+ 'name': m.group(1),
+ 'text': m.group(2)
+ })
+
+@undoc
+class MathInlineGrammar(mistune.InlineGrammar):
+ math = re.compile("^\$(.+?)\$")
+ text = re.compile(r'^[\s\S]+?(?=[\\%s
\n' % \
+ mistune.escape(code)
+
+ formatter = HtmlFormatter()
+ return highlight(code, lexer, formatter)
+
+ def header(self, text, level, raw=None):
+ html = super(IPythonRenderer, self).header(text, level, raw=raw)
+ return add_anchor(html)
+
+ # Pass math through unaltered - mathjax does the rendering in the browser
+ def block_math(self, text):
+ return '$$%s$$' % text
+
+ def latex_environment(self, name, text):
+ return r'\begin{%s}%s\end{%s}' % (name, text, name)
+
+ def inline_math(self, text):
+ return '$%s$' % text
+
+def markdown2html_mistune(source):
+ """Convert a markdown string to HTML using mistune"""
+ return MarkdownWithMath(renderer=IPythonRenderer()).render(source)