const fs = require("fs"); const path = require("path"); const argv = require("yargs").argv; const weights = ["thin", "extralight", "light", "book", "medium", "bold", "heavy"]; const slantnesses = ["upright", "italic", "oblique"]; const widths = ["term", "normal", "cc"]; const designs = ["sans", "slab"]; function present(x) { return !!x; } function tofn(a) { return a.filter(present).join("-"); } function getMapping(options) { options = options || { design: [], width: "normal", weight: "book", slantness: "upright", styles: {}, dirPrefix: "", dirSuffix: "", filePrefix: "", infix: "", fileSuffix: "" }; let design = options.design || []; let weight = options.weight || "book"; let slantness = options.slantness || "upright"; let hives = ["iosevka"].concat( design, ["w-" + weight, "s-" + slantness], (options.styles || {})[slantness] || [] ); let dir = [ options.dirPrefix || "", "iosevka", options.infix || tofn(design), options.dirSuffix || "" ].filter(present).join("-"); let filename = [ options.filePrefix || "", "iosevka", options.infix || tofn(design), options.fileSuffix || "", (weight === "book" ? (slantness === "upright" ? "regular" : "") : weight) + (slantness === "upright" ? "" : slantness) ].filter(present).join("-"); return {hives, dir, filename, custom: options.custom}; } let definedBuildSeqs = {}; function createMake(mapping) { const {hives, dir, filename, cm, custom} = mapping; let tfname = `$(BUILD)/${filename}.0.otd`; let target = `$(DIST)/${dir}/${filename}.ttf`; let cmTarget = `$(BUILD)/${filename}.charmap`; let woffTarget = `$(DIST)/${dir}/web/${filename}.woff`; let woff2Target = `$(DIST)/${dir}/web/${filename}.woff2`; let buf = ""; if (!definedBuildSeqs[tfname]) { buf += ` ${tfname} : scripts ${custom || ''} | $(BUILD) $(DIST)/${dir}/ @echo Building ${filename} with ${hives.join(' ')} $(GENERATE) ${hives.join(' ')} -o $@ ${cm ? ('--charmap $(BUILD)/'+filename+'.charmap') :''}`; definedBuildSeqs[tfname] = true; } buf += ` ${target} : ${tfname} | $(DIST)/${dir}/ @echo Hinting and optimizing ${tfname} '->' $@ @otfccbuild ${tfname} -o $(BUILD)/${filename}.1.ttf @ttfautohint $(BUILD)/${filename}.1.ttf $(BUILD)/${filename}.2.ttf @otfccdump $(BUILD)/${filename}.2.ttf -o $(BUILD)/${filename}.2.otd --pretty @otfccbuild $(BUILD)/${filename}.2.otd -o $@ -O3 -s @rm $(BUILD)/${filename}.1.ttf $(BUILD)/${filename}.2.ttf $(BUILD)/${filename}.2.otd`; buf += ` ${woffTarget} : ${target} | $(DIST)/${dir}/web/ sfnt2woff $< mv $(subst .ttf,.woff,$<) $@`; buf += ` ${woff2Target} : ${target} | $(DIST)/${dir}/web/ woff2_compress $< mv $(subst .ttf,.woff2,$<) $@`; return {buf, target, woffTarget, woff2Target, cmTarget}; } let designGroups = []; if (argv.custom) { designGroups = [ { custom: '$(BUILD)/targets-' + argv.custom + '.mk', name: "customized-" + argv.custom, design: argv.design.trim().split(/ +/), width: argv.width, infix: argv.custom, styles: { upright: argv.upright.trim().split(/ +/), italic: argv.italic.trim().split(/ +/), oblique: argv.oblique.trim().split(/ +/) } } ]; } else { designGroups = [ {name: "sans", design: [], dirPrefix: ""}, {name: "slab", design: ["slab"], dirPrefix: ""}, {name: "r-sans", design: [], dirPrefix: "01"}, {name: "r-sans-term", design: ["term"], dirPrefix: "02"}, {name: "r-sans-cc", design: ["cc"], dirPrefix: "03"}, {name: "r-slab", design: ["slab"], dirPrefix: "04"}, {name: "r-slab-term", design: ["term", "slab"], dirPrefix: "05"}, {name: "r-slab-cc", design: ["cc", "slab"], dirPrefix: "06"}, {name: "r-hooky", design: [], infix: "hooky", dirPrefix: "07", styles: {upright: ["v-l-hooky", "v-i-hooky"]}}, {name: "r-hooky-term", design: ["term"], infix: "hooky-term", dirPrefix: "08", styles: {upright: ["v-l-hooky", "v-i-hooky"]}}, {name: "r-zshaped", design: [], infix: "zshaped",dirPrefix: "09", styles: {upright: ["v-l-zshaped", "v-i-zshaped"]}}, {name: "r-zshaped-term", design: ["term"], infix: "zshaped-term", dirPrefix: "10", styles: {upright: ["v-l-zshaped", "v-i-zshaped"]}}, ]; } let makes = []; for (let dg of designGroups) { let groupTargets = { ttf: [], upright: [], italic: [], oblique: [], woff: [], woff2: [] }; const groupMapping = getMapping(dg); makes.push(` $(DIST)/${groupMapping.dir}/ : | $(DIST)/ -@mkdir -p $@`); makes.push(` $(DIST)/${groupMapping.dir}/web/ : | $(DIST)/${groupMapping.dir}/ -@mkdir -p $@`); for (let weight of weights) for (let slantness of slantnesses) { let config = Object.create(dg); config.weight = weight; config.slantness = slantness; const mapping = getMapping(config); if (weight === "book" && slantness === "upright") { mapping.cm = true; } let {buf, target, woffTarget, woff2Target, cmTarget} = createMake(mapping); makes.push(buf); groupTargets.ttf.push(target); groupTargets[slantness].push(target); groupTargets.woff.push(woffTarget); groupTargets.woff2.push(woff2Target); } makes.push(`fonts-${dg.name} : ${groupTargets.ttf.join(' ')}`); makes.push(`fonts-${dg.name}-upright : ${groupTargets.upright.join(' ')}`); makes.push(`fonts-${dg.name}-italic : ${groupTargets.italic.join(' ')}`); makes.push(`fonts-${dg.name}-oblique : ${groupTargets.oblique.join(' ')}`); makes.push(`web-${dg.name} : ${groupTargets.woff.join(' ')} ${groupTargets.woff2.join(' ')}`); makes.push(`$(ARCHIVEDIR)/${groupMapping.dir}-$(VERSION).zip : fonts-${dg.name} | $(ARCHIVEDIR)/ cd $(DIST)/${groupMapping.dir}/ && 7z a -tzip -mx=9 ../../$@ ./*.ttf`); makes.push(`archive-${dg.name} : $(ARCHIVEDIR)/${groupMapping.dir}-$(VERSION).zip`); } if (argv.custom) { } else { const ttcgroups = [ {groups: [designGroups[2], designGroups[3], designGroups[4]]}, {groups: [designGroups[5], designGroups[6], designGroups[7]]} ]; // ttc let ttcs = []; makes.push(` $(DIST)/ttc/ : | $(DIST)/ -@mkdir -p $@`); for (let tg of ttcgroups) { for (let weight of weights) { for (let slantness of slantnesses) { let ttctargets = []; for (let dg of tg.groups) { let config = Object.create(dg); config.weight = weight; config.slantness = slantness; const mapping = getMapping(config); ttctargets.push(createMake(mapping).target); } let config = Object.create(tg.groups[0]); config.weight = weight; config.slantness = slantness; const mapping = getMapping(config); ttcs.push(`$(DIST)/ttc/${mapping.filename}.ttc`); makes.push(` $(DIST)/ttc/${mapping.filename}.ttc : ${ttctargets.join(' ')} | $(DIST)/ttc/ otfcc-ttcize -o $@ ${ttctargets.join(' ')} `); } } } makes.push(`ttc : ${ttcs.join(' ')}`); makes.push(`$(ARCHIVEDIR)/iosevka-pack-$(VERSION).zip : ttc | $(ARCHIVEDIR)/ cd $(DIST)/ttc/ && 7z a -tzip -mx=9 ../../$@ ./*.ttc`); makes.push(`archive-ttc : $(ARCHIVEDIR)/iosevka-pack-$(VERSION).zip`); makes.push(`default : fonts-sans fonts-slab`); } console.log(makes.join("\n\n"));