Repository navigation
fix(latex): do not re-escape a dollar that is already escaped - #15602
darkskygit merged 1 commit into
Conversation
The currency pass escapes any `$` followed by a digit, without looking at what precedes it. When the dollar is already escaped, that turns an odd backslash run even: `\$4` becomes `\\$4`, which is a literal backslash followed by an unescaped `$`. The preprocessor runs before the markdown is parsed, so remark-math can then read that `$` as an active delimiter — the opposite of what escaping it was meant to achieve. Escape only a dollar whose preceding backslash run is even, preserving the run itself. An odd run already means the dollar is escaped, so it is left alone; `$4` and `\\$4` are unaffected. `preprocessLatex` is exported so the rule can be tested directly.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe PR exports ChangesLaTeX currency escaping
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The currency escaping update preserves already escaped amounts while continuing to escape unescaped currency values. No actionable merge risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
6e036ea to
18371c5
Compare
| * @returns The preprocessed content | ||
| */ | ||
| function preprocessLatex(content: string) { | ||
| export function preprocessLatex(content: string) { |
There was a problem hiding this comment.
test can import this directly, no reason to export to global
| test.each([ | ||
| ['a plain price', 'costs $5 today', 'costs \\$5 today'], | ||
| ['a bare amount', '$4', '\\$4'], | ||
| ['two prices', 'costs $5 and $10', 'costs \\$5 and \\$10'], | ||
| ])('escapes %s', (_, markdown, expected) => { | ||
| expect(preprocessLatex(markdown)).toBe(expected); | ||
| }); |
There was a problem hiding this comment.
missing tests for the case fixed in this pr
Description
Split out of #15596 on review feedback — this is an independent, pre-existing bug in the currency pass, so it does not belong in that PR.
The currency pass escapes any
$followed by a digit without looking at what precedes it:When the dollar is already escaped, that turns an odd backslash run even:
MarkdownPreprocessorManager.processruns this before_markdownToAst, so remark-math sees that bare$and can take it as an active delimiter — the opposite of what escaping it was for.The fix
Escape only a dollar whose preceding backslash run is even, keeping the run itself:
(?<!\\)anchors the run to its start and((?:\\\\)*)takes backslashes in pairs, so an odd run never matches. Behaviour that was already correct is untouched:costs $5 todaycosts \$5 todaycosts \\$4 today(even run — literal\then a real$)costs \\\$4 todaycosts \$4 today(odd run — already escaped)costs \\$4 todaycosts \$4 todayRelationship to #15596
Both touch this file, so whichever lands second will need a trivial rebase:
exporttopreprocessLatex(the same one-word change).latex-preprocessor.unit.spec.tsthere,latex-currency-escape.unit.spec.tshere) so they do not collide. Happy to fold them into one file once both are in, if you'd prefer that.I verified this bug is not introduced by #15596:
\$4preprocesses to\\$4identically with and without that branch.Checklist
license/clacheck must be green (how it works)canarybranch and its title follows Conventional Commitsyarn lintandyarn typecheckpass locallyNotes on the checklist
CLA: not signed yet — the repository owner is signing it; the
license/clacheck will go green once that happens.Tests: 7 cases in
latex-currency-escape.unit.spec.ts. Reverting only the regex fails exactly the three already-escaped cases and leaves the four guards (plain price, bare amount, two prices, even run) green — they are regression guards, not props. Fullblocksuite/affine/allsuite: 230 passing.Lint/format:
oxlint --deny-warningsandoxfmt --checkare both clean on the two changed files.Typecheck: clean for these files. For transparency, a full
yarn typecheckon my machine also reports pre-existing@prisma/clienterrors underpackages/backend/server; those come from my installing with--mode=skip-build(soprisma generatenever ran) and are unrelated to this change.Summary by CodeRabbit
Bug Fixes
Tests