fix(math): $…$ inside a backtick code span stays literal (#194 P4-4)
Verifying the KaTeX checklist: `$x^2$` in inline code was turned into math and the backticks were left as literal text, because the math split runs before markdown. The splitter now skips backtick code spans (N ticks close with N), so markdown's inline code wins: wire is <code>$y^2$</code>. Fenced blocks were already fine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -81,3 +81,18 @@ test('block and inline mixed with text', () => {
|
||||
{ type: 'text', value: ' ok' },
|
||||
]);
|
||||
});
|
||||
|
||||
test('math inside a backtick code span stays literal text (#194 P4-4)', () => {
|
||||
assert.deepEqual(splitMathSegments('inline `$y^2$` here'), [
|
||||
{ type: 'text', value: 'inline `$y^2$` here' },
|
||||
]);
|
||||
assert.deepEqual(splitMathSegments('``$a$`` and $b$'), [
|
||||
{ type: 'text', value: '``$a$`` and ' },
|
||||
{ type: 'inline', value: 'b' },
|
||||
]);
|
||||
// An unclosed backtick is just a character.
|
||||
assert.deepEqual(splitMathSegments('tick ` then $c$'), [
|
||||
{ type: 'text', value: 'tick ` then ' },
|
||||
{ type: 'inline', value: 'c' },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -88,6 +88,23 @@ export const splitMathSegments = (text: string): MathSegment[] => {
|
||||
};
|
||||
|
||||
while (i < text.length) {
|
||||
// Backtick code spans are literal: `$x$` inside them must stay text so
|
||||
// markdown's inline code wins (a run of N backticks closes with N).
|
||||
if (text[i] === '`') {
|
||||
let ticks = 0;
|
||||
while (text[i + ticks] === '`') ticks += 1;
|
||||
const fence = '`'.repeat(ticks);
|
||||
const close = text.indexOf(fence, i + ticks);
|
||||
if (close !== -1) {
|
||||
buffer += text.slice(i, close + ticks);
|
||||
i = close + ticks;
|
||||
continue;
|
||||
}
|
||||
buffer += fence;
|
||||
i += ticks;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Escaped dollar: consume `\$` and emit a literal `$` as text.
|
||||
if (text[i] === '\\' && text[i + 1] === '$') {
|
||||
buffer += '$';
|
||||
|
||||
Reference in New Issue
Block a user