Skip to content

Commit 566e173

Browse files
committed
fix(math): reject currency patterns and cross-line matches in inline math
Fix three bugs in INLINE_MATH_PATTERN that cause false-positive inline math detection on currency values like $51,300: 1. Add (?!\$) after opening $ to reject $$ block delimiter starts 2. Change [^$\\] to [^$\\\n] to disallow newlines (single-line only) 3. Add (?!\d) after closing $ to reject currency (GFM-compatible) 4. Remove broken (?!\s) lookahead before closing $ (was always a no-op since it checked the $ delimiter itself, not preceding content) The (?!\s) at the opening is preserved — inline math still requires non-whitespace after the opening $. Reported-by: geopanther (geopanther/mdfluence#70)
1 parent f21a29b commit 566e173

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

‎src/mistune/plugins/math.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
__all__ = ["math", "math_in_quote", "math_in_list"]
1111

1212
BLOCK_MATH_PATTERN = r"^ {0,3}\$\$[ \t]*\n(?P<math_text>[\s\S]+?)\n\$\$[ \t]*$"
13-
INLINE_MATH_PATTERN = r"\$(?!\s)(?P<math_text>(?:[^$\\]|\\.)+?)(?!\s)\$"
13+
INLINE_MATH_PATTERN = r"\$(?!\$)(?!\s)(?P<math_text>(?:[^$\\\n]|\\.)+?)\$(?!\d)"
1414

1515

1616
def parse_block_math(block: "BlockParser", m: Match[str], state: "BlockState") -> int:

‎tests/fixtures/math.txt‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,39 @@ Escaped dollar sign in math: $x=\$$
6161
.
6262
<p>Escaped dollar sign in math: <span class="math">\(x=\$\)</span></p>
6363
````````````````````````````````
64+
65+
```````````````````````````````` example
66+
The $n$th element is valid.
67+
.
68+
<p>The <span class="math">\(n\)</span>th element is valid.</p>
69+
````````````````````````````````
70+
71+
```````````````````````````````` example
72+
Result is $x^2$.
73+
.
74+
<p>Result is <span class="math">\(x^2\)</span>.</p>
75+
````````````````````````````````
76+
77+
## Currency rejection
78+
79+
```````````````````````````````` example
80+
Price is $51,300 and cost is $51,300 total.
81+
.
82+
<p>Price is $51,300 and cost is $51,300 total.</p>
83+
````````````````````````````````
84+
85+
```````````````````````````````` example
86+
The $1.6T valuation narrative.
87+
.
88+
<p>The $1.6T valuation narrative.</p>
89+
````````````````````````````````
90+
91+
## Cross-line rejection
92+
93+
```````````````````````````````` example
94+
Line one $500
95+
Line two $600
96+
.
97+
<p>Line one $500
98+
Line two $600</p>
99+
````````````````````````````````

0 commit comments

Comments
 (0)