import Slugger from "github-slugger";
import React, { type ReactNode } from "react";
import {
Dimensions,
type ImageStyle,
ScrollView,
Text,
type TextStyle,
TouchableHighlight,
View,
type ViewStyle,
} from "react-native";
import MDImage from "./../components/MDImage";
import MDList from "./../components/MDList";
import MDSvg from "./../components/MDSvg";
import MDTable from "./../components/MDTable";
import { onLinkPress } from "../utils/handlers";
import { getTableWidthArr } from "../utils/table";
import type { RendererInterface } from "./types";
class Renderer implements RendererInterface {
private slugPrefix = "react-native-marked-ele";
private slugger: Slugger;
private windowWidth: number;
constructor() {
this.slugger = new Slugger();
const { width } = Dimensions.get("window");
this.windowWidth = width;
}
paragraph(children: ReactNode[], styles?: ViewStyle): ReactNode {
return this.getViewNode(children, styles);
}
blockquote(children: ReactNode[], styles?: ViewStyle): ReactNode {
return this.getBlockquoteNode(children, styles);
}
heading(text: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(text, styles);
}
code(
text: string,
_language?: string,
containerStyle?: ViewStyle,
textStyle?: TextStyle,
): ReactNode {
return (
{/*
Wrapped in View node to avoid the following error
Error: Cannot add a child that doesn't have a YogaNode to a parent without a measure function!
ref: https://github.com/facebook/react-native/issues/18773
*/}
{this.getTextNode(text, textStyle)}
);
}
hr(styles?: ViewStyle): ReactNode {
return this.getViewNode(null, styles);
}
listItem(children: ReactNode[], styles?: ViewStyle): ReactNode {
return this.getViewNode(children, styles);
}
list(
ordered: boolean,
li: ReactNode[],
listStyle?: ViewStyle,
textStyle?: TextStyle,
startIndex?: number,
): ReactNode {
return (
);
}
escape(text: string, styles?: TextStyle): ReactNode {
return this.getTextNode(text, styles);
}
link(
children: string | ReactNode[],
href: string,
styles?: TextStyle,
title?: string,
): ReactNode {
return (
{children}
);
}
image(
uri: string,
alt?: string,
style?: ImageStyle,
title?: string,
): ReactNode {
const key = this.getKey();
if (uri.endsWith(".svg")) {
return ;
}
return ;
}
strong(children: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(children, styles);
}
em(children: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(children, styles);
}
codespan(text: string, styles?: TextStyle): ReactNode {
return this.getTextNode(text, styles);
}
br(): ReactNode {
return this.getTextNode("\n", {});
}
del(children: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(children, styles);
}
text(text: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(text, styles);
}
html(text: string | ReactNode[], styles?: TextStyle): ReactNode {
return this.getTextNode(text, styles);
}
linkImage(
href: string,
imageUrl: string,
alt?: string,
style?: ImageStyle,
title?: string,
): ReactNode {
const imageNode = this.image(imageUrl, alt, style, title);
return (
{imageNode}
);
}
table(
header: ReactNode[][],
rows: ReactNode[][][],
tableStyle?: ViewStyle,
rowStyle?: ViewStyle,
cellStyle?: ViewStyle,
): React.ReactNode {
const widthArr = getTableWidthArr(header.length, this.windowWidth);
const { borderWidth, borderColor } = tableStyle || {};
return (
);
}
getKey(): string {
return this.slugger.slug(this.slugPrefix);
}
private getTextNode(
children: string | ReactNode[],
styles?: TextStyle,
): ReactNode {
return (
{children}
);
}
private getViewNode(
children: ReactNode[] | null,
styles?: ViewStyle,
): ReactNode {
return (
{children}
);
}
private getBlockquoteNode(
children: ReactNode[],
styles?: ViewStyle,
): ReactNode {
return (
{children}
);
}
}
export default Renderer;