| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | const fs = require('fs');const path = require('path');const lodash = require('lodash');const isComment = codeLine => lodash.startsWith(codeLine, '//') || lodash.startsWith(codeLine, '/*');const getTokenCategory = codeLine => {    const categorySet = new Set(['color', 'width', 'height', 'spacing', 'radius', 'font', 'motion']);    const firstWord = lodash.get(codeLine.match(/\$([\w\W]+?)-/), 1, { toLowerCase: () => null }).toLowerCase();    if (firstWord) {        return categorySet.has(firstWord) ? firstWord : 'other';    } else {        return 'other';    }};const codeLineSplit = codeLine => {    const [key, value, comment] = codeLine.split(/:|\/\/|\/\*/).map(code => code.trim()).filter(code => code);    return { key, value: lodash.trimEnd(value, ';'), comment, category: getTokenCategory(codeLine), raw: codeLine };};const getGlobalDesignToken = () => {    const globalScssContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/global.scss'), { encoding: 'utf-8' }).split('\n');    const paletteScssContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/_palette.scss'), { encoding: 'utf-8' }).split('\n');    const normalContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/variables.scss'), { encoding: 'utf-8' }).split('\n');    const getLightAndDarkScss = scssFileContentArray => {        const contentArray = scssFileContentArray.map(codeLine => codeLine.trim())            .filter(codeLine => codeLine && !isComment(codeLine))            .filter(codeLine => !codeLine.startsWith('}'))            .filter(codeLine => !codeLine.startsWith('@'));        // {key,value,category,raw};        const rawData = {            light: [],            dark: []        };        let currentMode = 'light';        for (let i in contentArray) {            i = Number(i);            const codeLine = contentArray[i];            if (/body/.test(codeLine)) {                if (/semi-always-dark/.test(codeLine)) {                    currentMode = 'dark';                }                continue;            }            rawData[currentMode].push(codeLineSplit(codeLine));        }        return rawData;    };    let globalScssContent = getLightAndDarkScss(globalScssContentArray);    let paletteContent = getLightAndDarkScss(paletteScssContentArray);    const mergeCommentLightToDark = content => {        const map = new Map();        content.light.forEach(token => {            const { key } = token;            map.set(key, { light: token });        });        content.dark.forEach(token => {            const { key } = token;            const data = map.get(key);            if (!data) {                console.warn(`${key} in dark but not in light`);                return;            }            data.dark = token;        });        Array.from(map.values()).forEach(({ light, dark }) => {            if (!dark.comment) {                dark.comment = light.comment;            }        });        return content;    };    globalScssContent = mergeCommentLightToDark(globalScssContent);    paletteContent = mergeCommentLightToDark(paletteContent);    const normalContent = normalContentArray.map(codeLine => codeLine.trim())        .filter(codeLine => codeLine && !isComment(codeLine))        .map(codeLine => codeLineSplit(codeLine));    return { global: globalScssContent, palette: paletteContent, normal: normalContent };};// 官网组件 design token 注入async function main() {    const componentVariablesMap = {};    const semiUIDir = path.join(__dirname, '../packages/semi-foundation');    fs.readdirSync(semiUIDir).map(dirname => {        const variableSCSSPath = path.join(semiUIDir, dirname, 'variables.scss');        if (fs.existsSync(variableSCSSPath)) {            const raw = fs.readFileSync(variableSCSSPath, { encoding: 'utf-8' });            const scssCodeLineList = raw.split('\n').filter(codeLine => codeLine && !isComment(codeLine));            componentVariablesMap[dirname.toLowerCase()] = scssCodeLineList.map(codeLine => codeLineSplit(codeLine));        }    });    componentVariablesMap.global = getGlobalDesignToken();    const [_, __, savePath] = process.argv;    fs.writeFileSync(savePath || './designToken.json', JSON.stringify(componentVariablesMap));}main();
 |