import React, { type FunctionComponent, type ReactNode, useMemo } from "react"; import { ScrollView, type ScrollViewProps, type StyleProp, StyleSheet, Text, type TextStyle, View, type ViewStyle, } from "react-native"; import SyntaxHighlighter, { type SyntaxHighlighterProps, } from "react-syntax-highlighter"; import { trimNewlines } from "trim-newlines"; import { getRNStylesFromHljsStyle, type HighlighterStyleSheet, type ReactStyle, } from "./../utils/styles"; export interface CodeHighlighterProps extends SyntaxHighlighterProps { hljsStyle: ReactStyle; textStyle?: StyleProp; scrollViewProps?: ScrollViewProps; /** * @deprecated Use scrollViewProps.contentContainerStyle instead */ containerStyle?: StyleProp; } export const CodeHighlighter: FunctionComponent = ({ children, textStyle, hljsStyle, scrollViewProps, containerStyle, ...rest }) => { const stylesheet: HighlighterStyleSheet = useMemo( () => getRNStylesFromHljsStyle(hljsStyle), [hljsStyle], ); const getStylesForNode = (node: rendererNode): TextStyle[] => { const classes: string[] = node.properties?.className ?? []; return classes .map((c: string) => stylesheet[c]) .filter((c) => !!c) as TextStyle[]; }; const renderNode = (nodes: rendererNode[], keyPrefix = "row") => nodes.reduce((acc, node, index) => { const keyPrefixWithIndex = `${keyPrefix}_${index}`; if (node.children) { const styles = StyleSheet.flatten([ textStyle, { color: stylesheet.hljs?.color }, getStylesForNode(node), ]); acc.push( {renderNode(node.children, `${keyPrefixWithIndex}_child`)} , ); } if (node.value) { acc.push(trimNewlines(String(node.value))); } return acc; }, []); const renderer = (props: rendererProps) => { const { rows } = props; return ( true}>{renderNode(rows)} ); }; return ( {children} ); }; export default CodeHighlighter;