You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native中无需手动正则解析即可同时渲染Markdown与LaTeX的方案咨询

React Native中无需手动正则解析即可同时渲染Markdown与LaTeX的方案咨询

我正在开发一款AI助手应用,目前在实现Markdown渲染文本与LaTeX内容共存的功能时遇到了瓶颈。当前我用react-native-markdown-display来支持Markdown语法渲染,用已废弃的react-native-math-view处理LaTeX公式内容。

我试过一种解决方案:用正则表达式解析消息内容,把Markdown文本和LaTeX片段拆分出来,然后分别用<Markdown /><MathView />组件进行条件渲染。虽然这种方法能勉强实现基础功能,但会带来严重的对齐和格式排版问题。

下面是我当前实现这个思路的MessageRenderer组件代码:

import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
import MathView, {MathText} from 'react-native-math-view';
import {textStyle} from "../styles/common.style";
import Markdown from "react-native-markdown-display";
import {MsgType} from "./class/MessageItem";

const MessageRenderer = ({message, type}) => {
    const parts = parseMessage(message);
    
    return (
        <View style={styles().main}>
            {parts.map((part, index) => {
                if (part.type === 'text') {
                    return (
                        <Markdown 
                            key={index} 
                            style={{ body: type === MsgType.USER ? styles().normalText : styles().assistantNormalText }}
                        >
                            {part.content}
                        </Markdown>
                    );
                } else if (part.type === 'math') {
                    return (
                        <MathView
                            key={index}
                            math={part.content}
                            style={styles().mathText}
                        />
                    );
                }
                return null;
            })}
        </View>
    );
};

const parseMessage = (message) => {
    const regex = /\\\(([\s\S]*?)\\\)|\\\[([\s\S]*?)\\]/g; // Matches math expressions within \(...\) or \[...\]
    const parts = [];
    let lastIndex = 0;
    
    try {
        message.replace(regex, (match, group1, group2, index) => {
            // Add text content before the current match
            if (lastIndex < index) {
                parts.push({ type: 'text', content: message.slice(lastIndex, index) });
            }
            
            // Add the matched math content
            const formula = group1 || group2; 
            parts.push({ type: 'math', content: formula });
            
            // Update the lastIndex to the end of the current match
            lastIndex = index + match.length;
        });
        
        // Add any remaining text after the last match
        if (lastIndex < message.length) {
            parts.push({ type: 'text', content: message.slice(lastIndex) });
        }
    } catch (e) {
        console.log("error", e);
        return parts;
    }
    
    return parts;
};

const styles = () => {
    return StyleSheet.create({
        main: {
            flexDirection: 'row',
            flexWrap: 'wrap',
            alignItems: 'center'
        },
        normalText: {
            ...textStyle.Body_4,
            color: 'white'
        },
        mathText: {
            ...textStyle.Body_4,
            marginHorizontal: 2,
            color: 'white'
        },
        assistantNormalText: {
            ...textStyle.Body3,
            color: 'white'
        }
    });
};

export default MessageRenderer;

测试示例数据

const message = `

- This is a paragraph with some inline math: \\(E = mc^2\\).

- Some text with inline math \\(a^2 + b^2 = c^2\\)

- And block math

\\[
e = sum_(n=0)^oo 1/n!
\\]

\\[
\\int_{a}^{b} x^2 dx
\\]

Here is a JavaScript code block:

\`\`\`javascript
function greet() {
  console.log("Hello, world!");
}
\`\`\`

And some more inline math: \\(a^2 + b^2 = c^2\\).
`;

问题

有没有更稳健、更直接的方法,能在React Native中同时渲染Markdown和LaTeX内容,而不用手动通过正则表达式来解析拆分内容?


备注:内容来源于stack exchange,提问作者Vishal Naikawadi

火山引擎 最新活动