facilmap/leaflet/download-icons.ts

72 wiersze
2.4 KiB
TypeScript

import fetch from "node-fetch";
import * as yauzl from "yauzl-promise";
import * as svgo from "svgo";
import { load, type Element } from "cheerio";
import { writeFile } from "fs/promises";
import { fileURLToPath } from "url";
import { Readable } from "stream";
const outDir = fileURLToPath(new URL('./assets/icons/osmi', import.meta.url));
async function updateIcons() {
const buffer = await fetch("https://github.com/twain47/Open-SVG-Map-Icons/archive/master.zip").then((res) => res.arrayBuffer());
const zip = await yauzl.fromBuffer(Buffer.from(buffer)) as any; // yauzl-promise types are outdated, see https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/67963
for await (const entry of zip) {
if (entry.filename.endsWith(".svg")) {
const readStream = Readable.toWeb(await zip.openReadStream(entry));
const buffers: Buffer[] = [];
for await (const buffer of readStream) {
buffers.push(buffer);
}
const content = Buffer.concat(buffers);
const cleanedContent = cleanIcon(content.toString());
const outFile = `${outDir}/${entry.filename.split('/').slice(-2).join('_')}`;
await writeFile(outFile, Buffer.from(cleanedContent));
}
}
}
function cleanIcon(icon: string): string {
const optimized = svgo.optimize(icon);
const $ = load(optimized.data, {
xmlMode: true
});
for (const el of $("*").toArray() as Element[]) {
el.name = el.name.replace(/^svg:/, "");
}
$("metadata,sodipodi\\:namedview,defs,image").remove();
for (const el of $("*").toArray()) {
const $el = $(el);
const fill = $el.css("fill") || $el.attr("fill");
if(fill && fill != "none") {
if(fill != "#ffffff" && fill != "#fff") { // This is the background
$el.remove();
continue;
}
if($el.css("fill"))
$el.css("fill", "#000");
else
$el.attr("fill", "#000");
}
if($el.css("stroke") && $el.css("stroke") != "none")
$el.css("stroke", "#000");
else if($el.attr("stroke") && $el.attr("stroke") != "none")
$el.attr("stroke", "#000");
}
return $(":root").html()!.replace(/(>|^)\s+(<|$)/g, "$1$2");
}
updateIcons().then(() => {
console.log('Success!');
}).catch((err) => {
console.error('Fatal error', err);
});