Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cd2bb8e
Rewrite emphasis handling
facelessuser Sep 7, 2026
59fdb1d
Remove outdated comment
facelessuser Sep 8, 2026
aa2ed07
If Markdown object is ever left in a bad state reset the stack
facelessuser Sep 8, 2026
99594f2
Consolidate reset behavior and ensure we update our tracked run
facelessuser Sep 8, 2026
19d247f
Have other reset locations call the reset function as well
facelessuser Sep 8, 2026
b82bd46
Add return type
facelessuser Sep 8, 2026
dd24bcd
Fix link errors
facelessuser Sep 8, 2026
ee81828
Add a changelog item
facelessuser Sep 8, 2026
7f76bfb
Consolidate duplicate code
facelessuser Sep 9, 2026
cc84192
Fix some edge cases
facelessuser Sep 10, 2026
abe63fb
Separate cache info defines from reset
facelessuser Sep 10, 2026
08d6519
Fix lint
facelessuser Sep 10, 2026
c2a0b0e
Fix a possible scenario where the next region is contiguous
facelessuser Sep 10, 2026
ee8114e
Rework how resetting is performed
facelessuser Sep 10, 2026
cf01269
Remove unused module
facelessuser Sep 10, 2026
116de54
Spelling
facelessuser Sep 10, 2026
8f616ab
Use test harness dedent
facelessuser Sep 10, 2026
bddce4b
Handle emphasis token chains longer than 3
facelessuser Sep 12, 2026
1eb6be6
Ignore redundant tests
facelessuser Sep 12, 2026
cfab483
Remove dead code
facelessuser Sep 12, 2026
ecf963b
Fixes for if just a double or single token is every used
facelessuser Sep 12, 2026
8a8e668
A double width only delimiter processor could fail on single width token
facelessuser Sep 12, 2026
4f1b093
Avoid flipping strong/em tag nesting for triple emphasis tokens
facelessuser Sep 12, 2026
c3a73b4
Forgot to commit last fix, better cache point
facelessuser Sep 13, 2026
e7efd85
Another fix that missed getting committed
facelessuser Sep 14, 2026
882d308
Combine emphasis handling into one processor
facelessuser Sep 14, 2026
a2ef4e1
Add punctuation logic
facelessuser Sep 15, 2026
54284be
Fix typo
facelessuser Sep 15, 2026
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 docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ See the [Contributing Guide](contributing.md) for details.
performance for repeated inline patterns (#1619).
* Officially support Python 3.15 and drop support for Python 3.10
* Walk backtick runs in `BacktickInlineProcessor` without a regex (#1620).
* Complete rework of emphasis handling to imporove nested emphasis handling better (#1632).

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion docs/extensions/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ Here are some convenience functions and other examples:

| Class | Kind | Description |
| -------------------------------------------------------------------------------------|-----------|---------------------------------------------------------------|
| [`AsteriskProcessor`][markdown.inlinepatterns.AsteriskProcessor] | built-in | Emphasis processor for handling strong and em matches inside asterisks |
| [`DelimiterProcessor`][markdown.inlinepatterns.DelimiterProcessor] | built-in | Emphasis processor for handling strong and em matches |
| [`WikiLinksInlineProcessor`][markdown.extensions.wikilinks.WikiLinksInlineProcessor] | extension | Link `[[article names]]` to wiki given in metadata |
| [`FootnoteInlineProcessor`][markdown.extensions.footnotes.FootnoteInlineProcessor] | extension | Replaces footnote in text with link to footnote div at bottom |

Expand Down
9 changes: 8 additions & 1 deletion markdown/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from .preprocessors import build_preprocessors
from .blockprocessors import build_block_parser
from .treeprocessors import build_treeprocessors
from .inlinepatterns import build_inlinepatterns
from .inlinepatterns import build_inlinepatterns, DelimiterProcessor
from .postprocessors import build_postprocessors
from .extensions import Extension
from .serializers import to_html_string, to_xhtml_string
Expand Down Expand Up @@ -106,6 +106,7 @@ def __init__(self, **kwargs):

"""

self.last_run: float = 0.0
self.tab_length: int = kwargs.get('tab_length', 4)

self.ESCAPED_CHARS: list[str] = [
Expand All @@ -118,6 +119,7 @@ def __init__(self, **kwargs):
self.registeredExtensions: list[Extension] = []
self.docType = "" # TODO: Maybe delete this. It does not appear to be used anymore.
self.stripTopLevelTags: bool = True
self.delimiters: DelimiterProcessor | None = None

self.build_parser()

Expand Down Expand Up @@ -270,6 +272,11 @@ def reset(self) -> Markdown:
self.htmlStash.reset()
self.references.clear()

if self.delimiters is not None:
self.delimiters.reset()
if self.delimiters not in self.inlinePatterns:
self.delimiters = None

for extension in self.registeredExtensions:
if hasattr(extension, 'reset'):
extension.reset()
Expand Down
37 changes: 9 additions & 28 deletions markdown/extensions/legacy_em.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,7 @@
from __future__ import annotations

from . import Extension
from ..inlinepatterns import UnderscoreProcessor, EmStrongItem, EM_STRONG2_RE, STRONG_EM2_RE
import re

# _emphasis_
EMPHASIS_RE = r'(_)([^_]+)\1'

# __strong__
STRONG_RE = r'(_{2})(.+?)\1'

# __strong_em___
STRONG_EM_RE = r'(_)\1(?!\1)([^_]+?)\1(?!\1)(.+?)\1{3}'


class LegacyUnderscoreProcessor(UnderscoreProcessor):
"""Emphasis processor for handling strong and em matches inside underscores."""

PATTERNS = [
EmStrongItem(re.compile(EM_STRONG2_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
EmStrongItem(re.compile(STRONG_EM2_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'),
EmStrongItem(re.compile(STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
EmStrongItem(re.compile(STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'),
EmStrongItem(re.compile(EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em')
]
from ..inlinepatterns import DelimiterProcessor


class LegacyEmExtension(Extension):
Expand All @@ -45,14 +23,17 @@ class LegacyEmExtension(Extension):
def extendMarkdown(self, md):
""" Register the processor.

| Class Instance | Registry | Name | Priority |
| ------------------------------------------------------------- | ---------------------------------------------------------------- | ------ | :------: |
| [`LegacyUnderscoreProcessor`][markdown.extensions.legacy_em.LegacyUnderscoreProcessor] | [`inlinepatterns`][markdown.inlinepatterns.build_inlinepatterns] | `em_strong2` | `50` |
| Class Instance | Registry | Name | Priority |
| ------------------------------------------------------------------ | ---------------------------------------------------------------- | ------------ | :------: |
| [`DelimiterProcessor`][markdown.inlinepatterns.DelimiterProcessor] | [`inlinepatterns`][markdown.inlinepatterns.build_inlinepatterns] | `em_strong` | `60` |

"""
# flake8: noqa: E501 48-50
md.inlinePatterns.register(LegacyUnderscoreProcessor(r'_'), 'em_strong2', 50)
# flake8: noqa: E501 27-29

if md.delimiters is not None:
md.delimiters.add('_', 'strong,em')
else:
md.inlinePatterns.register(DelimiterProcessor('_', 'strong,em', md), 'em_strong', 60)

def makeExtension(**kwargs): # pragma: no cover
""" Return an instance of the `LegacyEmExtension` """
Expand Down
Loading
Loading