UNPKG

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