oadp-material
Version:
oadp-material
114 lines (98 loc) • 2.28 kB
text/typescript
export const STATE_MARK: any = {
'-': 'disabled',
// tslint:disable-next-line:object-literal-sort-keys
'*': 'active',
'~': 'hover',
'': 'normal',
};
export enum NodeType {
divider = 'divider',
node = 'node',
comment = 'comment',
}
export enum ContentType {
text = 'text',
icon = 'icon',
}
export interface IContent {
type: ContentType;
value: string;
}
export interface INode {
type: NodeType;
state: string;
value: string | IContent[];
children: INode[];
}
export interface IParseOption {
parseContent: boolean;
}
const getChildren = (template: string = ''): IContent[] => {
if (!template) {
return [];
}
return template
.replace(/(\[.*?\])/g, '\n$1\n')
.split('\n')
.filter((v) => !!v)
.map((d) => {
switch (true) {
case /^\[(.*)\]$/.test(d):
return {
type: 'icon',
value: RegExp.$1,
} as IContent;
default:
return {
type: 'text',
value: d,
} as IContent;
}
});
};
export const parseData = (
text: string,
options: IParseOption = { parseContent: false },
): INode[] => {
if (!text) {
return [];
}
const root: INode = {
type: NodeType.node,
state: 'normal',
value: '',
children: [],
};
const stack: INode[] = [root];
text
.split('\n')
.filter((line) => line.trim())
.forEach((line) => {
const re: any = /^(\t*)([#\-~*]?)(.*)$/.exec(line);
const indent = (re[1] || '').length;
const prefix = re[2] || '';
const item: INode = {
type: NodeType.node,
state: 'normal',
value: re[3] || '',
children: [],
};
if (prefix === '-' && /^-{2,}$/.test(item.value as string)) {
item.type = NodeType.divider;
} else if (prefix === '#') {
item.type = NodeType.comment;
} else {
item.state = STATE_MARK[prefix];
}
if (item.type === 'node' && options.parseContent) {
item.value = getChildren(item.value as string);
}
while (indent <= stack.length - 2) {
stack.pop();
}
stack[stack.length - 1].children.push(item);
stack.push(item);
});
return root.children;
};
export default parseData;