From eef2069e0949912fabf0fc082970ad7b4aa26267 Mon Sep 17 00:00:00 2001 From: bendtherules Date: Sun, 15 Dec 2019 16:33:56 +0530 Subject: [PATCH] renderer - Handle children and nested jsx, render to markdown --- src/renderer.ts | 128 +++++++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/src/renderer.ts b/src/renderer.ts index 83151d6..ea32cb4 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -1,59 +1,97 @@ +import { root, text } from "mdast-builder"; import { Children as ReactChildren } from "react"; +import * as stringify from "remark-stringify"; +import * as unified from "unified"; +import { Parent as MDASTParent } from "unist"; + import { - ReactElementSubset, - ReactElementSubsetWithPrimitive, + isClassComponent, isFunctionalComponent, - isClassComponent + ReactElementSubsetWithPrimitive } from "./helpers"; function render( node: ReactElementSubsetWithPrimitive, - parentNode?: ReactElementSubset -) { - // Skip null and undefined nodes + parentASTNode?: MDASTParent +): string | null { + let parentASTNodeMod: MDASTParent; + if (parentASTNode === undefined) { + parentASTNodeMod = root([]); + } else { + parentASTNodeMod = parentASTNode; + } + if (node === null || node === undefined) { - return; + // Handle (skip) null and undefined nodes + } else if (typeof node === "string" || typeof node === "number") { + // Handle (render) string and number nodes as string in markdown + + const currASTNode = text(node.toString()); + parentASTNodeMod.children.push(currASTNode); + } else if (Array.isArray(node)) { + // Handle (render) Fragment nodes or arrays + + node.forEach(fragmentEle => render(fragmentEle, parentASTNodeMod)); + } else { + const { props, type: elementType } = node; + + // Handle nested function or class components + { + if (isFunctionalComponent(elementType)) { + const renderOutputRaw = elementType.call(null, props); + const renderOutput = ReactChildren.toArray( + renderOutputRaw + ) as ReactElementSubsetWithPrimitive[]; + + // Render processed array of children + render(renderOutput, parentASTNodeMod); + } + + if (isClassComponent(elementType)) { + const elementInstance = new elementType(props); + const renderOutputRaw = elementInstance.render(); + const renderOutput = ReactChildren.toArray( + renderOutputRaw + ) as ReactElementSubsetWithPrimitive[]; + + // Render processed array of children + render(renderOutput, parentASTNodeMod); + + } + } + + // Handle intrinsic types of element like div, h1 + { + } + + { + // Handle children + const { children } = props; + + // Render processed array of children + const renderOutput = ReactChildren.toArray( + children + ) as ReactElementSubsetWithPrimitive[]; + + render(renderOutput, parentASTNodeMod); + } } - // Render string and number nodes - if (typeof node === "string" || typeof node === "number") { - return; - } - - // Render Fragment nodes - if (Array.isArray(node)) { - node.forEach(fragmentEle => render(fragmentEle)); - return; - } - - const { props, type: elementType } = node; - const { children } = props; - - if (isFunctionalComponent(elementType)) { - const renderOutput = elementType.call( - null, - props - ) as ReactElementSubsetWithPrimitive; - - render(renderOutput); - return; - } - - if (isClassComponent(elementType)) { - const elementInstance = new elementType(props); - const renderOutputRaw = elementInstance.render(); - const renderOutput = ReactChildren.toArray( - renderOutputRaw - ) as ReactElementSubsetWithPrimitive[]; - - // Render array of children, just like fragments - render(renderOutput); - - return; - } - - // Handle intrinsic types of element like div, h1 + // Return stuff { + // For root call, return string + if (parentASTNode === undefined && parentASTNodeMod.children.length > 0) { + const processor = unified().use(stringify, { + bullet: "-", + fence: "`", + fences: true, + incrementListMarker: false + }); + const output = processor.stringify(parentASTNodeMod); + + return output; + } + return null; } }