// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import {Parser} from 'commonmark'; import Renderer from 'commonmark-react-renderer'; import React, {type ReactElement, useCallback, useMemo, useRef} from 'react'; import {type StyleProp, Text, type TextStyle} from 'react-native'; import Emoji from '@components/emoji'; import {computeTextStyle} from '@utils/markdown'; import type {MarkdownBaseRenderer, MarkdownEmojiRenderer, MarkdownTextStyles} from '@typings/global/markdown'; type Props = { enableEmoji?: boolean; enableCodeSpan?: boolean; enableHardBreak?: boolean; enableSoftBreak?: boolean; baseStyle?: StyleProp; textStyle?: MarkdownTextStyles; value: string; }; const RemoveMarkdown = ({enableEmoji, enableHardBreak, enableSoftBreak, enableCodeSpan, baseStyle, textStyle = {}, value}: Props) => { const renderEmoji = useCallback(({emojiName, literal}: MarkdownEmojiRenderer) => { if (!enableEmoji) { return renderText({literal}); } return ( ); }, [baseStyle, enableEmoji]); const renderBreak = useCallback(() => { return '\n'; }, []); const renderText = useCallback(({literal}: {literal: string}) => { return {literal}; }, [baseStyle]); const renderCodeSpan = useCallback(({context, literal}: MarkdownBaseRenderer) => { if (!enableCodeSpan) { return renderText({literal}); } const {code} = textStyle; return ( {literal} ); }, [baseStyle, textStyle, enableCodeSpan]); const renderNull = () => { return null; }; const createRenderer = () => { return new Renderer({ renderers: { text: renderText, emph: Renderer.forwardChildren, strong: Renderer.forwardChildren, del: Renderer.forwardChildren, code: renderCodeSpan, link: Renderer.forwardChildren, image: renderNull, atMention: Renderer.forwardChildren, channelLink: Renderer.forwardChildren, emoji: renderEmoji, hashtag: Renderer.forwardChildren, latexinline: Renderer.forwardChildren, paragraph: Renderer.forwardChildren, heading: Renderer.forwardChildren, codeBlock: renderNull, blockQuote: renderNull, list: renderNull, item: renderNull, hardBreak: enableHardBreak ? renderBreak : renderNull, thematicBreak: renderNull, softBreak: enableSoftBreak ? renderBreak : renderNull, htmlBlock: renderNull, htmlInline: renderNull, table: renderNull, table_row: renderNull, table_cell: renderNull, mention_highlight: Renderer.forwardChildren, editedIndicator: Renderer.forwardChildren, } as any, }); }; const parser = useRef(new Parser()).current; const renderer = useMemo(createRenderer, [renderText, renderEmoji]); const ast = parser.parse(value); return renderer.render(ast) as ReactElement; }; export default RemoveMarkdown;