UNPKG

2.18 kBJavaScriptView Raw
1const _ = require('lodash');
2const fs = require('fs');
3
4function extractGlyphMapFromCss(files, selectorPattern) {
5 const styleRulePattern =
6 '(\\.[A-Za-z0-9_.:, \\n\\t-]+)\\{[^}]*content: ?["\\\'](?:\\\\([A-Fa-f0-9]+)|([^"\\\']+))["\\\'][^}]*\\}';
7 const allStyleRules = new RegExp(styleRulePattern, 'g');
8 const singleStyleRules = new RegExp(styleRulePattern);
9 const allSelectors = new RegExp(selectorPattern, 'g');
10 const singleSelector = new RegExp(selectorPattern);
11
12 const extractGlyphFromRule = rule => {
13 const ruleParts = rule.match(singleStyleRules);
14 if (ruleParts[2]) {
15 // Hex value in CSS
16 return parseInt(ruleParts[2], 16);
17 } else if (ruleParts[3].length > 1) {
18 // String value in CSS that we'll keep as a string because it's not a single character
19 return ruleParts[3];
20 }
21 // String value in CSS that we'll convert to a charcode
22 return ruleParts[3].charCodeAt();
23 };
24
25 const extractSelectorsFromRule = rule => {
26 const ruleParts = rule.match(singleStyleRules);
27 const selectors = ruleParts[1].match(allSelectors) || [];
28 return selectors.map(selector => selector.match(singleSelector)[1]);
29 };
30
31 return (typeof files === 'string' ? [files] : files)
32 .map(fileName => fs.readFileSync(fileName, { encoding: 'utf8' }))
33 .map(contents => contents.match(allStyleRules) || [])
34 .reduce((acc, rules) => acc.concat(rules), [])
35 .map(rule => {
36 const glyph = extractGlyphFromRule(rule);
37 const selectors = extractSelectorsFromRule(rule);
38 return selectors.map(selector => [selector, glyph]);
39 })
40 .reduce((acc, glyphs) => Object.assign(acc, _.fromPairs(glyphs)), {});
41}
42
43function escapeRegExp(str) {
44 return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
45}
46
47function generateIconSetFromCss(cssFiles, selectorPrefix, template, data = {}) {
48 const glyphMap = extractGlyphMapFromCss(
49 cssFiles,
50 `${escapeRegExp(selectorPrefix)}([A-Za-z0-9_-]+):before`
51 );
52 const content = JSON.stringify(glyphMap, null, ' ');
53 if (template) {
54 return _.template(template)(Object.assign({ glyphMap: content }, data));
55 }
56 return content;
57}
58
59module.exports = generateIconSetFromCss;