Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ repos:
hooks:
- id: mypy
additional_dependencies: [markdown-it-py~=3.0]
exclude: ^tests/
24 changes: 18 additions & 6 deletions mdit_py_plugins/admon/index.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# Process admonitions and pass to cb.
from __future__ import annotations

from typing import Callable, List, Optional, Tuple
from typing import TYPE_CHECKING, Callable, Sequence

from markdown_it import MarkdownIt
from markdown_it.rules_block import StateBlock

from mdit_py_plugins.utils import is_code_block

if TYPE_CHECKING:
from markdown_it.renderer import RendererProtocol
from markdown_it.token import Token
from markdown_it.utils import EnvType, OptionsDict

def _get_tag(params: str) -> Tuple[str, str]:

def _get_tag(params: str) -> tuple[str, str]:
"""Separate the tag name from the admonition title."""
if not params.strip():
return "", ""
Expand Down Expand Up @@ -36,7 +42,7 @@ def _validate(params: str) -> bool:
MAX_MARKER_LEN = max(len(_m) for _m in MARKERS)


def _extra_classes(markup: str) -> List[str]:
def _extra_classes(markup: str) -> list[str]:
"""Return the list of additional classes based on the markup."""
if markup.startswith("?"):
if markup.endswith("+"):
Expand Down Expand Up @@ -158,7 +164,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
return True


def admon_plugin(md: MarkdownIt, render: Optional[Callable] = None) -> None:
def admon_plugin(md: MarkdownIt, render: None | Callable[..., str] = None) -> None:
"""Plugin to use
`python-markdown style admonitions
<https://python-markdown.github.io/extensions/admonition>`_.
Expand All @@ -181,8 +187,14 @@ def admon_plugin(md: MarkdownIt, render: Optional[Callable] = None) -> None:
<https://github.com/commenthol/markdown-it-admon>`_.
"""

def renderDefault(self, tokens, idx, _options, env):
return self.renderToken(tokens, idx, _options, env)
def renderDefault(
self: RendererProtocol,
tokens: Sequence[Token],
idx: int,
_options: OptionsDict,
env: EnvType,
) -> str:
return self.renderToken(tokens, idx, _options, env) # type: ignore

render = render or renderDefault

Expand Down
27 changes: 22 additions & 5 deletions mdit_py_plugins/amsmath/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
"""An extension to capture amsmath latex environments."""
from __future__ import annotations

import re
from typing import Callable, Optional
from typing import TYPE_CHECKING, Callable, Optional, Sequence

from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml
from markdown_it.rules_block import StateBlock

from mdit_py_plugins.utils import is_code_block

if TYPE_CHECKING:
from markdown_it.renderer import RendererProtocol
from markdown_it.token import Token
from markdown_it.utils import EnvType, OptionsDict

# Taken from amsmath version 2.1
# http://anorien.csc.warwick.ac.uk/mirrors/CTAN/macros/latex/required/amsmath/amsldoc.pdf
ENVIRONMENTS = [
Expand Down Expand Up @@ -49,7 +56,9 @@
RE_OPEN = re.compile(r"\\begin\{(" + "|".join(ENVIRONMENTS) + r")([\*]?)\}")


def amsmath_plugin(md: MarkdownIt, *, renderer: Optional[Callable[[str], str]] = None):
def amsmath_plugin(
md: MarkdownIt, *, renderer: Optional[Callable[[str], str]] = None
) -> None:
"""Parses TeX math equations, without any surrounding delimiters,
only for top-level `amsmath <https://ctan.org/pkg/amsmath>`__ environments:

Expand All @@ -72,14 +81,20 @@ def amsmath_plugin(md: MarkdownIt, *, renderer: Optional[Callable[[str], str]] =

_renderer = (lambda content: escapeHtml(content)) if renderer is None else renderer

def render_amsmath_block(self, tokens, idx, options, env):
def render_amsmath_block(
self: RendererProtocol,
tokens: Sequence[Token],
idx: int,
options: OptionsDict,
env: EnvType,
) -> str:
content = _renderer(str(tokens[idx].content))
return f'<div class="math amsmath">\n{content}\n</div>\n'

md.add_render_rule("amsmath", render_amsmath_block)


def match_environment(string):
def match_environment(string: str) -> None | tuple[str, str, int]:
match_open = RE_OPEN.match(string)
if not match_open:
return None
Expand All @@ -93,7 +108,9 @@ def match_environment(string):
return (environment, numbered, match_close.end())


def amsmath_block(state: StateBlock, startLine: int, endLine: int, silent: bool):
def amsmath_block(
state: StateBlock, startLine: int, endLine: int, silent: bool
) -> bool:
if is_code_block(state, startLine):
return False

Expand Down
10 changes: 5 additions & 5 deletions mdit_py_plugins/anchors/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def anchors_plugin(
permalinkSymbol: str = "¶",
permalinkBefore: bool = False,
permalinkSpace: bool = True,
):
) -> None:
"""Plugin for adding header anchors, based on
`markdown-it-anchor <https://github.com/valeriangalliat/markdown-it-anchor>`__

Expand Down Expand Up @@ -64,8 +64,8 @@ def _make_anchors_func(
permalinkSymbol: str,
permalinkBefore: bool,
permalinkSpace: bool,
):
def _anchor_func(state: StateCore):
) -> Callable[[StateCore], None]:
def _anchor_func(state: StateCore) -> None:
slugs: Set[str] = set()
for idx, token in enumerate(state.tokens):
if token.type != "heading_open":
Expand Down Expand Up @@ -115,11 +115,11 @@ def _anchor_func(state: StateCore):
return _anchor_func


def slugify(title: str):
def slugify(title: str) -> str:
return re.sub(r"[^\w\u4e00-\u9fff\- ]", "", title.strip().lower().replace(" ", "-"))


def unique_slug(slug: str, slugs: set):
def unique_slug(slug: str, slugs: Set[str]) -> str:
uniq = slug
i = 1
while uniq in slugs:
Expand Down
18 changes: 9 additions & 9 deletions mdit_py_plugins/attrs/index.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Optional
from typing import List, Optional, Sequence

from markdown_it import MarkdownIt
from markdown_it.rules_block import StateBlock
Expand All @@ -14,10 +14,10 @@
def attrs_plugin(
md: MarkdownIt,
*,
after=("image", "code_inline", "link_close", "span_close"),
spans=False,
span_after="link",
):
after: Sequence[str] = ("image", "code_inline", "link_close", "span_close"),
spans: bool = False,
span_after: str = "link",
) -> None:
"""Parse inline attributes that immediately follow certain inline elements::

![alt](https://image.com){#id .a b=c}
Expand Down Expand Up @@ -50,7 +50,7 @@ def attrs_plugin(
:param span_after: The name of an inline rule after which spans may be specified.
"""

def _attr_inline_rule(state: StateInline, silent: bool):
def _attr_inline_rule(state: StateInline, silent: bool) -> bool:
if state.pending or not state.tokens:
return False
token = state.tokens[-1]
Expand All @@ -77,7 +77,7 @@ def _attr_inline_rule(state: StateInline, silent: bool):
md.inline.ruler.push("attr", _attr_inline_rule)


def attrs_block_plugin(md: MarkdownIt):
def attrs_block_plugin(md: MarkdownIt) -> None:
"""Parse block attributes.

Block attributes are attributes on a single line, with no other content.
Expand Down Expand Up @@ -111,7 +111,7 @@ def _find_opening(tokens: List[Token], index: int) -> Optional[int]:
return None


def _span_rule(state: StateInline, silent: bool):
def _span_rule(state: StateInline, silent: bool) -> bool:
if state.src[state.pos] != "[":
return False

Expand Down Expand Up @@ -197,7 +197,7 @@ def _attr_block_rule(
return True


def _attr_resolve_block_rule(state: StateCore):
def _attr_resolve_block_rule(state: StateCore) -> None:
"""Find attribute block then move its attributes to the next block."""
i = 0
len_tokens = len(state.tokens)
Expand Down
6 changes: 3 additions & 3 deletions mdit_py_plugins/attrs/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ class State(Enum):


class TokenState:
def __init__(self):
self._tokens = []
def __init__(self) -> None:
self._tokens: list[tuple[int, int, str]] = []
self.start: int = 0

def set_start(self, start: int) -> None:
self.start = start

def append(self, start: int, end: int, ttype: str):
def append(self, start: int, end: int, ttype: str) -> None:
self._tokens.append((start, end, ttype))

def compile(self, string: str) -> dict[str, str]:
Expand Down
21 changes: 18 additions & 3 deletions mdit_py_plugins/colon_fence.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Sequence

from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml, unescapeAll
from markdown_it.rules_block import StateBlock

from mdit_py_plugins.utils import is_code_block

if TYPE_CHECKING:
from markdown_it.renderer import RendererProtocol
from markdown_it.token import Token
from markdown_it.utils import EnvType, OptionsDict


def colon_fence_plugin(md: MarkdownIt):
def colon_fence_plugin(md: MarkdownIt) -> None:
"""This plugin directly mimics regular fences, but with `:` colons.

Example::
Expand All @@ -25,7 +34,7 @@ def colon_fence_plugin(md: MarkdownIt):
md.add_render_rule("colon_fence", _render)


def _rule(state: StateBlock, startLine: int, endLine: int, silent: bool):
def _rule(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
if is_code_block(state, startLine):
return False

Expand Down Expand Up @@ -126,7 +135,13 @@ def _skipCharsStr(state: StateBlock, pos: int, ch: str) -> int:
return pos


def _render(self, tokens, idx, options, env):
def _render(
self: RendererProtocol,
tokens: Sequence[Token],
idx: int,
options: OptionsDict,
env: EnvType,
) -> str:
token = tokens[idx]
info = unescapeAll(token.info).strip() if token.info else ""
content = escapeHtml(token.content)
Expand Down
31 changes: 23 additions & 8 deletions mdit_py_plugins/container/index.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
"""Process block-level custom containers."""
from __future__ import annotations

from math import floor
from typing import Callable, Optional
from typing import TYPE_CHECKING, Any, Callable, Sequence

from markdown_it import MarkdownIt
from markdown_it.rules_block import StateBlock

from mdit_py_plugins.utils import is_code_block

if TYPE_CHECKING:
from markdown_it.renderer import RendererProtocol
from markdown_it.token import Token
from markdown_it.utils import EnvType, OptionsDict


def container_plugin(
md: MarkdownIt,
name: str,
marker: str = ":",
validate: Optional[Callable[[str, str], bool]] = None,
render=None,
):
validate: None | Callable[[str, str], bool] = None,
render: None | Callable[..., str] = None,
) -> None:
"""Plugin ported from
`markdown-it-container <https://github.com/markdown-it/markdown-it-container>`__.

Expand All @@ -35,15 +42,21 @@ def container_plugin(

"""

def validateDefault(params: str, *args):
def validateDefault(params: str, *args: Any) -> bool:
return params.strip().split(" ", 2)[0] == name

def renderDefault(self, tokens, idx, _options, env):
def renderDefault(
self: RendererProtocol,
tokens: Sequence[Token],
idx: int,
_options: OptionsDict,
env: EnvType,
) -> str:
# add a class to the opening tag
if tokens[idx].nesting == 1:
tokens[idx].attrJoin("class", name)

return self.renderToken(tokens, idx, _options, env)
return self.renderToken(tokens, idx, _options, env) # type: ignore

min_markers = 3
marker_str = marker
Expand All @@ -52,7 +65,9 @@ def renderDefault(self, tokens, idx, _options, env):
validate = validate or validateDefault
render = render or renderDefault

def container_func(state: StateBlock, startLine: int, endLine: int, silent: bool):
def container_func(
state: StateBlock, startLine: int, endLine: int, silent: bool
) -> bool:
if is_code_block(state, startLine):
return False

Expand Down
8 changes: 4 additions & 4 deletions mdit_py_plugins/deflist/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from mdit_py_plugins.utils import is_code_block


def deflist_plugin(md: MarkdownIt):
def deflist_plugin(md: MarkdownIt) -> None:
"""Plugin ported from
`markdown-it-deflist <https://github.com/markdown-it/markdown-it-deflist>`__.

Expand All @@ -25,7 +25,7 @@ def deflist_plugin(md: MarkdownIt):

"""

def skipMarker(state: StateBlock, line: int):
def skipMarker(state: StateBlock, line: int) -> int:
"""Search `[:~][\n ]`, returns next pos after marker on success or -1 on fail."""
start = state.bMarks[line] + state.tShift[line]
maximum = state.eMarks[line]
Expand All @@ -51,7 +51,7 @@ def skipMarker(state: StateBlock, line: int):

return start

def markTightParagraphs(state: StateBlock, idx: int):
def markTightParagraphs(state: StateBlock, idx: int) -> None:
level = state.level + 2

i = idx + 2
Expand All @@ -66,7 +66,7 @@ def markTightParagraphs(state: StateBlock, idx: int):
i += 2
i += 1

def deflist(state: StateBlock, startLine: int, endLine: int, silent: bool):
def deflist(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
if is_code_block(state, startLine):
return False

Expand Down
Loading