// @ts-ignore
import parseFence from '@microflash/fenceparser';
;
;
;
;
export class MarkdownParser {
    constructor() {
        this.currentLine = 0;
        this.lines = [];
    }
    readWitespace() {
        while (true) {
            const line = this.peekLine();
            if (line === null)
                break;
            if (line.trim().length === 0) {
                this.eatLine();
            }
            else
                break;
        }
    }
    readBlock() {
        const startLine = this.currentLine;
        const codeOpening = /^(\s*)(```+\s*)(.*)\s*$/;
        const line = this.eatLine();
        if (line !== null) {
            const opening = codeOpening.exec(line);
            if (opening) {
                const headingSpaces = new RegExp("^" + opening[1] + "", "gm");
                const codeClosing = new RegExp("^" + opening[1] + opening[2] + "$");
                const code = this.eatUntil(codeClosing)?.replace(headingSpaces, "") || "";
                const endLine = this.currentLine - 1;
                const fence = opening[3].trim();
                const [language] = fence.split(/\s+/g, 1);
                const meta = fence.substring(language.length + 1);
                return {
                    type: 'code',
                    text: this.lines.slice(startLine, this.currentLine).join('\n'),
                    code,
                    language: language,
                    meta: meta ?? "",
                    fence: parseFence(meta ?? ""),
                    startLine,
                    endLine
                };
            }
        }
        this.currentLine = startLine;
        return null;
    }
    readHeader() {
        const startLine = this.currentLine;
        const headerMark = /^---$/;
        const line = this.eatLine();
        if (line !== null) {
            const opening = headerMark.exec(line);
            if (opening) {
                const code = this.eatUntil(headerMark) || "";
                return {
                    type: 'frontmatter',
                    text: this.lines.slice(startLine, this.currentLine).join('\n'),
                    code,
                    startLine,
                    endLine: this.currentLine - 1
                };
            }
        }
        this.currentLine = startLine;
        return null;
    }
    eatUntil(token) {
        let content = null;
        while (true) {
            const line = this.eatLine();
            if (line === null)
                break;
            if (token.test(line))
                break;
            content = content === null ? line : content + '\n' + line;
        }
        return content;
    }
    parseFile() {
        const result = [];
        const header = this.readHeader();
        if (header)
            result.push(header);
        while (this.currentLine < this.lines.length) {
            const ret = this.readBlock() || this.readTitle() || this.readParagraph();
            if (ret) {
                result.push(ret);
                continue;
            }
            const initialLine = this.currentLine;
            const text = this.eatLine();
            if (text !== null) {
                if (text.trim().length) {
                    result.push({
                        type: 'paragraph',
                        text,
                        startLine: initialLine,
                        endLine: this.currentLine - 1
                    });
                }
            }
            else {
                break;
            }
        }
        return result;
    }
    readTitle() {
        const startLine = this.currentLine;
        this.readWitespace();
        const titleRE = /^\s*(#+)(.+)(#*)$/;
        const line = this.eatLine();
        if (line !== null) {
            const title = titleRE.exec(line);
            if (title) {
                return {
                    type: 'title',
                    level: title[1].length,
                    text: line,
                    title: title[2]
                        .trim()
                        .replace(/(#+)$/, '')
                        .trim(),
                    startLine,
                    endLine: this.currentLine - 1
                };
            }
        }
        this.currentLine = startLine;
        return null;
    }
    readParagraph() {
        const initialLine = this.currentLine;
        const lines = [];
        while (true) {
            const line = this.peekLine();
            if (line === null || line.trim().length == 0)
                break;
            if (line.trim().startsWith("#") || line.trim().match(/^```+/))
                break;
            lines.push(this.eatLine());
            if (line.endsWith('  '))
                break;
        }
        if (lines.length) {
            return {
                type: 'paragraph',
                text: lines.join('\n'),
                startLine: initialLine,
                endLine: this.currentLine - 1
            };
        }
        this.currentLine = initialLine;
        return null;
    }
    eatLine() {
        if (this.currentLine >= this.lines.length)
            return null;
        const ret = this.lines[this.currentLine];
        this.currentLine++;
        return ret;
    }
    peekLine(forward = 0) {
        if (this.currentLine + forward >= this.lines.length)
            return null;
        return this.lines[this.currentLine + forward];
    }
    parseMD(document) {
        this.lines = document.replace(/\t/gm, '    ').split(/\r\n|\r|\n/gm);
        this.currentLine = 0;
        return this.parseFile();
    }
}
//# sourceMappingURL=markdown.mjs.map