import { ContentImage } from "$/ui/objects/ContentImage.tsx"; import { type Node, type DefaultInlineNode } from "./schema.ts"; export function walkBlocks( content: (Node | DefaultInlineNode)[], fn: (_: Node | DefaultInlineNode) => unknown, ): void { for (const node of content) { fn(node); switch (node.type) { case "heading": case "code": case "quote": case "paragraph": case "list": case "list-item": case "link": { return walkBlocks(node.children, fn); } } } } function blocksNodeToTSX(node: Node | DefaultInlineNode) { switch (true) { case node.type === "heading": { switch (node.level) { case 1: return

{blocksToTSX(node.children)}

; case 2: return

{blocksToTSX(node.children)}

; case 3: return

{blocksToTSX(node.children)}

; case 4: return

{blocksToTSX(node.children)}

; case 5: return
{blocksToTSX(node.children)}
; default: return
{blocksToTSX(node.children)}
; } } case node.type === "image" && !!node.image.caption: { return (
{node.image.caption}
); } case node.type === "image": { return ; } case node.type === "code": { return (
					{blocksToTSX(node.children)}
				
); } case node.type === "quote": { return
{blocksToTSX(node.children)}
; } case node.type === "paragraph" && node.children.length === 1 && node.children[0]?.type === "text" && node.children[0].text === "---": { return
; } case node.type === "paragraph": { return

{blocksToTSX(node.children)}

; } case node.type === "list" && node.format === "ordered": { return
    ${blocksToTSX(node.children)}
; } case node.type === "list": { return ; } case node.type === "list-item": { return
  • ${blocksToTSX(node.children)}
  • ; } case node.type === "link": { return {blocksToTSX(node.children)}; } case node.type === "text": { return [ node.bold ? "strong" : undefined, node.code ? "code" : undefined, node.italic ? "em" : undefined, node.strikethrough ? "del" : undefined, node.underline ? "u" : undefined, ].reduce((res: JSX.Element, Tag) => (Tag ? {res} : res), node.text); } } } export function blocksToTSX( content: (Node | DefaultInlineNode)[], filter: (node: Node | DefaultInlineNode) => boolean = () => true, ): JSX.Element { return content .filter(filter) .map(blocksNodeToTSX) .filter((s) => s !== undefined); } export const Blocks = ({ content, filter = () => true, }: { content: (Node | DefaultInlineNode)[]; filter?: (node: Node | DefaultInlineNode) => boolean; }) => blocksToTSX(content, filter);