archive-org-link-grabber/scripts/build-icons.js
wagesj45 982a16d86e feat(theme): apply new color palette and polish UI
- Add theme variables and restyle popup/options using Primary 3 as background and Primary 2 as surfaces; accents use Primary 1.\n- Move Save to a footer section on the options page; add responsive layout and button variants.\n- Update icon build defaults to use Primary 2 for add-on and Primary 1 for toolbar icons.\n- Add build-and-commit helper to run build, stage generated assets, commit, and optionally push.\n- Add npm scripts: build:commit and build:commit:push.
2025-08-24 00:39:20 -05:00

90 lines
3 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`).
Theme defaults (aligned with project palette):
Primary 2 (deep): #223544 → add-on icon strokes (default)
Primary 1 (light): #5AC3D6 → toolbar icon strokes (default)
Override via environment variables (optional):
ICON_COLOR_ADDON hex color for add-on icons (48/96/128). Default: #223544
ICON_COLOR_TOOLBAR hex color for toolbar icons (16/32). Default: #5AC3D6
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 || '#223544';
const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#5AC3D6';
function ensureMagick() {
// Prefer calling binaries directly to avoid shell init output polluting stdout.
let ok = spawnSync('magick', ['-version']);
if (ok && ok.status === 0) return 'magick';
ok = spawnSync('convert', ['-version']);
if (ok && ok.status === 0) return 'convert';
return 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 args = ['-background', 'none', '-density', '384', 'svg:-', '-resize', `${size}x${size}`, outPath];
const proc = spawnSync(magickBin, args, { 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();