##// END OF EJS Templates
Integrate pass-through of mathematical expressions with markdown rendering
Thomas Kluyver -
Show More
@@ -19,6 +19,7 b' from __future__ import print_function'
19 19 import os
20 20 import subprocess
21 21 from io import TextIOWrapper, BytesIO
22 import re
22 23
23 24 import mistune
24 25 from pygments import highlight
@@ -69,6 +70,48 b' def markdown2latex(source):'
69 70 """
70 71 return pandoc(source, 'markdown', 'latex')
71 72
73 class MathBlockGrammar(mistune.BlockGrammar):
74 block_math = re.compile("^\$\$(.*?)\$\$")
75
76 class MathBlockLexer(mistune.BlockLexer):
77 default_features = ['block_math'] + mistune.BlockLexer.default_features
78
79 def __init__(self, rules=None, **kwargs):
80 if rules is None:
81 rules = MathBlockGrammar()
82 super(MathBlockLexer, self).__init__(rules, **kwargs)
83
84 def parse_block_math(self, m):
85 """Parse a $$math$$ block"""
86 self.tokens.append({
87 'type': 'block_math',
88 'text': m.group(1)
89 })
90
91 class MathInlineGrammar(mistune.InlineGrammar):
92 math = re.compile("^\$(.+?)\$")
93
94 class MathInlineLexer(mistune.InlineLexer):
95 default_features = ['math'] + mistune.InlineLexer.default_features
96
97 def __init__(self, renderer, rules=None, **kwargs):
98 if rules is None:
99 rules = MathInlineGrammar()
100 super(MathInlineLexer, self).__init__(renderer, rules, **kwargs)
101
102 def output_math(self, m):
103 self.renderer.inline_math(m.group(1))
104
105 class MarkdownWithMath(mistune.Markdown):
106 def __init__(self, renderer, **kwargs):
107 if 'inline' not in kwargs:
108 kwargs['inline'] = MathInlineLexer(renderer, **kwargs)
109 if 'block' not in kwargs:
110 kwargs['block'] = MathBlockLexer(**kwargs)
111 super(MarkdownWithMath, self).__init__(renderer, **kwargs)
112
113 def parse_block_math(self):
114 return self.renderer.block_math(self.token['text'])
72 115
73 116 class MyRenderer(mistune.Renderer):
74 117 def block_code(self, code, lang):
@@ -79,9 +122,16 b' class MyRenderer(mistune.Renderer):'
79 122 formatter = HtmlFormatter()
80 123 return highlight(code, lexer, formatter)
81 124
125 # Pass math through unaltered - mathjax does the rendering in the browser
126 def block_math(self, text):
127 return '$$%s$$' % text
128
129 def inline_math(self, text):
130 return '$%s$' % text
131
82 132 def markdown2html_mistune(source):
83 133 """Convert a markdown string to HTML using mistune"""
84 return mistune.Markdown(renderer=MyRenderer()).render(source)
134 return MarkdownWithMath(renderer=MyRenderer()).render(source)
85 135
86 136 def markdown2html_pandoc(source):
87 137 """Convert a markdown string to HTML via pandoc"""
@@ -114,7 +164,7 b" def markdown2html_marked(source, encoding='utf-8'):"
114 164 return out.rstrip('\n')
115 165
116 166 # The mistune renderer is the default, because it's simple to depend on it
117 markdown2html = markdown2html_mistune
167 markdown2html = markdown2html_marked
118 168
119 169 def markdown2rst(source):
120 170 """Convert a markdown string to ReST via pandoc.
General Comments 0
You need to be logged in to leave comments. Login now