diff --git a/services/web/frontend/js/features/source-editor/lezer-typst/tokens.mjs b/services/web/frontend/js/features/source-editor/lezer-typst/tokens.mjs index 557614d5ec..186b9945c4 100644 --- a/services/web/frontend/js/features/source-editor/lezer-typst/tokens.mjs +++ b/services/web/frontend/js/features/source-editor/lezer-typst/tokens.mjs @@ -105,6 +105,20 @@ export const rawTokenizer = new ExternalTokenizer( } if (stack.canShift(RawBlockBody)) { + // Guard: must genuinely follow a RawBlockOpen (which ends with \n). + // Walk backward past any lang tag (A-Za-z0-9) and require ```. + // This blocks spurious LALR-merged states from consuming body text. + if (input.peek(-1) !== NEWLINE) return + let back = -2 + while ( + (input.peek(back) >= 65 && input.peek(back) <= 90) || + (input.peek(back) >= 97 && input.peek(back) <= 122) || + (input.peek(back) >= 48 && input.peek(back) <= 57) + ) { back-- } + if (input.peek(back) !== BACKTICK || + input.peek(back - 1) !== BACKTICK || + input.peek(back - 2) !== BACKTICK) return + let hasContent = false while (input.next !== -1) { if (