Minor engineering updates
This commit is contained in:
parent
abf1715495
commit
150db9dc52
3 changed files with 11 additions and 5 deletions
267
utility/generate-ttfa-ranges/index.mjs
Normal file
267
utility/generate-ttfa-ranges/index.mjs
Normal file
|
@ -0,0 +1,267 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import { ArrayUtil } from "../../font-src/support/utils.mjs";
|
||||
|
||||
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
setImmediate(() => {
|
||||
main().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
async function main() {
|
||||
for (const target of Targets) {
|
||||
await target.filter.load();
|
||||
}
|
||||
|
||||
const results = new Map();
|
||||
|
||||
nextChar: for (let lch = 0; lch < 0x20000; lch++) {
|
||||
for (const target of Targets) {
|
||||
if (target.filter.has(lch)) {
|
||||
const resultKey = `${target.scriptTag}-${target.featureTag}`;
|
||||
let result = results.get(resultKey);
|
||||
if (!result) {
|
||||
result = [];
|
||||
results.set(resultKey, result);
|
||||
}
|
||||
result.push(lch);
|
||||
|
||||
continue nextChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let out = [];
|
||||
|
||||
for (const [key, value] of results) {
|
||||
out.push({
|
||||
scriptTag: key.split("-")[0],
|
||||
featureTag: key.split("-")[1],
|
||||
ranges: ArrayUtil.toRanges(value)
|
||||
});
|
||||
}
|
||||
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(__dirname, "../../font-src/generated/ttfa-ranges.mjs"),
|
||||
`/* eslint-disable */\n` +
|
||||
`// Machine generated. Do not modify。\n` +
|
||||
`export default ` +
|
||||
JSON.stringify(out, null, "\t") +
|
||||
";\n"
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class InUnicodeDataSet {
|
||||
constructor(subpath) {
|
||||
this.subpath = subpath;
|
||||
this.dataset = null;
|
||||
}
|
||||
|
||||
async load() {
|
||||
if (this.dataset) return;
|
||||
const d = (await import(`@unicode/unicode-15.0.0/${this.subpath}/code-points.js`)).default;
|
||||
this.dataset = new Set(d);
|
||||
}
|
||||
|
||||
has(lch) {
|
||||
return this.dataset.has(lch);
|
||||
}
|
||||
}
|
||||
|
||||
class InScriptDataSet extends InUnicodeDataSet {
|
||||
constructor(script) {
|
||||
super(`Script/${script}`);
|
||||
}
|
||||
}
|
||||
|
||||
class InBlockDataSet extends InUnicodeDataSet {
|
||||
constructor(block) {
|
||||
super(`Block/${block}`);
|
||||
}
|
||||
}
|
||||
|
||||
class InGeneralCategoryDataSet extends InUnicodeDataSet {
|
||||
constructor(general_category) {
|
||||
super(`General_Category/${general_category}`);
|
||||
}
|
||||
}
|
||||
|
||||
class InString {
|
||||
constructor(s) {
|
||||
this.s = s;
|
||||
this.dataset = null;
|
||||
}
|
||||
|
||||
async load() {
|
||||
if (this.dataset) return;
|
||||
this.dataset = new Set(this.s);
|
||||
}
|
||||
|
||||
has(lch) {
|
||||
return this.dataset.has(String.fromCodePoint(lch));
|
||||
}
|
||||
}
|
||||
|
||||
class Negation {
|
||||
constructor(operand) {
|
||||
this.operand = operand;
|
||||
}
|
||||
async load() {
|
||||
await this.operand.load();
|
||||
}
|
||||
has(lch) {
|
||||
return !this.operand.has(lch);
|
||||
}
|
||||
}
|
||||
|
||||
class Conjunct {
|
||||
constructor(operands) {
|
||||
this.operands = operands;
|
||||
}
|
||||
async load() {
|
||||
for (const operand of this.operands) await operand.load();
|
||||
}
|
||||
has(lch) {
|
||||
for (const operand of this.operands) if (!operand.has(lch)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Disjunct {
|
||||
constructor(operands) {
|
||||
this.operands = operands;
|
||||
}
|
||||
async load() {
|
||||
for (const operand of this.operands) await operand.load();
|
||||
}
|
||||
has(lch) {
|
||||
for (const operand of this.operands) if (operand.has(lch)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Script = s => new InScriptDataSet(s);
|
||||
const Block = b => new InBlockDataSet(b);
|
||||
const GeneralCategory = gc => new InGeneralCategoryDataSet(gc);
|
||||
const In = s => new InString(s);
|
||||
|
||||
const All = (...operands) => new Conjunct(operands);
|
||||
const Either = (...operands) => new Disjunct(operands);
|
||||
const Not = operand => new Negation(operand);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const LatinBase = {
|
||||
scriptTag: "latn",
|
||||
featureTag: "dflt",
|
||||
filter: Either(
|
||||
All(
|
||||
Script("Latin"),
|
||||
Either(GeneralCategory("Uppercase_Letter"), GeneralCategory("Lowercase_Letter")),
|
||||
Not(Block("Halfwidth_And_Fullwidth_Forms"))
|
||||
),
|
||||
Block("Currency_Symbols"),
|
||||
All(Block("Letterlike_Symbols"), Not(In("℀℁⅍℠℡™℻")))
|
||||
)
|
||||
};
|
||||
const CyrillicBase = {
|
||||
scriptTag: "cyrl",
|
||||
featureTag: "dflt",
|
||||
filter: All(
|
||||
Script("Cyrillic"),
|
||||
Either(GeneralCategory("Uppercase_Letter"), GeneralCategory("Lowercase_Letter"))
|
||||
)
|
||||
};
|
||||
const GreekBase = {
|
||||
scriptTag: "grek",
|
||||
featureTag: "dflt",
|
||||
filter: All(
|
||||
Script("Greek"),
|
||||
Either(GeneralCategory("Uppercase_Letter"), GeneralCategory("Lowercase_Letter"))
|
||||
)
|
||||
};
|
||||
const DigitBase = {
|
||||
scriptTag: "latn",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("0123456789"))
|
||||
};
|
||||
|
||||
const LatinSubscript = {
|
||||
scriptTag: "latb",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("ₐₑₔₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ"))
|
||||
};
|
||||
const GreekSubscript = {
|
||||
scriptTag: "latb",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("ᵦᵧᵨᵩᵪ"))
|
||||
};
|
||||
const CyrillicSubscript = {
|
||||
scriptTag: "latb",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("𞁑𞁒𞁓𞁔𞁧𞁕𞁖𞁗𞁘𞁩𞁙𞁨𞁚𞁛𞁜𞁝𞁞𞁟𞁠𞁡𞁢𞁣𞁪𞁤𞁥𞁦"))
|
||||
};
|
||||
const DigitSubscript = {
|
||||
scriptTag: "latb",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎"))
|
||||
};
|
||||
|
||||
const LatinSuperscript = {
|
||||
scriptTag: "latp",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("ªº"), All(Script("Latin"), Either(GeneralCategory("Modifier_Letter"))))
|
||||
};
|
||||
const GreekSuperscript = {
|
||||
scriptTag: "latp",
|
||||
featureTag: "dflt",
|
||||
filter: All(Script("Greek"), Either(GeneralCategory("Modifier_Letter")))
|
||||
};
|
||||
const CyrillicSuperscript = {
|
||||
scriptTag: "latp",
|
||||
featureTag: "dflt",
|
||||
filter: All(Script("Cyrillic"), Either(GeneralCategory("Modifier_Letter")))
|
||||
};
|
||||
const DigitSuperscript = {
|
||||
scriptTag: "latp",
|
||||
featureTag: "dflt",
|
||||
filter: Either(In("⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾"))
|
||||
};
|
||||
|
||||
const LatinPunctuation = {
|
||||
scriptTag: "latn",
|
||||
featureTag: "dflt",
|
||||
filter: Either(
|
||||
Block("Basic_Latin"),
|
||||
Block("Latin_1_Supplement"),
|
||||
Block("General_Punctuation"),
|
||||
Block("Supplemental_Punctuation")
|
||||
)
|
||||
};
|
||||
|
||||
const Targets = [
|
||||
LatinBase,
|
||||
LatinSubscript,
|
||||
LatinSuperscript,
|
||||
GreekBase,
|
||||
GreekSubscript,
|
||||
GreekSuperscript,
|
||||
CyrillicBase,
|
||||
CyrillicSubscript,
|
||||
CyrillicSuperscript,
|
||||
DigitBase,
|
||||
DigitSubscript,
|
||||
DigitSuperscript,
|
||||
LatinPunctuation
|
||||
];
|
Loading…
Add table
Add a link
Reference in a new issue