2024-06-21 19:17:32 +00:00
|
|
|
import File from "vinyl";
|
|
|
|
import tmp from "tmp";
|
|
|
|
import { execFile } from "node:child_process";
|
|
|
|
import { readFileSync, unlinkSync } from "node:fs";
|
|
|
|
import hashPaths from "../hash.js";
|
2024-06-26 21:42:33 +00:00
|
|
|
import { src, then, synchronise, dest } from "../rx-utils.js";
|
|
|
|
import { map } from "rxjs";
|
2024-06-21 19:17:32 +00:00
|
|
|
|
|
|
|
const FONT_PRESETS = {
|
|
|
|
mono: { ranges: ["20-7F", "2205", "2E22-2E25", "2713", "2717"] },
|
|
|
|
text: { ranges: ["20-7F", "A0-FF", "2000-206F", "20AC"] },
|
|
|
|
};
|
|
|
|
|
2024-06-26 21:42:33 +00:00
|
|
|
function compileFont(font: File): Promise<File> {
|
|
|
|
const [, variant, weight] = /([A-Z][a-z]+)-(\w+)\.ttf$/.exec(font.basename);
|
|
|
|
const tmpOutput = tmp.fileSync({ discardDescriptor: true });
|
|
|
|
const unicodes = FONT_PRESETS[variant.toLowerCase()].ranges;
|
2024-06-21 19:17:32 +00:00
|
|
|
|
2024-06-26 21:42:33 +00:00
|
|
|
return new Promise((resolve) => {
|
|
|
|
execFile("pyftsubset", [
|
|
|
|
font.path,
|
|
|
|
`--unicodes=${unicodes.join(",")}`,
|
|
|
|
`--output-file=${tmpOutput.name}`,
|
|
|
|
"--flavor=woff2",
|
|
|
|
]).once("exit", () => {
|
|
|
|
font.path = `iosevka-adaedra-${variant.toLowerCase()}-${weight.toLowerCase()}.woff2`;
|
|
|
|
font.contents = readFileSync(tmpOutput.name);
|
|
|
|
font.base = null;
|
2024-06-21 19:17:32 +00:00
|
|
|
|
2024-06-26 21:42:33 +00:00
|
|
|
unlinkSync(tmpOutput.name);
|
|
|
|
resolve(font);
|
|
|
|
});
|
2024-06-21 19:17:32 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export const fonts = () =>
|
2024-06-26 21:42:33 +00:00
|
|
|
src("vendor/*.ttf").pipe(
|
|
|
|
then(compileFont),
|
|
|
|
synchronise(),
|
|
|
|
hashPaths("fonts.manifest"),
|
|
|
|
map(dest("dist/_assets")),
|
|
|
|
);
|