1 | 'use strict';
|
---|
2 | const path = require('path');
|
---|
3 | const fs = require('fs');
|
---|
4 | const css = require('css');
|
---|
5 | const camel = require('to-camel-case');
|
---|
6 | const autogenMessage =
|
---|
7 | '//\n// This file has been auto-generated by the `npm run build-styles-prism` task\n//\n\n';
|
---|
8 |
|
---|
9 | let directories = [
|
---|
10 | '../node_modules/prismjs/themes',
|
---|
11 | '../node_modules/prism-themes/themes'
|
---|
12 | ];
|
---|
13 |
|
---|
14 | directories.map(directory => {
|
---|
15 | fs.readdir(path.join(__dirname, directory), (err, files) => {
|
---|
16 | files.forEach(file => {
|
---|
17 | if (file.includes('.css') && !file.includes('.min')) {
|
---|
18 | createJavascriptStyleSheet(file, directory);
|
---|
19 | }
|
---|
20 | });
|
---|
21 | updateDocs(files);
|
---|
22 | });
|
---|
23 | });
|
---|
24 |
|
---|
25 | function getSimpleFilename(filename) {
|
---|
26 | let nameWithoutExtension = filename.split('.css')[0].split('prism-')[1];
|
---|
27 | if (filename === 'prism.css') nameWithoutExtension = 'prism';
|
---|
28 | if (filename === 'prism.min.css') nameWithoutExtension = 'prism.min';
|
---|
29 | return nameWithoutExtension;
|
---|
30 | }
|
---|
31 |
|
---|
32 | let allFiles = [];
|
---|
33 | let callCount = 0;
|
---|
34 | function updateDocs(files) {
|
---|
35 | allFiles = allFiles.concat(files);
|
---|
36 | callCount += 1;
|
---|
37 |
|
---|
38 | if (callCount != directories.length) {
|
---|
39 | return;
|
---|
40 | }
|
---|
41 | const onlyCSSFiles = allFiles.filter(file => file.includes('.css'));
|
---|
42 | const onlyNonMinifiedCSS = onlyCSSFiles.filter(
|
---|
43 | file => !file.includes('.min')
|
---|
44 | );
|
---|
45 | const availableStyleNames = onlyNonMinifiedCSS.map(file =>
|
---|
46 | getSimpleFilename(file)
|
---|
47 | );
|
---|
48 | const styles = availableStyleNames.map(name => `\n* ${camel(name)}`);
|
---|
49 | const defaultExports = availableStyleNames.map(
|
---|
50 | name => `export { default as ${camel(name)} } from './${name}';\n`
|
---|
51 | );
|
---|
52 | const styleMD = `## Available \`stylesheet\` props ${styles.join('')}`;
|
---|
53 | fs.writeFile(
|
---|
54 | path.join(__dirname, '../AVAILABLE_STYLES_PRISM.MD'),
|
---|
55 | styleMD,
|
---|
56 | () => {}
|
---|
57 | );
|
---|
58 | fs.writeFile(
|
---|
59 | path.join(__dirname, '../src/styles/prism/index.js'),
|
---|
60 | defaultExports.join(''),
|
---|
61 | () => {}
|
---|
62 | );
|
---|
63 |
|
---|
64 | const demoStylesArray = `${autogenMessage}export default [${availableStyleNames
|
---|
65 | .sort()
|
---|
66 | .map(style => `\n '${style}'`)}\n];`;
|
---|
67 | fs.writeFile(
|
---|
68 | path.join(__dirname, '../demo/styles/prism.js'),
|
---|
69 | demoStylesArray,
|
---|
70 | err => {
|
---|
71 | if (err) {
|
---|
72 | throw err;
|
---|
73 | }
|
---|
74 | }
|
---|
75 | );
|
---|
76 | }
|
---|
77 |
|
---|
78 | function createJavascriptStyleSheet(file, directory) {
|
---|
79 | let fileWithoutCSS = getSimpleFilename(file);
|
---|
80 | console.log(fileWithoutCSS);
|
---|
81 |
|
---|
82 | fs.readFile(
|
---|
83 | path.join(__dirname, `${directory}/${file}`),
|
---|
84 | 'utf-8',
|
---|
85 | (err, data) => {
|
---|
86 | const javacriptStylesheet = css
|
---|
87 | .parse(data)
|
---|
88 | .stylesheet.rules.reduce((sheet, rule) => {
|
---|
89 | if (rule.type === 'rule') {
|
---|
90 | const style = rule.selectors.reduce((selectors, selector) => {
|
---|
91 | const selectorObject = rule.declarations.reduce(
|
---|
92 | (declarations, declaration) => {
|
---|
93 | if (
|
---|
94 | declaration.type === 'declaration' &&
|
---|
95 | declaration.property
|
---|
96 | ) {
|
---|
97 | const camelCaseDeclarationProp = camel(
|
---|
98 | declaration.property
|
---|
99 | );
|
---|
100 | const key =
|
---|
101 | camelCaseDeclarationProp.includes('moz') ||
|
---|
102 | camelCaseDeclarationProp.includes('webkit') ||
|
---|
103 | (camelCaseDeclarationProp[0] === 'o' &&
|
---|
104 | !camelCaseDeclarationProp.includes('overflow'))
|
---|
105 | ? `${camelCaseDeclarationProp
|
---|
106 | .substring(0, 1)
|
---|
107 | .toUpperCase()}${camelCaseDeclarationProp.substring(
|
---|
108 | 1
|
---|
109 | )}`
|
---|
110 | : camelCaseDeclarationProp;
|
---|
111 | declarations[key] = declaration.value;
|
---|
112 | }
|
---|
113 | return declarations;
|
---|
114 | },
|
---|
115 | {}
|
---|
116 | );
|
---|
117 |
|
---|
118 | if (selector.substring(0, 6) === '.token') {
|
---|
119 | selector = selector.substring(7);
|
---|
120 |
|
---|
121 | // Regex to fix Prism theme selectors
|
---|
122 | // - Remove further `.token` classes
|
---|
123 | // - Remove the space (descendant combinator)
|
---|
124 | // to allow for styling multiple classes
|
---|
125 | // Ref: https://github.com/react-syntax-highlighter/react-syntax-highlighter/pull/305
|
---|
126 | selector = selector.replace(/(?<=\w) (\.token)?(?=\.)/g, '');
|
---|
127 | }
|
---|
128 | selectors[selector] = selectorObject;
|
---|
129 | return selectors;
|
---|
130 | }, {});
|
---|
131 | sheet = Object.keys(style).reduce((stylesheet, selector) => {
|
---|
132 | if (stylesheet[selector]) {
|
---|
133 | stylesheet[selector] = Object.assign(
|
---|
134 | {},
|
---|
135 | stylesheet[selector],
|
---|
136 | style[selector]
|
---|
137 | );
|
---|
138 | } else {
|
---|
139 | stylesheet[selector] = style[selector];
|
---|
140 | }
|
---|
141 | return stylesheet;
|
---|
142 | }, sheet);
|
---|
143 | }
|
---|
144 | return sheet;
|
---|
145 | }, {});
|
---|
146 | fs.writeFile(
|
---|
147 | path.join(__dirname, `../src/styles/prism/${fileWithoutCSS}.js`),
|
---|
148 | `export default ${JSON.stringify(javacriptStylesheet, null, 4)}`,
|
---|
149 | () => {}
|
---|
150 | );
|
---|
151 | }
|
---|
152 | );
|
---|
153 | }
|
---|