mirror of
https://github.com/bendtherules/react-to-markdown.git
synced 2026-08-18 13:53:11 +00:00
renderer - Handle children and nested jsx, render to markdown
This commit is contained in:
+66
-28
@@ -1,42 +1,50 @@
|
|||||||
|
import { root, text } from "mdast-builder";
|
||||||
import { Children as ReactChildren } from "react";
|
import { Children as ReactChildren } from "react";
|
||||||
|
import * as stringify from "remark-stringify";
|
||||||
|
import * as unified from "unified";
|
||||||
|
import { Parent as MDASTParent } from "unist";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ReactElementSubset,
|
isClassComponent,
|
||||||
ReactElementSubsetWithPrimitive,
|
|
||||||
isFunctionalComponent,
|
isFunctionalComponent,
|
||||||
isClassComponent
|
ReactElementSubsetWithPrimitive
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
|
|
||||||
function render(
|
function render(
|
||||||
node: ReactElementSubsetWithPrimitive,
|
node: ReactElementSubsetWithPrimitive,
|
||||||
parentNode?: ReactElementSubset
|
parentASTNode?: MDASTParent
|
||||||
) {
|
): string | null {
|
||||||
// Skip null and undefined nodes
|
let parentASTNodeMod: MDASTParent;
|
||||||
|
if (parentASTNode === undefined) {
|
||||||
|
parentASTNodeMod = root([]);
|
||||||
|
} else {
|
||||||
|
parentASTNodeMod = parentASTNode;
|
||||||
|
}
|
||||||
|
|
||||||
if (node === null || node === undefined) {
|
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
|
||||||
|
|
||||||
// Render string and number nodes
|
const currASTNode = text(node.toString());
|
||||||
if (typeof node === "string" || typeof node === "number") {
|
parentASTNodeMod.children.push(currASTNode);
|
||||||
return;
|
} else if (Array.isArray(node)) {
|
||||||
}
|
// Handle (render) Fragment nodes or arrays
|
||||||
|
|
||||||
// Render Fragment nodes
|
|
||||||
if (Array.isArray(node)) {
|
|
||||||
node.forEach(fragmentEle => render(fragmentEle));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
node.forEach(fragmentEle => render(fragmentEle, parentASTNodeMod));
|
||||||
|
} else {
|
||||||
const { props, type: elementType } = node;
|
const { props, type: elementType } = node;
|
||||||
const { children } = props;
|
|
||||||
|
|
||||||
|
// Handle nested function or class components
|
||||||
|
{
|
||||||
if (isFunctionalComponent(elementType)) {
|
if (isFunctionalComponent(elementType)) {
|
||||||
const renderOutput = elementType.call(
|
const renderOutputRaw = elementType.call(null, props);
|
||||||
null,
|
const renderOutput = ReactChildren.toArray(
|
||||||
props
|
renderOutputRaw
|
||||||
) as ReactElementSubsetWithPrimitive;
|
) as ReactElementSubsetWithPrimitive[];
|
||||||
|
|
||||||
render(renderOutput);
|
// Render processed array of children
|
||||||
return;
|
render(renderOutput, parentASTNodeMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isClassComponent(elementType)) {
|
if (isClassComponent(elementType)) {
|
||||||
@@ -46,15 +54,45 @@ function render(
|
|||||||
renderOutputRaw
|
renderOutputRaw
|
||||||
) as ReactElementSubsetWithPrimitive[];
|
) as ReactElementSubsetWithPrimitive[];
|
||||||
|
|
||||||
// Render array of children, just like fragments
|
// Render processed array of children
|
||||||
render(renderOutput);
|
render(renderOutput, parentASTNodeMod);
|
||||||
|
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle intrinsic types of element like div, h1
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { render };
|
export { render };
|
||||||
|
|||||||
Reference in New Issue
Block a user