import type { Reader } from './readers/reader' import { createLineData, parseLine } from './parser' type Document = { ended: boolean, clone: () => Document, next: () => Promise current: () => Document line: () => string, head: () => string, tail: () => string, content: (contentLevel: number, lines: string[]) => Promise, seek: (matchHead: string, contentLevel: number) => Promise } export function useDocument (reader: Reader, indent: string = ' '): Document { let lineData = createLineData(null, indent) const document = { ended: false, clone() { return useDocument(reader.clone(), indent) }, async next() { lineData.line = await reader.next() if (lineData.line === null) return true else parseLine(lineData) }, current() { return document }, line() { return lineData.line?.slice(lineData.offsetHead) }, head () { return lineData.line?.slice(lineData.offsetHead, lineData.offsetTail) }, tail () { return lineData.line?.slice(lineData.offsetTail) }, level () { return lineData.level }, async content (contentLevel = -1, lines: string[] = []): Promise { if (contentLevel === -1) contentLevel = lineData.level + 1 const ended = await document.next() if (ended) return lines.join('\n') if (lineData.level < contentLevel) return lines.join('\n') lines.push(lineData.line?.slice(contentLevel) || '') return document.content(contentLevel, lines) }, async seek (matchHead: string, contentLevel = -1): Promise { if (contentLevel === -1) contentLevel = lineData.level const ended = await document.next() if (ended) return false if (document.head() === matchHead) return document if (lineData.level < contentLevel) return false return document.seek(matchHead, contentLevel) } } return document }