mathjax/katex 如何在网络上呈现复杂的公式?

how do mathjax/katex render complex formulas on the web?

mathjax 和 katex 等库可以在网络上呈现复杂的公式,而无需任何插件。有没有关于如何实现的信息?

从我对现有字体的有限了解来看,字体形状基本上是固定的。例如,我可以增大或减小字母 'A' 的大小,使其变为斜体或粗体,但没有任意改变其形状(对于给定字体)的机制。

另一方面,像 mathjax/katex 这样的库似乎可以做标准字体不可能做的事情。例如,取平方根符号。可以有一个由平方根符号括起来的函数,也可以有一个任意长的复杂表达式。平方根符号相应地调整。这怎么可能?

一种可能是这些数学 'fonts' 不是典型意义上的字体。就 html 而言,它们只是 svg 直线和曲线。但是,情况似乎并非如此,因为我可以 select (部分)表达式,就像我可能 select 句子中的几个单词一样。

我问这个是因为一些人类语言,比如 arabic/persian/urdu 在大多数网页上呈现得不是很好,原因似乎是因为个别字符(或字符的一部分)根据什么而变化继续或跟随角色。换句话说,这些语言需要一种上下文敏感的算法,而大多数文本渲染引擎似乎都不是这种情况。

很想知道数学公式是如何呈现的,这样我就可以弄清楚如何使用该技术来呈现乌尔都语(特别是 nastaleeq)

如果加载包含 MathJax 内容的页面并检查渲染元素的 HTML 源,您可以自己看看。

不好看。

这是 MathJax 为表达式 $\sqrt{x^2 + y^2}$ 生成的 HTML 代码(我添加了换行符):

<div id="wmd-preview" class="wmd-preview"><p><span class="MathJax_Preview" style="color:
inherit;"></span><span class="MathJax" id="MathJax-Element-41-Frame"><nobr><span
class="math" id="MathJax-Span-314" role="math" style="width: 4.836em; display:
inline-block;"><span style="display: inline-block; position: relative; width: 4.003em;
height: 0px; font-size: 120%;"><span style="position: absolute; clip: rect(2.947em
1000.003em 4.503em -999.997em); top: -3.997em; left: 0.003em;"><span class="mrow"
id="MathJax-Span-315"><span class="msqrt" id="MathJax-Span-316"><span style="display:
inline-block; position: relative; width: 4.003em; height: 0px;"><span style="position:
absolute; clip: rect(3.058em 1000.003em 4.392em -999.997em); top: -3.997em; left:
0.947em;"><span class="mrow" id="MathJax-Span-317"><span class="msubsup"
id="MathJax-Span-318"><span style="display: inline-block; position: relative; width:
0.947em; height: 0px;"><span style="position: absolute; clip: rect(3.392em 1000.003em
4.169em -999.997em); top: -3.997em; left: 0.003em;"><span class="mi"
id="MathJax-Span-319" style="font-family: STIXGeneral-Italic;">x<span style="display:
inline-block; overflow: hidden; height: 1px; width: 0.003em;"></span></span><span
style="display: inline-block; width: 0px; height: 4.003em;"></span></span><span
style="position: absolute; top: -4.275em; left: 0.503em;"><span class="mn"
id="MathJax-Span-320" style="font-size: 70.7%; font-family:
STIXGeneral-Regular;">2</span><span style="display: inline-block; width: 0px; height:
4.003em;"></span></span></span></span><span class="mo" id="MathJax-Span-321"
style="font-family: STIXGeneral-Regular; padding-left: 0.281em;">+</span><span
class="msubsup" id="MathJax-Span-322" style="padding-left: 0.281em;"><span
style="display: inline-block; position: relative; width: 0.892em; height: 0px;"><span
style="position: absolute; clip: rect(3.392em 1000.003em 4.392em -999.997em); top:
-3.997em; left: 0.003em;"><span class="mi" id="MathJax-Span-323" style="font-family:
STIXGeneral-Italic;">y</span><span style="display: inline-block; width: 0px; height:
4.003em;"></span></span><span style="position: absolute; top: -4.275em; left:
0.447em;"><span class="mn" id="MathJax-Span-324" style="font-size: 70.7%; font-family:
STIXGeneral-Regular;">2</span><span style="display: inline-block; width: 0px; height:
4.003em;"></span></span></span></span></span><span style="display: inline-block; width:
0px; height: 4.003em;"></span></span><span style="position: absolute; clip: rect(3.003em
1000.003em 3.392em -999.997em); top: -4.053em; left: 0.947em;"><span style="display:
inline-block; position: relative; width: 3.058em; height: 0px;"><span style="position:
absolute; font-family: STIXGeneral-Regular; top: -3.997em; left: 0.003em;">‾<span
style="display: inline-block; width: 0px; height: 4.003em;"></span></span><span
style="position: absolute; font-family: STIXGeneral-Regular; top: -3.997em; left:
2.558em;">‾<span style="display: inline-block; width: 0px; height:
4.003em;"></span></span><span style="font-family: STIXGeneral-Regular; position:
absolute; top: -3.997em; left: 0.392em;">‾<span style="display: inline-block; width:
0px; height: 4.003em;"></span></span><span style="font-family: STIXGeneral-Regular;
position: absolute; top: -3.997em; left: 0.836em;">‾<span style="display: inline-block;
width: 0px; height: 4.003em;"></span></span><span style="font-family:
STIXGeneral-Regular; position: absolute; top: -3.997em; left: 1.281em;">‾<span
style="display: inline-block; width: 0px; height: 4.003em;"></span></span><span
style="font-family: STIXGeneral-Regular; position: absolute; top: -3.997em; left:
1.725em;">‾<span style="display: inline-block; width: 0px; height:
4.003em;"></span></span><span style="font-family: STIXGeneral-Regular; position:
absolute; top: -3.997em; left: 2.114em;">‾<span style="display: inline-block; width:
0px; height: 4.003em;"></span></span></span><span style="display: inline-block; width:
0px; height: 4.003em;"></span></span><span style="position: absolute; clip: rect(2.836em
1000.003em 4.447em -999.997em); top: -3.942em; left: 0.003em;"><span style="font-family:
STIXGeneral-Regular;">√</span><span style="display: inline-block; width: 0px; height:
4.003em;"></span></span></span></span></span><span style="display: inline-block; width:
0px; height: 4.003em;"></span></span></span><span style="border-left-width: 0.003em;
border-left-style: solid; display: inline-block; overflow: hidden; width: 0px; height:
1.603em; vertical-align: -0.463em;"></span></span></nobr></span><script type="math/tex"
id="MathJax-Element-41">\sqrt{x^2 + y^2}</script></p></div>

如果仔细观察,您会看到多次出现 font-family: STIXGeneral-Regular — 这是 MathJax 用来在所有平台上生成一致渲染输出的 web font

如果你再仔细看,你会看到几个超划线字符 () 嵌在 <span> 元素的嵌套中。这些是 MathJax 用来在平方根顶部绘制直线的内容。

不过我不会仔细看它。正如我所说,它并不漂亮。不过最终结果看起来不错:

幸运的是,现代网络浏览器应该可以毫无问题地呈现上下文相关的脚本,只要它们被正确标记(例如,使用正确的 lang and dir 属性)。