diff options
Diffstat (limited to 'src/mistune/plugins/formatting.py')
-rw-r--r-- | src/mistune/plugins/formatting.py | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/mistune/plugins/formatting.py b/src/mistune/plugins/formatting.py new file mode 100644 index 0000000..57e5def --- /dev/null +++ b/src/mistune/plugins/formatting.py @@ -0,0 +1,173 @@ +import re +from ..helpers import PREVENT_BACKSLASH + +__all__ = ["strikethrough", "mark", "insert", "superscript", "subscript"] + +_STRIKE_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\~|[^\s~])~~(?!~)') +_MARK_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\=|[^\s=])==(?!=)') +_INSERT_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\\^|[^\s^])\^\^(?!\^)') + +SUPERSCRIPT_PATTERN = r'\^(?:' + PREVENT_BACKSLASH + r'\\\^|\S|\\ )+?\^' +SUBSCRIPT_PATTERN = r'~(?:' + PREVENT_BACKSLASH + r'\\~|\S|\\ )+?~' + + +def parse_strikethrough(inline, m, state): + return _parse_to_end(inline, m, state, 'strikethrough', _STRIKE_END) + + +def render_strikethrough(renderer, text): + return '<del>' + text + '</del>' + + +def parse_mark(inline, m, state): + return _parse_to_end(inline, m, state, 'mark', _MARK_END) + + +def render_mark(renderer, text): + return '<mark>' + text + '</mark>' + + +def parse_insert(inline, m, state): + return _parse_to_end(inline, m, state, 'insert', _INSERT_END) + + +def render_insert(renderer, text): + return '<ins>' + text + '</ins>' + + +def parse_superscript(inline, m, state): + return _parse_script(inline, m, state, 'superscript') + + +def render_superscript(renderer, text): + return '<sup>' + text + '</sup>' + + +def parse_subscript(inline, m, state): + return _parse_script(inline, m, state, 'subscript') + + +def render_subscript(renderer, text): + return '<sub>' + text + '</sub>' + + +def _parse_to_end(inline, m, state, tok_type, end_pattern): + pos = m.end() + m1 = end_pattern.search(state.src, pos) + if not m1: + return + end_pos = m1.end() + text = state.src[pos:end_pos-2] + new_state = state.copy() + new_state.src = text + children = inline.render(new_state) + state.append_token({'type': tok_type, 'children': children}) + return end_pos + + +def _parse_script(inline, m, state, tok_type): + text = m.group(0) + new_state = state.copy() + new_state.src = text[1:-1].replace('\\ ', ' ') + children = inline.render(new_state) + state.append_token({ + 'type': tok_type, + 'children': children + }) + return m.end() + + +def strikethrough(md): + """A mistune plugin to support strikethrough. Spec defined by + GitHub flavored Markdown and commonly used by many parsers: + + .. code-block:: text + + ~~This was mistaken text~~ + + It will be converted into HTML: + + .. code-block:: html + + <del>This was mistaken text</del> + + :param md: Markdown instance + """ + md.inline.register( + 'strikethrough', + r'~~(?=[^\s~])', + parse_strikethrough, + before='link', + ) + if md.renderer and md.renderer.NAME == 'html': + md.renderer.register('strikethrough', render_strikethrough) + + +def mark(md): + """A mistune plugin to add ``<mark>`` tag. Spec defined at + https://facelessuser.github.io/pymdown-extensions/extensions/mark/: + + .. code-block:: text + + ==mark me== ==mark \\=\\= equal== + + :param md: Markdown instance + """ + md.inline.register( + 'mark', + r'==(?=[^\s=])', + parse_mark, + before='link', + ) + if md.renderer and md.renderer.NAME == 'html': + md.renderer.register('mark', render_mark) + + +def insert(md): + """A mistune plugin to add ``<ins>`` tag. Spec defined at + https://facelessuser.github.io/pymdown-extensions/extensions/caret/#insert: + + .. code-block:: text + + ^^insert me^^ + + :param md: Markdown instance + """ + md.inline.register( + 'insert', + r'\^\^(?=[^\s\^])', + parse_insert, + before='link', + ) + if md.renderer and md.renderer.NAME == 'html': + md.renderer.register('insert', render_insert) + + +def superscript(md): + """A mistune plugin to add ``<sup>`` tag. Spec defined at + https://pandoc.org/MANUAL.html#superscripts-and-subscripts: + + .. code-block:: text + + 2^10^ is 1024. + + :param md: Markdown instance + """ + md.inline.register('superscript', SUPERSCRIPT_PATTERN, parse_superscript, before='linebreak') + if md.renderer and md.renderer.NAME == 'html': + md.renderer.register('superscript', render_superscript) + + +def subscript(md): + """A mistune plugin to add ``<sub>`` tag. Spec defined at + https://pandoc.org/MANUAL.html#superscripts-and-subscripts: + + .. code-block:: text + + H~2~O is a liquid. + + :param md: Markdown instance + """ + md.inline.register('subscript', SUBSCRIPT_PATTERN, parse_subscript, before='linebreak') + if md.renderer and md.renderer.NAME == 'html': + md.renderer.register('subscript', render_subscript) |