Files
micronomicon/frontend/src/components/editor/micronHighlight.ts
2026-04-01 00:53:55 +02:00

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)];
}