2022-04-11 18:34:09 +00:00
|
|
|
import { Tag } from "@codemirror/highlight";
|
|
|
|
import type { MarkdownConfig } from "@lezer/markdown";
|
|
|
|
import { System } from "../plugos/system";
|
|
|
|
import { Manifest } from "../common/manifest";
|
|
|
|
|
|
|
|
export type MDExt = {
|
|
|
|
// unicode char code for efficiency .charCodeAt(0)
|
|
|
|
firstCharCodes: number[];
|
|
|
|
regex: RegExp;
|
|
|
|
nodeType: string;
|
|
|
|
tag: Tag;
|
|
|
|
styles: { [key: string]: string };
|
|
|
|
};
|
|
|
|
|
|
|
|
export function mdExtensionSyntaxConfig({
|
|
|
|
regex,
|
|
|
|
firstCharCodes,
|
|
|
|
nodeType,
|
|
|
|
}: MDExt): MarkdownConfig {
|
|
|
|
return {
|
|
|
|
defineNodes: [nodeType],
|
|
|
|
parseInline: [
|
|
|
|
{
|
|
|
|
name: nodeType,
|
|
|
|
parse(cx, next, pos) {
|
|
|
|
if (!firstCharCodes.includes(next)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
let match = regex.exec(cx.slice(pos, cx.end));
|
|
|
|
if (!match) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return cx.addElement(cx.elt(nodeType, pos, pos + match[0].length));
|
|
|
|
},
|
2022-04-12 11:33:07 +00:00
|
|
|
// after: "Emphasis",
|
2022-04-11 18:34:09 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function mdExtensionStyleTags({ nodeType, tag }: MDExt): {
|
|
|
|
[selector: string]: Tag | readonly Tag[];
|
|
|
|
} {
|
|
|
|
return {
|
|
|
|
[nodeType]: tag,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function loadMarkdownExtensions(system: System<any>): MDExt[] {
|
|
|
|
let mdExtensions: MDExt[] = [];
|
|
|
|
for (let plug of system.loadedPlugs.values()) {
|
|
|
|
let manifest = plug.manifest as Manifest;
|
|
|
|
if (manifest.syntax) {
|
|
|
|
for (let [nodeType, def] of Object.entries(manifest.syntax)) {
|
|
|
|
mdExtensions.push({
|
|
|
|
nodeType,
|
|
|
|
tag: Tag.define(),
|
|
|
|
firstCharCodes: def.firstCharacters.map((ch) => ch.charCodeAt(0)),
|
|
|
|
regex: new RegExp("^" + def.regex),
|
|
|
|
styles: def.styles,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mdExtensions;
|
|
|
|
}
|