tex-mml-svg.js渲染化学公式化学反应式(对不能渲染的化学公式进行强制兼容)

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      window.MathJax = {
        tex: {
          packages: { '[+]': ['mhchem'] },
        },
      }
    </script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-svg.js"></script> -->
    <script src="./public/tex-mml-svg.js"></script>
  </head>
  <body>
    <div id="preview"></div>
    <div id="preview2"></div>
    <script></script>
    <script>
      const cleanChemLatex = (tex, type) => {
        console.log('Original LaTeX:', tex)

        // 1. 移除 \[ 和 \] 标记(因为我们通过 display 参数控制)
        tex = tex
          .replace(/^\s*\\?\[/, '')
          .replace(/\\?\]\s*$/, '')
          .trim()

        // 2. 清理可能的双倍反斜杠(需要在字符串中处理)
        tex = tex.replace(/\\\\/g, '\\')

        // 3. 修复 \chemabove 和 \chembelow 的空第一个参数问题

        if (type === '1') {
          tex = tex.replace(/\\chemabove/g, '')
          tex = tex.replace(/\\chembelow/g, '-')
        } else {
          tex = tex.replace(/\\chemabove/g, '')
          tex = tex.replace(/\\chembelow/g, '')
        }
        tex = tex.replace(/\\ce/g, '')

        // 4. 修复 \phantom{} 空内容
        tex = tex.replace(/\\phantom\{\}/g, '\\phantom{X}')

        // 5. 修复 \phantom{|} 问题
        tex = tex.replace(/\\phantom\{\|\}/g, '\\phantom{X}')

        // 6. 检查并移除多余的右花括号
        let depth = 0
        let cleaned = ''
        let skipNext = false

        for (let i = 0; i < tex.length; i++) {
          if (skipNext) {
            skipNext = false
            continue
          }

          const char = tex[i]
          const nextChar = tex[i + 1]

          // 跳过转义字符
          if (char === '\\') {
            cleaned += char
            if (nextChar) {
              cleaned += nextChar
              i++
            }
            continue
          }

          if (char === '{') {
            depth++
            cleaned += char
          } else if (char === '}') {
            // 只添加右括号如果有匹配的左括号
            if (depth > 0) {
              depth--
              cleaned += char
            } else {
              // 跳过多余的右括号
              console.log('Skipping extra closing brace at position', i)
            }
          } else {
            cleaned += char
          }
        }

        // 7. 如果还有未闭合的左括号,添加对应的右括号
        while (depth > 0) {
          cleaned += '}'
          depth--
        }

        // 8. 移除连续的空格和换行
        cleaned = cleaned.replace(/\s+/g, ' ').trim()

        console.log('Cleaned LaTeX:', cleaned)
        return cleaned
      }

      try {
        async function renderTexToSVG(tex, display = false) {
          await MathJax.startup.promise

          const node = await MathJax.tex2svgPromise(tex, { display })

          return node
        }

        const preview = document.getElementById('preview')

        let tex =
          '\n\n\\[\\ce{\\chembelow{I}{\\phantom{}}} \\chemabove{}{\\displaystyle\\overset{\\displaystyle OCH3}{\\phantom{|}}} \\chembelow{}{\\phantom{}}} + \\chembelow{}{\\displaystyle\\overset{\\displaystyle O}{||}} \\chemabove{Ph}{\\phantom{}}}C-CH=CH-Ph ->[\\text{Ni(acac)2, (S)-DTBM-Segphos}][\\text{Mn powder, Ball Milling (30 Hz, 8 h)}] \\chembelow{}{\\displaystyle\\overset{\\displaystyle O}{||}} \\chemabove{Ph}{\\phantom{}}}C-CH( \\chembelow{}{\\displaystyle\\overset{\\displaystyle OCH3}{\\phantom{|}}} \\chemabove{}{\\phantom{}}} )-CH2-Ph\\]\n\n'

        tex = cleanChemLatex(tex, '2')

        renderTexToSVG(tex, true).then((node) => {
          preview.innerHTML = ''
          preview.appendChild(node)
        })
      } catch (error) {
        console.error('Error rendering TeX to SVG:', error)
      }

      try {
        async function renderTexToSVG(tex, display = false) {
          await MathJax.startup.promise

          const node = await MathJax.tex2svgPromise(tex, { display })

          return node
        }

        const preview = document.getElementById('preview2')

        let tex =
          '\n\n\\[\\ce{Ar^{1}-X + \\chemabove{R}{\\phantom{}} \\chembelow{}{\\displaystyle\\overset{\\displaystyle O}{||}} -CH=CH-Ar^{2} ->[\\text{Ni cat. / L*, Ball Milling}][\\text{Additive}] \\chemabove{R}{\\phantom{}} \\chembelow{}{\\displaystyle\\overset{\\displaystyle O}{||}} -CH(Ar^{1})-CH2-Ar^{2}}\\]\n\n'

        tex = cleanChemLatex(tex, '1')

        renderTexToSVG(tex, true).then((node) => {
          preview.innerHTML = ''
          preview.appendChild(node)
        })
      } catch (error) {
        console.error('Error rendering TeX to SVG:', error)
      }
    </script>
  </body>
</html>
相关推荐
咔咔一顿操作41 分钟前
轻量无依赖!autoviwe 页面自适应组件实战:从安装到源码深度解析
javascript·arcgis·npm·css3·html5
杨超越luckly2 小时前
从传统 GIS 向智能/自动化脚本演进:地铁接驳公交识别的 ArcGIS 与 Python 双路径实践
开发语言·arcgis·php·交互·数据可视化
枝上棉蛮2 天前
2026年GIS软件精选:五款工具的专业性与实用性解析
arcgis·gis·qgis·超图·gisbox·地图数据处理·gis工具
激动的兔子2 天前
Arcgis二次开发--评价单元综合限制级别判断矩阵工具
线性代数·arcgis·矩阵
yngsqq2 天前
arcgis 制作图例、视图页面设置
arcgis
规划酱3 天前
Arcgis中pip安装ezdxf部分GIS有pyparsing安装失败的情况处理
python·arcgis·pip·规划酱
奔跑的呱呱牛3 天前
geojson-to-kml (KML 格式转换工具)
arcgis·json
GISer_Jing3 天前
原生HTML项目重构:Vue/React双框架实战
vue.js·人工智能·arcgis·重构·html
智航GIS6 天前
ArcGIS大师之路500技---070对齐边工具
arcgis
智航GIS6 天前
ArcGIS Python零基础脚本开发教程---10.3 Exists函数
开发语言·python·arcgis