Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-mdit-py-plugins for openSUSE:Factory checked in at 2024-07-01 11:21:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-mdit-py-plugins (Old) and /work/SRC/openSUSE:Factory/.python-mdit-py-plugins.new.18349 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-mdit-py-plugins" Mon Jul 1 11:21:46 2024 rev:5 rq:1184138 version:0.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-mdit-py-plugins/python-mdit-py-plugins.changes 2023-11-23 21:38:35.758955897 +0100 +++ /work/SRC/openSUSE:Factory/.python-mdit-py-plugins.new.18349/python-mdit-py-plugins.changes 2024-07-01 11:22:37.399979217 +0200 @@ -1,0 +2,6 @@ +Sun Jun 30 20:34:50 UTC 2024 - Dirk Müller <dmueller@suse.com> + +- update to 0.4.1: + * Add option for footnotes references to always be matched + +------------------------------------------------------------------- Old: ---- python-mdit-py-plugins-0.4.0.tar.gz New: ---- python-mdit-py-plugins-0.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-mdit-py-plugins.spec ++++++ --- /var/tmp/diff_new_pack.gpggFw/_old 2024-07-01 11:22:37.951999196 +0200 +++ /var/tmp/diff_new_pack.gpggFw/_new 2024-07-01 11:22:37.951999196 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-mdit-py-plugins # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-mdit-py-plugins -Version: 0.4.0 +Version: 0.4.1 Release: 0 Summary: Collection of plugins for markdown-it-py License: MIT ++++++ python-mdit-py-plugins-0.4.0.tar.gz -> python-mdit-py-plugins-0.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/.coveragerc new/mdit-py-plugins-0.4.1/.coveragerc --- old/mdit-py-plugins-0.4.0/.coveragerc 1970-01-01 01:00:00.000000000 +0100 +++ new/mdit-py-plugins-0.4.1/.coveragerc 2024-05-12 22:13:45.000000000 +0200 @@ -0,0 +1,4 @@ +[report] +exclude_lines = + pragma: no cover + if TYPE_CHECKING: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/.github/workflows/tests.yml new/mdit-py-plugins-0.4.1/.github/workflows/tests.yml --- old/mdit-py-plugins-0.4.0/.github/workflows/tests.yml 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/.github/workflows/tests.yml 2024-05-12 22:13:45.000000000 +0200 @@ -17,12 +17,12 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.8 - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 tests: @@ -30,12 +30,12 @@ strategy: fail-fast: false matrix: - python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11'] + python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -48,6 +48,7 @@ - name: Upload to Codecov uses: codecov/codecov-action@v3 with: + token: ${{ secrets.CODECOV_TOKEN }} name: mdit-py-plugins-pytests flags: pytests file: ./coverage.xml @@ -69,9 +70,9 @@ runs-on: ubuntu-latest steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.8" - name: install flit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/.pre-commit-config.yaml new/mdit-py-plugins-0.4.1/.pre-commit-config.yaml --- old/mdit-py-plugins-0.4.0/.pre-commit-config.yaml 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/.pre-commit-config.yaml 2024-05-12 22:13:45.000000000 +0200 @@ -12,30 +12,22 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: check-json - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.4 hooks: - - id: isort - - - repo: https://github.com/psf/black - rev: 23.3.0 - hooks: - - id: black - - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.270 - hooks: - - id: ruff + - id: ruff + args: [--fix] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 + rev: v1.10.0 hooks: - id: mypy additional_dependencies: [markdown-it-py~=3.0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/.readthedocs.yml new/mdit-py-plugins-0.4.1/.readthedocs.yml --- old/mdit-py-plugins-0.4.0/.readthedocs.yml 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/.readthedocs.yml 2024-05-12 22:13:45.000000000 +0200 @@ -1,7 +1,11 @@ version: 2 +build: + os: ubuntu-22.04 + tools: + python: "3.8" + python: - version: "3.8" install: - method: pip path: . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/CHANGELOG.md new/mdit-py-plugins-0.4.1/CHANGELOG.md --- old/mdit-py-plugins-0.4.0/CHANGELOG.md 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/CHANGELOG.md 2024-05-12 22:13:45.000000000 +0200 @@ -1,5 +1,11 @@ # Change Log +## 0.4.1 - 2024-05-12 + +* 👌 Add option for footnotes references to always be matched + + Usually footnote references are only matched when a footnote definition of the same label has already been found. If `always_match_refs=True`, any `[^...]` syntax will be treated as a footnote. + ## 0.4.0 - 2023-06-05 * ⬆️ UPGRADE: Drop python 3.7 and support 3.11 ([#77](https://github.com/executablebooks/mdit-py-plugins/pull/77)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1 @@ -__version__ = "0.4.0" +__version__ = "0.4.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/admon/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/admon/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/admon/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/admon/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import admon_plugin # noqa: F401 +from .index import admon_plugin + +__all__ = ("admon_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/admon/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/admon/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/admon/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/admon/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,6 +1,9 @@ # Process admonitions and pass to cb. + from __future__ import annotations +from contextlib import suppress +import re from typing import TYPE_CHECKING, Callable, Sequence from markdown_it import MarkdownIt @@ -14,20 +17,34 @@ from markdown_it.utils import EnvType, OptionsDict -def _get_tag(params: str) -> tuple[str, str]: +def _get_multiple_tags(params: str) -> tuple[list[str], str]: + """Check for multiple tags when the title is double quoted.""" + re_tags = re.compile(r'^\s*(?P<tokens>[^"]+)\s+"(?P<title>.*)"\S*$') + match = re_tags.match(params) + if match: + tags = match["tokens"].strip().split(" ") + return [tag.lower() for tag in tags], match["title"] + raise ValueError("No match found for parameters") + + +def _get_tag(_params: str) -> tuple[list[str], str]: """Separate the tag name from the admonition title.""" - if not params.strip(): - return "", "" + params = _params.strip() + if not params: + return [""], "" + + with suppress(ValueError): + return _get_multiple_tags(params) - tag, *_title = params.strip().split(" ") + tag, *_title = params.split(" ") joined = " ".join(_title) title = "" if not joined: title = tag.title() - elif joined != '""': + elif joined != '""': # Specifically check for no title title = joined - return tag.lower(), title + return [tag.lower()], title def _validate(params: str) -> bool: @@ -125,12 +142,13 @@ # this will prevent lazy continuations from ever going past our end marker state.lineMax = next_line - tag, title = _get_tag(params) + tags, title = _get_tag(params) + tag = tags[0] token = state.push("admonition_open", "div", 1) token.markup = markup token.block = True - token.attrs = {"class": " ".join(["admonition", tag, *_extra_classes(markup)])} + token.attrs = {"class": " ".join(["admonition", *tags, *_extra_classes(markup)])} token.meta = {"tag": tag} token.content = title token.info = params @@ -194,7 +212,7 @@ _options: OptionsDict, env: EnvType, ) -> str: - return self.renderToken(tokens, idx, _options, env) # type: ignore + return self.renderToken(tokens, idx, _options, env) # type: ignore[attr-defined,no-any-return] render = render or renderDefault diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/amsmath/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/amsmath/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/amsmath/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/amsmath/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,8 +1,9 @@ """An extension to capture amsmath latex environments.""" + from __future__ import annotations import re -from typing import TYPE_CHECKING, Callable, Optional, Sequence +from typing import TYPE_CHECKING, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml @@ -57,7 +58,7 @@ def amsmath_plugin( - md: MarkdownIt, *, renderer: Optional[Callable[[str], str]] = None + md: MarkdownIt, *, renderer: Callable[[str], str] | None = None ) -> None: """Parses TeX math equations, without any surrounding delimiters, only for top-level `amsmath <https://ctan.org/pkg/amsmath>`__ environments: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/anchors/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/anchors/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/anchors/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/anchors/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import anchors_plugin # noqa F401 +from .index import anchors_plugin + +__all__ = ("anchors_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import attrs_block_plugin, attrs_plugin # noqa: F401 +from .index import attrs_block_plugin, attrs_plugin + +__all__ = ("attrs_block_plugin", "attrs_plugin") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -140,7 +140,7 @@ state.pos = labelStart state.posMax = labelEnd token = state.push("span_open", "span", 1) - token.attrs = attrs # type: ignore + token.attrs = attrs # type: ignore[assignment] state.md.inline.tokenize(state) token = state.push("span_close", "span", -1) @@ -190,7 +190,7 @@ return True token = state.push("attrs_block", "", 0) - token.attrs = attrs # type: ignore + token.attrs = attrs # type: ignore[assignment] token.map = [startLine, startLine + 1] state.line = startLine + 1 @@ -211,9 +211,9 @@ # classes are appended if "class" in state.tokens[i].attrs and "class" in next_token.attrs: - state.tokens[i].attrs[ - "class" - ] = f"{state.tokens[i].attrs['class']} {next_token.attrs['class']}" + state.tokens[i].attrs["class"] = ( + f"{state.tokens[i].attrs['class']} {next_token.attrs['class']}" + ) if next_token.type == "attrs_block": # subsequent attribute blocks take precedence, when merging diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/parse.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/parse.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/attrs/parse.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/attrs/parse.py 2024-05-12 22:13:45.000000000 +0200 @@ -19,6 +19,7 @@ bareval <- (ASCII_ALPHANUM | ':' | '_' | '-')+ quotedval <- '"' ([^"] | '\"') '"' """ + from __future__ import annotations from enum import Enum diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/container/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/container/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/container/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/container/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import container_plugin # noqa F401 +from .index import container_plugin + +__all__ = ("container_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/container/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/container/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/container/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/container/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,4 +1,5 @@ """Process block-level custom containers.""" + from __future__ import annotations from math import floor @@ -56,7 +57,7 @@ if tokens[idx].nesting == 1: tokens[idx].attrJoin("class", name) - return self.renderToken(tokens, idx, _options, env) # type: ignore + return self.renderToken(tokens, idx, _options, env) # type: ignore[attr-defined,no-any-return] min_markers = 3 marker_str = marker diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/deflist/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/deflist/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/deflist/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/deflist/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import deflist_plugin # noqa F401 +from .index import deflist_plugin + +__all__ = ("deflist_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/deflist/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/deflist/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/deflist/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/deflist/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,4 +1,5 @@ """Process definition lists.""" + from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/dollarmath/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/dollarmath/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/dollarmath/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/dollarmath/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import dollarmath_plugin # noqa F401 +from .index import dollarmath_plugin + +__all__ = ("dollarmath_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/dollarmath/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/dollarmath/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/dollarmath/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/dollarmath/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,7 +1,7 @@ from __future__ import annotations import re -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Sequence +from typing import TYPE_CHECKING, Any, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml, isWhiteSpace @@ -24,9 +24,9 @@ allow_digits: bool = True, allow_blank_lines: bool = True, double_inline: bool = False, - label_normalizer: Optional[Callable[[str], str]] = None, - renderer: Optional[Callable[[str, Dict[str, Any]], str]] = None, - label_renderer: Optional[Callable[[str], str]] = None, + label_normalizer: Callable[[str], str] | None = None, + renderer: Callable[[str, dict[str, Any]], str] | None = None, + label_renderer: Callable[[str], str] | None = None, ) -> None: """Plugin for parsing dollar enclosed math, e.g. inline: ``$a=1$``, block: ``$$b=2$$`` @@ -53,7 +53,7 @@ """ if label_normalizer is None: - label_normalizer = lambda label: re.sub(r"\s+", "-", label) + label_normalizer = lambda label: re.sub(r"\s+", "-", label) # noqa: E731 md.inline.ruler.before( "escape", @@ -76,8 +76,8 @@ _label_renderer: Callable[[str], str] if label_renderer is None: - _label_renderer = ( - lambda label: f'<a href="#{label}" class="mathlabel" title="Permalink to this equation">¶</a>' # noqa: E501 + _label_renderer = ( # noqa: E731 + lambda label: f'<a href="#{label}" class="mathlabel" title="Permalink to this equation">¶</a>' ) else: _label_renderer = label_renderer @@ -286,7 +286,7 @@ def math_block_dollar( allow_labels: bool = True, - label_normalizer: Optional[Callable[[str], str]] = None, + label_normalizer: Callable[[str], str] | None = None, allow_blank_lines: bool = False, ) -> Callable[[StateBlock, int, int, bool], bool]: """Generate block dollar rule.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/field_list/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/field_list/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/field_list/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/field_list/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,4 +1,5 @@ """Field list plugin""" + from contextlib import contextmanager from typing import Iterator, Optional, Tuple @@ -176,7 +177,7 @@ has_first_line = contentStart < maximum if block_indent is None: # no body content - if not has_first_line: # noqa SIM108 + if not has_first_line: # noqa: SIM108 # no body or first line, so just use default block_indent = 2 else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/footnote/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/footnote/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/footnote/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/footnote/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import footnote_plugin # noqa: F401 +from .index import footnote_plugin + +__all__ = ("footnote_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/footnote/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/footnote/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/footnote/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/footnote/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,7 +1,9 @@ """Process footnotes""" + from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Sequence +from functools import partial +from typing import TYPE_CHECKING, Sequence, TypedDict from markdown_it import MarkdownIt from markdown_it.helpers import parseLinkLabel @@ -17,7 +19,13 @@ from markdown_it.utils import EnvType, OptionsDict -def footnote_plugin(md: MarkdownIt) -> None: +def footnote_plugin( + md: MarkdownIt, + *, + inline: bool = True, + move_to_end: bool = True, + always_match_refs: bool = False, +) -> None: """Plugin ported from `markdown-it-footnote <https://github.com/markdown-it/markdown-it-footnote>`__. @@ -37,13 +45,22 @@ Subsequent paragraphs are indented to show that they belong to the previous footnote. + :param inline: If True, also parse inline footnotes (^[...]). + :param move_to_end: If True, move footnote definitions to the end of the token stream. + :param always_match_refs: If True, match references, even if the footnote is not defined. + """ md.block.ruler.before( "reference", "footnote_def", footnote_def, {"alt": ["paragraph", "reference"]} ) - md.inline.ruler.after("image", "footnote_inline", footnote_inline) - md.inline.ruler.after("footnote_inline", "footnote_ref", footnote_ref) - md.core.ruler.after("inline", "footnote_tail", footnote_tail) + _footnote_ref = partial(footnote_ref, always_match=always_match_refs) + if inline: + md.inline.ruler.after("image", "footnote_inline", footnote_inline) + md.inline.ruler.after("footnote_inline", "footnote_ref", _footnote_ref) + else: + md.inline.ruler.after("image", "footnote_ref", _footnote_ref) + if move_to_end: + md.core.ruler.after("inline", "footnote_tail", footnote_tail) md.add_render_rule("footnote_ref", render_footnote_ref) md.add_render_rule("footnote_block_open", render_footnote_block_open) @@ -57,6 +74,29 @@ md.add_render_rule("footnote_anchor_name", render_footnote_anchor_name) +class _RefData(TypedDict, total=False): + # standard + label: str + count: int + # inline + content: str + tokens: list[Token] + + +class _FootnoteData(TypedDict): + refs: dict[str, int] + """A mapping of all footnote labels (prefixed with ``:``) to their ID (-1 if not yet set).""" + list: dict[int, _RefData] + """A mapping of all footnote IDs to their data.""" + + +def _data_from_env(env: EnvType) -> _FootnoteData: + footnotes = env.setdefault("footnotes", {}) + footnotes.setdefault("refs", {}) + footnotes.setdefault("list", {}) + return footnotes # type: ignore[no-any-return] + + # ## RULES ## @@ -96,7 +136,8 @@ pos += 1 label = state.src[start + 2 : pos - 2] - state.env.setdefault("footnotes", {}).setdefault("refs", {})[":" + label] = -1 + footnote_data = _data_from_env(state.env) + footnote_data["refs"][":" + label] = -1 open_token = Token("footnote_reference_open", "", 1) open_token.meta = {"label": label} @@ -181,10 +222,10 @@ # so all that's left to do is to call tokenizer. # if not silent: - refs = state.env.setdefault("footnotes", {}).setdefault("list", {}) + refs = _data_from_env(state.env)["list"] footnoteId = len(refs) - tokens: List[Token] = [] + tokens: list[Token] = [] state.md.inline.parse( state.src[labelStart:labelEnd], state.md, state.env, tokens ) @@ -199,7 +240,9 @@ return True -def footnote_ref(state: StateInline, silent: bool) -> bool: +def footnote_ref( + state: StateInline, silent: bool, *, always_match: bool = False +) -> bool: """Process footnote references ([^...])""" maximum = state.posMax @@ -209,7 +252,9 @@ if start + 3 > maximum: return False - if "footnotes" not in state.env or "refs" not in state.env["footnotes"]: + footnote_data = _data_from_env(state.env) + + if not (always_match or footnote_data["refs"]): return False if state.src[start] != "[": return False @@ -218,9 +263,7 @@ pos = start + 2 while pos < maximum: - if state.src[pos] == " ": - return False - if state.src[pos] == "\n": + if state.src[pos] in (" ", "\n"): return False if state.src[pos] == "]": break @@ -233,22 +276,19 @@ pos += 1 label = state.src[start + 2 : pos - 1] - if (":" + label) not in state.env["footnotes"]["refs"]: + if ((":" + label) not in footnote_data["refs"]) and not always_match: return False if not silent: - if "list" not in state.env["footnotes"]: - state.env["footnotes"]["list"] = {} - - if state.env["footnotes"]["refs"][":" + label] < 0: - footnoteId = len(state.env["footnotes"]["list"]) - state.env["footnotes"]["list"][footnoteId] = {"label": label, "count": 0} - state.env["footnotes"]["refs"][":" + label] = footnoteId + if footnote_data["refs"].get(":" + label, -1) < 0: + footnoteId = len(footnote_data["list"]) + footnote_data["list"][footnoteId] = {"label": label, "count": 0} + footnote_data["refs"][":" + label] = footnoteId else: - footnoteId = state.env["footnotes"]["refs"][":" + label] + footnoteId = footnote_data["refs"][":" + label] - footnoteSubId = state.env["footnotes"]["list"][footnoteId]["count"] - state.env["footnotes"]["list"][footnoteId]["count"] += 1 + footnoteSubId = footnote_data["list"][footnoteId]["count"] + footnote_data["list"][footnoteId]["count"] += 1 token = state.push("footnote_ref", "", 0) token.meta = {"id": footnoteId, "subId": footnoteSubId, "label": label} @@ -270,7 +310,7 @@ if "footnotes" not in state.env: return - current: List[Token] = [] + current: list[Token] = [] tok_filter = [] for tok in state.tokens: if tok.type == "footnote_reference_open": @@ -290,18 +330,18 @@ if insideRef: current.append(tok) - tok_filter.append((not insideRef)) + tok_filter.append(not insideRef) state.tokens = [t for t, f in zip(state.tokens, tok_filter) if f] - if "list" not in state.env.get("footnotes", {}): + footnote_data = _data_from_env(state.env) + if not footnote_data["list"]: return - foot_list = state.env["footnotes"]["list"] token = Token("footnote_block_open", "", 1) state.tokens.append(token) - for i, foot_note in foot_list.items(): + for i, foot_note in footnote_data["list"].items(): token = Token("footnote_open", "", 1) token.meta = {"id": i, "label": foot_note.get("label", None)} # TODO propagate line positions of original foot note @@ -325,11 +365,11 @@ tokens.append(token) elif "label" in foot_note: - tokens = refTokens[":" + foot_note["label"]] + tokens = refTokens.get(":" + foot_note["label"], []) state.tokens.extend(tokens) if state.tokens[len(state.tokens) - 1].type == "paragraph_close": - lastParagraph: Optional[Token] = state.tokens.pop() + lastParagraph: Token | None = state.tokens.pop() else: lastParagraph = None @@ -482,4 +522,4 @@ ident += ":" + str(tokens[idx].meta["subId"]) # ↩ with escape code to prevent display as Apple Emoji on iOS - return ' <a href="#fnref' + ident + '" class="footnote-backref">\u21a9\uFE0E</a>' + return ' <a href="#fnref' + ident + '" class="footnote-backref">\u21a9\ufe0e</a>' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/front_matter/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/front_matter/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/front_matter/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/front_matter/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import front_matter_plugin # noqa: F401 +from .index import front_matter_plugin + +__all__ = ("front_matter_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/front_matter/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/front_matter/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/front_matter/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/front_matter/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -1,4 +1,5 @@ """Process front matter.""" + from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/myst_blocks/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/myst_blocks/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/myst_blocks/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/myst_blocks/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import myst_block_plugin # noqa: F401 +from .index import myst_block_plugin + +__all__ = ("myst_block_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/myst_role/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/myst_role/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/myst_role/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/myst_role/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import myst_role_plugin # noqa: F401 +from .index import myst_role_plugin + +__all__ = ("myst_role_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/texmath/__init__.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/texmath/__init__.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/texmath/__init__.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/texmath/__init__.py 2024-05-12 22:13:45.000000000 +0200 @@ -1 +1,3 @@ -from .index import texmath_plugin # noqa F401 +from .index import texmath_plugin + +__all__ = ("texmath_plugin",) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/mdit_py_plugins/texmath/index.py new/mdit-py-plugins-0.4.1/mdit_py_plugins/texmath/index.py --- old/mdit-py-plugins-0.4.0/mdit_py_plugins/texmath/index.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/mdit_py_plugins/texmath/index.py 2024-05-12 22:13:45.000000000 +0200 @@ -228,7 +228,7 @@ "rex": re.compile( r"^`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)", re.M ), - "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', # noqa: E501 + "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', "tag": "```math", }, { @@ -328,7 +328,7 @@ { "name": "math_block_eqno", "rex": re.compile(r"^\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)", re.M), - "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', # noqa: E501 + "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', "tag": "$$", }, { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/pyproject.toml new/mdit-py-plugins-0.4.1/pyproject.toml --- old/mdit-py-plugins-0.4.0/pyproject.toml 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/pyproject.toml 2024-05-12 22:13:45.000000000 +0200 @@ -18,6 +18,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", @@ -53,15 +54,30 @@ "tests/", ] -[tool.isort] -profile = "black" -force_sort_within_sections = true -known_first_party = ["mdit_py_plugins", "tests"] - -[tool.ruff] -line-length = 110 -extend-select = ["B0", "C4", "ICN", "ISC", "N", "RUF", "SIM"] -extend-ignore = ["E731", "N802", "N803", "N806"] +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "I", # isort + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "N", # pep8-naming + "PERF", # perflint (performance anti-patterns) + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PTH", # flake8-use-pathlib + "RUF", # Ruff-specific rules + "SIM", # flake8-simplify + "UP", # pyupgrade + "T20", # flake8-print +] +extend-ignore = ["ISC001", "N802", "N803", "N806"] + +[tool.ruff.lint.per-file-ignores] +"tests/**.py" = ["T201"] + +[tool.ruff.lint.isort] +force-sort-within-sections = true [tool.mypy] show_error_codes = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/tests/fixtures/admon.md new/mdit-py-plugins-0.4.1/tests/fixtures/admon.md --- old/mdit-py-plugins-0.4.0/tests/fixtures/admon.md 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/tests/fixtures/admon.md 2024-05-12 22:13:45.000000000 +0200 @@ -53,6 +53,32 @@ . +Removes extra quotes from the title +. +!!! danger "Don't try this at home" + ... + +. +<div class="admonition danger"> +<p class="admonition-title">Don't try this at home</p> +<p>...</p> +</div> +. + + +Parse additional classes to support Python markdown (https://github.com/executablebooks/mdit-py-plugins/issues/93#issuecomment-16...) +. +!!! a b c d inline-classes "Note: note about "foo"" + ... + +. +<div class="admonition a b c d inline-classes"> +<p class="admonition-title">Note: note about "foo"</p> +<p>...</p> +</div> +. + + Closes block after 2 empty lines . !!! note diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/tests/fixtures/footnote.md new/mdit-py-plugins-0.4.1/tests/fixtures/footnote.md --- old/mdit-py-plugins-0.4.0/tests/fixtures/footnote.md 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/tests/fixtures/footnote.md 2024-05-12 22:13:45.000000000 +0200 @@ -372,3 +372,23 @@ </ol> </section> . + +refs with no definition standard +. +[^1] [^1] +. +<p>[^1] [^1]</p> +. + +refs with no definition, ALWAYS_MATCH-REFS +. +[^1] [^1] +. +<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup></p> +<hr class="footnotes-sep"> +<section class="footnotes"> +<ol class="footnotes-list"> +<li id="fn1" class="footnote-item"> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a></li> +</ol> +</section> +. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/tests/test_footnote.py new/mdit-py-plugins-0.4.1/tests/test_footnote.py --- old/mdit-py-plugins-0.4.0/tests/test_footnote.py 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/tests/test_footnote.py 2024-05-12 22:13:45.000000000 +0200 @@ -96,7 +96,7 @@ "hidden": False, }, ] - assert state.env == {"footnotes": {"refs": {":a": -1}}} + assert state.env == {"footnotes": {"refs": {":a": -1}, "list": {}}} def test_footnote_ref(): @@ -188,89 +188,79 @@ tokens = [ Token( - **{ - "type": "footnote_reference_open", - "tag": "", - "nesting": 1, - "attrs": None, - "map": None, - "level": 0, - "children": None, - "content": "", - "markup": "", - "info": "", - "meta": {"label": "a"}, - "block": False, - "hidden": False, - } - ), - Token( - **{ - "type": "paragraph_open", - "tag": "p", - "nesting": 1, - "attrs": None, - "map": [0, 1], - "level": 1, - "children": None, - "content": "", - "markup": "", - "info": "", - "meta": {}, - "block": True, - "hidden": False, - } - ), - Token( - **{ - "type": "inline", - "tag": "", - "nesting": 0, - "attrs": None, - "map": [0, 1], - "level": 2, - "children": [], - "content": "xyz", - "markup": "", - "info": "", - "meta": {}, - "block": True, - "hidden": False, - } - ), - Token( - **{ - "type": "paragraph_close", - "tag": "p", - "nesting": -1, - "attrs": None, - "map": None, - "level": 1, - "children": None, - "content": "", - "markup": "", - "info": "", - "meta": {}, - "block": True, - "hidden": False, - } - ), - Token( - **{ - "type": "footnote_reference_close", - "tag": "", - "nesting": -1, - "attrs": None, - "map": None, - "level": 0, - "children": None, - "content": "", - "markup": "", - "info": "", - "meta": {}, - "block": False, - "hidden": False, - } + type="footnote_reference_open", + tag="", + nesting=1, + attrs=None, + map=None, + level=0, + children=None, + content="", + markup="", + info="", + meta={"label": "a"}, + block=False, + hidden=False, + ), + Token( + type="paragraph_open", + tag="p", + nesting=1, + attrs=None, + map=[0, 1], + level=1, + children=None, + content="", + markup="", + info="", + meta={}, + block=True, + hidden=False, + ), + Token( + type="inline", + tag="", + nesting=0, + attrs=None, + map=[0, 1], + level=2, + children=[], + content="xyz", + markup="", + info="", + meta={}, + block=True, + hidden=False, + ), + Token( + type="paragraph_close", + tag="p", + nesting=-1, + attrs=None, + map=None, + level=1, + children=None, + content="", + markup="", + info="", + meta={}, + block=True, + hidden=False, + ), + Token( + type="footnote_reference_close", + tag="", + nesting=-1, + attrs=None, + map=None, + level=0, + children=None, + content="", + markup="", + info="", + meta={}, + block=False, + hidden=False, ), Token("other", "", 0), ] @@ -443,14 +433,16 @@ </li> </ol> </section> - """ # noqa: E501 + """ ) ) @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): - md = MarkdownIt("commonmark").use(footnote_plugin) + md = MarkdownIt().use( + footnote_plugin, always_match_refs="ALWAYS_MATCH-REFS" in title + ) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mdit-py-plugins-0.4.0/tox.ini new/mdit-py-plugins-0.4.1/tox.ini --- old/mdit-py-plugins-0.4.0/tox.ini 2023-06-05 21:25:03.000000000 +0200 +++ new/mdit-py-plugins-0.4.1/tox.ini 2024-05-12 22:13:45.000000000 +0200 @@ -9,7 +9,7 @@ [testenv] usedevelop = true -[testenv:py{37,38,39,310,311}] +[testenv:py{38,39,310,311,312}] extras = testing commands = pytest {posargs}