#!/usr/bin/env node
const path = require('path'); const fs = require('fs-promise'); const program = require('commander'); const cheerio = require('cheerio');
program
.option('-i, --input [input]', 'Specifies input dir (current dir by default)') .option('-o, --output [output]', 'Specifies output file ("./sprite.svg" by default)') .option('-v, --viewbox [viewbox]', 'Specifies viewBox attribute (parsed by default)') .option('-p, --prefix [prefix]', 'Specifies prefix for id attribute (none by default)') .option('-q, --quiet', 'Disable informative output') .parse(process.argv);
const SRC_FOLDER = program.input || '.'; const DEST_FILE = program.output || 'sprite.svg'; const ID_PREFIX = program.prefix || ''; const VIEWBOX = program.viewbox || null; const QUIET = program.quiet || false;
const log = (message) => {
if (!QUIET) console.log(message);
};
const getSvgElement = (content) => {
const $ = cheerio.load(content); return $('svg').first();
};
const getViewbox = (content) => {
return VIEWBOX || getSvgElement(content).attr('viewbox');
};
const getPreserveAspectRatio = (content) => {
return getSvgElement(content).attr('preserveaspectratio');
};
const constructId = (fileName) => {
return (ID_PREFIX + fileName).replace(' ', '-');
};
const constructAttributesString = (attributes) => {
return Object.keys(attributes).reduce((acc, key) => { const value = attributes[key] return value ? `${acc} ${key}='${value}'` : acc; }, '');
};
const getSvgContent = (content) => {
return getSvgElement(content).html();
};
const createSymbol = (content, attributes) => {
return `<symbol ${constructAttributesString(attributes)}> ${getSvgContent(content)} </symbol>`;
};
const wrapFile = (fileName, content) => {
const attributes = { viewBox: getViewbox(content), id: constructId(fileName), preserveAspectRatio: getPreserveAspectRatio(content) }; log(`Processing ‘${fileName}’ (viewBox ‘${attributes.viewBox}’)…`); return createSymbol(content, attributes);
};
const processFile = (file) => {
const filePath = path.resolve(SRC_FOLDER, file); const fileName = path.basename(file, path.extname(file)); const wrapContent = wrapFile.bind(null, fileName); return fs.readFile(filePath, 'utf8').then(wrapContent);
};
const removeDestFile = () => {
return fs.remove(DEST_FILE);
};
const readSrcFolder = (foo) => {
return fs.readdir(SRC_FOLDER);
};
const processFiles = (files) => {
const processedFiles = files .filter(filterFile) .map(processFile); return Promise.all(processedFiles);
};
const filterFile = (file) => {
return path.extname(file) === '.svg';
};
const getSpriteContent = (contents) => {
return '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">' + contents.join('') + '</svg>';
};
const writeDestFile = (content) => {
return fs.writeFile(DEST_FILE, content, 'utf8');
};
const printFinish = () => {
log(`File ‘${DEST_FILE}’ successfully generated.`);
};
const catchErrors = (err) => {
throw err;
};
removeDestFile()
.then(readSrcFolder) .then(processFiles) .then(getSpriteContent) .then(writeDestFile) .then(printFinish) .catch(catchErrors);