1、背景
项目做的文档的采编结果展示,部分文档中会包含数据公式,后端返回的为采编后的html片段,用$$符号或者$符号包裹数学公式。
2、LaTex 、KaTex、MathJax
LaTeX 早在1980就已经开始使用了,是一种流行的排版系统,广泛用于学术界、出版业和科技领域。它通过一系列的命令和标记语言,使用户能够以专业、美观和一致的方式排版文档。
LaTex有各种本地客户端,可以使用客户端编辑LaTex文档,本篇主要讨论LaTex公式的渲染,可以在 在线LaTex编辑器 操作感受下。
使用javascript 渲染LaTex 目前主流有两种解决方案,即KaTex和MathJax
维度 | KaTex | MathJax |
适用范围 |
仅仅支持关于 TeX/LaTeX 输入和 HTML、MathMl 的输出,更加轻量化,不会支持Latex的所有功能,特别是一些高级宏包和命令。 支持的语法范围没有MathJax丰富。 |
更加综合,支持MathML和AsciiMath的输入,且输出格式支持svg、mathML。 提供了对辅助技术的支持(例如,为数学生成语音文本,或为它输出盲文,并提供数学的交互式探索,等等)。 |
渲染速度 | 快速,使用纯 JavaScript 来生成和渲染。 | 较慢,但MathJax3对mathjax2版本重写后,在性能上有了很大的提升。 |
扩展依赖 | KaTex扩展支持相对有限 | MathJax有更丰富的扩展包,如physics.js,使得可以支持更丰富的物理公式(e.g. \pderivative{x} ) |
浏览器兼容 | 对旧版本浏览器兼容较差,各种浏览器上的性能表现相对一致 | 支持更广泛的浏览器,包括一些旧版本,但不同浏览器的性能可能会有所不同 |
社区支持 | 作为一个相对较新的项目,KaTeX 的社区可能没有 MathJax 的社区那么成熟 | 存在时间较长,MathJax 拥有一个成熟的社区和大量的用户基础,提供了大量的教程、问答和第三方资源。 |
3、本项目使用katex
1、安装KaTeX
npm install katex
2、创建KaTeX渲染组件KatexComponent.vue
<template><divclass="katex-component"v-dompurify-html="renderedMath"style="white-space: pre-line"></div> </template><script setup lang="ts"> import { ref, watch, nextTick, onMounted, computed, onUnmounted } from 'vue'; import katex from 'katex'; import 'katex/dist/katex.min.css';const props = withDefaults(defineProps<{htmlStr: string;needHandleImg?: boolean;keyword?: string; // 图片中的关键字搜索}>(),{// htmlStr: `20210914_开源证券_金融工程专题_分析师目标价的Alpha信息--金融工程专题_魏建榕.pdf-图表目录-4、一致预期目标收益率因子改进优化-4.1、加权预期收益率因子WTR\n我们回顾了一致预期目标收益率因子的构造方法,由于分析师会参考股票当前的价格设置目标价,在构造目标收益率的时候,应该考虑报告发布时的价格而不是月末计算因子时候的股票价格。\n股票的目标价格预测需要得到后续行情的验证。若在回看窗口内的股票价格走势能够印证分析师的目标收益率,则应给予目标价格更大的权重;若是股票价格并不符合预期走势,在计算因子时赋予该预测值较低的权重。\n基于上述思路,<em>构造加权目标收益率因子</em>,如下所示:\n $$WTR=\\sum \\frac{P_{i}^{e}}{P_{i}^{0}}=\\frac{\\sum P_{i}^{e}\\times P/P_{i}^{0}}{P}\\omega _{i}=TR\\times W$$ \n其中`htmlStr: '',needHandleImg: true,keyword: ''} ); const renderedMath = ref(''); watch(() => props.htmlStr,val => {if (val) {let replacedHtml = val;// 先处理双美元符号 $$...$$const latexDoubleRegex = /\$\$(.*?)\$\$/g;// 然后处理单美元符号 $...$(确保前后不是$)const latexSingleRegex = /(?<!\$)\$(?!\$)(.*?)(?<!\$)\$(?!\$)/g;// 先处理双美元公式replacedHtml = replacedHtml.replace(latexDoubleRegex,(match, latexFormula) => {return katex.renderToString(latexFormula, {throwOnError: false,macros: {'\\textcelsius': '^{\\circ}C', // 展示℃ }});});// 然后处理单美元公式replacedHtml = replacedHtml.replace(latexSingleRegex,(match, latexFormula) => {return katex.renderToString(latexFormula, {throwOnError: false,macros: {'\\textcelsius': '^{\\circ}C'}});});renderedMath.value = replacedHtml;// console.log('renderedMath', renderedMath); }},{ immediate: true } ); </script><style lang="scss" scoped></style>
3、在父组件中使用
<template><KatexComponent :htmlStr="content" /> </template><script setup lang="ts"> import KatexComponent from '@/views/components/KatexComponent.vue';let content = ref<string>('$$c = \pm\sqrt{a^2 + b^2}$$'); </script>