Skip to content

Commit d8ecae6

Browse files
committed
Add the requested changes:
- Fix docstrings in footnotes extension - Modify style of new tests to use self.dedent() - Add an entry in the changelog concerning the change to ensure inline processing occurs in document order
1 parent bc3f493 commit d8ecae6

File tree

3 files changed

+77
-22
lines changed

3 files changed

+77
-22
lines changed

docs/changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ See the [Contributing Guide](contributing.md) for details.
1616

1717
* Fix handling of incomplete HTML tags in code spans in Python 3.14.
1818
* Fix issue with footnote ordering (#1367).
19+
* Ensure inline processing iterates through elements in document order.
1920

2021
## [3.8.2] - 2025-06-19
2122

markdown/extensions/footnotes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def makeFootnotesDiv(self, root: etree.Element) -> etree.Element | None:
226226

227227

228228
class FootnoteBlockProcessor(BlockProcessor):
229-
""" Find footnote definitions and references, storing both for later use. """
229+
""" Find footnote definitions and store for later use. """
230230

231231
RE = re.compile(r'^[ ]{0,3}\[\^([^\]]*)\]:[ ]*(.*)$', re.MULTILINE)
232232

@@ -238,7 +238,7 @@ def test(self, parent: etree.Element, block: str) -> bool:
238238
return True
239239

240240
def run(self, parent: etree.Element, blocks: list[str]) -> bool:
241-
""" Find, set, and remove footnote definitions. Find footnote references."""
241+
""" Find, set, and remove footnote definitions. """
242242
block = blocks.pop(0)
243243

244244
m = self.RE.search(block)

tests/test_syntax/extensions/test_footnotes.py

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,14 @@ def test_footnote_order(self):
341341
"""Test that footnotes occur in order of reference appearance."""
342342

343343
self.assertMarkdownRenders(
344-
'First footnote reference[^first]. Second footnote reference[^last].\n\n'
345-
'[^last]: Second footnote.\n[^first]: First footnote.',
344+
self.dedent(
345+
"""
346+
First footnote reference[^first]. Second footnote reference[^last].
347+
348+
[^last]: Second footnote.
349+
[^first]: First footnote.
350+
"""
351+
),
346352
'<p>First footnote reference<sup id="fnref:first"><a class="footnote-ref" '
347353
'href="#fn:first">1</a></sup>. Second footnote reference<sup id="fnref:last">'
348354
'<a class="footnote-ref" href="#fn:last">2</a></sup>.</p>\n'
@@ -362,17 +368,23 @@ def test_footnote_order(self):
362368
)
363369

364370
def test_footnote_order_tricky(self):
365-
"""Test that tricky sequence of footnote references."""
371+
"""Test a tricky sequence of footnote references."""
366372

367373
self.assertMarkdownRenders(
368-
'`Footnote reference in code spans should be ignored[^tricky]`. '
369-
'A footnote reference[^ordinary]. '
370-
'Another footnote reference[^tricky].\n\n'
371-
'[^ordinary]: This should be the first footnote.\n'
372-
'[^tricky]: This should be the second footnote.',
373-
'<p><code>Footnote reference in code spans should be ignored[^tricky]</code>. '
374-
'A footnote reference<sup id="fnref:ordinary"><a class="footnote-ref" '
375-
'href="#fn:ordinary">1</a></sup>. Another footnote reference<sup id="fnref:tricky">'
374+
self.dedent(
375+
"""
376+
`Footnote reference in code spans should be ignored[^tricky]`.
377+
A footnote reference[^ordinary].
378+
Another footnote reference[^tricky].
379+
380+
[^ordinary]: This should be the first footnote.
381+
[^tricky]: This should be the second footnote.
382+
"""
383+
),
384+
'<p><code>Footnote reference in code spans should be ignored[^tricky]</code>.\n'
385+
'A footnote reference<sup id="fnref:ordinary">'
386+
'<a class="footnote-ref" href="#fn:ordinary">1</a></sup>.\n'
387+
'Another footnote reference<sup id="fnref:tricky">'
376388
'<a class="footnote-ref" href="#fn:tricky">2</a></sup>.</p>\n'
377389
'<div class="footnote">\n'
378390
'<hr />\n'
@@ -409,9 +421,14 @@ def test_footnote_reference_within_footnote_definition(self):
409421
"""Test footnote definition containing another footnote reference."""
410422

411423
self.assertMarkdownRenders(
412-
'Main footnote[^main].\n\n'
413-
'[^main]: This footnote references another[^nested].\n'
414-
'[^nested]: Nested footnote.',
424+
self.dedent(
425+
"""
426+
Main footnote[^main].
427+
428+
[^main]: This footnote references another[^nested].
429+
[^nested]: Nested footnote.
430+
"""
431+
),
415432
'<p>Main footnote<sup id="fnref:main"><a class="footnote-ref" href="#fn:main">1</a></sup>.</p>\n'
416433
'<div class="footnote">\n'
417434
'<hr />\n'
@@ -433,7 +450,13 @@ def test_footnote_reference_within_blockquote(self):
433450
"""Test footnote reference within a blockquote."""
434451

435452
self.assertMarkdownRenders(
436-
'> This is a quote with a footnote[^quote].\n\n[^quote]: Quote footnote.',
453+
self.dedent(
454+
"""
455+
> This is a quote with a footnote[^quote].
456+
457+
[^quote]: Quote footnote.
458+
"""
459+
),
437460
'<blockquote>\n'
438461
'<p>This is a quote with a footnote<sup id="fnref:quote">'
439462
'<a class="footnote-ref" href="#fn:quote">1</a></sup>.</p>\n'
@@ -453,7 +476,14 @@ def test_footnote_reference_within_list(self):
453476
"""Test footnote reference within a list item."""
454477

455478
self.assertMarkdownRenders(
456-
'1. First item with footnote[^note]\n1. Second item\n\n[^note]: List footnote.',
479+
self.dedent(
480+
"""
481+
1. First item with footnote[^note]
482+
1. Second item
483+
484+
[^note]: List footnote.
485+
"""
486+
),
457487
'<ol>\n'
458488
'<li>First item with footnote<sup id="fnref:note">'
459489
'<a class="footnote-ref" href="#fn:note">1</a></sup></li>\n'
@@ -511,7 +541,13 @@ def test_footnote_reference_within_html(self):
511541
"""Test footnote reference within HTML tags."""
512542

513543
self.assertMarkdownRenders(
514-
'A <span>footnote reference[^1] within a span element</span>.\n\n[^1]: The footnote.',
544+
self.dedent(
545+
"""
546+
A <span>footnote reference[^1] within a span element</span>.
547+
548+
[^1]: The footnote.
549+
"""
550+
),
515551
'<p>A <span>footnote reference<sup id="fnref:1">'
516552
'<a class="footnote-ref" href="#fn:1">1</a>'
517553
'</sup> within a span element</span>.</p>\n'
@@ -530,7 +566,13 @@ def test_duplicate_footnote_references(self):
530566
"""Test multiple references to the same footnote."""
531567

532568
self.assertMarkdownRenders(
533-
'First[^dup] and second[^dup] reference.\n\n[^dup]: Duplicate footnote.',
569+
self.dedent(
570+
"""
571+
First[^dup] and second[^dup] reference.
572+
573+
[^dup]: Duplicate footnote.
574+
"""
575+
),
534576
'<p>First<sup id="fnref:dup">'
535577
'<a class="footnote-ref" href="#fn:dup">1</a></sup> and second<sup id="fnref2:dup">'
536578
'<a class="footnote-ref" href="#fn:dup">1</a></sup> reference.</p>\n'
@@ -560,7 +602,13 @@ def test_footnote_definition_without_reference(self):
560602
"""Test footnote definition without corresponding reference."""
561603

562604
self.assertMarkdownRenders(
563-
'No reference here.\n\n[^orphan]: Orphaned footnote.',
605+
self.dedent(
606+
"""
607+
No reference here.
608+
609+
[^orphan]: Orphaned footnote.
610+
"""
611+
),
564612
'<p>No reference here.</p>\n'
565613
'<div class="footnote">\n'
566614
'<hr />\n'
@@ -577,7 +625,13 @@ def test_footnote_id_with_special_chars(self):
577625
"""Test footnote id containing special and Unicode characters."""
578626

579627
self.assertMarkdownRenders(
580-
'Special footnote id[^!#¤%/()=?+}{§øé].\n\n[^!#¤%/()=?+}{§øé]: The footnote.',
628+
self.dedent(
629+
"""
630+
Special footnote id[^!#¤%/()=?+}{§øé].
631+
632+
[^!#¤%/()=?+}{§øé]: The footnote.
633+
"""
634+
),
581635
'<p>Special footnote id<sup id="fnref:!#¤%/()=?+}{§øé">'
582636
'<a class="footnote-ref" href="#fn:!#¤%/()=?+}{§øé">1</a></sup>.</p>\n'
583637
'<div class="footnote">\n'

0 commit comments

Comments
 (0)