fix: render inline math while typing

This commit is contained in:
lucaronin
2026-04-27 10:39:00 +02:00
parent 8141644729
commit 3e8a6e5d7c
7 changed files with 369 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import {
MATH_INLINE_TYPE,
injectMathInBlocks,
preProcessMathMarkdown,
readCompletedInlineMathAtEnd,
serializeMathAwareBlocks,
} from './mathMarkdown'
@@ -107,4 +108,18 @@ describe('math markdown round-trip', () => {
expect(preProcessMathMarkdown({ markdown })).toBe(markdown)
})
it('recognizes completed inline math at the end of text', () => {
expect(readCompletedInlineMathAtEnd({ text: 'Energy is $E=mc^2$' })).toEqual({
latex: 'E=mc^2',
start: 10,
end: 17,
})
})
it('ignores incomplete, escaped, and display-style dollar sequences at text end', () => {
expect(readCompletedInlineMathAtEnd({ text: 'Energy is $E=mc^2' })).toBeNull()
expect(readCompletedInlineMathAtEnd({ text: String.raw`Energy is $E=mc^2\$` })).toBeNull()
expect(readCompletedInlineMathAtEnd({ text: '$$x^2$$' })).toBeNull()
})
})

View File

@@ -55,6 +55,10 @@ interface InlineMathMatch extends LatexPayload {
end: number
}
interface CompletedInlineMathMatch extends InlineMathMatch {
start: number
}
interface MarkdownSource {
markdown: string
}
@@ -137,6 +141,30 @@ function readInlineMath({ text, index }: TextPosition): InlineMathMatch | null {
return isValidInlineLatex({ latex }) ? { latex, end } : null
}
function isCompletedInlineMathEnd({ text, index }: TextPosition): boolean {
return isInlineMathEnd({ text, index }) && text[index - 1] !== '$'
}
function findCompletedInlineMathStart({ text, index: end }: TextPosition): number {
for (let i = end - 1; i >= 0; i--) {
if (isInlineMathEnd({ text, index: i }) && text[i - 1] !== '$') {
return i
}
}
return -1
}
export function readCompletedInlineMathAtEnd({ text }: { text: string }): CompletedInlineMathMatch | null {
const end = text.length - 1
if (end < 1 || !isCompletedInlineMathEnd({ text, index: end })) return null
const start = findCompletedInlineMathStart({ text, index: end })
if (start === -1) return null
const latex = text.slice(start + 1, end)
return isValidInlineLatex({ latex }) ? { latex, start, end } : null
}
function replaceInlineMath({ line }: MarkdownLine): string {
let result = ''
let index = 0