mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
141 lines
2.9 KiB
TypeScript
141 lines
2.9 KiB
TypeScript
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<string, Attribute>;
|
|
};
|
|
|
|
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,
|
|
};
|