Repository: Python-Markdown/markdown (python)

Issue:
Abbreviation extension should not inject markup in mathjax contexts
Assume we have defined an abbreviation

```
*[YAFR]: Yet Another Feature Request
```

Then the following markdown

```markdown
Our function $f_\text{YAFR}$ does some things
```

will be expanded to (something like):

```
Our function $f_\text{<abbr title="Yet Another Feature Request">YAFR</abbr>}$ does some things
```

This will cause a maths renderer like [mathjax](https://www.mathjax.org/) to fail. It is actually rather common to add subindices to notation in maths that refer to abbreviations defined in the text, so I think it would be nice to have the extension not try to expand the text.

Pull request:
Abbr should respect AtomicStrings
Fixes #1512

Patch:
diff --git a/.pyspelling.yml b/.pyspelling.yml
index bede971..62ad026 100644
--- a/.pyspelling.yml
+++ b/.pyspelling.yml
@@ -20,6 +20,7 @@ matrix:
       - alt
       ignores:
       - 'code, pre'
+      - '.autorefs-internal[title]'
       captures:
       - '[role=main] *|*:not(script,style)'
   - pyspelling.filters.context:
diff --git a/docs/changelog.md b/docs/changelog.md
index 34817bd..29ff8d3 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * `md_in_html` handle tags within inline code blocks better (#1075).
 * `md_in_html` fix handling of one-liner block HTML handling (#1074).
 * Ensure `<center>` is treated like a block-level element (#1481).
+* Ensure that `abbr` extension respects `AtomicString` and does not process
+  perceived abbreviations in these strings (#1512).
 
 ## [3.7] -- 2024-08-16
 
diff --git a/markdown/extensions/abbr.py b/markdown/extensions/abbr.py
index 36c1d91..ab7c374 100644
--- a/markdown/extensions/abbr.py
+++ b/markdown/extensions/abbr.py
@@ -98,20 +98,22 @@ class AbbrTreeprocessor(Treeprocessor):
         for child in reversed(el):
             self.iter_element(child, el)
         if text := el.text:
-            for m in reversed(list(self.RE.finditer(text))):
-                if self.abbrs[m.group(0)]:
-                    abbr = self.create_element(self.abbrs[m.group(0)], m.group(0), text[m.end():])
-                    el.insert(0, abbr)
-                    text = text[:m.start()]
-            el.text = text
+            if not isinstance(text, AtomicString):
+                for m in reversed(list(self.RE.finditer(text))):
+                    if self.abbrs[m.group(0)]:
+                        abbr = self.create_element(self.abbrs[m.group(0)], m.group(0), text[m.end():])
+                        el.insert(0, abbr)
+                        text = text[:m.start()]
+                el.text = text
         if parent is not None and el.tail:
             tail = el.tail
             index = list(parent).index(el) + 1
-            for m in reversed(list(self.RE.finditer(tail))):
-                abbr = self.create_element(self.abbrs[m.group(0)], m.group(0), tail[m.end():])
-                parent.insert(index, abbr)
-                tail = tail[:m.start()]
-            el.tail = tail
+            if not isinstance(tail, AtomicString):
+                for m in reversed(list(self.RE.finditer(tail))):
+                    abbr = self.create_element(self.abbrs[m.group(0)], m.group(0), tail[m.end():])
+                    parent.insert(index, abbr)
+                    tail = tail[:m.start()]
+                el.tail = tail
 
     def run(self, root: etree.Element) -> etree.Element | None:
         ''' Step through tree to find known abbreviations. '''


Test patch:
diff --git a/tests/test_syntax/extensions/test_abbr.py b/tests/test_syntax/extensions/test_abbr.py
index 9d3ebb2..32016e1 100644
--- a/tests/test_syntax/extensions/test_abbr.py
+++ b/tests/test_syntax/extensions/test_abbr.py
@@ -30,6 +30,18 @@ class TestAbbr(TestCase):
 
     default_kwargs = {'extensions': ['abbr']}
 
+    def test_ignore_atomic(self):
+        self.assertMarkdownRenders(
+            self.dedent(
+                """
+                This <https://example.com/{YAFR}>
+
+                *[YAFR]: Yet Another Feature Request
+                """
+            ),
+            '<p>This <a href="https://example.com/{YAFR}">https://example.com/{YAFR}</a></p>'
+        )
+
     def test_abbr_upper(self):
         self.assertMarkdownRenders(
             self.dedent(