【问题标题】:Detect the presence of Math to process in MathJax在 MathJax 中检测是否存在要处理的 Math
【发布时间】:2019-05-11 21:43:27
【问题描述】:

我正在使用 MathJax,我有以下场景:

当页面包含一些 MathJax 将正确处理和呈现的数学时,我想运行一些代码

考虑这个例子:

<p>
This is a page containing an equation: $b^2 - 4ac$.
</p>

这里的函数,或者我可以使用的任何函数,都会返回true。但是,如果页面不包含要处理的 TeX 代码块(或任何根据 MathJax 配置触发的代码),则此 API 将返回 false

更多细节

这与修改渲染管道无关。 MathJax 最终会完成它的工作,我对此很好。我只需要一种可靠的方法(希望由库的 API 提供)来检测页面是否有一些需要处理的数学运算。

MathJax 是否具有可用于获取此信息的功能?另外,为了完整起见,我添加了配置 MathJax(内联)的方式:

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX", "output/CommonHTML"],
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
      processEscapes: true
    },
    "CommonHTML": { linebreaks: { automatic: true } }
  });
</script>
<script src="//mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>

或者...

如果我的要求实际上不可行,那么这个怎么样:

我可以附加到渲染管道中的事件,以便在 MathJax 完成数学渲染时执行回调函数吗?

我看到了MathJax startup sequence,这可能就是我的答案。但是,当页面上没有数学时,我看到触发器也会运行。


疑难解答

我试图检测添加到生成的元素中的类的存在,例如 MathJax_Previewmjx-chtml。但是这段代码并不可靠,因为它需要在渲染过程之后触发。这会增加计算时间。

我找不到用于查询要呈现的数学是否存在的 API,但似乎很奇怪,MathJax 没有公开这样的东西。

【问题讨论】:

  • 如果其中一个引用了 mathjax ,如何检查脚本标签?
  • 我总是把它们放在页面上。它总是返回true
  • 你的“另类”让我有点吃惊。通常会出现这个问题,因为人们不想在没有数学的时候加载 MathJax。替代方案是真正的问题吗?
  • @PeterKrautzberger:回头看,你是对的。我的问题基本上是如果页面上没有数学,我不想加载 MathJax。但它也有点复杂。你看,我有一些特殊的代码可以监听页面上的ersize 事件,以便通过调用 MathJax 重新呈现数学。这可确保我的数学始终正确地适合页面换行。但是,如果页面上没有数学,我不想在调整大小时附加事件(从 UI 角度来看代价高昂)...
  • This sample from the MathJax repository 展示了如何拦截New Math 信号。要不加载 MathJax,唯一可靠的方法是构建 tex2jax 预处理器的修改。这是一个MathJax-independent copy,可能有助于构建。

标签: javascript html mathjax


【解决方案1】:

一种可能的解决方法是创建自己的类,然后测试该类是否存在于 DOM 中,然后在需要时动态嵌入 mathjax

数学片段:

var test  = document.querySelectorAll('.math2Process');

if(test.length>0){
  var mathJax_config = document.createElement('script');
  mathJax_config.setAttribute('type','text/x-mathjax-config');
  mathJax_config.text = `MathJax.Hub.Config({
      extensions: ["tex2jax.js"],
      jax: ["input/TeX", "output/CommonHTML"],
      tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"] ],
        displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
        processEscapes: true
      },
      "CommonHTML": { linebreaks: { automatic: true } }
    });`
  var mathJax_script = document.createElement('script');

  mathJax_script.setAttribute('src','//mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML');

  document.head.appendChild(mathJax_config);
  document.head.appendChild(mathJax_script);
}
<p class="math2Process">
This is a page containing an equation: $b^2 - 4ac$.
</p>

相同但没有数学:

var test  = document.querySelectorAll('.math2Process');

if(test.length>0){
  var mathJax_config = document.createElement('script');
  mathJax_config.setAttribute('type','text/x-mathjax-config');
  mathJax_config.text = `MathJax.Hub.Config({
      extensions: ["tex2jax.js"],
      jax: ["input/TeX", "output/CommonHTML"],
      tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"] ],
        displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
        processEscapes: true
      },
      "CommonHTML": { linebreaks: { automatic: true } }
    });`
  var mathJax_script = document.createElement('script');

  mathJax_script.setAttribute('src','//mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML');

  document.head.appendChild(mathJax_config);
  document.head.appendChild(mathJax_script);
}
<p>
This is a page containing an equation: $b^2 - 4ac$.
</p>

【讨论】:

  • 这是一个有效的替代方案,虽然我不喜欢它,因为它会使流程有点复杂,但它绝对是一个解决方案。谢谢,我会考虑的。
【解决方案2】:

下面的代码会检查当前页面是否需要MathJax,如果需要,只在脚本中加载:

<script>
document.addEventListener('DOMContentLoaded', () => {
  const skipHtmlTags = ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'annotation', 'annotation-xml'].map((v) => `:not(${v})`).join('')
  const ignoreHtmlClasses = ['mathjax_ignore'].map((v) => `:not(.${v})`).join('')
  const requiresMathjax = Array.from(document.body.querySelectorAll('*' + skipHtmlTags + ignoreHtmlClasses))
    .some((el) => el.textContent.match(/\\\(|\$\$|\\\[/))

  if (requiresMathjax) {
    const sc = document.createElement('script')
    sc.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-mml-chtml.min.js')
    sc.setAttribute('integrity', 'sha512-9DkJEmXbL/Tdj8b1SxJ4H2p3RCAXKsu8RqbznEjhFYw0cFIWlII+PnGDU2FX3keyE9Ev6eFaDPyEAyAL2cEX0Q==')
    sc.setAttribute('crossorigin', 'anonymous')
    sc.setAttribute('referrerpolicy', 'no-referrer')
    document.head.appendChild(sc)
  }
})
</script>

缩小:

document.addEventListener("DOMContentLoaded",()=>{var t=["script","noscript","style","textarea","pre","code","annotation","annotation-xml"].map(t=>`:not(${t})`).join(""),e=["mathjax_ignore"].map(t=>`:not(.${t})`).join("");if(Array.from(document.body.querySelectorAll("*"+t+e)).some(t=>t.textContent.match(/\\\(|\$\$|\\\[/))){const n=document.createElement("script");n.setAttribute("src","https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-mml-chtml.min.js"),n.setAttribute("integrity","sha512-9DkJEmXbL/Tdj8b1SxJ4H2p3RCAXKsu8RqbznEjhFYw0cFIWlII+PnGDU2FX3keyE9Ev6eFaDPyEAyAL2cEX0Q=="),n.setAttribute("crossorigin","anonymous"),n.setAttribute("referrerpolicy","no-referrer"),document.head.appendChild(n)}});

您有inlineMath: [ ['$','$'], ["\\(","\\)"] ],,但您可能希望停止只使用一个美元符号——您会得到太多误报。如果您想继续使用单个美元符号,可以更新脚本中的正则表达式。

如果您想要不同的脚本,请使用 https://cdnjs.com/libraries/mathjax(或您的首选 CDN)上的 URL 更新 srcintegrity 属性

【讨论】:

    猜你喜欢
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多