From a5bd4fdf1b2a814fe665591bc3755ead8038fa94 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 18:24:58 -0300 Subject: [PATCH 1/6] two-steps - separete css generator from font creation; commit: postcss-webfont-css --- src/createFontFaceSrc.js | 90 +++++++++++ src/createFonts.js | 62 ++++++++ src/createWebFontRuleSets.js | 133 ++++++++++++++++ src/css_generator.js | 116 ++++++++++++++ src/index.js | 18 ++- src/rulesets.js | 289 +---------------------------------- 6 files changed, 425 insertions(+), 283 deletions(-) create mode 100644 src/createFontFaceSrc.js create mode 100644 src/createFonts.js create mode 100644 src/createWebFontRuleSets.js create mode 100644 src/css_generator.js diff --git a/src/createFontFaceSrc.js b/src/createFontFaceSrc.js new file mode 100644 index 0000000..b1d7cab --- /dev/null +++ b/src/createFontFaceSrc.js @@ -0,0 +1,90 @@ +const stringTemplate = require('string-template'); + +// Templates src property by font type +module.export = { + + eotIE: 'url(\'{fontPath}.eot{fontHash}\')', + eot: 'url(\'{fontPath}.eot{fontHash}#iefix\') format(\'embedded-opentype\')', + woff2: 'url(\'{fontPath}.woff2{fontHash}\') format(\'woff2\')', + woff: 'url(\'{fontPath}.woff{fontHash}\') format(\'woff\')', + ttf: 'url(\'{fontPath}.ttf{fontHash}\') format(\'truetype\')', + svg: 'url(\'{fontPath}.svg{fontHash}#${fontName}\') format(\'svg\')', + +}; + +/** + * Get template font hash string. + * + * @param {string} fontHash use fontHash + */ +const getTemplateFontHash = (fontHash) => { + + return fontHash ? `?${fontHash}` : ''; + +}; + + + +/** + * Creates font-face src property. + * + * @param {object} iconFont icon font properties. + * @param {object} options options of generating fonts. + * @returns {string} font-face src property. + */ +exports.createFontFaceSrcProperty = (iconFont, options) => { + + // Creates font path + const fontPath = path.relative( + path.resolve(options.publishPath, options.stylesheetPath), + path.join(options.outputPath, iconFont.fontName) + ).replace(/\\/g, path.posix.sep); + + const srcFormats = []; + + // for each formats + options.formats.forEach((format) => { + + const template = srcPropertyTemplates[format]; + + // Is not empty template? + if (template) { + + srcFormats.push(stringTemplate(template, { + fontPath, + fontHash: getTemplateFontHash(iconFont.fontHash), + fontName: iconFont.fontName + })); + + } + + }); + + // returns src property + return srcFormats.join(', '); + +}; + +/** + * Creates font-face src property with EOT. + * + * @param {object} iconFont icon font properties. + * @param {object} options options of generating fonts. + * @returns {string} font-face src property. + */ +exports.createFontFaceSrcPropertyWithEOT = (iconFont, options) => { + + // Creates font path + const fontPath = path.relative( + path.resolve(options.publishPath, options.stylesheetPath), + path.join(options.outputPath, iconFont.fontName) + ); + + // returns src property + return stringTemplate(srcPropertyTemplates.eotIE, { + fontPath, + fontHash: getTemplateFontHash(iconFont.fontHash), + fontName: iconFont.fontName + }); + +}; \ No newline at end of file diff --git a/src/createFonts.js b/src/createFonts.js new file mode 100644 index 0000000..26a5d3a --- /dev/null +++ b/src/createFonts.js @@ -0,0 +1,62 @@ +const fontGenerator = require('./font_generator'); + +/** + * Creates icon fonts. + * + * @param {object} iconFont icon font options. + * @param {object} rulesets Rulesets of PostCSS object. + * @param {object} options web font options. + * @returns {Promise} returns glyphs when successed. + */ +module.exports = (iconFont, rulesets, options) => { + + // Empty font src? + if (!iconFont.src) { + + // noop + return Promise.resolve(); + + } + + const files = [].concat(glob.sync(iconFont.src)); + + // Empty files? + if (files.length === 0) { + + // noop + return Promise.resolve(); + + } + + return new Promise((resolve, reject) => { + + fontGenerator({ + files, + dest: path.resolve(options.outputPath), + cachePath: options.cachePath, + fontOptions: { + formats: options.formats, + fontName: iconFont.fontName, + fontHeight: options.fontHeight, + ascent: options.ascent, + descent: options.descent, + normalize: options.normalize, + centerHorizontally: options.centerHorizontally, + fixedWidth: options.fixedWidth, + fixedHash: options.fixedHash, + startUnicode: options.startUnicode, + prependUnicode: options.prependUnicode, + } + }).then((glyphs) => { + + resolve(glyphs); + + }).catch((error) => { + + reject(error); + + }); + + }); + +}; diff --git a/src/createWebFontRuleSets.js b/src/createWebFontRuleSets.js new file mode 100644 index 0000000..05f46b9 --- /dev/null +++ b/src/createWebFontRuleSets.js @@ -0,0 +1,133 @@ +const { + createFontFaceSrcProperty, + createFontFaceSrcPropertyWithEOT +} = require('./createFontFaceSrc'); + + +/** + * Creates rulesets of web font. + * + * @param {string} iconFont target icon font. + * @param {object} rulesets Rulesets of PostCSS object. + * @param {object} glyphs glyphs of web font. + * @param {object} options generating font options. + */ +module.exports = (iconFont, rulesets, glyphs, options) => { + + // inserts new src property + rulesets.fontFaceRule.insertAfter(iconFont.srcDecl, postcss.decl({ + prop: 'src', + value: createFontFaceSrcProperty(iconFont, options) + })); + + // No contains eot format? + if (options.formats.indexOf('eot') === -1) { + + // Remove src property + iconFont.srcDecl.remove(); + + } else { + + // Replace src property + iconFont.srcDecl.replaceWith({ + prop: 'src', + value: createFontFaceSrcPropertyWithEOT(iconFont, options) + }); + + } + + // creates class prefix names + const useClassNamePrefix = options.classNamePrefix ? `${options.classNamePrefix}-` : ''; + const useClassNamePrefixBefore = options.classNamePrefixBefore ? `${options.classNamePrefixBefore}-` : ''; + const useClassNamePrefixAfter = options.classNamePrefixAfter ? `${options.classNamePrefixAfter}-` : ''; + + // append base ruleset + const iconRule = postcss.rule({ + selectors: [ + `[class^='${useClassNamePrefix}${iconFont.fontName}-']::before`, + `[class*=' ${useClassNamePrefix}${iconFont.fontName}-']::before`, + `[class^='${useClassNamePrefix}${useClassNamePrefixBefore}${iconFont.fontName}-']::before`, + `[class*=' ${useClassNamePrefix}${useClassNamePrefixBefore}${iconFont.fontName}-']::before`, + `[class^='${useClassNamePrefix}${useClassNamePrefixAfter}${iconFont.fontName}-']::after`, + `[class*=' ${useClassNamePrefix}${useClassNamePrefixAfter}${iconFont.fontName}-']::after`, + ] + }); + iconRule.append({ + prop: 'font-family', + value: `'${iconFont.fontName}', sans-serif` + }, + { + prop: 'font-style', + value: 'normal' + }, + { + prop: 'font-weight', + value: 'normal' + }, + { + prop: 'font-variant', + value: 'normal' + }, + { + prop: 'text-transform', + value: 'none' + }, + { + prop: 'line-height', + value: '1' + }, + { + prop: 'vertical-align', + value: `${options.verticalAlign}` + }, + { + prop: '-webkit-font-smoothing', + value: 'antialiased' + }, + { + prop: '-moz-osx-font-smoothing', + value: 'grayscale' + } + ); + rulesets.root.insertAfter(rulesets.fontFaceRule, iconRule); + + + let baseRule = iconRule; + + // append glyphs + glyphs.forEach((glyph) => { + + [ + { + prefix: useClassNamePrefix, + pseudo: 'before', + }, + { + prefix: `${useClassNamePrefix}${useClassNamePrefixBefore}`, + pseudo: 'before', + }, + { + prefix: `${useClassNamePrefix}${useClassNamePrefixAfter}`, + pseudo: 'after', + }, + ].forEach((classNamingConvention) => { + + const fontRule = postcss.rule({ + selector: `.${classNamingConvention.prefix}${iconFont.fontName}-${glyph.name}::${classNamingConvention.pseudo}`, + }); + fontRule.append({ + prop: 'content', + value: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` + }); + + // insert ruleset + rulesets.root.insertAfter(baseRule, fontRule); + + // replace base ruleset + baseRule = fontRule; + + }); + + }); + +}; diff --git a/src/css_generator.js b/src/css_generator.js new file mode 100644 index 0000000..cec9e9c --- /dev/null +++ b/src/css_generator.js @@ -0,0 +1,116 @@ +/** + * @file Generate iconfonts from stylesheets - rulesets + */ +const postcss = require('postcss'); +const path = require('path'); +const glob = require('glob'); + +const createFonts = require('./createFonts'); +const createWebFontRuleSets = require('./createWebFontRuleSets'); + + +/** + * Parsing font-face rulesets. + * + * @param {object} rulesets Rulesets of PostCSS object. + * @param {object} options Generating font options. + * @returns {Promise} promise object. + */ +const processFontFace = (rulesets, options) => { + const iconFont = {}; + + // Get 'font-family' property. + rulesets.fontFaceRule.walkDecls('font-family', (decl) => { + + // set value as font name + iconFont.fontName = decl.value.replace(/^['"]?/, '').replace(/['"]?$/, ''); + + }); + + // Get 'src' property. + rulesets.fontFaceRule.walkDecls('src', (decl) => { + + const matcher = decl.value.match(/^url\(['"]?(.*\.svg)['"]?\)/); + + // match src property + if (matcher) { + + // Absolute url? + if (/^\//.test(matcher[1])) { + + iconFont.src = path.resolve(options.basePath + matcher[1]); + + } else { + + iconFont.src = path.resolve(path.dirname(rulesets.root.source.input.file), matcher[1]); + + } + + } + + // set target src + iconFont.srcDecl = decl; + + }); + + const files = [].concat(glob.sync(iconFont.src)); + + if (!files.length) return void; + + const glyphs = files + .map(file => ({ + name: path.basename(file), + conent: `url('${file}')` + })) + .map(options.glyphNormalizer); + + // creates rulesets + createWebFontRuleSets(iconFont, rulesets, glyphs, options); +}; + + +/** + * Process generating rulesets of web fonts. + * + * @param {object} root root of PostCSS. + * @param {object} options options of generating fonts. + * @returns {Promise} promise object. + */ +module.exports = (root, options) => { + + return new Promise((resolve, reject) => { + + const fontFaceProcesses = []; + + // for each font face rule + root.walkAtRules('font-face', (rule) => { + + // append font face processing + fontFaceProcesses.push(() => { + + return processFontFace({ root, fontFaceRule: rule }, options); + + }); + + }); + + // serial executing processing + fontFaceProcesses.reduce((prev, current) => { + + return prev.then(() => current()); + + }, Promise.resolve()).then(() => { + + // returns successful + resolve(); + + }).catch((error) => { + + // returns error + reject(error); + + }); + + }); + +}; diff --git a/src/index.js b/src/index.js index ee2523f..b985709 100644 --- a/src/index.js +++ b/src/index.js @@ -21,10 +21,11 @@ const defaultOptions = { classNamePrefixAfter: 'after', cachebuster: 'hash', cachebusterFixed: '', + glyphNormalizer: glyph => glyph }; -module.exports = postcss.plugin('postcss-webfont', (options) => { +const defaultExport = postcss.plugin('postcss-webfont', (options) => { const usingOptions = Object.assign({}, defaultOptions, options); @@ -35,3 +36,18 @@ module.exports = postcss.plugin('postcss-webfont', (options) => { }; }); + +defaultExport.onlyCss = postcss.plugin('postcss-webfont-css', (options) => { + + const usingOptions = Object.assign({}, defaultOptions, options); + + return (root) => { + + return rulesets(root, usingOptions); + + }; + +}); + + +module.exports = defaultExport; diff --git a/src/rulesets.js b/src/rulesets.js index dd53901..9e571b2 100644 --- a/src/rulesets.js +++ b/src/rulesets.js @@ -4,289 +4,10 @@ const postcss = require('postcss'); const path = require('path'); const glob = require('glob'); -const stringTemplate = require('string-template'); -const fontGenerator = require('./font_generator'); +const createFonts = require('./createFonts'); +const createWebFontRuleSets = require('./createWebFontRuleSets'); -// Templates src property by font type -const srcPropertyTemplates = { - - eotIE: 'url(\'{fontPath}.eot{fontHash}\')', - eot: 'url(\'{fontPath}.eot{fontHash}#iefix\') format(\'embedded-opentype\')', - woff2: 'url(\'{fontPath}.woff2{fontHash}\') format(\'woff2\')', - woff: 'url(\'{fontPath}.woff{fontHash}\') format(\'woff\')', - ttf: 'url(\'{fontPath}.ttf{fontHash}\') format(\'truetype\')', - svg: 'url(\'{fontPath}.svg{fontHash}#${fontName}\') format(\'svg\')', - -}; - - -/** - * Get template font hash string. - * - * @param {string} fontHash use fontHash - */ -const getTemplateFontHash = (fontHash) => { - - return fontHash ? `?${fontHash}` : ''; - -}; - - -/** - * Creates icon fonts. - * - * @param {object} iconFont icon font options. - * @param {object} rulesets Rulesets of PostCSS object. - * @param {object} options web font options. - * @returns {Promise} returns glyphs when successed. - */ -const createFonts = (iconFont, rulesets, options) => { - - // Empty font src? - if (!iconFont.src) { - - // noop - return Promise.resolve(); - - } - - const files = [].concat(glob.sync(iconFont.src)); - - // Empty files? - if (files.length === 0) { - - // noop - return Promise.resolve(); - - } - - return new Promise((resolve, reject) => { - - fontGenerator({ - files, - dest: path.resolve(options.outputPath), - cachePath: options.cachePath, - fontOptions: { - formats: options.formats, - fontName: iconFont.fontName, - fontHeight: options.fontHeight, - ascent: options.ascent, - descent: options.descent, - normalize: options.normalize, - centerHorizontally: options.centerHorizontally, - fixedWidth: options.fixedWidth, - fixedHash: options.fixedHash, - startUnicode: options.startUnicode, - prependUnicode: options.prependUnicode, - } - }).then((glyphs) => { - - resolve(glyphs); - - }).catch((error) => { - - reject(error); - - }); - - }); - -}; - - -/** - * Creates font-face src property. - * - * @param {object} iconFont icon font properties. - * @param {object} options options of generating fonts. - * @returns {string} font-face src property. - */ -const createFontFaceSrcProperty = (iconFont, options) => { - - // Creates font path - const fontPath = path.relative( - path.resolve(options.publishPath, options.stylesheetPath), - path.join(options.outputPath, iconFont.fontName) - ).replace(/\\/g, path.posix.sep); - - const srcFormats = []; - - // for each formats - options.formats.forEach((format) => { - - const template = srcPropertyTemplates[format]; - - // Is not empty template? - if (template) { - - srcFormats.push(stringTemplate(template, { - fontPath, - fontHash: getTemplateFontHash(iconFont.fontHash), - fontName: iconFont.fontName - })); - - } - - }); - - // returns src property - return srcFormats.join(', '); - -}; - - -/** - * Creates font-face src property with EOT. - * - * @param {object} iconFont icon font properties. - * @param {object} options options of generating fonts. - * @returns {string} font-face src property. - */ -const createFontFaceSrcPropertyWithEOT = (iconFont, options) => { - - // Creates font path - const fontPath = path.relative( - path.resolve(options.publishPath, options.stylesheetPath), - path.join(options.outputPath, iconFont.fontName) - ); - - // returns src property - return stringTemplate(srcPropertyTemplates.eotIE, { - fontPath, - fontHash: getTemplateFontHash(iconFont.fontHash), - fontName: iconFont.fontName - }); - -}; - -/** - * Creates rulesets of web font. - * - * @param {string} iconFont target icon font. - * @param {object} rulesets Rulesets of PostCSS object. - * @param {object} glyphs glyphs of web font. - * @param {object} options generating font options. - */ -const createWebFontRuleSets = (iconFont, rulesets, glyphs, options) => { - - // inserts new src property - rulesets.fontFaceRule.insertAfter(iconFont.srcDecl, postcss.decl({ - prop: 'src', - value: createFontFaceSrcProperty(iconFont, options) - })); - - // No contains eot format? - if (options.formats.indexOf('eot') === -1) { - - // Remove src property - iconFont.srcDecl.remove(); - - } else { - - // Replace src property - iconFont.srcDecl.replaceWith({ - prop: 'src', - value: createFontFaceSrcPropertyWithEOT(iconFont, options) - }); - - } - - // creates class prefix names - const useClassNamePrefix = options.classNamePrefix ? `${options.classNamePrefix}-` : ''; - const useClassNamePrefixBefore = options.classNamePrefixBefore ? `${options.classNamePrefixBefore}-` : ''; - const useClassNamePrefixAfter = options.classNamePrefixAfter ? `${options.classNamePrefixAfter}-` : ''; - - // append base ruleset - const iconRule = postcss.rule({ - selectors: [ - `[class^='${useClassNamePrefix}${iconFont.fontName}-']::before`, - `[class*=' ${useClassNamePrefix}${iconFont.fontName}-']::before`, - `[class^='${useClassNamePrefix}${useClassNamePrefixBefore}${iconFont.fontName}-']::before`, - `[class*=' ${useClassNamePrefix}${useClassNamePrefixBefore}${iconFont.fontName}-']::before`, - `[class^='${useClassNamePrefix}${useClassNamePrefixAfter}${iconFont.fontName}-']::after`, - `[class*=' ${useClassNamePrefix}${useClassNamePrefixAfter}${iconFont.fontName}-']::after`, - ] - }); - iconRule.append({ - prop: 'font-family', - value: `'${iconFont.fontName}', sans-serif` - }, - { - prop: 'font-style', - value: 'normal' - }, - { - prop: 'font-weight', - value: 'normal' - }, - { - prop: 'font-variant', - value: 'normal' - }, - { - prop: 'text-transform', - value: 'none' - }, - { - prop: 'line-height', - value: '1' - }, - { - prop: 'vertical-align', - value: `${options.verticalAlign}` - }, - { - prop: '-webkit-font-smoothing', - value: 'antialiased' - }, - { - prop: '-moz-osx-font-smoothing', - value: 'grayscale' - } - ); - rulesets.root.insertAfter(rulesets.fontFaceRule, iconRule); - - - let baseRule = iconRule; - - // append glyphs - glyphs.forEach((glyph) => { - - [ - { - prefix: useClassNamePrefix, - pseudo: 'before', - }, - { - prefix: `${useClassNamePrefix}${useClassNamePrefixBefore}`, - pseudo: 'before', - }, - { - prefix: `${useClassNamePrefix}${useClassNamePrefixAfter}`, - pseudo: 'after', - }, - ].forEach((classNamingConvention) => { - - const fontRule = postcss.rule({ - selector: `.${classNamingConvention.prefix}${iconFont.fontName}-${glyph.name}::${classNamingConvention.pseudo}`, - }); - fontRule.append({ - prop: 'content', - value: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` - }); - - // insert ruleset - rulesets.root.insertAfter(baseRule, fontRule); - - // replace base ruleset - baseRule = fontRule; - - }); - - }); - -}; /** @@ -373,9 +94,13 @@ const processFontFace = (rulesets, options) => { iconFont.fontHash = null; } + const glyphs = fontResult.glyphs.map(glyph => ({ + name: glyph.name, + conent: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` + })); // creates rulesets - createWebFontRuleSets(iconFont, rulesets, fontResult.glyphs, options); + createWebFontRuleSets(iconFont, rulesets, glyphs, options); } From 62851df072198d66262c103efde47f1b7d889076 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 18:38:41 -0300 Subject: [PATCH 2/6] two-steps - separete css generator from font creation; commit: postcss-webfont-css --- src/createFontFaceSrc.js | 3 ++- src/createFonts.js | 2 ++ src/createWebFontRuleSets.js | 3 ++- src/rulesets.js | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/createFontFaceSrc.js b/src/createFontFaceSrc.js index b1d7cab..8a809e0 100644 --- a/src/createFontFaceSrc.js +++ b/src/createFontFaceSrc.js @@ -1,7 +1,8 @@ +const path = require('path'); const stringTemplate = require('string-template'); // Templates src property by font type -module.export = { +const srcPropertyTemplates = { eotIE: 'url(\'{fontPath}.eot{fontHash}\')', eot: 'url(\'{fontPath}.eot{fontHash}#iefix\') format(\'embedded-opentype\')', diff --git a/src/createFonts.js b/src/createFonts.js index 26a5d3a..2f98609 100644 --- a/src/createFonts.js +++ b/src/createFonts.js @@ -1,3 +1,5 @@ +const path = require('path'); +const glob = require('glob'); const fontGenerator = require('./font_generator'); /** diff --git a/src/createWebFontRuleSets.js b/src/createWebFontRuleSets.js index 05f46b9..f62245e 100644 --- a/src/createWebFontRuleSets.js +++ b/src/createWebFontRuleSets.js @@ -1,3 +1,4 @@ +const postcss = require('postcss'); const { createFontFaceSrcProperty, createFontFaceSrcPropertyWithEOT @@ -117,7 +118,7 @@ module.exports = (iconFont, rulesets, glyphs, options) => { }); fontRule.append({ prop: 'content', - value: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` + value: glyph.content }); // insert ruleset diff --git a/src/rulesets.js b/src/rulesets.js index 9e571b2..e7de4e3 100644 --- a/src/rulesets.js +++ b/src/rulesets.js @@ -96,7 +96,7 @@ const processFontFace = (rulesets, options) => { } const glyphs = fontResult.glyphs.map(glyph => ({ name: glyph.name, - conent: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` + content: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` })); // creates rulesets From d643aeae7ac5a801e26d476beb2d9f5c6f74db77 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 20:16:42 -0300 Subject: [PATCH 3/6] two-steps - separete css generator from font creation; commit: postcss-webfont-font --- src/css_font_generator.js | 57 +++++++++++++++++++++++++++++++++++++++ src/css_generator.js | 6 ++--- src/font_generator.js | 1 + src/index.js | 20 +++++++++++++- src/rulesets.js | 11 ++++---- 5 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 src/css_font_generator.js diff --git a/src/css_font_generator.js b/src/css_font_generator.js new file mode 100644 index 0000000..ca9887f --- /dev/null +++ b/src/css_font_generator.js @@ -0,0 +1,57 @@ +const path = require('path'); +const fontGenerator = require('./font_generator'); + + +/** + * Process generating web fonts of rulesets. + * + * @param {object} root root of PostCSS. + * @param {object} options options of generating fonts. + * @returns {Promise} promise object. + */ +module.exports = async(root, options) => { + const contents = []; + + root.walkDecls( + 'content', + decl => { + if (!options.iconsBaseMatch.match(decl.value)) return; + + contents.push({ + decl, + file: decl.value.replace(/^\s*url\(['"]?([^'")])['"]?\)/, '$1') + }); + + } + ); + + if (!contents.length) return; + + const fontResult = await fontGenerator({ + files: contents.map(({ file }) => file), + dest: path.resolve(options.outputPath), + cachePath: options.cachePath, + fontOptions: { + formats: options.formats, + fontName: iconFont.fontName, + fontHeight: options.fontHeight, + ascent: options.ascent, + descent: options.descent, + normalize: options.normalize, + centerHorizontally: options.centerHorizontally, + fixedWidth: options.fixedWidth, + fixedHash: options.fixedHash, + startUnicode: options.startUnicode, + prependUnicode: options.prependUnicode, + } + }); + + if (!fontResult) return; + + fontResult.glyphs.forEach(glyph => contents + .filter(({ file }) => file === glyph.file) + .forEach(({ decl }) => { + decl.value = `'\\${glyph.codepoint.toString(16).toUpperCase()}'`; + }) + ); +}; diff --git a/src/css_generator.js b/src/css_generator.js index cec9e9c..c49a154 100644 --- a/src/css_generator.js +++ b/src/css_generator.js @@ -55,12 +55,12 @@ const processFontFace = (rulesets, options) => { const files = [].concat(glob.sync(iconFont.src)); - if (!files.length) return void; + if (!files.length) return; const glyphs = files .map(file => ({ - name: path.basename(file), - conent: `url('${file}')` + name: path.basename(file, '.svg'), + content: `url('${file}')` })) .map(options.glyphNormalizer); diff --git a/src/font_generator.js b/src/font_generator.js index dbe4e02..f0ffe1a 100644 --- a/src/font_generator.js +++ b/src/font_generator.js @@ -221,6 +221,7 @@ const FONT_GENERATORS = { // append simple glyphs simpleGlyphs.push({ name, + file, codepoint: currentCodePoint }); diff --git a/src/index.js b/src/index.js index b985709..d05cf7f 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,8 @@ */ const postcss = require('postcss'); const rulesets = require('./rulesets'); +const cssrulesets = require('./css_generator'); +const font_from_rulesets = require('./css_font_generator'); // default options const defaultOptions = { @@ -43,7 +45,23 @@ defaultExport.onlyCss = postcss.plugin('postcss-webfont-css', (options) => { return (root) => { - return rulesets(root, usingOptions); + return cssrulesets(root, usingOptions); + + }; + +}); + +defaultExport.onlyFont = postcss.plugin('postcss-webfont-font', (options) => { + + const usingOptions = Object.assign( + { contentIconMatch: /.+\.svg/ }, + defaultOptions, + options + ); + + return (root) => { + + return font_from_rulesets(root, usingOptions); }; diff --git a/src/rulesets.js b/src/rulesets.js index e7de4e3..99e095b 100644 --- a/src/rulesets.js +++ b/src/rulesets.js @@ -3,7 +3,6 @@ */ const postcss = require('postcss'); const path = require('path'); -const glob = require('glob'); const createFonts = require('./createFonts'); const createWebFontRuleSets = require('./createWebFontRuleSets'); @@ -94,10 +93,12 @@ const processFontFace = (rulesets, options) => { iconFont.fontHash = null; } - const glyphs = fontResult.glyphs.map(glyph => ({ - name: glyph.name, - content: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` - })); + const glyphs = fontResult.glyphs + .map(glyph => ({ + name: glyph.name, + content: `'\\${glyph.codepoint.toString(16).toUpperCase()}'` + })) + .map(options.glyphNormalizer); // creates rulesets createWebFontRuleSets(iconFont, rulesets, glyphs, options); From a0d78096c9f83be9124c2bbd137645b458dd7b45 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 20:24:11 -0300 Subject: [PATCH 4/6] two-steps - separete css generator from font creation; commit: postcss-webfont-font --- src/css_font_generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css_font_generator.js b/src/css_font_generator.js index ca9887f..b4d58a5 100644 --- a/src/css_font_generator.js +++ b/src/css_font_generator.js @@ -33,7 +33,7 @@ module.exports = async(root, options) => { cachePath: options.cachePath, fontOptions: { formats: options.formats, - fontName: iconFont.fontName, + fontName: options.fontName, fontHeight: options.fontHeight, ascent: options.ascent, descent: options.descent, From 5e9b6fcd40ad549d34ee0181a41b5fb4293c2c34 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 20:59:06 -0300 Subject: [PATCH 5/6] two-steps - separete css generator from font creation; commit: postcss-webfont-font --- src/css_font_generator.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/css_font_generator.js b/src/css_font_generator.js index b4d58a5..73a1f3d 100644 --- a/src/css_font_generator.js +++ b/src/css_font_generator.js @@ -15,20 +15,21 @@ module.exports = async(root, options) => { root.walkDecls( 'content', decl => { - if (!options.iconsBaseMatch.match(decl.value)) return; + if (!options.contentIconMatch.exec(decl.value)) return; contents.push({ decl, - file: decl.value.replace(/^\s*url\(['"]?([^'")])['"]?\)/, '$1') + file: decl.value.replace(/^\s*url\(['"]?([^'")])+['"]?\)/, '$1') }); } ); if (!contents.length) return; + const files = Array.from(new Set(contents.map(({ file }) => file))); const fontResult = await fontGenerator({ - files: contents.map(({ file }) => file), + files, dest: path.resolve(options.outputPath), cachePath: options.cachePath, fontOptions: { From 4f541c178e619a60539575d57d7ba3620b367ba7 Mon Sep 17 00:00:00 2001 From: Hugo Ribeiro Date: Fri, 6 Mar 2020 22:34:20 -0300 Subject: [PATCH 6/6] two-steps - separete css generator from font creation; commit: postcss-webfont-font --- src/css_font_generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css_font_generator.js b/src/css_font_generator.js index 73a1f3d..7e2d78f 100644 --- a/src/css_font_generator.js +++ b/src/css_font_generator.js @@ -19,7 +19,7 @@ module.exports = async(root, options) => { contents.push({ decl, - file: decl.value.replace(/^\s*url\(['"]?([^'")])+['"]?\)/, '$1') + file: decl.value.replace(/^\s*url\(['"]?([^'")]+)['"]?\)/, '$1') }); }