archive-org-link-grabber/scripts/build-icons.js

87 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/*
Generates extension and toolbar PNG icons from the base SVG with transparent
background and configurable stroke colors. Requires ImageMagick (`magick`).
Config via environment variables (optional):
ICON_COLOR_ADDON hex color for add-on icons (48/96/128). Default: #111827
ICON_COLOR_TOOLBAR hex color for toolbar icons (16/32). Default: #111827
Usage:
node scripts/build-icons.js
*/
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const REPO_ROOT = path.join(__dirname, '..');
const ICONS_DIR = path.join(REPO_ROOT, 'icons');
const SRC_SVG = path.join(ICONS_DIR, 'file-search.svg');
const ADDON_SIZES = [48, 96, 128];
const TOOLBAR_SIZES = [16, 32];
const COLOR_ADDON = process.env.ICON_COLOR_ADDON || '#111827';
const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#111827';
function ensureMagick() {
const which = spawnSync('bash', ['-lc', 'command -v magick || command -v convert']);
if (which.status !== 0) return null;
const bin = which.stdout.toString().trim();
return bin || null;
}
function readSvg() {
if (!fs.existsSync(SRC_SVG)) {
console.error(`Base SVG not found: ${path.relative(REPO_ROOT, SRC_SVG)}`);
process.exit(1);
}
return fs.readFileSync(SRC_SVG, 'utf8');
}
function colorize(svg, color) {
// Replace currentColor with explicit hex color. Keep case-insensitive safety.
return svg.replace(/currentColor/gi, color);
}
function rasterize(magickBin, svgString, size, outPath) {
// Use ImageMagick, transparent background, high density for crisp vector rasterization.
const proc = spawnSync('bash', ['-lc', `${magickBin} -background none -density 384 svg:- -resize ${size}x${size} ${outPath}`], {
input: svgString,
stdio: ['pipe', 'inherit', 'inherit'],
});
if (proc.status !== 0) {
console.error(`Failed to generate ${outPath}`);
process.exit(proc.status || 1);
}
}
function main() {
const magick = ensureMagick();
if (!magick) {
console.error('ImageMagick not found. Please install it or adjust this script to use inkscape/rsvg-convert.');
process.exit(1);
}
if (!fs.existsSync(ICONS_DIR)) fs.mkdirSync(ICONS_DIR, { recursive: true });
const base = readSvg();
// Add-on icons
const addonSvg = colorize(base, COLOR_ADDON);
for (const s of ADDON_SIZES) {
const out = path.join(ICONS_DIR, `icon-${s}.png`);
rasterize(magick, addonSvg, s, out);
console.log(`Generated ${path.relative(REPO_ROOT, out)}`);
}
// Toolbar icons
const toolbarSvg = colorize(base, COLOR_TOOLBAR);
for (const s of TOOLBAR_SIZES) {
const out = path.join(ICONS_DIR, `icon-${s}.png`);
rasterize(magick, toolbarSvg, s, out);
console.log(`Generated ${path.relative(REPO_ROOT, out)}`);
}
}
main();