const convert = require( 'color-convert' ); const fs = require( 'fs' ); const path = require( 'path' ); /** * Recursively find all files with extension in a directory * @param {string} dir The directory to search. Either absolute or relative path * @param {string} extension The file extension to look for * @returns {string[]} returns a list of html files with their full path */ const treeWalker = ( dir, extension, ignoreList ) => { const ls = fs.readdirSync( dir ); const fileList = []; for ( let file in ls ) { if ( fs.statSync( path.join( dir, ls[ file ] ) ).isDirectory() ) { // Filter ignored directories if ( ignoreList === undefined || !ignoreList.includes( ls[ file ] ) ) { const newFiles = treeWalker( path.join( dir, ls[ file ] ), extension, ignoreList ); for (let file = 0; file < newFiles.length; file++) { fileList.push( newFiles[ file ] ); } } } else if ( extension == '*' || ls[ file ].includes( extension ) ) { if ( ignoreList === undefined || !ignoreList.includes( ls[ file ] ) ) { fileList.push( path.join( dir, ls[ file ] ) ); } } } return fileList; } const renderColourAsHex = ( colour ) => { return '#' + convert.default.rgb.hex( colour[ 0 ], colour[ 1 ], colour[ 2 ] ); } const renderColourAsRGB = ( colour ) => { return `rgb( ${ colour[ 0 ] }, ${ colour[ 1 ] }, ${ colour[ 2 ] } )` } const renderColourAsRGBA = ( colour, ambiance ) => { return `rgba( ${ colour[ 0 ] }, ${ colour[ 1 ] }, ${ colour[ 2 ] }, ${ ambiance } )` } /* * Replace the colours with variable names */ const replacements = { '#0f1011': '@bg', 'rgba(9, 9, 10, 0.9)': '@bg_rgba_07', 'rgba(26, 28, 30, 0.3)': '@bg_rgba_05', '#000': '@bg_accent', '#000000': '@bg_accent', 'rgba(0, 0, 0, 0.7)': '@bg_accent_rgba_07', 'rgba(0, 0, 0, 0.6)': '@bg_accent_rgba_06', 'rgba(0, 0, 0, 0.5)': '@bg_accent_rgba_05', 'rgba(0, 0, 0, 0.4)': '@bg_accent_rgba_04', 'rgba(0, 0, 0, 0.3)': '@bg_accent_rgba_03', 'rgba(0, 0, 0, 0.12)': '@bg_accent_rgba_015', 'rgba(0, 0, 0, 0.08)': '@bg_accent_rgba_01', 'rgba(9, 9, 10, 0.9)': '@bg_inactive', '#80868b': '@inactive', 'rgba(128, 134, 139, 0.7)': '@inactive_rgba_07', 'rgba(128, 134, 139, 0.5)': '@inactive_rgba_05', 'rgba(128, 134, 139, 0.3)': '@inactive_rgba_03', 'rgba(128, 134, 139, 0.2)': '@inactive_rgba_02', // '#555A': '@shadow_rgba', // '#555': '@shadow', '#387db7': '@accent', 'rgba(56, 125, 183, 0.5)': '@accent_rgba_05', 'rgba(56, 125, 183, 0.32)': '@accent_rgba_03', 'rgba(56, 125, 183, 0.24)': '@accent_rgba_02', 'rgba(56, 125, 183, 0.16)': '@accent_rgba_015', 'rgba(56, 125, 183, 0.12)': '@accent_rgba_011', 'rgba(56, 125, 183, 0.08)': '@accent_rgba_007', '#1a1a1b': '@accent_gradient_5', '#1f1f21': '@accent_gradient_4', '#1a2530': '@accent_gradient_3', '#1c2c3b': '@accent_gradient_2', '#1e3040': '@accent_gradient_1', '#4887bd': '@accent_gradient_inverse_1', '#508dc0': '@accent_gradient_inverse_2', '#5892c3': '@accent_gradient_inverse_3', '#673ab7': '@accent2', 'rgba(103, 58, 183, 0.12)': '@accent2_rgba_015', '#fff': '@fg_accent', 'rgba(255, 255, 255, 0.7)': '@fg_accent_rgba_07', 'rgba(255, 255, 255, 0.6)': '@fg_accent_rgba_06', 'rgba(255, 255, 255, 0.5)': '@fg_accent_rgba_05', 'rgba(255, 255, 255, 0.3)': '@fg_accent_rgba_03', 'rgba(255, 255, 255, 0.2)': '@fg_accent_rgba_02', '#9e9e9e': '@fg', 'rgba(158, 158, 158, 0.7)': '@fg_rgba_07', 'rgba(158, 158, 158, 0.6)': '@fg_rgba_06', 'rgba(158, 158, 158, 0.5)': '@fg_rgba_05', 'rgba(158, 158, 158, 0.3)': '@fg_rgba_03', 'rgba(158, 158, 158, 0.2)': '@fg_rgba_02', 'rgba(158, 158, 158, 0.1168)': '@fg_rgba_01' }; const themePreProcessor = ( file, replacement, out ) => { const colours = Object.keys( replacements ); let data = '' + fs.readFileSync( file ); for (let index = 0; index < colours.length; index++) { const colour = colours[index]; data = data.replaceAll(colour, replacements[ colour ]); } const outPath = file.replace( replacement, out ); try { fs.mkdirSync( path.dirname( outPath ), { recursive: true, } ); } catch ( e ) { console.error( e ); } fs.writeFileSync( outPath, data ); } const getGradientColour = ( colour, index, multiplier ) => { if ( index === 0 ) { return [ colour[ 0 ] * multiplier, colour[ 1 ] * multiplier, colour[ 2 ] * multiplier ]; } const gradient = getGradientColour( colour, index - 1, multiplier ); return [ Math.min( 255, gradient[ 0 ] * multiplier ), Math.min( 255, gradient[ 1 ] * multiplier ), Math.min( 255, gradient[ 2 ] * multiplier ) ]; } module.exports = { treeWalker, renderColourAsHex, renderColourAsRGB, renderColourAsRGBA, themePreProcessor, getGradientColour }