2019-08-22 11:37:13 +08:00

110 lines
2.2 KiB
TypeScript

/* eslint-disable no-cond-assign */
const TITLE_REG = /^(#+)\s+([^\n]*)/;
const TABLE_REG = /^\|.+\n\|\s*-+/;
const TD_REG = /\s*`[^`]+`\s*|([^|`]+)/g;
const TABLE_SPLIT_LINE_REG = /^\|\s*-/;
interface TableContent {
head: Array<string>;
body: Array<Array<string>>;
}
interface SimpleMdAst {
type: string;
content?: string;
table?: TableContent;
level?: number;
}
export interface Artical extends Array<SimpleMdAst> {}
function readLine(input: string) {
const end = input.indexOf('\n');
return input.substr(0, end !== -1 ? end : input.length);
}
function tableParse(input: string) {
let start = 0;
let isHead = true;
const end = input.length;
const table: TableContent = {
head: [],
body: []
};
while (start < end) {
const target = input.substr(start);
const line = readLine(target);
if (!/^\|/.test(target)) {
break;
}
if (TABLE_SPLIT_LINE_REG.test(target)) {
isHead = false;
} else if (isHead) {
// temp do nothing
} else {
const matched = line.trim().match(TD_REG);
if (matched) {
table.body.push(
matched.map(i => {
if (i.indexOf('|') !== 0) {
return i
.trim()
.toLowerCase()
.split('|')
.map(s => s.trim())
.join('|');
}
return i.trim();
})
);
}
}
start += line.length + 1;
}
return {
table,
usedLength: start
};
}
export function mdParser(input: string): Array<SimpleMdAst> {
const artical = [];
let start = 0;
const end = input.length;
while (start < end) {
const target = input.substr(start);
let match;
if ((match = TITLE_REG.exec(target))) {
artical.push({
type: 'title',
content: match[2],
level: match[1].length
});
start += match.index + match[0].length;
} else if ((match = TABLE_REG.exec(target))) {
const { table, usedLength } = tableParse(target.substr(match.index));
artical.push({
type: 'table',
table
});
start += match.index + usedLength;
} else {
start += readLine(target).length + 1;
}
}
return artical;
}