/* eslint-disable no-use-before-define */ import React, { ReactNode } from "react"; import { render as htmlrender } from "@bbob/html"; import core from "@bbob/core"; import { isTagNode, isStringNode, isEOL, TagNode, } from "@bbob/plugin-helper"; import type { BBobCoreOptions, BBobCoreTagNodeTree, BBobPlugins, TagNodeTree, } from "@bbob/types"; const toAST = ( source: string, plugins?: BBobPlugins, options?: BBobCoreOptions ) => core(plugins).process(source, { ...options, render: (input) => { return htmlrender(input, { stripTags: true }) }, }).tree; const isContentEmpty = (content: TagNodeTree) => { if (!content) { return true; } if (typeof content === "number") { return String(content).length === 0; } return Array.isArray(content) ? content.length === 0 : !content; }; function tagToReactElement(node: TagNode, index: number) { return React.createElement( node.tag, { ...node.attrs, key: index }, isContentEmpty(node.content) ? null : renderToReactNodes(node.content) ); } function renderToReactNodes(nodes?: BBobCoreTagNodeTree | TagNodeTree) { if (nodes && Array.isArray(nodes) && nodes.length) { return nodes.reduce((arr, node, index) => { if (isTagNode(node)) { arr.push(tagToReactElement(node, index)); return arr; } if (isStringNode(node)) { if (isEOL(String(node))) { arr.push(node); return arr; } const lastIdx = arr.length - 1; const prevArr = arr; // stupid eslint const prevNode = lastIdx >= 0 ? prevArr[lastIdx] : null; if (prevArr[lastIdx] && isStringNode(prevArr[lastIdx]) && prevNode !== null && !isEOL(String(prevNode))) { prevArr[lastIdx] += String(node); return prevArr; } arr.push(node); } return arr; }, []); } return []; } function render( source: string, plugins?: BBobPlugins, options?: BBobCoreOptions ) { return renderToReactNodes(toAST(source, plugins, options)); } export { render }; export default render;