summaryrefslogtreecommitdiff
path: root/client/simple/tools/jinja_svg_catalog.js
blob: 0adffa5af1d07c202726e6677af72252831f91a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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,
};