langium-cli
Version:
CLI for Langium - the language engineering tool
74 lines • 3.33 kB
JavaScript
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { GrammarAST, GrammarUtils, RegExpUtils } from 'langium';
import { expandToNode, joinToNode, toString } from 'langium/generate';
import { collectKeywords } from '../langium-util.js';
const idRegex = /^[a-zA-Z_]+$/;
export function generatePrismHighlighting(grammar, config) {
const highlighter = {};
const keywords = collectKeywords(grammar);
const terminals = getTerminals(grammar);
const modifier = config.caseInsensitive ? 'i' : '';
const commentTerminals = terminals.filter(GrammarUtils.isCommentTerminal);
if (commentTerminals.length === 1) {
highlighter.comment = {
pattern: GrammarUtils.terminalRegex(commentTerminals[0]).toString(),
greedy: true
};
}
else if (commentTerminals.length > 0) {
highlighter.comment = commentTerminals.map(e => ({
pattern: GrammarUtils.terminalRegex(e).toString(),
greedy: true
}));
}
const stringTerminal = terminals.find(e => e.name.toLowerCase() === 'string');
if (stringTerminal) {
highlighter.string = {
pattern: GrammarUtils.terminalRegex(stringTerminal).toString(),
greedy: true
};
}
const filteredKeywords = keywords.filter(e => idRegex.test(e)).sort((a, b) => b.length - a.length).map(RegExpUtils.escapeRegExp);
highlighter.keyword = {
pattern: `/\\b(${filteredKeywords.join('|')})\\b/${modifier}`
};
return generate(highlighter, config.id);
}
function generate(highlighter, languageId) {
return toString(expandToNode `
// This file is generated using a best effort guess for your language.
// It is not guaranteed contain all expected prism syntax highlighting rules.
// For more documentation, take a look at https://prismjs.com/extending.html'
Prism.languages["${languageId}"] = {
${joinToNode(Object.entries(highlighter), ([name, value]) => {
const propertyName = !idRegex.test(name) ? `"${name}"` : name;
return Array.isArray(value) ? expandToNode `
${propertyName}: [
${joinToNode(value, generateElement, { separator: ',', appendNewLineIfNotEmpty: true })}
]
` : expandToNode `
${propertyName}: ${generateElement(value)}
`;
}, { separator: ',', appendNewLineIfNotEmpty: true })}
};
`.appendNewLine());
}
function generateElement(element) {
const props = [
`pattern: ${element.pattern}`,
element.greedy ? 'greedy: true' : undefined
].filter(Boolean);
return expandToNode `
{
${joinToNode(props, { separator: ',', appendNewLineIfNotEmpty: true })}
}
`;
}
function getTerminals(grammar) {
return grammar.rules.filter(GrammarAST.isTerminalRule);
}
//# sourceMappingURL=prism-generator.js.map