From d26228cdf4dfb85363daf528be4a63fb122dbbe5 2015-03-03 22:32:18 From: Min RK Date: 2015-03-03 22:32:18 Subject: [PATCH] nbconvert: don't require mistune unless it's used - moves mistune-related functionality to filters.markdown_mistune - raises ImportError on call of markdown2html_mistune, rather than import of nbconvert --- 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)