mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-03-23 21:48:11 +00:00
87 lines
2.9 KiB
JavaScript
87 lines
2.9 KiB
JavaScript
// customMarkdownGrammar.js
|
|
|
|
// --- Custom tags with CM6-compatible class names ---
|
|
export const customTags = {
|
|
pageLine: "pageLine", // .cm-pageLine
|
|
snippetLine: "snippetLine", // .cm-snippetLine
|
|
columnSplit: "columnSplit", // .cm-columnSplit
|
|
snippetBreak: "snippetBreak", // .cm-snippetBreak
|
|
inlineBlock: "inline-block", // .cm-inline-block
|
|
block: "block", // .cm-block
|
|
emoji: "emoji", // .cm-emoji
|
|
superscript: "superscript", // .cm-superscript
|
|
subscript: "subscript", // .cm-subscript
|
|
definitionTerm: "dt-highlight", // .cm-dt-highlight
|
|
definitionDesc: "dd-highlight", // .cm-dd-highlight
|
|
injection: "injection", // .cm-injection
|
|
};
|
|
|
|
// --- Tokenizer function ---
|
|
export function tokenizeCustomMarkdown(text) {
|
|
const tokens = [];
|
|
const lines = text.split("\n");
|
|
|
|
// Track multi-line blocks
|
|
let inBlock = false;
|
|
let blockStart = 0;
|
|
|
|
lines.forEach((lineText, lineNumber) => {
|
|
// --- Page / snippet lines ---
|
|
if (/\\page/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.pageLine });
|
|
if (/\\snippet/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.snippetLine });
|
|
if (/^\\column(?:break)?$/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.columnSplit });
|
|
if (/\\snippet/.test(lineText)) tokens.push({ line: lineNumber, type: customTags.snippetBreak });
|
|
|
|
// --- Emoji ---
|
|
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 });
|
|
|
|
// --- Definition lists ---
|
|
if (/::/.test(lineText)) {
|
|
tokens.push({ line: lineNumber, type: customTags.definitionDesc });
|
|
tokens.push({ line: lineNumber, type: customTags.definitionTerm });
|
|
}
|
|
|
|
// --- Injection `{…}` ---
|
|
const injectorRegex = /{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1}/g;
|
|
let match;
|
|
while ((match = injectorRegex.exec(lineText)) !== null) {
|
|
tokens.push({
|
|
line: lineNumber,
|
|
type: customTags.injection,
|
|
from: match.index,
|
|
to: match.index + match[0].length,
|
|
});
|
|
}
|
|
|
|
// --- Inline block `{{…}}` on the same line ---
|
|
const inlineRegex = /{{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1 *}}/g;
|
|
while ((match = inlineRegex.exec(lineText)) !== null) {
|
|
tokens.push({
|
|
line: lineNumber,
|
|
type: customTags.inlineBlock,
|
|
from: match.index,
|
|
to: match.index + match[0].length,
|
|
});
|
|
}
|
|
|
|
// --- Multi-line blocks `{{…}}` --- only start/end lines
|
|
if (lineText.trimLeft().startsWith("{{") && !lineText.trimLeft().endsWith("}}")) {
|
|
inBlock = true;
|
|
blockStart = lineNumber;
|
|
tokens.push({ line: lineNumber, type: customTags.block });
|
|
}
|
|
if (lineText.trimLeft().startsWith("}}") && inBlock) {
|
|
tokens.push({ line: lineNumber, type: customTags.block });
|
|
inBlock = false;
|
|
}
|
|
|
|
|
|
});
|
|
|
|
return tokens;
|
|
}
|