131 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			131 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import fs from "fs";
							 | 
						||
| 
								 | 
							
								import { resolve, dirname } from "path";
							 | 
						||
| 
								 | 
							
								import { Edge } from 'edge.js';
							 | 
						||
| 
								 | 
							
								import { optimize as svgo } from "svgo";
							 | 
						||
| 
								 | 
							
								import { fileURLToPath } from 'url';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const __dirname = dirname(fileURLToPath(import.meta.url));
							 | 
						||
| 
								 | 
							
								const __jinja_class_placeholder__ = "__jinja_class_placeholder__";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -- types
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @typedef {object} IconSet - A set of icons
							 | 
						||
| 
								 | 
							
								 * @property {object[]} set - Array of SVG icons, where property name is the
							 | 
						||
| 
								 | 
							
								 * name of the icon and value is the src of the SVG (relative to base).
							 | 
						||
| 
								 | 
							
								 * @property {string} base - Folder in which the SVG src files are located.
							 | 
						||
| 
								 | 
							
								 * @property {import("svgo").Config} svgo_opts - svgo options for this set.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @typedef {object} IconSVG - Mapping of icon name to SVG source file.
							 | 
						||
| 
								 | 
							
								 * @property {string} name - Name of the icon isource file.
							 | 
						||
| 
								 | 
							
								 * @property {string} src - Name of the destination file.
							 | 
						||
| 
								 | 
							
								 * @property {import("svgo").Config} svgo_opts - Options passed to svgo.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @typedef {object} JinjaMacro - Arguments to create a jinja macro
							 | 
						||
| 
								 | 
							
								 * @property {string} name - Name of the jinja macro.
							 | 
						||
| 
								 | 
							
								 * @property {string} class - SVG's class name (value of XML class attribute)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -- functions
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Generate a jinja template with a catalog of SVG icons that can be
							 | 
						||
| 
								 | 
							
								 * used in in other HTML jinja templates.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param {string} dest - filename of the generate jinja template.
							 | 
						||
| 
								 | 
							
								 * @param {JinjaMacro} macros - Jinja macros to create.
							 | 
						||
| 
								 | 
							
								 * @param {IconSVG[]} items - Array of SVG items.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function jinja_svg_catalog(dest, macros, items) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const svg_catalog = {};
							 | 
						||
| 
								 | 
							
								  const edge_template = resolve(__dirname, "jinja_svg_catalog.html.edge");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  items.forEach(
							 | 
						||
| 
								 | 
							
								    (item) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /** @type {import("svgo").Config} */
							 | 
						||
| 
								 | 
							
								      const svgo_opts = JSON.parse(JSON.stringify(item.svgo_opts));
							 | 
						||
| 
								 | 
							
								      svgo_opts.plugins.push({
							 | 
						||
| 
								 | 
							
								        name: "addAttributesToSVGElement",
							 | 
						||
| 
								 | 
							
								        params: {
							 | 
						||
| 
								 | 
							
								          attributes: [{ "class": __jinja_class_placeholder__, }]
							 | 
						||
| 
								 | 
							
								        }}
							 | 
						||
| 
								 | 
							
								      );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      try {
							 | 
						||
| 
								 | 
							
								        const raw = fs.readFileSync(item.src, "utf8");
							 | 
						||
| 
								 | 
							
								        const opt = svgo(raw, svgo_opts);
							 | 
						||
| 
								 | 
							
								        svg_catalog[item.name] = opt.data;
							 | 
						||
| 
								 | 
							
								      } catch (err) {
							 | 
						||
| 
								 | 
							
								        console.error(`ERROR: jinja_svg_catalog processing ${item.name} src: ${item.src} -- ${err}`);
							 | 
						||
| 
								 | 
							
								        throw(err);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fs.mkdir(dirname(dest), { recursive: true }, (err) => {
							 | 
						||
| 
								 | 
							
								    if (err) throw err;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const ctx = {
							 | 
						||
| 
								 | 
							
								    svg_catalog: svg_catalog,
							 | 
						||
| 
								 | 
							
								    macros: macros,
							 | 
						||
| 
								 | 
							
								    edge_template: edge_template,
							 | 
						||
| 
								 | 
							
								    __jinja_class_placeholder__: __jinja_class_placeholder__,
							 | 
						||
| 
								 | 
							
								    // see https://github.com/edge-js/edge/issues/162
							 | 
						||
| 
								 | 
							
								    open_curly_brace : "{{",
							 | 
						||
| 
								 | 
							
								    close_curly_brace : "}}"
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const jinjatmpl = Edge.create().renderRawSync(
							 | 
						||
| 
								 | 
							
									  fs.readFileSync(edge_template, "utf-8"),
							 | 
						||
| 
								 | 
							
									  ctx
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fs.writeFileSync(dest, jinjatmpl);
							 | 
						||
| 
								 | 
							
								  console.log(`[jinja_svg_catalog] created: ${dest}`);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Calls jinja_svg_catalog for a collection of icon sets where each set has its
							 | 
						||
| 
								 | 
							
								 * own parameters.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param {string} dest - filename of the generate jinja template.
							 | 
						||
| 
								 | 
							
								 * @param {JinjaMacro} macros - Jinja macros to create.
							 | 
						||
| 
								 | 
							
								 * @param {IconSet[]} sets - Array of SVG sets.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function jinja_svg_sets(dest, macros, sets) {
							 | 
						||
| 
								 | 
							
								  /** @type IconSVG[] */
							 | 
						||
| 
								 | 
							
								  const items = [];
							 | 
						||
| 
								 | 
							
								  const all = [];
							 | 
						||
| 
								 | 
							
								  for (const obj of sets) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (const [name, file] of Object.entries(obj.set)) {
							 | 
						||
| 
								 | 
							
								      if (all.includes(name)) {
							 | 
						||
| 
								 | 
							
								        throw new Error(`ERROR: ${name} has already been defined`);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      items.push({
							 | 
						||
| 
								 | 
							
								        name: name,
							 | 
						||
| 
								 | 
							
								        src: resolve(obj.base, file),
							 | 
						||
| 
								 | 
							
								        svgo_opts: obj.svgo_opts,
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    jinja_svg_catalog(dest, macros, items);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -- exports
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export {
							 | 
						||
| 
								 | 
							
								  jinja_svg_sets,
							 | 
						||
| 
								 | 
							
								  jinja_svg_catalog,
							 | 
						||
| 
								 | 
							
								};
							 |