diff --git a/mistune_contrib/math.py b/mistune_contrib/math.py index 6588080..e52b387 100644 --- a/mistune_contrib/math.py +++ b/mistune_contrib/math.py @@ -9,6 +9,60 @@ :copyright: (c) 2014 by Hsiaoming Yang. """ + +""" + Usage: define your own block-lexer, inline-lexer, markdown engine and + renderer to customize math rendering. + + from mistune import Markdown + from mistune import BlockLexer + from mistune import InlineLexer + from mistune import Renderer + + class MathBlockLexer(MathBlockMixin, BlockLexer): + def __init__(self, *args, **kwargs): + super(MathBlockLexer, self).__init__(*args, **kwargs) + self.enable_math() + + + class MathInlineLexer(InlineLexer, MathInlineMixin): + def __init__(self, *args, **kwargs): + super(MathInlineLexer, self).__init__(*args, **kwargs) + self.enable_math() + + + class MathRenderer(Renderer, MathRendererMixin): + pass + + + class MathMarkdown(Markdown, MathMarkdownMixin): + pass + + render = MathRenderer() + md = MathMarkdown(render, + inline=MathInlineLexer(render), + block=MathBlockLexer + ) + + print md(''' + block math: + + $$ + y = x^2 + $$ + + inline math: $ y = \\frac{1}{x} $''') + + # output: + #

block math:

+ # + # $$ this is my math: + # y = x^2 + # $$ + #

inline math: $ this is my math: y = \frac{1}{x} $

+""" + + import re @@ -25,7 +79,12 @@ def enable_math(self): self.rules.block_latex = re.compile( r'^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}', re.DOTALL ) - self.default_rules.extend(['block_math', 'block_latex']) + + # block_math must come before paragraph, or it is rendered as a normal paragraph + rs = self.default_rules + i = rs.index('paragraph') + rs.insert(i, 'block_latex') + rs.insert(i, 'block_math') def parse_block_math(self, m): """Parse a $$math$$ block""" @@ -42,6 +101,23 @@ def parse_block_latex(self, m): }) + +class MathMarkdownMixin(object): + + # block level token requires a output_* function + def output_block_math(self): + body = '\n' + body += self.renderer.block_math(self.token['text']) + body += '\n' + return body + + def output_block_latex(self): + body = '\n' + body += self.renderer.block_latex(self.token['name'], + self.token['text']) + body += '\n' + return body + class MathInlineMixin(object): """Math mixin for InlineLexer, mix this with InlineLexer:: @@ -62,10 +138,13 @@ def output_math(self, m): class MathRendererMixin(object): def block_math(self, text): - return '$$%s$$' % text + # override with customized math rendering + return '$$ math-renderer-mixin-block: %s$$' % text def block_latex(self, name, text): - return r'\begin{%s}%s\end{%s}' % (name, text, name) + # override with customized math rendering + return r' math-renderer-mixin-latex: \begin{%s}%s\end{%s}' % (name, text, name) def math(self, text): - return '$%s$' % text + # override with customized math rendering + return '$ math-renderer-mixin-inline: %s$' % text diff --git a/tests/test_math.py b/tests/test_math.py index 9202159..7dd64cd 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -1,3 +1,9 @@ +from mistune import Markdown +from mistune import BlockLexer +from mistune import InlineLexer +from mistune import Renderer +from mistune_contrib import math + MIXED_CASE = '''The entries of $C$ are given by the exact formula: $$ C_{ik} = \sum_{j=1}^n A_{ij} B_{jk} @@ -43,3 +49,57 @@ def test_mixed(): def test_paragraph(): pass + +class MathBlockLexer(math.MathBlockMixin, BlockLexer): + def __init__(self, *args, **kwargs): + super(MathBlockLexer, self).__init__(*args, **kwargs) + self.enable_math() + +class MathInlineLexer(InlineLexer, math.MathInlineMixin): + def __init__(self, *args, **kwargs): + super(MathInlineLexer, self).__init__(*args, **kwargs) + self.enable_math() + +class MathRenderer(Renderer, math.MathRendererMixin): + pass + +class MathMarkdown(Markdown, math.MathMarkdownMixin): + pass + +def test_block_math(): + + md = MathMarkdown(MathRenderer(), + block=MathBlockLexer) + + res = md(''' +$$ +y = x^2 +$$ +''') + + assert 'math-renderer-mixin-block' in res + +def test_inline_math(): + + r = MathRenderer() + md = MathMarkdown(r, + inline=MathInlineLexer(r)) + + res = md('foo: $ y = x^2 $') + + assert 'math-renderer-mixin-inline' in res + +def test_latex_math(): + + md = MathMarkdown(MathRenderer(), + block=MathBlockLexer) + + res = md(''' +\\begin{foo} +y = x^2 +\\end{foo} +''') + + print res + + assert 'math-renderer-mixin-latex' in res