找回密码
 快速注册
搜索
楼主: kuing

今起用新的 MathJax 3 支持数学公式

[复制链接]

3

主题

452

回帖

6188

积分

积分
6188
QQ

显示全部楼层

爪机专用 发表于 2024-12-7 20:35
本帖最后由 kuing 于 2024-12-7 22:20 编辑
abababa 发表于 2024-12-7 19:43
比如在这页(如果回复没换页的话),可不可以这样:


前三行能不能改写成原生 JS,别的页面没有 jquery (本页有是 116# 引入了

最好顺便改写成批量的☺️

$\sqrt 2$
$\sqrt[3]2$

那个 findTeX 函数的原理也看不懂……

======
O,搜索发现代码出自这:groups.google.com/g/mathjax-users/c/x5Z7JBElOas/m/Z4DYXY_nEQAJ
I am majia of kuing

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-12-8 10:15
爪机专用 发表于 2024-12-7 20:35
前三行能不能改写成原生 JS,别的页面没有 jquery (本页有是 116# 引入了

最好顺便改写成批量的☺️

原生的javascript就像下面这样吧:
  1. function findTeX(container) {
  2.   for (const math of MathJax.startup.document.math) {
  3.     if (container === math.typesetRoot) return math.math;
  4.   }
  5. }
  6. var mjxes = document.getElementsByTagName('mjx-container');
  7. for(let mjx of mjxes){
  8.     let tex = findTeX(mjx);
  9.     mjx.setAttribute('title', tex);
  10. }
复制代码

然后就都能加上title了。
那个findTeX函数是搜索帖子找到的,就是楼上的那个链接。

点评

nice!😊  发表于 2024-12-8 13:42

3

主题

452

回帖

6188

积分

积分
6188
QQ

显示全部楼层

爪机专用 发表于 2024-12-8 13:59
abababa 发表于 2024-12-8 10:15
原生的javascript就像下面这样吧:

然后就都能加上title了。


现在手动运行代码没问题,下一步就是要将它加入到mathjax里吧,让它在mathjax渲染完所有公式后运行?
这方面 @hbghlyj 应该在行,快过来看看
I am majia of kuing

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-12-8 16:28
爪机专用 发表于 2024-12-8 13:59
现在手动运行代码没问题,下一步就是要将它加入到mathjax里吧,让它在mathjax渲染完所有公式后运行?
这 ...

应该是用这个MathJax.Hub.Queue吧,放在这里的代码就是在渲染结束后执行的。下面这么写,能起作用吗?
  1. MathJax.Hub.Queue(function() {
  2.         var mjxes = document.getElementsByTagName('mjx-container');
  3.         for(let mjx of mjxes){
  4.                 let tex = findTeX(mjx);
  5.                 mjx.setAttribute('title', tex);
  6.         }
  7. });
复制代码

3

主题

452

回帖

6188

积分

积分
6188
QQ

显示全部楼层

爪机专用 发表于 2024-12-8 16:58
本帖最后由 kuing 于 2024-12-8 17:33 编辑
abababa 发表于 2024-12-8 16:28
应该是用这个MathJax.Hub.Queue吧,放在这里的代码就是在渲染结束后执行的。下面这么写,能起作用吗?
...

这个好像是 mathjax V2 的写法?

docs.mathjax.org/en/v3.2-latest/upgrading/v2.html#changes-in-the-mathjax-api 里面说

  • The queues, signals, and callbacks that are central to version 2 have been replaced by ES6 promises in version 3. In particular, you can use MathJax.startup.promise as a replacement for MathJax.Hub.Queue(). See the Handling Asynchronous Typesetting section for how this is done. See the Version 2 Compatibility Example below for code that may make it possible for you to use your version 2 code in version 3.



I am majia of kuing

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-12-9 10:50
爪机专用 发表于 2024-12-8 16:58
这个好像是 mathjax V2 的写法?

https://docs.mathjax.org/en/v3.2-latest/upgrading/v2.html#changes-i ...

哦,那就按照链接里的说明修改就行了吧,比如下面这样的:
  1. function findTeX(container) {
  2.   for (const math of MathJax.startup.document.math) {
  3.     if (container === math.typesetRoot) return math.math;
  4.   }
  5. }
  6. MathJax.typesetPromise().then(() => {
  7.   var mjxes = document.getElementsByTagName('mjx-container');
  8.         for(let mjx of mjxes){
  9.                 let tex = findTeX(mjx);
  10.                 mjx.setAttribute('title', tex);
  11.         }
  12.   MathJax.typesetPromise();
  13. });
复制代码

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

 楼主| kuing 发表于 2024-12-9 12:17
abababa 发表于 2024-12-9 10:50
哦,那就按照链接里的说明修改就行了吧,比如下面这样的:

貌似不行……写个简单本地网页测试:
  1. <html>
  2. <head>
  3. <script>
  4. window.MathJax = {
  5.   tex: {
  6.     inlineMath: [ ['$','$'], ['`','`'], ["\\(","\\)"] ]
  7.   }
  8. };
  9. </script>
  10. <script src="https://kuing.cjhb.site/mathjax3/es5/tex-svg.js"></script>
  11. <script>
  12. function findTeX(container) {
  13.   for (const math of MathJax.startup.document.math) {
  14.     if (container === math.typesetRoot) return math.math;
  15.   }
  16. }
  17. MathJax.typesetPromise().then(() => {
  18.   var mjxes = document.getElementsByTagName('mjx-container');
  19.         for(let mjx of mjxes){
  20.                 let tex = findTeX(mjx);
  21.                 mjx.setAttribute('title', tex);
  22.         }
  23.   MathJax.typesetPromise();
  24. });
  25. </script>
  26. </head>
  27. <body>
  28. <p>
  29.     $\sqrt{a}$, $\sqrt[3]2$
  30. </p>
  31. </body>
  32. </html>
复制代码

公式能显示,title 没弄上,控制台显示有错误,看不懂。

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-12-9 12:24
kuing 发表于 2024-12-9 12:17
貌似不行……写个简单本地网页测试:

公式能显示,title 没弄上,控制台显示有错误,看不懂。 ...

把这些自己写的script什么的都放在最后,就是那个</body>的前面,这样就行了吧。

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

 楼主| kuing 发表于 2024-12-9 13:52
abababa 发表于 2024-12-9 12:24
把这些自己写的script什么的都放在最后,就是那个</body>的前面,这样就行了吧。 ...


原来如此😊可以了
我再看看论坛怎么放好,还得看看与草稿本之类有没有冲突

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

 楼主| kuing 发表于 2024-12-9 15:26
本帖最后由 kuing 于 2024-12-9 15:33 编辑
kuing 发表于 2024-12-9 13:52
原来如此😊可以了
我再看看论坛怎么放好,还得看看与草稿本之类有没有冲突 ...


将那段代码放入了 zdy3pc.js 里,也就是只对 PC 版的帖子内容页有效,加载该 js 的位置在本页所有楼层之后。

奇怪的是,现在是有时行,有时不行。
(不行时看控制台会有
Uncaught TypeError: MathJax.typesetPromise is not a function
    at zdy3pc.js?orG:266:9
的错误信息)

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

 楼主| kuing 发表于 2024-12-9 21:52
本帖最后由 kuing 于 2024-12-9 23:47 编辑
kuing 发表于 2024-12-9 15:26
...
奇怪的是,现在是有时行,有时不行。
...


刚才看这帖时出现公式不正常显示:
PixPin_2024-12-09_21-59-05.png
(更奇怪是留意上图中最后有两个公式正常显示(鼠标指着那里))
怀疑也与加了这段代码有关。

==========
想起了 @hbghlyj 的 标记搜索词 一帖,也曾讨论过执行顺序的问题。
或许这里也需要一个 startup: { typeset: false } ?就算是,恐怕也得加个条件判断,麻烦哩……

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 07:11
abababa 发表于 2024-12-9 04:24
把这些自己写的script什么的都放在最后,就是那个</body>的前面,这样就行了吧。 ...


这样会运行两次MathJax:初始化时运行一次,放在最后MathJax.typesetPromise()又运行一次。

docs.mathjax.org/en/latest/web/configuration.html#performing-actions-after-typesetting 建议在 MathJax的配置中 覆写 ready 或 pageReady

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 07:13
abababa 发表于 2024-12-9 02:50
MathJax.typesetPromise().then(() => {
  var mjxes = document.getElementsByTagName('mjx-container');
        for(let mjx of mjxes){
                let tex = findTeX(mjx);
                mjx.setAttribute('title', tex);
        }
  MathJax.typesetPromise();
});


第12行是多余的吧。

第6行已 MathJax.typesetPromise() 然后加了 title,为什么要在第12行再次MathJax.typesetPromise()?

3

主题

452

回帖

6188

积分

积分
6188
QQ

显示全部楼层

爪机专用 发表于 2024-12-10 08:08
hbghlyj 发表于 2024-12-10 07:11
这样会运行两次MathJax:初始化时运行一次,放在最后MathJax.typesetPromise()又运行一次。

https://doc ...

ready 与 pageReady 的区别是什么呢?
I am majia of kuing

3

主题

452

回帖

6188

积分

积分
6188
QQ

显示全部楼层

爪机专用 发表于 2024-12-10 08:10
hbghlyj 发表于 2024-12-10 07:13
第12行是多余的吧。

第6行已 MathJax.typesetPromise() 然后加了 title,为什么要在第12行再次MathJax.t ...


window.MathJax = {
  startup: {
    ready: () => {
      MathJax.startup.defaultReady();
      MathJax.startup.promise.then(() => {
        var mjxes = document.getElementsByTagName('mjx-container');
        for(let mjx of mjxes){
                let tex = findTeX(mjx);
                mjx.setAttribute('title', tex);
        }
      });
    }
  }
};
这样写吗?
I am majia of kuing

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 08:55
爪机专用 发表于 2024-12-10 00:08
ready 与 pageReady 的区别是什么呢?


ready 在 pageReady 之前,见:docs.mathjax.org/en/latest/options/startup/startup.html#startup-ready

如果您不需要修改启动模块创建的对象,那么替换 pageReady() 是更好的选择。

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 09:05
爪机专用 发表于 2024-12-7 12:35
O,搜索发现代码出自这:groups.google.com/g/mathjax-users/c/x5Z7JBElOas/m/Z4DYXY_nEQAJ


上面的需要在MathJax运行后多次调用findTeX,相当于循环了两次。
链接中的第二种办法“添加一个 renderAction”比上面的更好,这样当每个数学公式插入到页面时会将原始 TeX 添加为 mjx-container 的 title 属性,只循环了一次就完成。
  1. MathJax = {
  2.   options: {
  3.     renderActions: {
  4.       addTeX: [151,
  5.         (doc) => {for (const math of doc.math) MathJax.config.addTeX(math, doc)},
  6.         (math, doc) => MathJax.config.addTeX(math, doc)
  7.       ]
  8.     }
  9.   },
  10.   addTeX(math, doc) {
  11.     doc.adaptor.setAttribute(math.typesetRoot, 'title', math.math);
  12.   }
  13. };
复制代码

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 09:09
hbghlyj 发表于 2024-12-10 01:05
链接中的第二种办法“添加一个 renderAction”比上面的更好

renderAction在文档中:https://docs.mathjax.org/en/late ... ument-renderactions
示例:How can I manual modify mathjax renderActions with SVG ...

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-12-10 09:48
kuing 发表于 2024-12-9 15:26
将那段代码放入了 zdy3pc.js 里,也就是只对 PC 版的帖子内容页有效,加载该 js 的位置在本页所有楼层之 ...

我也不懂这些,昨天问了maven,他说只加title的话,可以像下面这样写(原话是“监听 dom 载入结束”):
  1. document.addEventListener('DOMContentLoaded', () => {
  2.         let mjxes = document.getElementsByTagName('mjx-container');
  3.         for(let mjx of mjxes) {
  4.                 let tex = findTeX(mjx);
  5.                 mjx.setAttribute('title', tex);
  6.         }
  7. });
复制代码

然后还有草稿本里的不加title的问题,我觉得写完那些,应该已经做完了加title了,然后草稿本里应该是自己新写的,显示的是后出现的mjx-container,应该不受影响。


3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2024-12-10 10:04
kuing 发表于 2024-12-9 07:26
奇怪的是,现在是有时行,有时不行。

放在MathJax配置pageReady中就可以固定执行先后顺序

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 15:46

Powered by Discuz!

× 快速回复 返回顶部 返回列表