From 7aace29bd33bc1734082b677c6f06aac0dcc6ac2 Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Fri, 13 Dec 2024 09:59:12 -0500 Subject: [PATCH] Backslash Unescape IDs set via `attr_list` on `toc` Fixes #1493. --- docs/changelog.md | 4 +++ markdown/extensions/toc.py | 2 +- .../test_syntax/extensions/test_attr_list.py | 6 +++++ tests/test_syntax/extensions/test_toc.py | 26 +++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 5ae254627..5ca092b23 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * DRY fix in `abbr` extension by introducing method `create_element` (#1483). +### Fixed + +* Backslash Unescape IDs set via `attr_list` on `toc` (#1493). + ## [3.7] -- 2024-08-16 ### Changed diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 5462a906c..c92f928b6 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -391,7 +391,7 @@ def run(self, doc: etree.Element) -> None: if int(el.tag[-1]) >= self.toc_top and int(el.tag[-1]) <= self.toc_bottom: toc_tokens.append({ 'level': int(el.tag[-1]), - 'id': el.attrib["id"], + 'id': unescape(el.attrib["id"]), 'name': name, 'html': innerhtml, 'data-toc-label': data_toc_label diff --git a/tests/test_syntax/extensions/test_attr_list.py b/tests/test_syntax/extensions/test_attr_list.py index e9a10960f..1a0ae12c2 100644 --- a/tests/test_syntax/extensions/test_attr_list.py +++ b/tests/test_syntax/extensions/test_attr_list.py @@ -72,6 +72,12 @@ def test_unclosed_quote_ignored(self): '

Heading

' ) + def test_backslash_escape_value(self): + self.assertMarkdownRenders( + '# `*Foo*` { id="\\*Foo\\*" }', + '

*Foo*

' + ) + def test_table_td(self): self.assertMarkdownRenders( self.dedent( diff --git a/tests/test_syntax/extensions/test_toc.py b/tests/test_syntax/extensions/test_toc.py index 9902072a2..372ba09cc 100644 --- a/tests/test_syntax/extensions/test_toc.py +++ b/tests/test_syntax/extensions/test_toc.py @@ -974,6 +974,32 @@ def test_escaped_char_in_id(self): extensions=['toc'] ) + def test_escaped_char_in_attr_list(self): + self.assertMarkdownRenders( + r'# `*Foo*` { id="\*Foo\*" }', + '

*Foo*

', + expected_attrs={ + 'toc': ( + '
\n' + '\n' # noqa + '
\n' # noqa + ), + 'toc_tokens': [ + { + 'level': 1, + 'id': '*Foo*', + 'name': '*Foo*', + 'html': '*Foo*', + 'data-toc-label': '', + 'children': [] + } + ] + }, + extensions=['toc', 'attr_list'] + ) + def testAutoLinkEmail(self): self.assertMarkdownRenders( '## ',