Skip to content

Commit 6e89cff

Browse files
Merge pull request #743 from ybai08/fix/header-ids-from-rendered-text
Add a strip-syntax option to header-ids to keep markdown syntax out of ids (#192)
2 parents adee453 + fe89c28 commit 6e89cff

18 files changed

Lines changed: 126 additions & 3 deletions

‎CHANGES.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- [pull #734] Fix empty list items being parsed as nested lists (#167)
2525
- [pull #735] Fix `smarty-pants` extra converting quotes inside inline HTML tags and comments (#150)
2626
- [pull #737] Fix XSS from code spans that the span gamut doesn't treat as code spans in safe mode (#726)
27+
- [pull #743] Add a `strip-syntax` option to the `header-ids` extra that leaves link URLs, image paths, inline HTML tags and emphasis markers out of header ids (#192)
2728
- [pull #747] Fix `link-patterns` extra linking text inside Markdown links and images whose label wraps onto another line
2829

2930

‎lib/markdown2.py‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@
5656
* footnotes: Support footnotes as in use on daringfireball.net and
5757
implemented in other Markdown processors (tho not in Markdown.pl v1.0.1).
5858
* header-ids: Adds "id" attributes to headers. The id value is a slug of
59-
the header text.
59+
the header text. With `{"strip-syntax": True}`, the slug is made from the
60+
rendered header, so link URLs, image paths, inline HTML tags and emphasis
61+
markers are left out of it.
6062
* highlightjs-lang: Allows specifying the language which used for syntax
6163
highlighting when using fenced-code-blocks and highlightjs.
6264
* html-classes: Takes a dict mapping html tag names (lowercase) to a
@@ -1667,6 +1669,8 @@ def _do_links(self, text: str) -> str:
16671669
text = link_processor.run(text)
16681670
return text
16691671

1672+
_html_tag_re = re.compile(r'<[^>]*>')
1673+
16701674
def header_id_from_text(self,
16711675
text: str,
16721676
prefix: str,
@@ -1751,16 +1755,26 @@ def _h_sub(self, match: re.Match[str]) -> str:
17511755
if demote_headers:
17521756
n = min(n + demote_headers, 6)
17531757
header_id_attr = ""
1758+
html = self._run_span_gamut(header_group)
17541759
if "header-ids" in self.extras:
17551760
# in safe mode, inline HTML is hashed by now. Unhash it so the
17561761
# sanitized HTML doesn't get swapped back into the id attribute
1757-
header_text = self._unhash_html_spans(header_group)
1762+
if self.extras["header-ids"].get('strip-syntax'):
1763+
# build the id from the rendered header so that markdown syntax
1764+
# (link URLs, image paths, emphasis markers) doesn't end up in it.
1765+
header_text = self._html_tag_re.sub('', self._unhash_html_spans(html))
1766+
if "footnotes" in self.extras:
1767+
# footnote refs are numbered later on. Drop the placeholder
1768+
# so it doesn't end up in the id
1769+
marker = self._footnote_marker + '-'
1770+
header_text = header_text.replace(marker, '')
1771+
else:
1772+
header_text = self._unhash_html_spans(header_group)
17581773
header_id = self.header_id_from_text(
17591774
self._unescape_special_chars(header_text),
17601775
self.extras["header-ids"].get('prefix'), n)
17611776
if header_id:
17621777
header_id_attr = ' id="%s"' % header_id
1763-
html = self._run_span_gamut(header_group)
17641778
if "toc" in self.extras and header_id:
17651779
self._toc_add_entry(n, header_id, html)
17661780
return "<h%d%s>%s</h%d>\n\n" % (n, header_id_attr, html, n)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h1 id="header-with-a-footnote1">Header with a footnote<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></h1>
2+
3+
<h1 id="linked-headernote"><a href="http://example.com">Linked</a> header<sup class="footnote-ref" id="fnref-note"><a href="#fn-note">2</a></sup></h1>
4+
5+
<div class="footnotes">
6+
<hr />
7+
<ol>
8+
<li id="fn-1">
9+
<p>The first note.&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
10+
</li>
11+
12+
<li id="fn-note">
13+
<p>The second note.&#160;<a href="#fnref-note" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">&#8617;</a></p>
14+
</li>
15+
</ol>
16+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": {"header-ids": {"strip-syntax": True}, "footnotes": None}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extra header-ids footnotes issue192
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Header with a footnote[^1]
2+
3+
# [Linked](http://example.com) header[^note]
4+
5+
[^1]: The first note.
6+
[^note]: The second note.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h1 id="header-with-a-footnote1">Header with a footnote<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></h1>
2+
3+
<h1 id="linkedhttpexamplecom-headernote"><a href="http://example.com">Linked</a> header<sup class="footnote-ref" id="fnref-note"><a href="#fn-note">2</a></sup></h1>
4+
5+
<div class="footnotes">
6+
<hr />
7+
<ol>
8+
<li id="fn-1">
9+
<p>The first note.&#160;<a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">&#8617;</a></p>
10+
</li>
11+
12+
<li id="fn-note">
13+
<p>The second note.&#160;<a href="#fnref-note" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">&#8617;</a></p>
14+
</li>
15+
</ol>
16+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": ["header-ids", "footnotes"]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extra header-ids footnotes issue192
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Header with a footnote[^1]
2+
3+
# [Linked](http://example.com) header[^note]
4+
5+
[^1]: The first note.
6+
[^note]: The second note.

0 commit comments

Comments
 (0)