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 2026-03-16 14:17:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mdit-py-plugins (Old)
and /work/SRC/openSUSE:Factory/.python-mdit-py-plugins.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-mdit-py-plugins"
Mon Mar 16 14:17:20 2026 rev:7 rq:1339200 version:0.5.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-mdit-py-plugins/python-mdit-py-plugins.changes
2024-11-14 16:09:49.925641626 +0100
+++
/work/SRC/openSUSE:Factory/.python-mdit-py-plugins.new.8177/python-mdit-py-plugins.changes
2026-03-16 14:20:42.401700373 +0100
@@ -1,0 +2,7 @@
+Mon Mar 16 03:48:37 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 0.5.0:
+ * Drop Python 3.9, which is EoL next month
+ * NEW: Add plugin & tests to render subscripts
+
+-------------------------------------------------------------------
Old:
----
python-mdit-py-plugins-0.4.2.tar.gz
New:
----
python-mdit-py-plugins-0.5.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-mdit-py-plugins.spec ++++++
--- /var/tmp/diff_new_pack.Z7CQRq/_old 2026-03-16 14:20:42.873720000 +0100
+++ /var/tmp/diff_new_pack.Z7CQRq/_new 2026-03-16 14:20:42.877720166 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-mdit-py-plugins
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,23 +18,23 @@
%{?sle15_python_module_pythons}
Name: python-mdit-py-plugins
-Version: 0.4.2
+Version: 0.5.0
Release: 0
Summary: Collection of plugins for markdown-it-py
License: MIT
URL: https://mdit-py-plugins.readthedocs.io/
Source:
https://github.com/executablebooks/mdit-py-plugins/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
-BuildRequires: %{python_module flit-core}
-BuildRequires: %{python_module markdown-it-py}
+BuildRequires: %{python_module base >= 3.10}
+BuildRequires: %{python_module flit-core >= 3.4}
+BuildRequires: %{python_module markdown-it-py >= 2}
BuildRequires: %{python_module pip}
-BuildRequires: %{python_module wheel}
# SECTION tests
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module pytest-regressions}
BuildRequires: fdupes
#Source:
https://files.pythonhosted.org/packages/source/m/mdit-py-plugins/mdit-py-plugins-%%{version}.tar.gz
BuildRequires: python-rpm-macros
-Requires: python-markdown-it-py
+Requires: python-markdown-it-py >= 2
BuildArch: noarch
%python_subpackages
@@ -58,5 +58,5 @@
%doc README.md CHANGELOG.md docs/index.md
%license LICENSE
%{python_sitelib}/mdit_py_plugins/
-%{python_sitelib}/mdit_py_plugins-%{version}*-info
+%{python_sitelib}/mdit_py_plugins-%{version}.dist-info
++++++ python-mdit-py-plugins-0.4.2.tar.gz ->
python-mdit-py-plugins-0.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/.github/workflows/tests.yml
new/mdit-py-plugins-0.5.0/.github/workflows/tests.yml
--- old/mdit-py-plugins-0.4.2/.github/workflows/tests.yml 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/.github/workflows/tests.yml 2025-08-11
09:23:08.000000000 +0200
@@ -18,10 +18,10 @@
steps:
- uses: actions/checkout@v4
- - name: Set up Python 3.8
+ - name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: 3.8
+ python-version: "3.10"
- uses: pre-commit/[email protected]
tests:
@@ -30,7 +30,7 @@
strategy:
fail-fast: false
matrix:
- python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11', '3.12']
+ python-version: ['pypy-3.10', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
@@ -46,13 +46,13 @@
run: |
pytest --cov=mdit_py_plugins --cov-report=xml --cov-report=term-missing
- name: Upload to Codecov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v5
if: github.event.pull_request.head.repo.full_name == github.repository
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: mdit-py-plugins-pytests
flags: pytests
- file: ./coverage.xml
+ files: ./coverage.xml
fail_ci_if_error: true
allgood:
@@ -75,7 +75,7 @@
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: "3.8"
+ python-version: "3.10"
- name: install flit
run: |
pip install flit~=3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/.pre-commit-config.yaml
new/mdit-py-plugins-0.5.0/.pre-commit-config.yaml
--- old/mdit-py-plugins-0.4.2/.pre-commit-config.yaml 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/.pre-commit-config.yaml 2025-08-11
09:23:08.000000000 +0200
@@ -12,7 +12,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.6.0
+ rev: v6.0.0
hooks:
- id: check-json
- id: check-yaml
@@ -20,14 +20,14 @@
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.4.4
+ rev: v0.12.8
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.10.0
+ rev: v1.17.1
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.2/.readthedocs.yml
new/mdit-py-plugins-0.5.0/.readthedocs.yml
--- old/mdit-py-plugins-0.4.2/.readthedocs.yml 2024-09-09 22:26:03.000000000
+0200
+++ new/mdit-py-plugins-0.5.0/.readthedocs.yml 2025-08-11 09:23:08.000000000
+0200
@@ -3,7 +3,7 @@
build:
os: ubuntu-22.04
tools:
- python: "3.8"
+ python: "3.10"
python:
install:
@@ -12,5 +12,6 @@
extra_requirements: [rtd]
sphinx:
+ configuration: docs/conf.py
builder: html
fail_on_warning: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/CHANGELOG.md
new/mdit-py-plugins-0.5.0/CHANGELOG.md
--- old/mdit-py-plugins-0.4.2/CHANGELOG.md 2024-09-09 22:26:03.000000000
+0200
+++ new/mdit-py-plugins-0.5.0/CHANGELOG.md 2025-08-11 09:23:08.000000000
+0200
@@ -1,5 +1,10 @@
# Change Log
+## 0.5.0 - 2025-08-11
+
+- ⬆️ Drop Python 3.9, which is EoL next month
<https://devguide.python.org/versions> and allow for the, soon to be released,
markdown-it-py v4.
+- ✨ NEW: Add plugin & tests to render subscripts, thanks to @miteshashar
+
## 0.4.2 - 2024-09-09
- 👌 Improve parsing of nested amsmath
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/docs/index.md
new/mdit-py-plugins-0.5.0/docs/index.md
--- old/mdit-py-plugins-0.4.2/docs/index.md 2024-09-09 22:26:03.000000000
+0200
+++ new/mdit-py-plugins-0.5.0/docs/index.md 2025-08-11 09:23:08.000000000
+0200
@@ -113,6 +113,12 @@
.. autofunction:: mdit_py_plugins.amsmath.amsmath_plugin
```
+## Subscripts
+
+```{eval-rst}
+.. autofunction:: mdit_py_plugins.subscript.sub_plugin
+```
+
## MyST plugins
`myst_blocks` and `myst_role` plugins are also available, for utilisation by
the [MyST
renderer](https://myst-parser.readthedocs.io/en/latest/using/syntax.html)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/mdit_py_plugins/__init__.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/__init__.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/__init__.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/__init__.py 2025-08-11
09:23:08.000000000 +0200
@@ -1 +1 @@
-__version__ = "0.4.2"
+__version__ = "0.5.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/mdit_py_plugins/admon/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/admon/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/admon/index.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/admon/index.py 2025-08-11
09:23:08.000000000 +0200
@@ -2,9 +2,10 @@
from __future__ import annotations
+from collections.abc import Callable, Sequence
from contextlib import suppress
import re
-from typing import TYPE_CHECKING, Callable, Sequence
+from typing import TYPE_CHECKING
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.2/mdit_py_plugins/amsmath/__init__.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/amsmath/__init__.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/amsmath/__init__.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/amsmath/__init__.py
2025-08-11 09:23:08.000000000 +0200
@@ -2,8 +2,9 @@
from __future__ import annotations
+from collections.abc import Callable, Sequence
import re
-from typing import TYPE_CHECKING, Callable, Sequence
+from typing import TYPE_CHECKING
from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/anchors/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/anchors/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/anchors/index.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/anchors/index.py 2025-08-11
09:23:08.000000000 +0200
@@ -1,5 +1,5 @@
+from collections.abc import Callable
import re
-from typing import Callable, List, Optional, Set
from markdown_it import MarkdownIt
from markdown_it.rules_core import StateCore
@@ -10,7 +10,7 @@
md: MarkdownIt,
min_level: int = 1,
max_level: int = 2,
- slug_func: Optional[Callable[[str], str]] = None,
+ slug_func: Callable[[str], str] | None = None,
permalink: bool = False,
permalinkSymbol: str = "¶",
permalinkBefore: bool = False,
@@ -58,7 +58,7 @@
def _make_anchors_func(
- selected_levels: List[int],
+ selected_levels: list[int],
slug_func: Callable[[str], str],
permalink: bool,
permalinkSymbol: str,
@@ -66,7 +66,7 @@
permalinkSpace: bool,
) -> Callable[[StateCore], None]:
def _anchor_func(state: StateCore) -> None:
- slugs: Set[str] = set()
+ slugs: set[str] = set()
for idx, token in enumerate(state.tokens):
if token.type != "heading_open":
continue
@@ -119,7 +119,7 @@
return re.sub(r"[^\w\u4e00-\u9fff\- ]", "",
title.strip().lower().replace(" ", "-"))
-def unique_slug(slug: str, slugs: Set[str]) -> str:
+def unique_slug(slug: str, slugs: set[str]) -> str:
uniq = slug
i = 1
while uniq in slugs:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/attrs/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/index.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/attrs/index.py 2025-08-11
09:23:08.000000000 +0200
@@ -1,7 +1,8 @@
from __future__ import annotations
+from collections.abc import Sequence
from functools import partial
-from typing import Any, Sequence
+from typing import Any
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.2/mdit_py_plugins/attrs/parse.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/attrs/parse.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/parse.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/attrs/parse.py 2025-08-11
09:23:08.000000000 +0200
@@ -22,9 +22,9 @@
from __future__ import annotations
+from collections.abc import Callable
from enum import Enum
import re
-from typing import Callable
class State(Enum):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/mdit_py_plugins/colon_fence.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/colon_fence.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/colon_fence.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/colon_fence.py 2025-08-11
09:23:08.000000000 +0200
@@ -1,6 +1,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Sequence
+from collections.abc import Sequence
+from typing import TYPE_CHECKING
from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml, unescapeAll
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/container/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/container/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/container/index.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/container/index.py
2025-08-11 09:23:08.000000000 +0200
@@ -2,8 +2,9 @@
from __future__ import annotations
+from collections.abc import Callable, Sequence
from math import floor
-from typing import TYPE_CHECKING, Any, Callable, Sequence
+from typing import TYPE_CHECKING, Any
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.2/mdit_py_plugins/dollarmath/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/dollarmath/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/dollarmath/index.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/dollarmath/index.py
2025-08-11 09:23:08.000000000 +0200
@@ -1,7 +1,8 @@
from __future__ import annotations
+from collections.abc import Callable, Sequence
import re
-from typing import TYPE_CHECKING, Any, Callable, Sequence
+from typing import TYPE_CHECKING, Any
from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml, isWhiteSpace
@@ -146,7 +147,7 @@
return False
# if an odd number of \ then ignore
- if (backslashes % 2) != mod:
+ if (backslashes % 2) != mod: # noqa: SIM103
return True
return False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/field_list/__init__.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/field_list/__init__.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/field_list/__init__.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/field_list/__init__.py
2025-08-11 09:23:08.000000000 +0200
@@ -1,7 +1,7 @@
"""Field list plugin"""
+from collections.abc import Iterator
from contextlib import contextmanager
-from typing import Iterator, Optional, Tuple
from markdown_it import MarkdownIt
from markdown_it.rules_block import StateBlock
@@ -45,7 +45,7 @@
)
-def parseNameMarker(state: StateBlock, startLine: int) -> Tuple[int, str]:
+def parseNameMarker(state: StateBlock, startLine: int) -> tuple[int, str]:
"""Parse field name: `:name:`
:returns: position after name marker, name text
@@ -159,7 +159,7 @@
# to figure out the indent of the body,
# we look at all non-empty, indented lines and find the minimum
indent
- block_indent: Optional[int] = None
+ block_indent: int | None = None
_line = startLine + 1
while _line < endLine:
# if start_of_content < end_of_content, then non-empty line
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/footnote/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/index.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/footnote/index.py 2025-08-11
09:23:08.000000000 +0200
@@ -2,8 +2,9 @@
from __future__ import annotations
+from collections.abc import Sequence
from functools import partial
-from typing import TYPE_CHECKING, Sequence, TypedDict
+from typing import TYPE_CHECKING, TypedDict
from markdown_it import MarkdownIt
from markdown_it.helpers import parseLinkLabel
@@ -332,7 +333,7 @@
tok_filter.append(not insideRef)
- state.tokens = [t for t, f in zip(state.tokens, tok_filter) if f]
+ state.tokens = [t for t, f in zip(state.tokens, tok_filter, strict=False)
if f]
footnote_data = _data_from_env(state.env)
if not footnote_data["list"]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/myst_blocks/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/myst_blocks/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/myst_blocks/index.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/myst_blocks/index.py
2025-08-11 09:23:08.000000000 +0200
@@ -1,7 +1,8 @@
from __future__ import annotations
+from collections.abc import Sequence
import itertools
-from typing import TYPE_CHECKING, Sequence
+from typing import TYPE_CHECKING
from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/myst_role/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/myst_role/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/myst_role/index.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/myst_role/index.py
2025-08-11 09:23:08.000000000 +0200
@@ -1,5 +1,6 @@
+from collections.abc import Sequence
import re
-from typing import TYPE_CHECKING, Sequence
+from typing import TYPE_CHECKING
from markdown_it import MarkdownIt
from markdown_it.common.utils import escapeHtml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/subscript/__init__.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/subscript/__init__.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/subscript/__init__.py
1970-01-01 01:00:00.000000000 +0100
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/subscript/__init__.py
2025-08-11 09:23:08.000000000 +0200
@@ -0,0 +1,117 @@
+"""
+Markdown-it-py plugin to introduce <sub> markup using ~subscript~.
+
+Ported from
+https://github.com/markdown-it/markdown-it-sub/blob/master/index.mjs
+
+Originally ported during implementation of
https://github.com/hasgeek/funnel/blob/main/funnel/utils/markdown/mdit_plugins/sub_tag.py
+"""
+
+from __future__ import annotations
+
+from collections.abc import Sequence
+import re
+
+from markdown_it import MarkdownIt
+from markdown_it.renderer import RendererHTML
+from markdown_it.rules_inline import StateInline
+from markdown_it.token import Token
+from markdown_it.utils import EnvType, OptionsDict
+
+__all__ = ["sub_plugin"]
+
+TILDE_CHAR = "~"
+
+WHITESPACE_RE = re.compile(r"(^|[^\\])(\\\\)*\s")
+UNESCAPE_RE = re.compile(r'\\([ \\!"#$%&\'()*+,.\/:;<=>?@[\]^_`{|}~-])')
+
+
+def tokenize(state: StateInline, silent: bool) -> bool:
+ """Parse a ~subscript~ token."""
+ start = state.pos
+ ch = state.src[start]
+ maximum = state.posMax
+ found = False
+
+ # Don't run any pairs in validation mode
+ if silent:
+ return False
+
+ if ch != TILDE_CHAR:
+ return False
+
+ if start + 2 >= maximum:
+ return False
+
+ state.pos = start + 1
+
+ while state.pos < maximum:
+ if state.src[state.pos] == TILDE_CHAR:
+ found = True
+ break
+ state.md.inline.skipToken(state)
+
+ if not found or start + 1 == state.pos:
+ state.pos = start
+ return False
+
+ content = state.src[start + 1 : state.pos]
+
+ # Don't allow unescaped spaces/newlines inside
+ if WHITESPACE_RE.search(content) is not None:
+ state.pos = start
+ return False
+
+ # Found a valid pair, so update posMax and pos
+ state.posMax = state.pos
+ state.pos = start + 1
+
+ # Earlier we checked "not silent", but this implementation does not need it
+ token = state.push("sub_open", "sub", 1)
+ token.markup = TILDE_CHAR
+
+ token = state.push("text", "", 0)
+ token.content = UNESCAPE_RE.sub(r"\1", content)
+
+ token = state.push("sub_close", "sub", -1)
+ token.markup = TILDE_CHAR
+
+ state.pos = state.posMax + 1
+ state.posMax = maximum
+ return True
+
+
+def sub_open(
+ renderer: RendererHTML,
+ tokens: Sequence[Token],
+ idx: int,
+ options: OptionsDict,
+ env: EnvType,
+) -> str:
+ """Render the opening tag for a ~subscript~ token."""
+ return "<sub>"
+
+
+def sub_close(
+ renderer: RendererHTML,
+ tokens: Sequence[Token],
+ idx: int,
+ options: OptionsDict,
+ env: EnvType,
+) -> str:
+ """Render the closing tag for a ~subscript~ token."""
+ return "</sub>"
+
+
+def sub_plugin(md: MarkdownIt) -> None:
+ """
+ Markdown-it-py plugin to introduce <sub> markup using ~subscript~.
+
+ Ported from
+ https://github.com/markdown-it/markdown-it-sub/blob/master/index.mjs
+
+ Originally ported during implementation of
https://github.com/hasgeek/funnel/blob/main/funnel/utils/markdown/mdit_plugins/sub_tag.py
+ """
+ md.inline.ruler.after("emphasis", "sub", tokenize)
+ md.add_render_rule("sub_open", sub_open)
+ md.add_render_rule("sub_close", sub_close)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/subscript/port.yaml
new/mdit-py-plugins-0.5.0/mdit_py_plugins/subscript/port.yaml
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/subscript/port.yaml
1970-01-01 01:00:00.000000000 +0100
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/subscript/port.yaml
2025-08-11 09:23:08.000000000 +0200
@@ -0,0 +1,9 @@
+- package: markdown-it-sub
+ commit: 422e93885b3c611234d602aa795f3d75a62cc93e
+ date: 5 Dec 2023
+ version: 3.0.0
+ changes:
+ - TODO - Some strikethrough and subscript combinations are not rendered
+ correctly in markdown-it either, but that can be fixed at a later stage,
+ perhaps in both markdown-it and markdown-it-py.
+ See `tests/fixtures/subscript_strikethrough.md` for examples.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/index.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/texmath/index.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/index.py 2024-09-09
22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/texmath/index.py 2025-08-11
09:23:08.000000000 +0200
@@ -1,7 +1,9 @@
from __future__ import annotations
+from collections.abc import Callable, Sequence
import re
-from typing import TYPE_CHECKING, Any, Callable, Match, Sequence, TypedDict
+from re import Match
+from typing import TYPE_CHECKING, Any, TypedDict
from markdown_it import MarkdownIt
from markdown_it.common.utils import charCodeAt
@@ -152,7 +154,7 @@
def dollar_pre(src: str, beg: int) -> bool:
prv = charCodeAt(src[beg - 1], 0) if beg > 0 else False
return (
- (not prv) or prv != 0x5C and (prv < 0x30 or prv > 0x39) # no
backslash,
+ (not prv) or (prv != 0x5C and (prv < 0x30 or prv > 0x39)) # no
backslash,
) # no decimal digit .. before opening '$'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/mdit_py_plugins/wordcount/__init__.py
new/mdit-py-plugins-0.5.0/mdit_py_plugins/wordcount/__init__.py
--- old/mdit-py-plugins-0.4.2/mdit_py_plugins/wordcount/__init__.py
2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/mdit_py_plugins/wordcount/__init__.py
2025-08-11 09:23:08.000000000 +0200
@@ -1,5 +1,5 @@
+from collections.abc import Callable
import string
-from typing import Callable, List
from markdown_it import MarkdownIt
from markdown_it.rules_core import StateCore
@@ -33,7 +33,7 @@
"""
def _word_count_rule(state: StateCore) -> None:
- text: List[str] = []
+ text: list[str] = []
words = 0
for token in state.tokens:
if token.type == "text":
@@ -53,6 +53,6 @@
data["text"] += text
data.setdefault("words", 0)
data["words"] += words
- data["minutes"] = int(round(data["words"] / per_minute))
+ data["minutes"] = int(round(data["words"] / per_minute)) # noqa:
RUF046
md.core.ruler.push("wordcount", _word_count_rule)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/pyproject.toml
new/mdit-py-plugins-0.5.0/pyproject.toml
--- old/mdit-py-plugins-0.4.2/pyproject.toml 2024-09-09 22:26:03.000000000
+0200
+++ new/mdit-py-plugins-0.5.0/pyproject.toml 2025-08-11 09:23:08.000000000
+0200
@@ -25,8 +25,8 @@
"Topic :: Text Processing :: Markup",
]
keywords = ["markdown", "markdown-it", "lexer", "parser", "development"]
-requires-python = ">=3.8"
-dependencies = ["markdown-it-py>=1.0.0,<4.0.0"]
+requires-python = ">=3.10"
+dependencies = ["markdown-it-py>=2.0.0,<5.0.0"]
[project.urls]
Homepage = "https://github.com/executablebooks/mdit-py-plugins"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/tests/fixtures/subscript.md
new/mdit-py-plugins-0.5.0/tests/fixtures/subscript.md
--- old/mdit-py-plugins-0.4.2/tests/fixtures/subscript.md 1970-01-01
01:00:00.000000000 +0100
+++ new/mdit-py-plugins-0.5.0/tests/fixtures/subscript.md 2025-08-11
09:23:08.000000000 +0200
@@ -0,0 +1,77 @@
+.
+~foo\~
+.
+<p>~foo~</p>
+.
+
+.
+~foo bar~
+.
+<p>~foo bar~</p>
+.
+
+.
+~foo\ bar\ baz~
+.
+<p><sub>foo bar baz</sub></p>
+.
+
+.
+~\ foo\ ~
+.
+<p><sub> foo </sub></p>
+.
+
+.
+~foo\\\\\\\ bar~
+.
+<p><sub>foo\\\ bar</sub></p>
+.
+
+.
+~foo\\\\\\ bar~
+.
+<p>~foo\\\ bar~</p>
+.
+
+.
+**~foo~ bar**
+.
+<p><strong><sub>foo</sub> bar</strong></p>
+.
+
+
+coverage
+.
+*~f
+.
+<p>*~f</p>
+.
+
+Basic:
+.
+H~2~O
+.
+<p>H<sub>2</sub>O</p>
+.
+
+Spaces:
+.
+H~2 O~2
+.
+<p>H~2 O~2</p>
+.
+
+Escaped:
+.
+H\~2\~O
+.
+<p>H~2~O</p>
+.
+
+Nested:
+.
+a~b~c~d~e
+.
+<p>a<sub>b</sub>c<sub>d</sub>e</p>
+.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mdit-py-plugins-0.4.2/tests/fixtures/subscript_strikethrough.md
new/mdit-py-plugins-0.5.0/tests/fixtures/subscript_strikethrough.md
--- old/mdit-py-plugins-0.4.2/tests/fixtures/subscript_strikethrough.md
1970-01-01 01:00:00.000000000 +0100
+++ new/mdit-py-plugins-0.5.0/tests/fixtures/subscript_strikethrough.md
2025-08-11 09:23:08.000000000 +0200
@@ -0,0 +1,68 @@
+Strikethrough versus subscript:
+.
+~~strikethrough~~versus~subscript~
+.
+<p><s>strikethrough</s>versus<sub>subscript</sub></p>
+.
+
+Subscript in strikethrough (beginning):
+.
+~~~subscript~strikethrough~~
+This ends up being rendered as a code block, but that's expected.
+Hence, it has to be closed with `~~~`
+~~~
+Only then will the following text be rendered as it is intended.
+We cannot use `~~~subscript~strikethrough~~` at the beginning of a line.
+.
+<pre><code class="language-subscript~strikethrough~~">This ends up being
rendered as a code block, but that's expected.
+Hence, it has to be closed with `~~~`
+</code></pre>
+<p>Only then will the following text be rendered as it is intended.
+We cannot use <code>~~~subscript~strikethrough~~</code> at the beginning of a
line.</p>
+.
+
+Strikethrough in subscript (beginning):
+.
+~~~strikethrough~~subscript~
+This ends up being rendered as a code block, but that's expected.
+Hence, it has to be closed with `~~~`
+~~~
+Only then will the following text be rendered as it is intended.
+We cannot use `~~~strikethrough~~subscript~` at the beginning of a line.
+.
+<pre><code class="language-strikethrough~~subscript~">This ends up being
rendered as a code block, but that's expected.
+Hence, it has to be closed with `~~~`
+</code></pre>
+<p>Only then will the following text be rendered as it is intended.
+We cannot use <code>~~~strikethrough~~subscript~</code> at the beginning of a
line.</p>
+.
+
+Subscript in strikethrough (end):
+.
+~~strikethrough~subscript~~~
+.
+<p><s>strikethrough<sub>subscript</sub></s></p>
+.
+
+Strikethrough in subscript (end):
+.
+TODO: ~subscript~~strikethrough~~~
+.
+<p>TODO: <sub>subscript</sub><sub>strikethrough</sub>~~</p>
+.
+
+Subscript in strikethrough:
+.
+~~strikethrough~subscript~strikethrough~~
+.
+<p><s>strikethrough<sub>subscript</sub>strikethrough</s></p>
+.
+
+Strikethrough in subscript:
+.
+TODO: ~subscript~~strikethrough~~subscript~
+This should have beeen similar to *emphasised**strong**emphasised*.
+.
+<p>TODO: <sub>subscript</sub><sub>strikethrough</sub><sub>subscript</sub>
+This should have beeen similar to
<em>emphasised<strong>strong</strong>emphasised</em>.</p>
+.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/tests/test_subscript.py
new/mdit-py-plugins-0.5.0/tests/test_subscript.py
--- old/mdit-py-plugins-0.4.2/tests/test_subscript.py 1970-01-01
01:00:00.000000000 +0100
+++ new/mdit-py-plugins-0.5.0/tests/test_subscript.py 2025-08-11
09:23:08.000000000 +0200
@@ -0,0 +1,40 @@
+"""Tests for subscript plugin."""
+
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.subscript import sub_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "subscript.md")
+STRIKETHROUGH_FIXTURE_PATH = Path(__file__).parent.joinpath(
+ "fixtures", "subscript_strikethrough.md"
+)
+
+
[email protected]("line,title,input,expected",
read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ """Tests for subscript plugin."""
+ md = MarkdownIt("commonmark").use(sub_plugin)
+ text = md.render(input)
+ try:
+ assert text.rstrip() == expected.rstrip()
+ except AssertionError:
+ print(text)
+ raise
+
+
[email protected](
+ "line,title,input,expected", read_fixture_file(STRIKETHROUGH_FIXTURE_PATH)
+)
+def test_all_strikethrough(line, title, input, expected):
+ """Tests for subscript plugin with strikethrough enabled."""
+ md = MarkdownIt("commonmark").enable("strikethrough").use(sub_plugin)
+ text = md.render(input)
+ try:
+ assert text.rstrip() == expected.rstrip()
+ except AssertionError:
+ print(text)
+ raise
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mdit-py-plugins-0.4.2/tox.ini
new/mdit-py-plugins-0.5.0/tox.ini
--- old/mdit-py-plugins-0.4.2/tox.ini 2024-09-09 22:26:03.000000000 +0200
+++ new/mdit-py-plugins-0.5.0/tox.ini 2025-08-11 09:23:08.000000000 +0200
@@ -4,18 +4,18 @@
# then run `tox` or `tox -- {pytest args}`
# run in parallel using `tox -p`
[tox]
-envlist = py38
+envlist = py310
[testenv]
usedevelop = true
-[testenv:py{38,39,310,311,312}]
+[testenv:py{310,311,312,313}]
extras = testing
commands = pytest {posargs}
[testenv:docs-{update,clean}]
extras = rtd
-whitelist_externals = rm
+allowlist_externals = rm
commands =
clean: rm -rf docs/_build
sphinx-build -nW --keep-going -b {posargs:html} docs/
docs/_build/{posargs:html}