blog/lib/tasks/fonts.ts

40 lines
1.3 KiB
TypeScript
Raw Normal View History

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-27 01:36:05 +00:00
import { dest, fromGlob } from "../rx-utils.js";
import { mergeMap } from "rxjs";
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-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-26 21:42:33 +00:00
unlinkSync(tmpOutput.name);
resolve(font);
});
});
}
export const fonts = () =>
2024-06-27 01:36:05 +00:00
fromGlob("vendor/*.ttf")
.pipe(mergeMap(compileFont), hashPaths("fonts.manifest"))
2024-06-27 01:28:17 +00:00
.forEach(dest("dist/_assets"));