Files

152 lines
4.1 KiB
JavaScript

const fs = require('fs').promises;
const path = require('path');
const deepmerge = require('deepmerge');
const env = require('gulp-environment');
const { importDirectory, cleanupSVG, parseColors, isEmptyColor, runSVGO } = require('@iconify/tools');
const { getIcons, stringToIcon, getIconsCSS } = require('@iconify/utils');
// Set environment variable
process.env.NODE_ENV = env.current.name;
let serverPath;
let templatePath;
let buildPath;
// Load configuration
const conf = (() => {
const _conf = require('../../build-config');
serverPath = _conf.base.serverPath;
templatePath = _conf.base.buildTemplatePath;
buildPath = _conf.base.buildPath;
return deepmerge.all([{}, _conf.base || {}, _conf[process.env.NODE_ENV] || {}]);
})();
// Icon sources
const sources = {
json: [require.resolve('@iconify/json/json/tabler.json')]
};
// CSS target path for generated icons
const cssTarget = path.resolve(__dirname, '../../' + conf.distPath.replace(/^\.\//, '') + '/fonts/iconify-icons.css');
// Main function to generate CSS
(async function () {
try {
const allIcons = [];
// Process JSON sources
if (sources.json) {
for (let i = 0; i < sources.json.length; i++) {
const item = sources.json[i];
const filename = typeof item === 'string' ? item : item.filename;
const content = JSON.parse(await fs.readFile(filename, 'utf8'));
// Filter icons if specific icons are provided
if (typeof item !== 'string' && item.icons?.length) {
const filteredContent = getIcons(content, item.icons);
if (!filteredContent) {
throw new Error(`Cannot find required icons in ${filename}`);
}
allIcons.push(filteredContent);
} else {
allIcons.push(content);
}
}
}
// Process SVG sources if provided
if (sources.svg) {
for (let i = 0; i < sources.svg.length; i++) {
const source = sources.svg[i];
const iconSet = await importDirectory(source.dir, {
prefix: source.prefix
});
// Iterate over icons and process each SVG
await iconSet.forEach(async (name, type) => {
if (type !== 'icon') {
return;
}
const svg = iconSet.toSVG(name);
if (!svg) {
iconSet.remove(name);
return;
}
try {
// Clean up and optimize SVG
await cleanupSVG(svg);
if (source.monotone) {
await parseColors(svg, {
defaultColor: 'currentColor',
callback: (attr, colorStr, color) => {
return !color || isEmptyColor(color) ? colorStr : 'currentColor';
}
});
}
await runSVGO(svg);
} catch (err) {
console.error(`Error parsing ${name} from ${source.dir}:`, err);
iconSet.remove(name);
return;
}
iconSet.fromSVG(name, svg);
allIcons.push(iconSet.export());
});
}
}
// Generate the CSS content from all collected icons
const cssContent = allIcons
.map(iconSet =>
getIconsCSS(iconSet, Object.keys(iconSet.icons), {
iconSelector: '.{prefix}-{name}',
commonSelector: '.ti',
format: conf.minify ? 'compressed' : 'expanded'
})
)
.join('\n');
// Write the generated CSS to the target file
await fs.writeFile(cssTarget, cssContent, 'utf8');
console.log(`Saved CSS to ${cssTarget}`);
} catch (err) {
console.error('Error during icon CSS generation:', err);
}
})();
/**
* Organizes a list of icons by prefix.
* @param {Array} icons - Array of icon names
* @returns {Object} - Sorted icons grouped by prefix
*/
function organizeIconsList(icons) {
const sorted = {};
icons.forEach(icon => {
const item = stringToIcon(icon);
if (!item) {
return;
}
const prefix = item.prefix;
const prefixList = sorted[prefix] ? sorted[prefix] : (sorted[prefix] = []);
const name = item.name;
if (prefixList.indexOf(name) === -1) {
prefixList.push(name);
}
});
return sorted;
}