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>
相关推荐
薛定猫AI1 天前
【一键配置】优雅使用Claude Code:从安装到上手的完整教程
人工智能·arcgis·编辑器·vim
NULIWEIMENXIANG2 天前
ArcPy 程序调用 QGIS 进程实现几何拓扑检查
python·arcgis·gis
三*一2 天前
基于 Turf.js 实现高精度多边形修整工具(模拟 ArcGIS 修整功能)
开发语言·前端·javascript·arcgis·maobox gl·turf.js
智航GIS2 天前
ArcGIS大师之路500技---074ArcGIS数据压缩:解决大文件卡顿的实用技巧
arcgis
城数派3 天前
我国省市县三级的餐饮服务设施数量(57类餐饮服务/Excel/Shp格式)2025年
arcgis·信息可视化·数据分析·excel
b_xinjun11203 天前
树莓派 Ubuntu 24.04.3 LTS 安装 OpenClaw 操作说明
linux·ubuntu·arcgis
科研online3 天前
基于ArcGIS的区域碳排放精细核算及空间格局分析
arcgis
asyxchenchong8884 天前
RWEQ 模型:ArcGIS+Arcpy 全流程解析风蚀模数估算与归因分析
arcgis
木易GIS4 天前
使用arcpy,批量读取多个文件夹的*.shp中的图层,统计提取图层的个数和要素总个数
python·arcgis
城数派4 天前
1901-2024年我国省市县三级逐月潜在蒸散发数据(Shp/Excel格式)
arcgis·信息可视化·数据分析·excel