让docsify-katex支持化学公式mhchem扩展
在使用docsify构建Markdown文档时,如果想要支持数学公式,可以使用docsify-katex插件,但是该插件不支持化学公式mhchem扩展,比如下面的代码:
1\ce{Zn^2+ <=>[+ 2OH-][+ 2H+] $\underset{\text{amphoteres Hydroxid}}{\ce{Zn(OH)2 v}}$ <=>[+ 2OH-][+ 2H+] $\underset{\text{Hydroxozikat}}{\ce{[Zn(OH)4]^2-}}$}
正常显示应该为:
docsify-katex已经很久没更新了,最新的katex已经支持mhchem扩展。为了让docsify-katex也支持mhchem扩展,需要做如下修改:
首先引入mhchem扩展
1import 'katex/contrib/mhchem/mhchem';
由于mhchem扩展的语法格式中包含有美元符号,与行内公式使用的标记一样,所以需要先处理掉块内的美元符号: 再定义:
1const blockDollar = '!!blockDollar!!';
2const blockDollarRegx = /!!blockDollar!!/g;
再把处理公式块内的美元符号处理掉: 将hook.beforeEach函数如原代码:
1// Block
2.replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
3 return preMathBlockOpen + c + preMathBlockClose;
4})
改为:
1// Block
2.replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
3 let x = c.replace(/\$/g, blockDollar)
4 return preMathBlockOpen + x + preMathBlockClose;
5})
再修改hook.afterEach函数中原代码:
1mathRendered = mathRendered
2 .replace(
3 preMathBlockRegex,
4 function (m, code) {
5 let rendered = katex.renderToString(code, blockOptions);
6 return rendered;
7 }
8);
修改为:
1mathRendered = mathRendered
2 .replace(
3 preMathBlockRegex,
4 function (m, code) {
5 code = code.replace(blockDollarRegx, '$')
6 let rendered = katex.renderToString(code, blockOptions);
7 return rendered;
8 }
9);
即可。 修改好源码后,编译,使用新编译的js代码即可。
附上修改后的源码:
1import 'katex/contrib/mhchem/mhchem';
2import katex from 'katex';
3
4let options = {
5 throwOnError: false,
6 displayMode: false
7};
8let blockOptions = {
9 throwOnError: false,
10 displayMode: true
11};
12
13const magicEscapedDollar = 'c194a9eb';
14const magicEscapedDollarRegex = /c194a9eb/g;
15const magicBacktickInCodeTag = 'c194a9ec';
16const magicBacktickInCodeTagRegex = /c194a9ec/g;
17const magicBacktickInDollars = 'c194a9ed';
18const magicBacktickInDollarsRegex = /c194a9ed/g;
19const magicEscapedBacktick = 'c194a9ee';
20const magicEscapedBacktickRegex = /c194a9ee/g;
21const magicDollarInBacktick = 'c194a9ef';
22const magicDollarInBacktickRegex = /c194a9ef/g;
23
24const preMathInlineOpen = 'c194a9eg<!-- begin-inline-katex';
25const preMathInlineClose = 'end-inline-katex-->';
26const preMathInlineRegex = /c194a9eg<!-- begin-inline-katex([\s\S]*?)end-inline-katex-->/g;
27
28
29const preMathBlockOpen = '<!-- begin-block-katex';
30const preMathBlockClose = 'end-block-katex-->';
31const preMathBlockRegex = /<!-- begin-block-katex([\s\S]*?)end-block-katex-->/g;
32
33const blockDollar = '!!blockDollar!!';
34const blockDollarRegx = /!!blockDollar!!/g;
35
36(function () {
37 function install(hook) {
38 hook.beforeEach(content => {
39 let mathPreserved = content
40 // Escape all <code>`</code>
41 .replace(/<code>(.*)<\/code>/g, function(a, b) {
42 return `<code>${b.replace(/`/g, magicBacktickInCodeTag)}</code>`;
43 })
44 // Escape all $`$
45 .replace(/\$`\$/g, magicBacktickInDollars)
46 // Escape all \`{
47 .replace(/\\`\{/g, magicEscapedBacktick)
48 // Escape all \$
49 .replace(/\\\$/g, magicEscapedDollar)
50 // Escape all & in `...`
51 .replace(/(`{1,})([\s\S]*?)\1/g, function (a) {
52 return a.replace(/\$/g, magicDollarInBacktick);
53 })
54 // Recover all <code>`</code>
55 .replace(magicBacktickInCodeTagRegex, '`');
56 mathPreserved = mathPreserved
57 // Recover all $`$
58 .replace(magicBacktickInDollarsRegex, '$ `$')
59 // Recover all \`{
60 .replace(magicEscapedBacktickRegex, '\\`{');
61 mathPreserved = mathPreserved
62 // Block
63 .replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
64 let x = c.replace(/\$/g, blockDollar)
65 return preMathBlockOpen + x + preMathBlockClose;
66 })
67 // Inline, no \$
68 .replace(/(\$)([\s\S]*?)(\$)/g, function (a, b, c) {
69 return preMathInlineOpen + c.replace(magicEscapedDollarRegex, '\\$') + preMathInlineClose;
70 })
71 .replace(magicEscapedDollarRegex, '\\$');
72 return mathPreserved;
73 });
74 hook.afterEach(function (html, next) {
75 let mathRendered = html
76 .replace(
77 preMathInlineRegex,
78 function (m, code) {
79 let rendered = katex.renderToString(code, options);
80 return rendered;
81 }
82 );
83 mathRendered = mathRendered
84 .replace(
85 preMathBlockRegex,
86 function (m, code) {
87 code = code.replace(blockDollarRegx, '$')
88 let rendered = katex.renderToString(code, blockOptions);
89 return rendered;
90 }
91 );
92 next(mathRendered
93 // Recover all & in `...`
94 .replace(magicDollarInBacktickRegex, '$'));
95 });
96 }
97
98 $docsify.plugins = [].concat(install, $docsify.plugins);
99}());
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2022/2022-03-16-让docsify-katex支持化学公式mhchem扩展/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。