/* 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; body: Array>; } interface SimpleMdAst { type: string; content?: string; table?: TableContent; level?: number; } export interface Artical extends Array {} 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 { 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; }