83 lines
1.8 KiB
TypeScript
83 lines
1.8 KiB
TypeScript
import { StreamLanguage } from "@codemirror/language";
|
|
|
|
const mermaidStreamParser = StreamLanguage.define({
|
|
token(stream) {
|
|
// Comments: %%...
|
|
if (stream.match(/^%%.*$/)) {
|
|
return "comment";
|
|
}
|
|
|
|
// Strings
|
|
if (stream.match(/^"(?:[^"\\]|\\.)*"/)) {
|
|
return "string";
|
|
}
|
|
|
|
// Diagram type keywords (at start of line or after whitespace)
|
|
if (
|
|
stream.match(
|
|
/^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey|gitGraph|timeline|quadrantChart|sankey|xychart)\b/i,
|
|
)
|
|
) {
|
|
return "keyword";
|
|
}
|
|
|
|
// Direction keywords
|
|
if (stream.match(/^(TB|TD|BT|RL|LR)\b/)) {
|
|
return "keyword";
|
|
}
|
|
|
|
// Keywords
|
|
if (
|
|
stream.match(
|
|
/^(subgraph|end|participant|actor|loop|alt|else|opt|par|critical|break|rect|note|over|activate|deactivate|title|section|class|style|linkStyle|classDef|click)\b/i,
|
|
)
|
|
) {
|
|
return "keyword";
|
|
}
|
|
|
|
// Arrows: -->, ---, -.->, ===>, etc.
|
|
if (stream.match(/^[-.=<>|ox]+>/)) {
|
|
return "operator";
|
|
}
|
|
if (stream.match(/^<[-.=<>|ox]+/)) {
|
|
return "operator";
|
|
}
|
|
if (stream.match(/^--+|\.\.+|==+/)) {
|
|
return "operator";
|
|
}
|
|
|
|
// Labels in brackets/parens: [text], (text), {text}, ((text)), etc.
|
|
if (stream.match(/^[[\](){}|<>]/)) {
|
|
return "bracket";
|
|
}
|
|
|
|
// Node IDs (alphanumeric)
|
|
if (stream.match(/^[A-Za-z_][A-Za-z0-9_]*/)) {
|
|
return "variableName";
|
|
}
|
|
|
|
// Numbers
|
|
if (stream.match(/^\d+(\.\d+)?/)) {
|
|
return "number";
|
|
}
|
|
|
|
// Punctuation
|
|
if (stream.match(/^[,:;]/)) {
|
|
return "punctuation";
|
|
}
|
|
|
|
// Skip whitespace
|
|
if (stream.eatSpace()) {
|
|
return null;
|
|
}
|
|
|
|
// Skip any other character
|
|
stream.next();
|
|
return null;
|
|
},
|
|
});
|
|
|
|
export function mermaidLite() {
|
|
return mermaidStreamParser;
|
|
}
|