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>
相关推荐
xa138508694 小时前
ARCGIS PRO SDK 多边形四至点计算
算法·arcgis
YAY_tyy5 小时前
数据处理:要素裁剪、合并与简化
前端·arcgis·turfjs
智航GIS1 天前
ArcGIS大师之路500技---046淹没动画详解
arcgis
杨超越luckly1 天前
ArcGIS应用指南:使用ArcScene制作三维热力图
arcgis·数据可视化·shp·arcscene·三维热力图
智航GIS2 天前
ArcGIS大师之路500技---045最小外接矩形
arcgis
hanfeng52682 天前
ArcGIS设置随机点
arcgis
智航GIS2 天前
ArcGIS大师之路500技---044检查几何与修复几何
arcgis
青春不败 177-3266-05202 天前
如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响
arcgis·gis·生态学·生态系统服务·大气污染·土壤科学·生态因子
智航GIS3 天前
ArcGIS大师之路500技---043计算点到线的最短距离(邻域分析)
arcgis