import { join } from 'path'; import { mdParser } from './md-parser'; import { codegen, Tag, Attribute } from './codegen'; import { PathLike, statSync, mkdirSync, existsSync, readdirSync, readFileSync, writeFileSync, } from 'fs'; export function parseText(input: string) { const ast = mdParser(input); return codegen(ast); } export type Options = { // 需要解析的文件夹路径 path: PathLike; // 文件匹配正则 test: RegExp; // 输出目录 outputDir?: string; // 递归的目录最大深度 maxDeep?: number; // 解析出来的组件名前缀 tagPrefix?: string; }; export type ParseResult = { tags: Record< string, { description: string; attributes: string[]; } >; attributes: Record; }; const defaultOptions = { maxDeep: Infinity, tagPrefix: '', }; export function parse(options: Options) { options = { ...defaultOptions, ...options, }; const result: ParseResult = { tags: {}, attributes: {}, }; function putResult(componentName: string, component: Tag) { componentName = options.tagPrefix + componentName; const attributes = Object.keys(component.attributes); const tag = { description: component.description, attributes, }; result.tags[componentName] = tag; attributes.forEach(key => { result.attributes[`${componentName}/${key}`] = component.attributes[key]; }); } function recursiveParse(options: Options, deep: number) { if (options.maxDeep && deep > options.maxDeep) { return; } deep++; const files = readdirSync(options.path); files.forEach(item => { const currentPath = join(options.path.toString(), item); const stats = statSync(currentPath); if (stats.isDirectory()) { recursiveParse( { ...options, path: currentPath, }, deep ); } else if (stats.isFile() && options.test.test(item)) { const file = readFileSync(currentPath); const tags = parseText(file.toString()); if (tags.default) { // one tag putResult(currentPath.split('/').slice(-2)[0], tags.default); } else { Object.keys(tags).forEach(key => { putResult(key, tags[key]); }); } } }); } recursiveParse(options, 0); return result; } export function parseAndWrite(options: Options) { const { tags, attributes } = parse(options); if (!options.outputDir) { return; } const isExist = existsSync(options.outputDir); if (!isExist) { mkdirSync(options.outputDir); } writeFileSync( join(options.outputDir, 'tags.json'), JSON.stringify(tags, null, 2) ); writeFileSync( join(options.outputDir, 'attributes.json'), JSON.stringify(attributes, null, 2) ); } export default { parse, parseText, parseAndWrite, };