UNPKG

iconfont

Version:

CLI that converts Icon Font CSS StyleSheets into CommonJS modules exporting the unicodes by name.

192 lines (140 loc) 4.12 kB
#!/usr/bin/env node 'use strict'; var fs = require('fs'), path = require('path'), util = require('util'); var program = require('commander'), updateNotifier = require('update-notifier'), chalk = require('chalk'), css = require('css'), _ = require('underscore'); var pkg = require('./package.json'); updateNotifier({ packageName: pkg.name, packageVersion: pkg.version }).notify(); css.stringifyRule = function(rule, options) { options = options || {}; options.compress = options.compress !== false; return this.stringify({ stylesheet: { rules: [rule] } }, options); }; program .version(pkg.version, '-v, --version') .option('-t, --tss', 'export to Titanium Alloy Style Sheet(tss)') .description(pkg.description) .usage('<stylesheet> [js]') .parse(process.argv); var ln = program.args.length; if (ln === 0) { program.help(); } if (ln > 2) { console.error(chalk.red('Just one stylesheet please')); process.exit(1); } var stylesheet = path.normalize(program.args[0]); var js; if (ln === 2) { js = path.normalize(program.args[1]); if (js.match(/\.tss$/)) { program.tss = true; } } else { js = stylesheet.replace(/\.css$/, program.tss ? '.tss' : '.js'); } fs.readFile(stylesheet, function(err, data) { if (err) { console.error(chalk.red(err)); process.exit(1); } var code = data.toString(); var obj = css.parse(code, stylesheet); if (!obj.stylesheet || !obj.stylesheet.rules) { console.error(chalk.red('Cannot find rules in the root')); process.exit(1); } var icons = {}; var prefixes = []; var fontFamily = ''; _.each(obj.stylesheet.rules, function(rule) { if (!rule.selectors || !rule.declarations) { if (rule.type == 'font-face') { fontFamily = _.findWhere(rule.declarations, { property: 'font-family' }).value.replace(/["']/g, ''); } return; } var declaration = _.findWhere(rule.declarations, { property: 'content' }); if (!declaration) { return; } var content = declaration.value; var matches = content.match(/^("|')(.+)\1$/i); if (!matches) { console.warn(chalk.yellow('Skipping content without string value: ') + chalk.blue(css.stringifyRule(rule))); return; } var string = matches[2]; if (string.match(/^\\[a-z0-9]{1,4}$/i)) { string = '\\u' + (new Array(4 + 2 - string.length)).join('0') + string.substr(1); } _.each(rule.selectors, function(selector) { var matches2 = selector.match(/^\.(([a-z0-9]+-)?[a-z0-9]+(?:[_-][a-z0-9]+)*):before$/i); if (!matches2) { return; } var name = matches2[1]; var prefix = matches2[2]; if (prefixes.indexOf(prefix) === -1) { prefixes.push(prefix); } icons[name] = string; }); }); var ln = _.size(icons); if (ln === 0) { console.error(chalk.red('Found no icons')); process.exit(1); } var prefix = (prefixes.length === 1) ? prefixes[0] : null; if (program.tss) { data = '/* ' + fontFamily + ' Styles (Generated by IconFont) */\n'; _.each(_.keys(icons), function(name, i) { var unicode = icons[name]; data += util.format('".%s": { font: { fontFamily: "%s"}, text: "%s", title: "%s"}\n', name, fontFamily, unicode, unicode); }); } else { data = 'module.exports = {\n'; _.each(_.keys(icons), function(name, i) { var unicode = icons[name]; if (prefix) { name = name.substr(prefix.length); } if (name.indexOf('-') !== -1 || name.indexOf('_') !== -1) { name = name.replace(/[_-]([a-z0-9])([^_-]*)/gi, function(match, p1, p2) { return p1.toUpperCase() + p2.toLowerCase(); }); } data += ' "' + name + '": "' + unicode + '"' + ((i === ln - 1) ? '' : ',') + '\n'; }); data += '};'; } fs.writeFile(js, data, null, function(err) { if (err) { console.error(chalk.red(err)); process.exit(1); } console.info(chalk.green('Written ' + ln + ' icons to: ' + js)); }); });