diff --git a/lib/markdown2.py b/lib/markdown2.py index 380b36d3..42a1518c 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2764,6 +2764,55 @@ def sub(self, match): def run(self, text): return self.fenced_code_block_re.sub(self.sub, text) +class Latex(Extra): + ''' + Convert $ and $$ to tags for inline and block math. + ''' + name = 'latex' + order = (Stage.CODE_BLOCKS, FencedCodeBlocks), () + + _single_dollar_re = re.compile(r'(?(.*?)", re.DOTALL) # Wraped in
+ _triple_re = re.compile(r'```(.*?)```', re.DOTALL) # Wrapped in a code block ``` + _single_re = re.compile(r'(?" + self.code_blocks[placeholder] = match.group(0) + return placeholder + + def run(self, text): + try: + import latex2mathml.converter + self.converter = latex2mathml.converter + except ImportError: + raise ImportError('The "latex" extra requires the "latex2mathml" package to be installed.') + + # Escape by replacing with a code block + text = self._pre_code_block_re.sub(self.code_placeholder, text) + text = self._single_re.sub(self.code_placeholder, text) + text = self._triple_re.sub(self.code_placeholder, text) + + text = self._single_dollar_re.sub(self._convert_single_match, text) + text = self._double_dollar_re.sub(self._convert_double_match, text) + + # Convert placeholder tag back to original code + for placeholder, code_block in self.code_blocks.items(): + text = text.replace(placeholder, code_block) + + return text class LinkPatterns(Extra): ''' @@ -3328,6 +3377,7 @@ def test(self, text): Breaks.register() CodeFriendly.register() FencedCodeBlocks.register() +Latex.register() LinkPatterns.register() MarkdownInHTML.register() MiddleWordEm.register() diff --git a/setup.py b/setup.py index 9962f64a..72cc5ef8 100755 --- a/setup.py +++ b/setup.py @@ -33,7 +33,8 @@ extras_require = { "code_syntax_highlighting": ["pygments>=2.7.3"], - "wavedrom": ["wavedrom; python_version>='3.7'"] + "wavedrom": ["wavedrom; python_version>='3.7'"], + "latex": ['latex2mathml; python_version>="3.8.1"'], } # nested listcomp to combine all optional extras into convenient "all" option extras_require["all"] = [i for v in tuple(extras_require.values()) for i in v] diff --git a/test/test.py b/test/test.py index 8cdf3a89..871cd2e1 100755 --- a/test/test.py +++ b/test/test.py @@ -38,7 +38,7 @@ def setup(): setup() default_tags = [] warnings = [] - for extra_lib in ('pygments', 'wavedrom'): + for extra_lib in ('pygments', 'wavedrom', 'latex2mathml'): try: mod = importlib.import_module(extra_lib) except ImportError: diff --git a/test/tm-cases/latex.html b/test/tm-cases/latex.html new file mode 100644 index 00000000..b91fd4b9 --- /dev/null +++ b/test/tm-cases/latex.html @@ -0,0 +1,18 @@ +Simple Test
+ +Inline Equations can be written as . +Block equations are wrapped using
+ + + +This code block will not have the math rendered. +
+ ++some random code, describing $a and $b will not be rendered, $y=mx$ +
+This will not work either$\sqrt{2}
ordiff --git a/test/tm-cases/latex.opts b/test/tm-cases/latex.opts new file mode 100644 index 00000000..627b9f1f --- /dev/null +++ b/test/tm-cases/latex.opts @@ -0,0 +1 @@ +{"extras": ["latex","latex2mathml"]} \ No newline at end of file diff --git a/test/tm-cases/latex.tags b/test/tm-cases/latex.tags new file mode 100644 index 00000000..b39d550d --- /dev/null +++ b/test/tm-cases/latex.tags @@ -0,0 +1 @@ +extra latex latex2mathml \ No newline at end of file diff --git a/test/tm-cases/latex.text b/test/tm-cases/latex.text new file mode 100644 index 00000000..92a9bf29 --- /dev/null +++ b/test/tm-cases/latex.text @@ -0,0 +1,17 @@ +## Simple Test +Inline Equations can be written as $y=mx+b$. +Block equations are wrapped using +$$ +x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} +$$ +This code block will not have the math rendered. +``` +some random code, describing $a and $b will not be rendered, $y=mx$ +``` +This will not work either `$\sqrt{2}` or + +``` +$$ +f = 12 +$$ +``` \ No newline at end of file
+$$ +f = 12 +$$ +