/** * Rasterize the circular mark into favicons and render the family OG image. * Usage: node scripts/render-social-assets.mjs */ import { readFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { execFileSync } from "node:child_process"; import { chromium } from "playwright-core"; const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const pub = join(root, "public"); const mark = join(pub, "brand/voculinux-mark-circle.svg"); const chrome = process.env.CHROME_PATH || ["/usr/bin/chromium-browser", "/usr/bin/chromium"].find(Boolean); function convertPng(size, dest, { paper } = {}) { const args = ["-background", paper ? "#f4f1e8" : "none", "-resize", `${size}x${size}`, mark]; if (paper) { args.push("-gravity", "center", "-extent", `${size}x${size}`); } args.push("-depth", "8", `png32:${dest}`); execFileSync("convert", args); } function toWebp(src, dest) { execFileSync("convert", [src, dest]); } const skipIcons = process.env.OG_ONLY === "1"; const sizes = [ [16, join(pub, "favicon-16x16.png")], [32, join(pub, "favicon-32x32.png")], [32, join(pub, "voculinux-32x32.png")], [64, join(pub, "voculinux-64x64.png")], [96, join(pub, "favicon-96x96.png")], [96, join(pub, "voculinux-96x96.png")], [192, join(pub, "voculinux-192x192.png")], [192, join(pub, "icon-192x192.png")], [512, join(pub, "voculinux-512x512.png")], [512, join(pub, "icon-512x512.png")], [512, join(pub, "voculinux.png")], ]; if (!skipIcons) { for (const [size, dest] of sizes) { convertPng(size, dest); if (dest.endsWith(".png") && !dest.includes("favicon-")) { const webp = dest.replace(/\.png$/i, ".webp"); if ( dest.includes("voculinux-") || dest.endsWith("/voculinux.png") ) { toWebp(dest, webp); } } } convertPng(180, join(pub, "apple-touch-icon.png"), { paper: true }); execFileSync("convert", [ join(pub, "favicon-16x16.png"), join(pub, "favicon-32x32.png"), join(pub, "favicon.ico"), ]); } const markSvg = readFileSync(mark, "utf8"); const markData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(markSvg)}`; const tuxData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent( readFileSync(join(pub, "brand/tux.svg"), "utf8"), )}`; const dotsData = `data:image/svg+xml;charset=utf-8,${encodeURIComponent( readFileSync(join(pub, "brand/paper-dots.svg"), "utf8"), )}`; const ogHtml = `
Hold Right Alt. Text lands in the focused window. Local engines by default.
voculinux.com