Skip to content

Commit 8f68dc4

Browse files
Merge pull request #713 from apoorvdarshan/fix/header-ids-duplicate-661
Fix header-ids extra generating duplicate ids (#661)
2 parents c0a892a + 43b9f1f commit 8f68dc4

6 files changed

Lines changed: 38 additions & 3 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [pull #701] Allow boolean attribute syntax in `markdown-in-html` extra
1010
- [pull #704] Fix XSS from smuggling spans into image attributes (#702, #703)
1111
- [pull #710] Add emoji support (#709)
12+
- [pull #713] Fix `header-ids` extra generating duplicate ids when a suffixed id collides with another header (#661)
1213

1314

1415
## python-markdown2 2.5.5

lib/markdown2.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ def _setup_extras(self):
413413
if "header-ids" in self.extras:
414414
if not hasattr(self, '_count_from_header_id') or self.extras['header-ids'].get('reset-count', False):
415415
self._count_from_header_id = defaultdict(int)
416+
if not hasattr(self, '_header_ids_seen') or self.extras['header-ids'].get('reset-count', False):
417+
self._header_ids_seen = set()
416418
if "metadata" in self.extras:
417419
self.metadata: dict[str, Any] = {}
418420

@@ -1583,9 +1585,17 @@ def header_id_from_text(self,
15831585
if prefix and isinstance(prefix, str):
15841586
header_id = prefix + '-' + header_id
15851587

1586-
self._count_from_header_id[header_id] += 1
1587-
if 0 == len(header_id) or self._count_from_header_id[header_id] > 1:
1588-
header_id += '-%s' % self._count_from_header_id[header_id]
1588+
base_id = header_id
1589+
self._count_from_header_id[base_id] += 1
1590+
if 0 == len(base_id) or self._count_from_header_id[base_id] > 1:
1591+
header_id = '%s-%s' % (base_id, self._count_from_header_id[base_id])
1592+
# A suffixed id may still collide with a differently-named header
1593+
# (e.g. "# Chapter" twice yields "chapter-2", which clashes with
1594+
# "# Chapter 2"). Keep bumping until the id is genuinely unique.
1595+
while header_id in self._header_ids_seen:
1596+
self._count_from_header_id[base_id] += 1
1597+
header_id = '%s-%s' % (base_id, self._count_from_header_id[base_id])
1598+
self._header_ids_seen.add(header_id)
15891599

15901600
return header_id
15911601

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<h1 id="chapter">Chapter</h1>
2+
3+
<p>Test</p>
4+
5+
<h1 id="chapter-2">Chapter</h1>
6+
7+
<p>Test</p>
8+
9+
<h1 id="chapter-2-2">Chapter 2</h1>
10+
11+
<p>Test</p>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": ["header-ids"]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extra header-ids issue661
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Chapter
2+
3+
Test
4+
5+
# Chapter
6+
7+
Test
8+
9+
# Chapter 2
10+
11+
Test

0 commit comments

Comments
 (0)