import { Command } from "./dependencies.ts"; import { pathExists, runCommand } from "./utilities.ts"; async function main(): Promise { const { args, options } = await new Command() .name("project-avatar") .description("Project Avatar Generator") .arguments(" ") .option("--width ", "The width of the image.", { default: 256, }) .option("--height ", "The height of the image.", { default: 256, }) .option("--font-size ", "Font size for the text.", { default: 150, }) .option("--overwrite", "Overwrite an existing image.") .option("--clean", "Use MAT2 to clean the image.") .parse(Deno.args); const [file, text] = args; if (await pathExists(file)) { if (options.overwrite) { await Deno.remove(file); } else { console.log("File exists, use --overwrite to overwrite."); Deno.exit(1); } } await runCommand("gegl", { args: [ "-o", file, "--", ...geglGraph({ fontSize: options.fontSize, height: options.height, text, width: options.width, }), ], }); if (!await pathExists(file)) { console.log("Something went wrong with GEGL."); Deno.exit(1); } await runCommand("convert", { args: [ file, "-background", "transparent", "-gravity", "center", "-extent", `${options.width}x${options.height}`, file, ], }); if (options.clean) { await runCommand("mat2", { args: ["--inplace", file] }); } } /** Customizable options for the GEGL graph. */ type GraphOptions = { fontSize: number; height: number; text: string; width: number; }; /** Create the GEGL graph for the project avatar image. */ function geglGraph({ fontSize, height, text, width }: GraphOptions): string[] { const graph = ` gegl:text string=${text} width=${width} height=${height} color=white font=Inter Heavy size=${fontSize} alignment=1 vertical-alignment=1 gegl:dropshadow x=0 y=0 color=black opacity=1 grow-radius=4 radius=0 gegl:long-shadow angle=90 color=black length=20`; // Replace duplicate whitespace with newlines and then split by those newlines. return graph.replace(/\s\s+/g, "\n").trim().split("\n"); } if (import.meta.main) { void main(); }