让docsify-katex支持化学公式mhchem扩展

在使用docsify构建Markdown文档时,如果想要支持数学公式,可以使用docsify-katex插件,但是该插件不支持化学公式mhchem扩展,比如下面的代码:

\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扩展

import 'katex/contrib/mhchem/mhchem';

由于mhchem扩展的语法格式中包含有美元符号,与行内公式使用的标记一样,所以需要先处理掉块内的美元符号:
再定义:

const blockDollar = '!!blockDollar!!';
const blockDollarRegx = /!!blockDollar!!/g;

再把处理公式块内的美元符号处理掉:
将hook.beforeEach函数如原代码:

// Block
.replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
   return preMathBlockOpen + c + preMathBlockClose;
})

改为:

// Block
.replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
   let x = c.replace(/\$/g, blockDollar)
   return preMathBlockOpen + x + preMathBlockClose;
})

再修改hook.afterEach函数中原代码:

mathRendered = mathRendered
  .replace(
    preMathBlockRegex,
    function (m, code) {
      let rendered = katex.renderToString(code, blockOptions);
      return rendered;
      }
);

修改为:

mathRendered = mathRendered
  .replace(
    preMathBlockRegex,
    function (m, code) {
      code = code.replace(blockDollarRegx, '$')
      let rendered = katex.renderToString(code, blockOptions);
      return rendered;
      }
);

即可。
修改好源码后,编译,使用新编译的js代码即可。

附上修改后的源码:

import 'katex/contrib/mhchem/mhchem';
import katex from 'katex';

let options = {
  throwOnError: false,
  displayMode: false
};
let blockOptions = {
  throwOnError: false,
  displayMode: true
};

const magicEscapedDollar = 'c194a9eb';
const magicEscapedDollarRegex = /c194a9eb/g;
const magicBacktickInCodeTag = 'c194a9ec';
const magicBacktickInCodeTagRegex = /c194a9ec/g;
const magicBacktickInDollars = 'c194a9ed';
const magicBacktickInDollarsRegex = /c194a9ed/g;
const magicEscapedBacktick = 'c194a9ee';
const magicEscapedBacktickRegex = /c194a9ee/g;
const magicDollarInBacktick = 'c194a9ef';
const magicDollarInBacktickRegex = /c194a9ef/g;

const preMathInlineOpen = 'c194a9eg<!-- begin-inline-katex';
const preMathInlineClose = 'end-inline-katex-->';
const preMathInlineRegex = /c194a9eg<!-- begin-inline-katex([\s\S]*?)end-inline-katex-->/g;


const preMathBlockOpen = '<!-- begin-block-katex';
const preMathBlockClose = 'end-block-katex-->';
const preMathBlockRegex = /<!-- begin-block-katex([\s\S]*?)end-block-katex-->/g;

const blockDollar = '!!blockDollar!!';
const blockDollarRegx = /!!blockDollar!!/g;

(function () {
  function install(hook) {
    hook.beforeEach(content => {
      let mathPreserved = content
        // Escape all <code>`</code>
        .replace(/<code>(.*)<\/code>/g, function(a, b) {
          return `<code>${b.replace(/`/g, magicBacktickInCodeTag)}</code>`;
        })
        // Escape all $`$
        .replace(/\$`\$/g, magicBacktickInDollars)  
        // Escape all \`{
        .replace(/\\`\{/g, magicEscapedBacktick)
        // Escape all \$
        .replace(/\\\$/g, magicEscapedDollar)
        // Escape all & in `...`
        .replace(/(`{1,})([\s\S]*?)\1/g, function (a) {
          return a.replace(/\$/g, magicDollarInBacktick);
        })
        // Recover all <code>`</code>
        .replace(magicBacktickInCodeTagRegex, '`');
      mathPreserved = mathPreserved
        // Recover all $`$
        .replace(magicBacktickInDollarsRegex, '$ `$')
        // Recover all \`{
        .replace(magicEscapedBacktickRegex, '\\`{');
      mathPreserved = mathPreserved
        // Block
        .replace(/(\$\$)([\s\S]*?)(\$\$)/g, function (a, b, c) {
          let x = c.replace(/\$/g, blockDollar)
          return preMathBlockOpen + x + preMathBlockClose;
        })
        // Inline, no \$
        .replace(/(\$)([\s\S]*?)(\$)/g, function (a, b, c) {
          return preMathInlineOpen + c.replace(magicEscapedDollarRegex, '\\$') + preMathInlineClose;
        })
        .replace(magicEscapedDollarRegex, '\\$');
      return mathPreserved;
    });
    hook.afterEach(function (html, next) {
      let mathRendered = html
        .replace(
          preMathInlineRegex,
          function (m, code) {
            let rendered = katex.renderToString(code, options);
            return rendered;
          }
        );
      mathRendered = mathRendered
        .replace(
          preMathBlockRegex,
          function (m, code) {
            code = code.replace(blockDollarRegx, '$')
            let rendered = katex.renderToString(code, blockOptions);
            return rendered;
          }
        );
      next(mathRendered
        // Recover all & in `...`
        .replace(magicDollarInBacktickRegex, '$'));
    });
  }

  $docsify.plugins = [].concat(install, $docsify.plugins);
}());
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值