1
0
silverbullet/packages/common/markdown/markdown.ts
2022-06-13 18:31:36 +02:00

73 lines
1.9 KiB
TypeScript

import {
Language,
defineLanguageFacet,
languageDataProp,
foldNodeProp,
indentNodeProp,
LanguageDescription,
ParseContext,
} from "@codemirror/language";
import {
parser as baseParser,
MarkdownParser,
GFM,
Subscript,
Superscript,
Emoji,
} from "@lezer/markdown";
const data = defineLanguageFacet({ block: { open: "<!--", close: "-->" } });
export const commonmark = baseParser.configure({
props: [
foldNodeProp.add((type) => {
if (!type.is("Block") || type.is("Document")) return undefined;
return (tree, state) => ({
from: state.doc.lineAt(tree.from).to,
to: tree.to,
});
}),
indentNodeProp.add({
Document: () => null,
}),
languageDataProp.add({
Document: data,
}),
],
});
export function mkLang(parser: MarkdownParser) {
return new Language(data, parser);
}
/// Language support for strict CommonMark.
export const commonmarkLanguage = mkLang(commonmark);
const extended = commonmark.configure([GFM, Subscript, Superscript, Emoji]);
/// Language support for [GFM](https://github.github.com/gfm/) plus
/// subscript, superscript, and emoji syntax.
export const markdownLanguage = mkLang(extended);
export function getCodeParser(
languages:
| readonly LanguageDescription[]
| ((info: string) => Language | LanguageDescription | null)
| undefined,
defaultLanguage?: Language
) {
return (info: string) => {
if (info && languages) {
let found = null;
if (typeof languages == "function") found = languages(info);
else found = LanguageDescription.matchLanguageName(languages, info, true);
if (found instanceof LanguageDescription)
return found.support
? found.support.language.parser
: ParseContext.getSkippingParser(found.load());
else if (found) return found.parser;
}
return defaultLanguage ? defaultLanguage.parser : null;
};
}