134 lines
3.5 KiB
JavaScript
134 lines
3.5 KiB
JavaScript
const fs = require("fs-extra");
|
|
const path = require("path");
|
|
const toml = require("@iarna/toml");
|
|
|
|
module.exports = async function () {
|
|
const variantsToml = await fs.readFile(
|
|
path.join(__dirname, "../../params/variants.toml"),
|
|
"utf8"
|
|
);
|
|
const variants = toml.parse(variantsToml);
|
|
|
|
const cvData = getCvData(variants);
|
|
const ssData = getSsData(variants, cvData);
|
|
|
|
return {
|
|
cvData,
|
|
ssData,
|
|
default: variants.default,
|
|
slabDefaultOverride: variants.composite.slab
|
|
};
|
|
};
|
|
|
|
function getCvData(variants) {
|
|
const samplerGroups = new Map();
|
|
for (const selector in variants.simple) {
|
|
let config = variants.simple[selector];
|
|
if (!config.sampler) continue;
|
|
config = { selector, ...config };
|
|
let gr = samplerGroups.get(config.sampler);
|
|
if (!gr) {
|
|
gr = { configs: [] };
|
|
samplerGroups.set(config.sampler, gr);
|
|
}
|
|
gr.configs.push({
|
|
selector,
|
|
tag: config.tag || null,
|
|
tagUpright: config.tagUpright || null,
|
|
tagItalic: config.tagItalic || null,
|
|
slopeHetero: !config.variant,
|
|
sampler: config.sampler,
|
|
description: config.description
|
|
});
|
|
}
|
|
|
|
for (const [sampler, gr] of samplerGroups) {
|
|
gr.ligatureSampler = / /.test(sampler);
|
|
gr.descSampleText = gr.ligatureSampler ? sampler.split(" ") : [...sampler];
|
|
gr.configs.sort((a, b) => {
|
|
const ta = (a.tag || a.tagUpright || a.tagItalic || "").toLowerCase();
|
|
const tb = (b.tag || b.tagUpright || b.tagItalic || "").toLowerCase();
|
|
if (ta < tb) return -1;
|
|
if (ta > tb) return 1;
|
|
return 0;
|
|
});
|
|
gr.rank = rankOf(gr.descSampleText[0][0]);
|
|
}
|
|
return [...samplerGroups.values()].sort((a, b) => b.rank - a.rank);
|
|
}
|
|
|
|
function rankOf(initialChar) {
|
|
if ("a" <= initialChar && initialChar <= "z") return 3;
|
|
if ("A" <= initialChar && initialChar <= "Z") return 2;
|
|
if ("0" <= initialChar && initialChar <= "9") return 1;
|
|
return 0;
|
|
}
|
|
|
|
function getSsData(variants, cvData) {
|
|
const result = [
|
|
{
|
|
tag: "off",
|
|
effective: false,
|
|
description: "Default",
|
|
uprightComposition: [],
|
|
italicComposition: [],
|
|
hotCharSetUpright: [],
|
|
hotCharSetItalic: []
|
|
}
|
|
];
|
|
const defaultUpright = buildupComposite(
|
|
cvData,
|
|
...variants.default.design,
|
|
...variants.default.upright
|
|
);
|
|
const defaultItalic = buildupComposite(
|
|
cvData,
|
|
...variants.default.design,
|
|
...variants.default.italic
|
|
);
|
|
for (const tag in variants.composite) {
|
|
if (!/^ss\d\d$/.test(tag)) continue;
|
|
const composition = variants.composite[tag];
|
|
const upright = buildupComposite(
|
|
cvData,
|
|
...(composition.design || []),
|
|
...(composition.upright || [])
|
|
);
|
|
const italic = buildupComposite(
|
|
cvData,
|
|
...(composition.design || []),
|
|
...(composition.italic || [])
|
|
);
|
|
result.push({
|
|
tag,
|
|
effective: true,
|
|
description: composition.description,
|
|
uprightComposition: Array.from(upright.composition),
|
|
italicComposition: Array.from(italic.composition),
|
|
hotCharSetUpright: Array.from(uniqueHotChars(defaultUpright, upright.hotChars)),
|
|
hotCharSetItalic: Array.from(uniqueHotChars(defaultItalic, italic.hotChars))
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
function buildupComposite(cvData, ..._cfg) {
|
|
const hch = new Map();
|
|
const cfg = new Set(_cfg);
|
|
for (const gr of cvData) {
|
|
if (gr.ligatureSampler) continue;
|
|
for (const config of gr.configs) {
|
|
if (cfg.has(config.selector)) {
|
|
for (const ch of gr.descSampleText) hch.set(ch, config.selector);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
composition: [...cfg],
|
|
hotChars: hch
|
|
};
|
|
}
|
|
function* uniqueHotChars(cfgDefault, cfgSS) {
|
|
for (const [hc, v] of cfgSS) {
|
|
if (cfgDefault.hotChars.get(hc) !== v) yield hc;
|
|
}
|
|
}
|