UNPKG

fontgen-loader

Version:

A WebPack loader to automaticaly generate font files and CSS to make your own icon font

186 lines (164 loc) 5.38 kB
var loaderUtils = require("loader-utils"); var fontgen = require("webfonts-generator"); var path = require("path"); var glob = require('glob'); var mimeTypes = { 'eot': 'application/vnd.ms-fontobject', 'svg': 'image/svg+xml', 'ttf': 'application/x-font-ttf', 'woff': 'application/font-woff' }; function absolute(from, to) { if (arguments.length < 2) { return function (to) { return path.resolve(from, to); }; } return path.resolve(from, to); } function getFilesAndDeps(patterns, context) { var files = []; var filesDeps = []; var directoryDeps = []; function addFile(file) { filesDeps.push(file); files.push(absolute(context, file)); } function addByGlob(globExp) { var globOptions = {cwd: context}; var foundFiles = glob.sync(globExp, globOptions); files = files.concat(foundFiles.map(absolute(context))); var globDirs = glob.sync(path.dirname(globExp) + '/', globOptions); directoryDeps = directoryDeps.concat(globDirs.map(absolute(context))); } // Re-work the files array. patterns.forEach(function (pattern) { if (glob.hasMagic(pattern)) { addByGlob(pattern); } else { addFile(pattern); } }); return { files: files, dependencies: { directories: directoryDeps, files: filesDeps } }; } module.exports = function (content) { this.cacheable(); var params = loaderUtils.parseQuery(this.query); var config; try { config = JSON.parse(content); } catch (ex) { config = this.exec(content, this.resourcePath); } config.__dirname = path.dirname(this.resourcePath); // Sanity check /* if(typeof config.fontName != "string" || typeof config.files != "array") { this.reportError("Typemismatch in your config. Verify your config for correct types."); return false; } */ var filesAndDeps = getFilesAndDeps(config.files, this.context); filesAndDeps.dependencies.files.forEach(this.addDependency.bind(this)); filesAndDeps.dependencies.directories.forEach(this.addContextDependency.bind(this)); config.files = filesAndDeps.files; // With everything set up, let's make an ACTUAL config. var formats = config.types || ['eot', 'woff', 'ttf', 'svg']; if (formats.constructor !== Array) { formats = [formats]; } var fontconf = { files: config.files, fontName: config.fontName, types: formats, order: formats, fontHeight: config.fontHeight || 1000, // Fixes conversion issues with small svgs templateOptions: { baseClass: config.baseClass || "icon", classPrefix: "classPrefix" in config ? config.classPrefix : "icon-" }, dest: "", writeFiles: false, formatOptions: config.formatOptions || {} }; // This originally was in the object notation itself. // Unfortunately that actually broke my editor's syntax-highlighting... // ... what a shame. if(typeof config.rename == "function") { fontconf.rename = config.rename; } else { fontconf.rename = function(f) { return path.basename(f, ".svg"); } } if (config.cssTemplate) { fontconf.cssTemplate = absolute(this.context, config.cssTemplate); } for(var option in config.templateOptions) { if(config.templateOptions.hasOwnProperty(option)) { fontconf.templateOptions[option] = config.templateOptions[option]; } } // svgicons2svgfont stuff var keys = [ "fixedWidth", "centerHorizontally", "normalize", "fontHeight", "round", "descent" ]; for (var x in keys) { if (typeof config[keys[x]] != "undefined") { fontconf[keys[x]] = config[keys[x]]; } } var cb = this.async(); var self = this; var opts = this.options; var pub = ( opts.output.publicPath || "/" ); var embed = !!params.embed; if (fontconf.cssTemplate) { this.addDependency(fontconf.cssTemplate) } fontgen(fontconf, function (err, res) { if (err) { return cb(err); } var urls = {}; for (var i in formats) { var format = formats[i]; if (!embed) { var filename = config.fileName || params.fileName || "[hash]-[fontname][ext]"; filename = filename .replace("[fontname]", fontconf.fontName) .replace("[ext]", "." + format); var url = loaderUtils.interpolateName(this, filename, { context: self.options.context || this.context, content: res[format] } ); urls[format] = path.join(pub, url).replace(/\\/g, '/'); self.emitFile(url, res[format]); } else { urls[format] = 'data:' + mimeTypes[format] + ';charset=utf-8;base64,' + (new Buffer(res[format]).toString('base64')); } } cb(null, res.generateCss(urls)); }); };