export abstract class Node { tag!: string; body?: Node[]; constructor(public attr?: Attr, public content?: string, body?: Node[]) { if (body) this.body = body.filter((n) => n); } abstract render(): string; setContent(content: string){ this.content = content; } } export class MarkdownNode extends Node<{}> { tag: string = "markdown"; constructor(attr: {}, body: Node[]) { super(attr, undefined, body); } render() { if (!this.body) return ""; return this.body .filter((node) => node?.render) .map((node) => node.render()) .join("\n"); } } export class BlockNode extends Node<{}> { tag: string = "block"; constructor(body: Node[]) { super({}, undefined, body); } render() { if (!this.body) return ""; return `
${this.body .map((node) => node.render()) .join("\n")}
`; } } export class InlineHeaderNode extends Node<{ level: number }> { tag: string = "inline-header"; constructor(attr: { level: number }, body: Node[]) { super(attr, undefined, body); } render() { if (!this.body) return ""; return `${"#".repeat( this.attr?.level ?? 0 )} ${this.body.map((node) => node.render()).join("")}`; } } export class InlineTextNode extends Node<{}> { tag: string = "inline-text"; constructor(body: Node[]) { super({}, undefined, body); } render() { return `${this.body ?.map((node) => node.render()) .join("")}`; } } export class TextNode extends Node<{}> { tag: string = "text"; constructor(content: string) { super({}, content); } render() { return `${this.content}`; } } export class InlineCodeNode extends Node<{}> { tag: string = "inline-code"; constructor(content: string) { super({}, content); } render() { return `\`${this.content}\``; } } export class BlockCodeNode extends Node<{ lang: string }> { tag: string = "block-code"; constructor(attr: { lang: string }, content: string) { super(attr, content); } render() { return `
${this.content}
`; } }