xmc/bin/splitter.js

128 lines
3.2 KiB
JavaScript

const mkdirp = require("mkdirp");
const usercssMeta = require("usercss-meta");
const fs = require("fs");
const path = require("path");
/****/
const inputFile = process.argv[2];
const outputDir = process.argv[3];
if (!fs.existsSync(inputFile)) {
console.log("input does not exist");
process.exit(1);
}
if (!fs.existsSync(outputDir)) mkdirp.sync(outputDir);
const css = fs.readFileSync(inputFile, "utf8");
const files = {};
const preprocessors = {
default: true,
uso: true,
};
const usercssParser = usercssMeta.createParser({
mandatoryKeys: [],
validateKey: {
preprocessor: (state) => {
const preprocessor = state.value ?? "default";
if (!preprocessors[preprocessor])
throw new usercssMeta.ParseError({
message: `Unsupported preprocessor: ${preprocessor}`,
code: "unknownPreprocessor",
args: [state.value],
index: state.valueIndex,
});
},
},
validateVar: {
select: (state) => {
if (state.varResult.options.every((o) => o.name !== state.value)) {
throw new usercssMeta.ParseError({
code: "invalidSelectValueMismatch",
index: state.valueIndex,
});
}
},
},
});
/****/
try {
//parser won't parse \r
const cssUnixEndings = css.replace(/\r/g, "");
const parsed = usercssParser.parse(cssUnixEndings);
if (!parsed?.metadata || Object.keys(parsed.metadata).length == 0) {
console.log("UserCSS file has no valid metadata.");
process.exit(1);
}
if (parsed.errors.length > 0) {
console.log("UserCSS parsed with errors:");
for (const error of parsed.errors) {
console.log(error);
}
}
const sections = cssUnixEndings.match(/@-moz-document(.*?){\n(.*?\n)}/gs);
if (sections) {
for (const index in sections) {
const section = sections[index];
const content = section.match(/@-moz-document(.*?){\n(.*?\n)}/s)[2];
if (sections.length > 1) {
files["section-" + index] = content;
} else {
files["base"] = content;
}
}
}
for (const key of Object.keys(parsed.metadata.vars)) {
const setting = parsed.metadata.vars[key];
if (setting.type != "select") continue;
const options = setting.options.filter((x) => x.value != "");
if (options.length > 1) {
for (const option of options) {
files[
key.replace("xmc_", "") +
"/" +
option.name.toLowerCase().replace(/ /g, "_")
] = option.value;
}
} else {
files[key.replace("xmc_", "")] = options[0].value;
}
}
} catch (err) {
console.log("UserCSS parsing failed: " + err);
process.exit(1);
}
/****/
try {
for (const filePath of Object.keys(files)) {
const contents = files[filePath];
if (filePath.indexOf("/") > -1) {
const [subfolder, name] = filePath.split("/");
if (!fs.existsSync(path.join(outputDir, subfolder)))
mkdirp.sync(path.join(outputDir, subfolder));
fs.writeFileSync(
path.join(outputDir, subfolder, name + ".css"),
contents
);
} else {
fs.writeFileSync(path.join(outputDir, filePath + ".css"), contents);
}
}
} catch (err) {
console.log("Failed to write files: " + err);
process.exit(1);
}