diff --git a/docs/changelog.md b/docs/changelog.md index 33f05ce8..7676c786 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Include `scripts/*.py` in the generated source tarballs (#1430). * Ensure lines after heading in loose list are properly detabbed (#1443). * Give smarty tree processor higher priority than toc (#1440). +* Explicitly omit carot (`^`) and backslash (`\`) from abbreviations (#1444). ## [3.5.2] -- 2024-01-10 diff --git a/docs/extensions/abbreviations.md b/docs/extensions/abbreviations.md index d03651f0..a460f421 100644 --- a/docs/extensions/abbreviations.md +++ b/docs/extensions/abbreviations.md @@ -36,6 +36,14 @@ will be rendered as: is maintained by the W3C.
``` +The following three characters are not permitted in an abbreviation. Any +abbreviation defninitiosn which include one will not be recognized as an +abbreviation definition. + +1. carrot (`^`) +2. backslash (`\`) +3. left square bracket (`]`) + Usage ----- diff --git a/markdown/extensions/abbr.py b/markdown/extensions/abbr.py index 738368af..46d3f35c 100644 --- a/markdown/extensions/abbr.py +++ b/markdown/extensions/abbr.py @@ -41,7 +41,7 @@ def extendMarkdown(self, md): class AbbrPreprocessor(BlockProcessor): """ Abbreviation Preprocessor - parse text for abbr references. """ - RE = re.compile(r'^[*]\[(?P[^\]]*)\][ ]?:[ ]*\n?[ ]*(?PSome text with an ABBR ' - 'and a REF. Ignore ' - 'REFERENCE and ref.
' - ) - - def testNestedAbbr(self): - """ Test Nested Abbreviations. """ - text = '[ABBR](/foo) and _ABBR_\n\n' + \ - '*[ABBR]: Abbreviation' - self.assertEqual( - self.md.convert(text), - 'ABBR ' - 'and ABBR
' - ) - - class TestMetaData(unittest.TestCase): """ Test `MetaData` extension. """ diff --git a/tests/test_syntax/extensions/test_abbr.py b/tests/test_syntax/extensions/test_abbr.py index fbb25ffb..708af51b 100644 --- a/tests/test_syntax/extensions/test_abbr.py +++ b/tests/test_syntax/extensions/test_abbr.py @@ -95,6 +95,25 @@ def test_abbr_override(self): ) ) + def test_abbr_nested(self): + self.assertMarkdownRenders( + self.dedent( + """ + [ABBR](/foo) + + _ABBR_ + + *[ABBR]: Abbreviation + """ + ), + self.dedent( + """ + +ABBR
+ """ + ) + ) + def test_abbr_no_blank_Lines(self): self.assertMarkdownRenders( self.dedent( @@ -240,3 +259,45 @@ def test_abbr_single_quoted(self): """ ) ) + + def test_abbr_ignore_special_chars(self): + self.assertMarkdownRenders( + self.dedent( + r""" + [^] [\\] [\]] []] + + *[^]: Not an abbreviation + + *[\\]: Not an abbreviation + + *[\]]: Not an abbreviation + + *[]]: Not an abbreviation + """ + ), + self.dedent( + r""" +[^] [\] []] []]
+*[^]: Not an abbreviation
+*[\]: Not an abbreviation
+*[]]: Not an abbreviation
+*[]]: Not an abbreviation
+ """ + ) + ) + + def test_abbr_hyphen(self): + self.assertMarkdownRenders( + self.dedent( + """ + ABBR-abbr + + *[ABBR-abbr]: Abbreviation + """ + ), + self.dedent( + """ +ABBR-abbr
+ """ + ) + )