aiChat开发日志1:如何将AI的生成的LaTeX代码转换成公式

开发日志没啥先后顺序,想到哪个就先记录哪个,主要目的是为了给对这个东西感兴趣的伙伴分享心得,供我和大家一起参考,内容不一定是最优解,但能跑(要不然那个网页也用不了)。

开发日志应该都会开启评论,欢迎看到的小伙伴参与讨论吧。

下面记录的ai聊天功能是基于通义千问的模型搭建,如果您使用的是其他品牌,信息的收发以及API调用部分可能会有差别,还请留意。

1 仅渲染页面固有的公式

在没有添加LaTeX数学公式渲染库之前,AI的回复内容会显示成这样:

$x^2 + y^2 = z^2$

目前最流行且轻量级的选择是 MathJax,它可以在浏览器中动态将LaTeX代码转换为美观的数学公式,一般渲染网站已经存在的公式很简单,只需要在网站的HTML加入MathJax的js库然后在body标签里面调用就可以了,大概的结构就是:

在HTML文件的<head>标签中添加以下代码,即可完成配置。

<!-- 引入KaTeX核心CSS样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css">
<!-- 引入KaTeX核心JS库 -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"></script>
<!-- 引入自动渲染扩展 -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"></script>

然后在<body>标签的任意位置插入下面的代码进行初始化与配置,公式分隔符参考设置如下(设置 display: true 表示独立成行的块级公式,display: false则为行内公式):

<script>
    document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.body, {
            delimiters: [
                {left: '$$', right: '$$', display: true},    // 例如:$$ E = mc^2 $$
                {left: '\\[', right: '\\]', display: true},  // 例如:\[ F = ma \]
                {left: '\\(', right: '\\)', display: false}, // 例如:\( E = mc^2 \)
                {left: '$', right: '$', display: false}      // 注意:可能与美元符号冲突
            ],
            throwOnError: false // 设为false可在公式错误时显示错误信息,避免页面崩溃[reference:6]
        });
    });
</script>

这样子整个页面的LaTeX代码都会变成好康的公式了,不过这不是重点。

2 将AI的生成的LaTeX代码转换成公式

由于AI生成的内容是外来接入的,第1节中的代码没法对中途产生的内容进行转换,以我们雨之庭的aiChat为例,只好将上面的内容插入到它的script.js里面去,并且小修一下js里的文本处理程序。

2.1 动态加载 MathJax 数学公式库

将第1节中的代码整合改成下列形式,放到js的开头。

// --- 动态加载 MathJax 数学公式库 ---
(function () {
if (window.MathJax) return;
const script = document.createElement('script');
script.src = 'https://polyfill.io/v3/polyfill.min.js?features=es6';
script.async = true;
document.head.appendChild(script);
const script2 = document.createElement('script');
script2.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
script2.async = true;
window.MathJax = {
    tex: {
        inlineMath: [['$', '$'], ['\\(', '\\)']],
        displayMath: [['$$', '$$'], ['\\[', '\\]']]
    },
    options: { skipHtmlTags: ['script', 'noscript', 'style', 'textarea'] }
};
document.head.appendChild(script2);
})();

2.2 定义进行公式渲染的函数

这个是执行渲染的核心,位置倒是能随便摆,不过一般放在2.3的两个函数之后。

// --- 新增:MathJax 渲染函数 ---
function renderMathInElement(element) {
    if (window.MathJax && window.MathJax.typeset) {
        try {
            window.MathJax.typesetClear(); 
            window.MathJax.typeset([element]); // 渲染这个特定元素
        } catch (err) {
            console.warn('MathJax 渲染失败:', err);
        }
    } else {
        // 如果库还没加载好,稍微等一下再试
        setTimeout(() => renderMathInElement(element), 100);
    }
}

2.3 修改 displayMessage 和 typeWriterEffect 函数

按理来讲,AI应该在生成一条公式的代码后,无论后面是否有内容生成,都应该先将这个公式代码进行渲染,但是搞这个又要多加一堆条件,什么异步与同步的,索性不干了,因此,我是将这个显示AI信息的函数displayMessage的最底部的 if (role === 'bot') 里加入一个回调函数,这样子的话,就只有当AI结果生成结束后,才会进行公式的渲染(虽然过程不好看,但是结果好看就行了)。

if (role === 'bot') {
 // 👇 修改这里:清空内容,并在打字机完成后触发公式渲染
 messageContent.innerHTML = ''; typeWriterEffect(messageContent, message, () => { renderMathInElement(messageContent); // 打字完成后渲染公式 }); }

然后是typeWriterEffect函数,这是处理打字机特效的,主要关注要修改的部分,就是这一块运行结束后callback执行renderMathInElement函数,这样就能完成AI生成内容里的公式渲染了。

// 3. 打字机效果核心函数 
function typeWriterEffect(element, text, callback) { // 👈 增加 callback 参数 
...
...
function type() { 
if (i < text.length) {
 element.innerHTML = formatMessage(text.substring(0, i + 1)); i++; setTimeout(type, speed); element.scrollIntoView({ behavior: 'smooth', block: 'end' }); 
} else {
 // 👇 增加这里:打字结束后,执行回调函数 
if (callback) callback(); } } type(); }

3 结果展示

来看看效果,随便写个让ai会冒出公式的问题,在ai生成内容的过程中,公式未经过渲染。

内容全部生成后,如下图所示,大功告成。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇