diff --git a/CHANGES.md b/CHANGES.md index afb0be54..93e5b900 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ## python-markdown2 2.5.6 (not yet released) +- [pull #762] Speed up documents with many links by skipping the backslash-escape scan for text without a backslash - [pull #746] Preserve query strings and fragments in `markdown-file-links` conversions, including reference-link targets. - [pull #739] Fix `header-ids` extra putting sanitized HTML into header ids in safe mode, which allowed attribute injection (#649) - [pull #732] Fix excessive CPU use in the inline HTML tokenizer on repeated unclosed tag fragments (#707) diff --git a/lib/markdown2.py b/lib/markdown2.py index e35bf5d2..9be0a262 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2371,6 +2371,9 @@ def incomplete_tags_sub(match): return text def _encode_backslash_escapes(self, text: str) -> str: + # Every search string below starts with a backslash. + if '\\' not in text: + return text for ch, escape in list(self._escape_table.items()): text = text.replace("\\"+ch, escape) return text diff --git a/test/test_markdown2.py b/test/test_markdown2.py index f4d105ac..1a69c5b7 100755 --- a/test/test_markdown2.py +++ b/test/test_markdown2.py @@ -254,6 +254,17 @@ def test_many_distinct_code_spans(self): expected = '\n\n'.join('

value_%s

' % i for i in range(1000)) + '\n' self.assertEqual(markdown2.markdown(source), expected) + def test_many_links_with_backslash_escapes(self): + link = 'Paragraph %s has [a link](https://example.com/%s).' + html = ('

Paragraph %s has ' + 'a link.

') + escaped = r'An \*escaped\* star and a C:\dir path.' + source = '\n\n'.join([link % (i, i) for i in range(1000)] + [escaped]) + expected = '\n\n'.join( + [html % (i, i) for i in range(1000)] + + [r'

An *escaped* star and a C:\dir path.

']) + '\n' + self.assertEqual(markdown2.markdown(source), expected) + def test_unescape_nested_tokens(self): md = markdown2.Markdown() md.reset()