// This is an helper script to generate the resources used by eDEX to display file-specific icons in fsDisp, from a fresh file-icons/source GitHub clone. // Generated files are: // - src/assets/icons/file-icons.json: monolithic JSON files containing SVG data needed to draw all the icons. // - src/assets/misc/file-icons-match.js: script to match filenames to icons by using regex expressions. // // The generated files are pretty-printed. See prebuild-minify.js for automatic, on-CI minification of source files before bundling them in binary release assets. // BEFORE RUNNING THIS SCRIPT: // - npm run init-file-icons // You can then use `npm run update-file-icons` which will pull the git submodules and run this script. const fs = require("fs"); const path = require("path"); const CSON = require("cson-parser"); var fileIconsObject = {}; // Get file icons from fontawesome fs.readdirSync(path.join(__dirname, "file-icons", "font-awesome", "svgs", "brands")).forEach(icon => { let iconName = icon.replace(".svg", ""); let text = fs.readFileSync(path.join(__dirname, "file-icons", "font-awesome", "svgs", "brands", icon), {encoding: "utf8"}); let width = text.substr(text.indexOf('viewBox="0 0 ')+13); width = Number(width.slice(0, width.indexOf(" "))); let height = text.substr(text.indexOf('viewBox="0 0 ')+13+width.toString().length+1); height = Number(height.slice(0, height.indexOf('"'))); let svg = text.substr(text.indexOf(">")+1); svg = svg.replace("", ""); if (width === null || height === null) console.log(icon); fileIconsObject[iconName] = { width, height, svg }; }); // Get file icons from file-icons/source fs.readdirSync(path.join(__dirname, "file-icons", "source", "svg")).forEach(icon => { let iconName = icon.toLowerCase().replace(".svg", "").replace("-1", ""); let text = fs.readFileSync(path.join(__dirname, "file-icons", "source", "svg", icon), {encoding: "utf8"}); let width = text.substr(text.indexOf('width="')+7); width = Number(width.slice(0, width.indexOf("px"))); let height = text.substr(text.indexOf('height="')+8); height = Number(height.slice(0, height.indexOf("px"))); let svg = text.substr(text.indexOf(">")+1); svg = svg.replace("", ""); if (width === null || height === null) console.log(icon); fileIconsObject[iconName] = { width, height, svg }; }); // Get file icons from file-icons/devopicons fs.readdirSync(path.join(__dirname, "file-icons", "devopicons", "svg")).forEach(icon => { if (!icon.endsWith(".svg")) return; let iconName = icon.toLowerCase().replace(".svg", "").replace("-1", ""); let text = fs.readFileSync(path.join(__dirname, "file-icons", "devopicons", "svg", icon), {encoding: "utf8"}); let width = text.substr(text.indexOf('width="')+7); width = Number(width.slice(0, width.indexOf("px"))); let height = text.substr(text.indexOf('height="')+8); height = Number(height.slice(0, height.indexOf("px"))); let svg = text.substr(text.indexOf(">")+1); svg = svg.replace("", ""); if (width === null || height === null) console.log(icon); fileIconsObject[iconName] = { width, height, svg }; }); // Get file icons from file-icons/mfixx fs.readdirSync(path.join(__dirname, "file-icons", "mfixx", "svg")).forEach(icon => { if (!icon.endsWith(".svg")) return; let iconName = icon.toLowerCase().replace(".svg", "").replace("-1", ""); let text = fs.readFileSync(path.join(__dirname, "file-icons", "mfixx", "svg", icon), {encoding: "utf8"}); let width = text.substr(text.indexOf('width="')+7); width = Number(width.slice(0, width.indexOf("px"))); let height = text.substr(text.indexOf('height="')+8); height = Number(height.slice(0, height.indexOf("px"))); let svg = text.substr(text.indexOf(">")+1); svg = svg.replace("", ""); if (width === null || height === null) console.log(icon); fileIconsObject[iconName] = { width, height, svg }; }); // Get file icons from file-icons/bytesize-icons fs.readdirSync(path.join(__dirname, "file-icons", "bytesize-icons", "dist", "icons")).forEach(icon => { if (!icon.endsWith(".svg")) return; let iconName = icon.toLowerCase().replace(".svg", ""); let text = fs.readFileSync(path.join(__dirname, "file-icons", "bytesize-icons", "dist", "icons", icon), {encoding: "utf8"}); let dimensions = text.match(/viewBox="0 0 (\d+) (\d+)"/); let width = dimensions[1]; let height = dimensions[2]; let svg = text.substr(text.indexOf(">")+1); svg = svg.replace("", ""); if (width === null || height === null) console.log(icon); fileIconsObject[iconName] = { width, height, svg }; }); // Override with eDEX-specific icons fileIconsObject.showDisks = { width: 24, height: 24, svg: '' }; fileIconsObject.up = { width: 24, height: 24, svg: '' }; fileIconsObject.dir = { width: 24, height: 24, svg: '' }; fileIconsObject.symlink = { width: 24, height: 24, svg: '' }; fileIconsObject.file = { width: 24, height: 24, svg: '' }; fileIconsObject.other = { width: 24, height: 24, svg: '' }; fileIconsObject.disk = { width: 24, height: 24, svg: '' }; fileIconsObject.rom = { width: 24, height: 24, svg: '' }; fileIconsObject.usb = { width: 24, height: 24, svg: '' }; fileIconsObject.audio = fileIconsObject.volume; // Write the file fs.writeFileSync(path.join(__dirname, "src", "assets", "icons", "file-icons.json"), JSON.stringify(fileIconsObject, "", 4)); console.log("Wrote file-icons.json"); var fileIconsMatchScript = `/* * Thanks everyone for pointing out this is probably on of the ugliest source code files on GitHub * This is script-generated code, however, so it might disqualify * See file-icons-generator.js at root dir of git tree */ function matchIcon(filename) {\n`; // Parse the configuration file of file-icons/atom let atomConfig = CSON.parse(fs.readFileSync(path.join(__dirname, "file-icons", "atom", "config.cson"), {encoding: "utf8"})); Object.keys(atomConfig.directoryIcons).forEach(key => { let config = atomConfig.directoryIcons[key]; if (config.icon.startsWith("_")) config.icon = config.icon.substr(1); if (Array.isArray(config.match)) { config.match.forEach(key => { let match = key[0]; if (typeof match === "string") match = new RegExp(match.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${match}.test(filename)) { return "${config.icon}"; }\n`; }); } else { if (typeof config.match === "string") config.match = new RegExp(config.match.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${config.match}.test(filename)) { return "${config.icon}"; }\n`; if (config.alias) { if (typeof config.alias === "string") config.alias = new RegExp(config.alias.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${config.alias}.test(filename)) { return "${config.icon}"; }\n`; } } }); Object.keys(atomConfig.fileIcons).forEach(key => { let config = atomConfig.fileIcons[key]; if (config.icon.startsWith("_")) config.icon = config.icon.substr(1); if (Array.isArray(config.match)) { config.match.forEach(key => { let match = key[0]; if (typeof match === "string") match = new RegExp(match.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${match}.test(filename)) { return "${config.icon}"; }\n`; }); } else { if (typeof config.match === "string") config.match = new RegExp(config.match.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${config.match}.test(filename)) { return "${config.icon}"; }\n`; if (config.alias) { if (typeof config.alias === "string") config.alias = new RegExp(config.alias.replace(/\./g, "\\.")+"$", "i"); // lgtm [js/incomplete-sanitization] fileIconsMatchScript += ` if (${config.alias}.test(filename)) { return "${config.icon}"; }\n`; } } }); // End script fileIconsMatchScript += "}\nmodule.exports = matchIcon;"; // Write the script fs.writeFileSync(path.join(__dirname, "src", "assets", "misc", "file-icons-match.js"), fileIconsMatchScript); console.log("Wrote file-icons-match.js");