fStringTemplating.ts•2.28 kB
import { LanguageSupport, LRLanguage } from "@codemirror/language";
import { styleTags, tags as t } from "@lezer/highlight";
import { extractVariables, format } from "../languageUtils";
import { parser } from "./fStringTemplating.syntax.grammar";
/**
* Define the language for the FString templating system
*
* @see https://codemirror.net/examples/lang-package/
*
* @example
* ```
* {question}
*
* {{
* "answer": {answer}
* }}
* ```
* In this example, the variables are `question` and `answer`.
* Double braces are not considered as variables, and will be converted to a single brace on format.
*/
export const FStringTemplatingLanguage = LRLanguage.define({
parser: parser.configure({
props: [
// https://lezer.codemirror.net/docs/ref/#highlight.styleTags
styleTags({
// style the opening brace of a template, not floating braces
"Template/LBrace": t.quote,
// style the closing brace of a template, not floating braces
"Template/RBrace": t.quote,
// style variables (stuff inside {})
"Template/Variable": t.variableName,
// style invalid stuff, undefined tokens will be highlighted
"⚠": t.invalid,
}),
],
}),
languageData: {},
});
/**
* Generates a string representation of the parse tree of the given text
*
* Useful for debugging the parser
*/
export const debugParser = (text: string) => {
const tree = FStringTemplatingLanguage.parser.parse(text);
return tree.toString();
};
/**
* Formats an FString template with the given variables.
*/
export const formatFString = ({
text,
variables,
}: Omit<Parameters<typeof format>[0], "parser" | "postFormat">) =>
format({
parser: FStringTemplatingLanguage.parser,
text,
variables,
postFormat: (text) =>
text.replaceAll("\\{", "{").replaceAll("{{", "{").replaceAll("}}", "}"),
});
/**
* Extracts the variables from an FString template
*/
export const extractVariablesFromFString = (text: string) => {
return extractVariables({
parser: FStringTemplatingLanguage.parser,
text,
});
};
/**
* Creates a CodeMirror extension for the FString templating system
*/
export function FStringTemplating() {
return new LanguageSupport(FStringTemplatingLanguage);
}