| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- import re
- from typing import TYPE_CHECKING, Match, Optional, Pattern
- from ..helpers import PREVENT_BACKSLASH
- if TYPE_CHECKING:
- from ..core import BaseRenderer, InlineState
- from ..inline_parser import InlineParser
- from ..markdown import Markdown
- __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: "InlineParser", m: Match[str], state: "InlineState") -> Optional[int]:
- return _parse_to_end(inline, m, state, "strikethrough", _STRIKE_END)
- def render_strikethrough(renderer: "BaseRenderer", text: str) -> str:
- return "<del>" + text + "</del>"
- def parse_mark(inline: "InlineParser", m: Match[str], state: "InlineState") -> Optional[int]:
- return _parse_to_end(inline, m, state, "mark", _MARK_END)
- def render_mark(renderer: "BaseRenderer", text: str) -> str:
- return "<mark>" + text + "</mark>"
- def parse_insert(inline: "InlineParser", m: Match[str], state: "InlineState") -> Optional[int]:
- return _parse_to_end(inline, m, state, "insert", _INSERT_END)
- def render_insert(renderer: "BaseRenderer", text: str) -> str:
- return "<ins>" + text + "</ins>"
- def parse_superscript(inline: "InlineParser", m: Match[str], state: "InlineState") -> int:
- return _parse_script(inline, m, state, "superscript")
- def render_superscript(renderer: "BaseRenderer", text: str) -> str:
- return "<sup>" + text + "</sup>"
- def parse_subscript(inline: "InlineParser", m: Match[str], state: "InlineState") -> int:
- return _parse_script(inline, m, state, "subscript")
- def render_subscript(renderer: "BaseRenderer", text: str) -> str:
- return "<sub>" + text + "</sub>"
- def _parse_to_end(
- inline: "InlineParser",
- m: Match[str],
- state: "InlineState",
- tok_type: str,
- end_pattern: Pattern[str],
- ) -> Optional[int]:
- pos = m.end()
- m1 = end_pattern.search(state.src, pos)
- if not m1:
- return None
- 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: "InlineParser", m: Match[str], state: "InlineState", tok_type: str) -> int:
- 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: "Markdown") -> None:
- """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: "Markdown") -> None:
- """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: "Markdown") -> None:
- """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: "Markdown") -> None:
- """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: "Markdown") -> None:
- """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)
|