Files
webawesome/scripts/preprocess-css.js
Lea Verou d8673a7d71 Preprocess (some) stylesheets with Nunjucks
- Run Prettier on preprocessed CSS
- Add comment at the start of every generated CSS file
- Generate multiple files via interpolation in filenames!
- Preprocess brand/*.css, variants.css
2025-02-20 13:14:18 -05:00

62 lines
2.1 KiB
JavaScript

import { readFile, writeFile } from 'fs/promises';
import nunjucks from 'nunjucks';
import * as prettier from 'prettier';
import prettierConfig from '../prettier.config.js';
import * as globalData from '../src/styles/data.js';
const prelude = inputFilename => `/* DO NOT EDIT THIS FILE. It is generated from "${inputFilename}" */`;
let env = nunjucks.configure({ autoescape: false });
let filenameVariables = Object.keys(globalData)
.filter(key => key.endsWith('s'))
.map(key => key.slice(0, -1));
let filenameVariablesRegex = RegExp(`\\{\\{\\s*(${filenameVariables.join('|')})\\s*\\}\\}`, 'g');
export async function preprocessStylesheet(inputPath) {
const content = await readFile(inputPath, 'utf-8');
let outputPath = inputPath.replace(/\.njk$/, '');
let filename = outputPath.split('/').pop();
if (filenameVariablesRegex.test(filename)) {
// NOTE only supports a single variable right now
filenameVariablesRegex.lastIndex = 0;
let ret = [];
for (let match of filename.matchAll(filenameVariablesRegex)) {
let variable = match[1];
let values = globalData[variable + 's'];
for (let value of values) {
let data = { [variable]: value };
let css = await renderCSS(content, { data, inputPath, outputPath });
// Now use Nunjucks *again*, to render the actual filename
let localOutputFilePath = env.renderString(outputPath, data);
ret.push(writeFile(localOutputFilePath, css, 'utf-8'));
}
}
return Promise.all(ret);
} else {
let css = await renderCSS(content, { inputPath, outputPath });
return writeFile(outputPath, css, 'utf-8');
}
// TODO add generated files to .gitignore?
}
export async function renderCSS(content, { data, inputPath, outputPath } = {}) {
let inputFilename = inputPath.split('/').pop();
data = data ? { ...globalData, ...data } : globalData;
let css = env.renderString(content, data);
if (prelude) {
css = prelude(inputFilename) + '\n' + css;
}
css = await prettier.format(css, { ...prettierConfig, filepath: outputPath });
return css;
}