diff --git a/services/web/frontend/js/features/source-editor/languages/typst/document-outline.ts b/services/web/frontend/js/features/source-editor/languages/typst/document-outline.ts index c769547df8..b416f32e07 100644 --- a/services/web/frontend/js/features/source-editor/languages/typst/document-outline.ts +++ b/services/web/frontend/js/features/source-editor/languages/typst/document-outline.ts @@ -35,8 +35,11 @@ function computeOutline( const depth = match[1].length const level = LEVELS[Math.min(depth, LEVELS.length) - 1] - // Strip a trailing label, e.g. '= Introduction '. - const title = match[2].replace(/\s*<[\w-]+>\s*$/, '').trim() + // Strip a trailing line comment, then a trailing label. + const title = match[2] + .replace(/\s*\/\/.*$/, '') + .replace(/\s*<[\w-]+>\s*$/, '') + .trim() items.push({ line: n, 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 5161ad47e8..bdcadf8e1a 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 @@ -60,6 +60,10 @@ export const headingTitleTokenizer = new ExternalTokenizer( (input, _stack) => { let hasContent = false while (input.next !== -1 && input.next !== NEWLINE) { + // Stop before a line comment (//) or block comment (/*) so that + // '= Heading // note' leaves the comment for the LineComment rule. + if (input.next === SLASH && + (input.peek(1) === SLASH || input.peek(1) === STAR)) break input.advance() hasContent = true }