// cuts the fonts down to the characters the site uses, before astro builds. fontsource's latin
// files carry every latin-1 letter and symbol, about 40% more than english docs need, so this
// keeps printable ascii plus whatever else appears in docs/ and the site's own source. a
// character outside that falls back to a system font, same as anything outside latin did.
// the output lands in src/fonts (ignored by git), and vite hashes it like any other asset, so
// a doc that brings in a new character changes the file name too.
import fs from "node:fs";
import path from "node:path";
import subsetFont from "subset-font";
const FACES = [
["hanken-grotesk", "latin-400-normal"],
["hanken-grotesk", "latin-400-italic"],
["hanken-grotesk", "latin-700-normal"],
["geist-mono", "latin-400-normal"],
["geist-mono", "latin-600-normal"],
];
function textIn(dir: string, exts: string[]): string {
return fs
.readdirSync(dir, { recursive: true, encoding: "utf8" })
.filter((f) => exts.includes(path.extname(f)))
.map((f) => fs.readFileSync(path.join(dir, f), "utf8"))
.join("");
}
const ascii = Array.from({ length: 0x7f - 0x20 }, (_, i) => String.fromCharCode(0x20 + i)).join("");
const text = [...new Set(ascii + textIn("../docs", [".md"]) + textIn("src", [".astro", ".ts"]))].join("");
fs.mkdirSync("src/fonts", { recursive: true });
for (const [pkg, face] of FACES) {
const font = fs.readFileSync(`node_modules/@fontsource/${pkg}/files/${pkg}-${face}.woff2`);
const cut = await subsetFont(font, text, { targetFormat: "woff2" });
fs.writeFileSync(`src/fonts/${pkg}-${face}.woff2`, cut);
}