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 |
|
|
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_m |
|
|
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