#!/usr/bin/env node // fix-svg.mjs // Usage: node fix-svg.mjs input.svg output.svg 10 "#202020" import { readFileSync, writeFileSync } from "node:fs"; import { DOMParser, XMLSerializer } from "@xmldom/xmldom"; const input = process.argv[2]; const output = process.argv[3]; const margin = Number.parseFloat(process.argv[4] ?? "0"); const bg = process.argv[5] ?? null; if (!input || !output) { process.exit(1); } const xml = readFileSync(input, "utf8"); const doc = new DOMParser().parseFromString(xml, "image/svg+xml"); const svg = doc.documentElement; if (!svg || svg.tagName.toLowerCase() !== "svg") { process.exit(1); } // 1) Adjust viewBox (or derive it from root width/height if needed) const vb = svg.getAttribute("viewBox"); if (vb) { const parts = vb.trim().split(/\s+/).map((s) => Number.parseFloat(s)); if (parts.length === 4 && parts.every((n) => Number.isFinite(n))) { let [x, y, w, h] = parts; x -= margin; y -= margin; w += margin * 2; h += margin * 2; svg.setAttribute("viewBox", `${x} ${y} ${w} ${h}`); } } // Remove ONLY root width/height so viewBox governs scaling (optional but common) if (svg.hasAttribute("width")) { svg.removeAttribute("width"); } if (svg.hasAttribute("height")) { svg.removeAttribute("height"); } // 2) Set global background color (no inserted rect): root style background if (bg) { const style = svg.getAttribute("style") ?? ""; const next = style.trim().length > 0 ? `${style.trim().replace(/;+\s*$/, "")};background:${bg}` : `background:${bg}`; svg.setAttribute("style", next); } const out = new XMLSerializer().serializeToString(doc); writeFileSync(output, out);