react native中markdown添加数学公式的支持
在react native中实现markdown最佳选择当然是 react-native-markdown-display,不过有一个问题是它不支持数学公式的显示,我的解决方法是通过rules和markdownit属性进行功能扩展
需要安装的lib
"katex": "^0.16.22","markdown-it-math": "^4.1.1","markdown-it-texmath": "^1.0.0","react-native-mathjax-svg": "^0.9.9",
功能代码如下:
import React, { useMemo, useCallback } from 'react';
import {Linking, ScrollView, StyleSheet, Text, View} from "react-native";
import Toast from "react-native-simple-toast";
import Markdown, {ASTNode,MarkdownIt,RenderRules,
} from "react-native-markdown-display";
import MathJax from 'react-native-mathjax-svg'
import MarkdownItMath from "markdown-it-math";// 简易 Markdown 预览组件
interface MarkdownViewProps {markdown: string;scrollable?: boolean;
}function MarkdownView({ markdown, scrollable = false }: MarkdownViewProps) {const markdownStyles = useMemo(() => StyleSheet.create({body: {color: '#333',fontSize: 16,lineHeight: 24,flexWrap:'wrap',backgroundColor:'green',overflow:'scroll'},heading1: {fontSize: 24,fontWeight: 'bold',marginVertical: 8,color: 'red',},heading2: {fontSize: 20,fontWeight: 'bold',marginVertical: 8,color: 'blue',},heading3: {fontSize: 18,fontWeight: 'bold',marginVertical: 6,color: 'green',},paragraph: {marginVertical: 8,fontSize: 14,lineHeight: 20,color: '#2E3742',},list_item: {marginVertical: 4,fontSize: 14,},code_inline: {backgroundColor: '#f1f1f1',color: '#e53935',borderRadius: 3,paddingHorizontal: 4,},code_block: {backgroundColor: '#f5f5f5',padding: 12,borderRadius: 6,marginVertical: 8,fontSize: 14,},blockquote: {borderLeftWidth: 4,borderLeftColor: '#3465F5',paddingLeft: 12,marginVertical: 8,backgroundColor: '#F8F9FA',paddingVertical: 6,borderRadius: 4,},link: {color: '#3465F5',textDecorationLine: 'underline',},bullet_list: {marginLeft: 8,},ordered_list: {marginLeft: 8,},}), []);const markdownItInstance = new MarkdownIt({typographer: true,}).use(MarkdownItMath, {inlineOpen: '$',inlineClose: '$',blockOpen: '$$',blockClose: '$$',}).use(MarkdownItMath, {inlineOpen: '\\(',inlineClose: '\\)',blockOpen: '\\[',blockClose: '\\]',})const renderEquation = (node: ASTNode) => {return <MathJax key={node.key}>{node.content}</MathJax>}const rules: RenderRules = {math_inline: renderEquation,math_block: renderEquation,textgroup: (node, children) => {return (<Text key={node.key} selectable={true}>{children}</Text>)},}const MarkdownContent = useMemo(() => (<Markdownstyle={markdownStyles}rules={rules}markdownit={markdownItInstance}>{markdown}</Markdown>), [markdown, markdownStyles]);if (scrollable) {return (<ScrollView style={styles.markdownPreview}>{MarkdownContent}</ScrollView>);}return (<View style={styles.markdownContainer}>{MarkdownContent}</View>);
}const styles = StyleSheet.create({equationContainer: {overflow: 'hidden',alignSelf: 'flex-start', // 防止拉伸maxWidth: '100%', // 公式最大宽度},markdownPreview: {flex: 1,padding: 0,},markdownContainer: {padding: 0,borderWidth:1,backgroundColor:'red'},markdownText: {fontSize: 14,lineHeight: 22,color: '#1F2937',},
});export default MarkdownView;
现在有一个已知问题是公式的内容超出一行的时候渲染内容会超出屏幕不会换行,这个我得抽时间来解决