markdown-vetur
Version:
simple parse markdown to vue component description for vetur auto-completion
133 lines (117 loc) • 2.75 kB
text/typescript
import { default as mdParse } from './md-parser';
import codegen, { Tag } from './codegen';
import {
PathLike,
readdirSync,
statSync,
readFileSync,
writeFileSync,
existsSync,
mkdirSync
} from 'fs';
import { join } from 'path';
export function parseText(input: string) {
const ast = mdParse(input);
return codegen(ast);
}
interface Options {
/**
* 需要解析的文件夹路径
*/
path: PathLike;
/**
* 哪些文件需要解析
*/
test: RegExp;
/**
* 输出目录
*/
outputDir?: string;
/**
* 递归的目录最大深度
*/
maxDeep?: number;
/**
* 解析出来的组件名前缀
*/
tagPrefix?: string;
}
const defaultOptions = {
maxDeep: Infinity,
tagPrefix: ''
};
export function parseAndWrite(options: Options) {
const { tags, attributes } = parse(options);
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 function parse(options: Options) {
options = {
...defaultOptions,
...options
};
const result = {
tags: {},
attributes: {}
};
recursiveParse(options, 0);
return result;
function recursiveParse(options: Options, deep: number) {
if (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]);
});
}
}
});
}
function putResult(componentName: string, compoennt: Tag) {
componentName = options.tagPrefix + componentName;
const attributes = Object.keys(compoennt.attributes);
const tag: Tag = {
description: compoennt.description,
attributes
};
result.tags[componentName] = tag;
attributes.forEach(key => {
result.attributes[`${componentName}/${key}`] = compoennt.attributes[key];
});
}
}
export default {
parseAndWrite,
parse,
parseText
}