From ea0c337409f46d066615ada773f3d33c019d1924 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Sun, 28 Sep 2025 12:28:19 +0100 Subject: [PATCH] Fix code friendly preventing other syntax from being processed (issue #638) --- CHANGES.md | 2 +- lib/markdown2.py | 26 +++++++++++++++-------- test/tm-cases/code_friendly_issue638.html | 1 + test/tm-cases/code_friendly_issue638.opts | 1 + test/tm-cases/code_friendly_issue638.text | 1 + 5 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 test/tm-cases/code_friendly_issue638.html create mode 100644 test/tm-cases/code_friendly_issue638.opts create mode 100644 test/tm-cases/code_friendly_issue638.text diff --git a/CHANGES.md b/CHANGES.md index 920c3024..40fd25cc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.5.5 (not yet released) -(nothing yet) +- [pull #640] Fix code friendly extra stopping other syntax being processed (#638) ## python-markdown2 2.5.4 diff --git a/lib/markdown2.py b/lib/markdown2.py index b706215f..24841f55 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2960,20 +2960,28 @@ class CodeFriendly(ItalicAndBoldProcessor): ''' name = 'code-friendly' + def __init__(self, md, options): + super().__init__(md, options) + + # add a prefix to it so we don't interfere with escaped/hashed chars from other stages + self.hash_table[_hash_text(self.name + '_')] = '_' + self.hash_table[_hash_text(self.name + '__')] = '__' + def sub(self, match: re.Match) -> str: syntax = match.group(1) text: str = match.string[match.start(): match.end()] if '_' in syntax: - # if using _this_ syntax, hash the whole thing so that it doesn't get processed - key = _hash_text(text) - self.hash_table[key] = text - return key + # if using _this_ syntax, hash it to avoid processing, but don't hash the contents incase of nested syntax + text = text.replace(syntax, _hash_text(self.name + syntax)) + return text elif '_' in text: - # if the text within the bold/em markers contains '_' then hash those contents to protect them from em_re - text = text[len(syntax): -len(syntax)] - key = _hash_text(text) - self.hash_table[key] = text - return syntax + key + syntax + # if the text within the bold/em markers contains '_' then hash those chars to protect them from em_re + text = ( + text[len(syntax): -len(syntax)] + .replace('__', _hash_text(self.name + '__')) + .replace('_', _hash_text(self.name + '_')) + ) + return syntax + text + syntax # if no underscores are present, the text is fine and we can just leave it alone return super().sub(match) diff --git a/test/tm-cases/code_friendly_issue638.html b/test/tm-cases/code_friendly_issue638.html new file mode 100644 index 00000000..c28476e3 --- /dev/null +++ b/test/tm-cases/code_friendly_issue638.html @@ -0,0 +1 @@ +

a_b this should be bold c_d this is bold

diff --git a/test/tm-cases/code_friendly_issue638.opts b/test/tm-cases/code_friendly_issue638.opts new file mode 100644 index 00000000..245e9828 --- /dev/null +++ b/test/tm-cases/code_friendly_issue638.opts @@ -0,0 +1 @@ +{"extras":["code-friendly"]} \ No newline at end of file diff --git a/test/tm-cases/code_friendly_issue638.text b/test/tm-cases/code_friendly_issue638.text new file mode 100644 index 00000000..a015bf5c --- /dev/null +++ b/test/tm-cases/code_friendly_issue638.text @@ -0,0 +1 @@ +a_b this should be **bold** c_d this is **bold** \ No newline at end of file