diff --git a/client/components/codeEditor/codeEditor.jsx b/client/components/codeEditor/codeEditor.jsx index d6d564a60..14fd4914a 100644 --- a/client/components/codeEditor/codeEditor.jsx +++ b/client/components/codeEditor/codeEditor.jsx @@ -64,18 +64,30 @@ const customHighlightPlugin = ViewPlugin.fromClass( } } buildDecorations(view) { - const widgets = []; + const decos = []; const tokens = tokenizeCustomMarkdown(view.state.doc.toString()); - // sort by line number - tokens.sort((a, b) => a.line - b.line); - tokens.forEach((tok) => { - const line = view.state.doc.line(tok.line + 1); // CM lines are 1-based - widgets.push(Decoration.line({ class: `cm-${tok.type}` }).range(line.from)); + const line = view.state.doc.line(tok.line + 1); + + if (tok.from != null && tok.to != null) { + decos.push({ + from: line.from + tok.from, + to: line.from + tok.to, + deco: Decoration.mark({ class: `cm-${tok.type}` }), + }); + } else { + decos.push({ + from: line.from, + to: line.from, + deco: Decoration.line({ class: `cm-${tok.type}` }), + }); + } }); - return Decoration.set(widgets); + decos.sort((a, b) => a.from - b.from || a.to - b.to); + + return Decoration.set(decos.map((d) => d.deco.range(d.from, d.to))); } }, { diff --git a/client/components/codeEditor/customMarkdownGrammar.js b/client/components/codeEditor/customMarkdownGrammar.js index bc45aee28..6290982e2 100644 --- a/client/components/codeEditor/customMarkdownGrammar.js +++ b/client/components/codeEditor/customMarkdownGrammar.js @@ -36,9 +36,37 @@ export function tokenizeCustomMarkdown(text) { if (/:\w+?:/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.emoji }); // --- Superscript / Subscript --- - if (/\^\^/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.subscript }); - if (/\^/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.superscript }); + if (/\^/.test(lineText)) { + let startIndex = lineText.indexOf("^"); + const superRegex = /\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/gy; + const subRegex = /\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/gy; + while (startIndex >= 0) { + superRegex.lastIndex = subRegex.lastIndex = startIndex; + + let match = subRegex.exec(lineText); + let type = customTags.subscript; + + if (!match) { + match = superRegex.exec(lineText); + type = customTags.superscript; + } + + if (match) { + tokens.push({ + line: lineNumber, + type, + from: match.index, + to: match.index + match[0].length, + }); + } + + startIndex = lineText.indexOf( + "^", + Math.max(startIndex + 1, superRegex.lastIndex || 0, subRegex.lastIndex || 0), + ); + } + }; // --- Definition lists --- if (/::/.test(lineText)) { tokens.push({ line: lineNumber, type: customTags.definitionDesc }); @@ -78,8 +106,6 @@ export function tokenizeCustomMarkdown(text) { tokens.push({ line: lineNumber, type: customTags.block }); inBlock = false; } - - }); return tokens;