58 lines
2.6 KiB
TypeScript
58 lines
2.6 KiB
TypeScript
import { StreamLanguage, HighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
import { tags } from "@lezer/highlight";
|
|
|
|
const micronLanguage = StreamLanguage.define({
|
|
token(stream) {
|
|
if (stream.sol()) {
|
|
// Depth-4+ indent (before >>> so ">>>> " doesn't match heading3)
|
|
if (stream.match(/>>>>/)) { stream.skipToEnd(); return "keyword"; }
|
|
// Headings — longest prefix first
|
|
if (stream.match(/>>>/)) { stream.skipToEnd(); return "heading3"; }
|
|
if (stream.match(/>>/)) { stream.skipToEnd(); return "heading2"; }
|
|
if (stream.match(/>/)) { stream.skipToEnd(); return "heading1"; }
|
|
// Dividers: line starting with - followed by a non-space, non-dash char
|
|
if (stream.match(/-[^\s\-]/)) { stream.skipToEnd(); return "contentSeparator"; }
|
|
// Comment lines
|
|
if (stream.match(/#/)) { stream.skipToEnd(); return "lineComment"; }
|
|
// Standalone depth-reset "<"
|
|
if (stream.string.trim() === "<") { stream.next(); return "meta"; }
|
|
}
|
|
|
|
// Backtick-based format tags: `! `* `_ `` `F `f `B `b `c `r `l `a `= `<
|
|
if (stream.match(/`[!*_`FfBbCcRrLlAa=<]/)) return "meta";
|
|
|
|
// Hex color values (exactly 3 hex digits) — appear right after `F or `B tags
|
|
if (stream.match(/[0-9a-fA-F]{3}(?![0-9a-fA-F])/)) return "number";
|
|
|
|
// Links [label`url] — consume the whole bracket expression
|
|
if (stream.match(/\[[^\]]*\]/)) return "link";
|
|
|
|
// Form elements <fieldname`default> etc.
|
|
if (stream.match(/<[^>]+>/)) return "string";
|
|
|
|
stream.next();
|
|
return null;
|
|
},
|
|
startState: () => ({}),
|
|
copyState: (s) => ({ ...s }),
|
|
blankLine: () => {},
|
|
languageData: {},
|
|
});
|
|
|
|
const micronStyle = HighlightStyle.define([
|
|
{ tag: tags.heading1, color: "#7ee8a2", fontWeight: "bold" },
|
|
{ tag: tags.heading2, color: "#70c4e8", fontWeight: "bold" },
|
|
{ tag: tags.heading3, color: "#a8c4e8", fontWeight: "bold" },
|
|
{ tag: tags.keyword, color: "#c9d1d9", fontStyle: "italic" }, // depth-4+ indent
|
|
{ tag: tags.contentSeparator, color: "#484f58", fontStyle: "italic" },
|
|
{ tag: tags.lineComment, color: "#484f58", fontStyle: "italic" }, // # comments
|
|
{ tag: tags.meta, color: "#d2a8ff" }, // backtick format codes
|
|
{ tag: tags.number, color: "#f8d4a8" }, // hex color values
|
|
{ tag: tags.link, color: "#7dc4e4", textDecoration: "underline" },
|
|
{ tag: tags.string, color: "#d4a8f8" }, // form elements
|
|
]);
|
|
|
|
export function micronHighlight() {
|
|
return [micronLanguage, syntaxHighlighting(micronStyle)];
|
|
}
|