/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import type { ReactNode } from 'react' import type { FootnoteNode, ParsedNode } from 'stream-markdown-parser' import { getNodeKey } from './response-content' import { hasParsedChildren, isBlockquoteNode, isCodeBlockNode, isDefinitionListNode, isHeadingNode, isHtmlBlockNode, isImageNode, isLinkNode, isListNode, isMathBlockNode, isMathInlineNode, isTableNode, isTextNode, } from './response-node-guards' import { renderBlockquote } from './response-renderer-alert' import { renderCodeBlock, renderDefinitionList, renderHeading, renderList, renderMathBlock, renderMathInline, } from './response-renderer-blocks' import { renderDetails } from './response-renderer-details' import { renderFootnotes as renderFootnotesBlock } from './response-renderer-footnotes' import { renderImage, renderLink, renderTextNode, } from './response-renderer-inline' import { renderTable } from './response-renderer-table' export function renderChildren(nodes: ParsedNode[]): ReactNode { return nodes.map((node, index) => renderNode(node, getNodeKey(node, index))) } export function renderFootnotes(footnotes: FootnoteNode[]): ReactNode { return renderFootnotesBlock(footnotes, { renderChildren }) } function renderNode(node: ParsedNode, key: string): ReactNode { if (isTextNode(node)) { return renderTextNode(node) } if (isHeadingNode(node)) { return renderHeading(node, key, { renderChildren }) } if (node.type === 'paragraph' && hasParsedChildren(node)) { return (

{renderChildren(node.children)}

) } if (node.type === 'inline' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (isListNode(node)) { return renderList(node, key, { renderChildren }) } if (isCodeBlockNode(node)) { return renderCodeBlock(node, key) } if (node.type === 'inline_code' && 'code' in node) { return ( {String(node.code)} ) } if (isLinkNode(node)) { return renderLink(node, key, renderChildren) } if (isImageNode(node)) { return renderImage(node, key) } if (isBlockquoteNode(node)) { return renderBlockquote(node, key, { renderChildren }) } if (isTableNode(node)) { return renderTable(node, key, { renderChildren }) } if (isDefinitionListNode(node)) { return renderDefinitionList(node, key, { renderChildren }) } if (node.type === 'strong' && hasParsedChildren(node)) { return ( {renderChildren(node.children)} ) } if (node.type === 'emphasis' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (node.type === 'strikethrough' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (node.type === 'highlight' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (node.type === 'insert' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (node.type === 'subscript' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if (node.type === 'superscript' && hasParsedChildren(node)) { return {renderChildren(node.children)} } if ( (node.type === 'checkbox' || node.type === 'checkbox_input') && 'checked' in node ) { return ( ) } if (node.type === 'hardbreak') { return
} if (node.type === 'thematic_break') { return
} if (isMathBlockNode(node)) { return renderMathBlock(node, key) } if (isMathInlineNode(node)) { return renderMathInline(node, key) } if (node.type === 'footnote_reference' && 'id' in node) { return ( [{String(node.id)}] ) } if (node.type === 'footnote_anchor') { return null } if (isHtmlBlockNode(node) && node.tag === 'details') { return renderDetails(node, key, { renderChildren }) } if (node.type === 'html_block' && 'content' in node) { return {String(node.content)} } if (node.type === 'html_inline' && 'content' in node) { return {String(node.content)} } if (hasParsedChildren(node)) { return {renderChildren(node.children)} } if ('content' in node && typeof node.content === 'string') { return {node.content} } return {node.raw} }