配置和加载mathjax

mathjax版本3的配置、加载和启动过程在许多方面与版本2不同。在版本2有几个不同的配置mathjax的方法的情况下,版本3简化了流程,并且只有一个方法,如下所述。在版本2中,您总是加载 MathJax.js, and added a config=... 参数以提供组合配置文件,但在版本3中,根据需要加载多个不同文件中的一个(这样可以避免多个文件传输,还可以同步使用mathjax,这在版本2中是不可能的)。

如果在版本3中使用组合的组件文件之一,如 mml-chtml ,您可能根本不需要进行任何配置。


配置mathjax

要配置mathjax,可以使用名为 MathJax 包含mathjax各个组件的配置数据。例如,要将tex输入组件配置为使用单个美元符号作为行内数学分隔符(除了通常的 \(...\) 分隔符)和svg输出组件要对页面上的所有表达式使用全局字体缓存,请使用

MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']]
  },
  svg: {
    fontCache: 'global'
  }
};

下面的部分描述了可以放置这种配置的不同位置。有关可以为每个组件设置的选项的信息,请参见 配置mathjax 页。

使用内嵌脚本的配置

配置MathJax的最简单方法是将 MathJax 对象中的 <script> 在加载mathjax本身的脚本之前标记。例如:

<script>
MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']]
  },
  svg: {
    fontCache: 'global'
  }
};
</script>
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

这将配置tex输入组件使用单个美元符号作为行内数学分隔符,而svg输出组件使用全局字体缓存(而不是页面上每个表达式的单独缓存),然后加载 tex-svg 组件文件来自 jsdelivr CDN。这将在页面上排版任何tex数学,生成表达式的svg版本。

使用本地文件进行配置

如果在多个页面上使用相同的mathjax配置,则可以将配置存储在加载到页面中的单独javascript文件中。例如,可以创建一个名为 mathjax-config.js 包含

window.MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']]
  },
  svg: {
    fontCache: 'global'
  }
};

然后使用

<script src="mathjax-config.js" defer></script>
<script type="text/javascript" id="MathJax-script" defer
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

首先加载配置文件,然后加载 tex-svg 组件来自 jsdelivr CDN。

注意,这里我们使用 defer 属性,以便在将文件下载到浏览器时按顺序执行,但仍不会阻止页面的其余部分。如果 async 属性被使用时,不能保证首先运行配置,因此您可能会得到mathjax没有正确配置的实例,并且这些实例看起来是随机发生的。

在一个脚本中配置和加载

还可以让mathjax配置文件加载mathjax,这是处理上述两个脚本同步问题的另一种方法。例如,您可以将 load-mathjax.js 包含

window.MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']]
  },
  svg: {
    fontCache: 'global'
  }
};

(function () {
  var script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js';
  script.async = true;
  document.head.appendChild(script);
})();

然后通过

<script src="load-mathjax.js" async></script>

这个脚本可以是 async 因为它不需要与任何其他脚本同步。这将允许它在加载后立即运行(因为它很小,因此成本很低),这意味着加载mathjax本身的脚本将尽快插入,以便mathjax可以尽早开始下载。(如果此脚本加载了 defer ,它在页面准备好之前不会运行,因此加载mathjax的脚本在此之前不会被插入,您必须等待mathjax被下载后才能运行。)

将v2配置转换为v3

由于版本3的配置选项与版本2的配置选项有些不同,我们提供了一个 configuration conversion tool 以帮助您从版本2移动到版本3。只需粘贴当前 MathJax.Hub.Config() 呼叫转换器,按 Convert 您应该获得等效的版本3配置,以及关于无法转换为版本3的任何选项的注释(一些选项尚未实现,其他选项在版本3中不再有意义)。有关详细信息,请参阅链接页上的说明。


加载mathjax

一旦配置了mathjax,就可以加载要使用的mathjax组件文件。最常见的情况是,这意味着您将加载一个组合组件,该组件将加载以特定输入和输出格式运行mathjax所需的所有内容。例如, tex-svg 组件将允许您处理tex输入并生成svg输出。为此,请使用如下脚本

<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

获取最新(3.x.x)版本的 tex-svg 来自的ES5格式的组件(当前唯一可用的) jsdelivr CDN。这利用了 jsdeliver 它允许您使用 mathjax@3 表示法。对于特定的版本,您可以使用

<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/tex-svg.js">
</script>

要始终获得3.0.0版本的 tex-svg 组件。

对于如何指定版本号,其他CDN的格式略有不同。例如, cdnjs 使用以下内容:

<script type="text/javascript" id="MathJax-script" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.0.0/es5/tex-svg.js">
</script>

有些CDN不提供自动获取最新版本的方法。为此,mathjax提供了 latest.js 会帮你的文件。例如, cdnjs 没有自动获取最新3.x.x版本的机制。如果你想用 cdnjs 然后使用

<script type="text/javascript" id="MathJax-script" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.0.0/es5/latest?tex-svg.js">
</script>

获取最新(3.x.x)版本的 tex-svg 组件。

mathjax组件 对于各种组件的列表,您可以选择它们的内容和描述。见 list of CDNs 用于服务于mathjax的多个cdn的url。

注意,加载mathjax组件文件的脚本应该 跟随 配置mathjax的脚本(否则mathjax将不知道您需要什么配置)。如果在版本3中使用组合的组件文件之一,则可能根本不需要进行任何配置。

单独加载组件

如果组合的组件文件都不适合您的需要,则可以通过设置 load 数组中 loader 您的mathjax配置和加载 startup 组件。

例如

<script>
MathJax = {
  loader: {
    load: ['input/tex-base', 'output/svg', 'ui/menu', '[tex]/require']
  },
  tex: {
    packages: ['base', 'require']
  }
};
</script>
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/startup.js">
</script>

会导致基本tex输入、svg输出、上下文菜单代码和tex \require 要加载的宏扩展组件(并告诉tex使用 require 除了基本tex宏之外的扩展名)。这样,就可以准确地加载所需的组件。但是,请注意,每个组件都将作为单独的文件加载,因此最好尽可能使用组合的组件文件。

加载附加组件

你可以使用 load 上一节中描述的数组,用于加载附加组件,即使您使用的是组合组件之一。例如

<script>
MathJax = {
  loader: {
    load: ['[tex]/colorv2']
  },
  tex: {
    packages: {'[+]': 'colorv2'},
    autoload: {color: []}
  }
};
</script>
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/tex-chtml.js">
</script>

将加载与版本2兼容的 \color 宏,通知tex将其添加到已加载的包中,而不是自动加载默认版本3 color (与 Latex 相容的那种)。这是在 tex-chtml 组合配置文件,因此已经包含了tex输入和commonhtml输出格式(上下文菜单和几个tex包也是如此;请参见 mathjax组件 详情请参阅。

在启动期间执行操作

mathjax允许多种方式连接到mathjax启动过程中,以便您可以执行其他配置、在初始排版之后执行操作等等。因为mathjax版本3使用 承诺 对于它的同步,mathjax提供了这些功能,以便您连接到启动过程中。有两个主要的钩子可以放在 startup 配置的块: ready() 函数和 pageReady() 功能。

这个 ready() 函数是mathjax在加载mathjax的所有组件时调用的函数。它构建mathjax所需的内部结构,在 MathJax 对象以使排版和格式转换更容易,执行初始排版调用,并为完成时设置承诺。您可以覆盖 ready() 使用自己的函数完全重写启动过程,或在通常的初始化之前或之后执行操作。例如,您可以在mathjax创建所需对象之前进行额外的设置,也可以挂接到排版承诺中,以便在完成初始排版时同步其他操作。这些例子如下。

这个 pageReady() 函数在mathjax准备就绪(它的所有组件都已加载,内部对象已创建)和页面本身准备就绪(即,可以对页面进行排版)时执行。默认为 pageReady() 执行页面的初始排版,但您可以重写它来执行其他操作,例如在动态加载其他内容时延迟初始排版。这个 ready() 函数设置对 pageReady() 作为其默认操作的一部分。

的返回值 pageReady() 是在初始排版完成时解决的承诺(它是初始排版的返回值) MathJax.typesetPromise() 呼叫)。如果您覆盖 pageReady() 方法,则函数也应返回一个promise。如果函数调用 MathJax.startup.defaultPageReady() ,则应返回它返回的承诺(或从其 then()catch() 方法)。这个 MathJax.startup.promise 当你归还的承诺得到解决;如果你不归还承诺, MathJax.startup.promise 将立即解决,这可能意味着它解决得太早。

单独或组合使用这两个函数可以完全控制mathjax在启动时所采取的操作,并允许您自定义mathjax的启动过程以满足您的需要。以下是一些常见情况的例子。

在初始化期间执行操作

如果您想在mathjax加载所有需要的组件之后执行操作,可以设置 ready() 函数转换为执行所需操作的函数,然后调用 MathJax.startup.defaultReady() 执行通常的启动过程。

行动在 MathJax.startup.defaultReady() 调用在完成任何初始化之前运行。特别是,这是在创建任何输入或输出jax之前,因此可以在这里执行mathjax对象定义的定制。例如,此时可以修改配置块,也可以创建mathjax对象的子类,这些子类重写其某些方法以生成自定义行为,然后将这些子类注册到mathjax中,以便将其用于替代原始的子类。

之后的行动 MathJax.startup.defaultReady() 调用在初始化完成后运行。特别是,math jax使用的所有内部对象(例如,输入和输出jax、数学文档、dom适配器等)都将被创建,并且排版和转换方法将在 MathJax 对象。也 MathJax.startup.promise 值将保留在初始排版完成时解析的承诺,但请注意,此时尚未执行排版。

window.MathJax = {
  startup: {
    ready: () => {
      console.log('MathJax is loaded, but not yet initialized');
      MathJax.startup.defaultReady();
      console.log('MathJax is initialized, and the initial typeset is queued');
    }
  }
};

下一节将展示如何使用 MathJax.startup.promise 与初始排版操作同步。

排版后执行操作

通常,在执行某些操作之前,您可能需要等待mathjax完成页面的排版。要完成此任务,可以重写 ready() 函数,让它执行 MathJax.startup.defaultReady() 操作,然后使用 MathJax.startup.promise 将操作排队;这些操作将在初始排版完成后执行。

window.MathJax = {
  startup: {
    ready: () => {
      MathJax.startup.defaultReady();
      MathJax.startup.promise.then(() => {
        console.log('MathJax initial typesetting complete');
      });
    }
  }
};

作为替代方法,您可以重写 pageReady() 函数,并使用从 MathJax.startup.defaultPageReady() 功能:

window.MathJax = {
  startup: {
    pageReady: () => {
      return MathJax.startup.defaultPageReady().then(() => {
        console.log('MathJax initial typesetting complete');
      });
    }
  }
};

一定要把你从 then() 否则,方法 MathJax.startup.promise 将在执行初始排版(和代码)之前解决。


在加载mathjax之后配置它

全局变量 MathJax 用于存储mathjax的配置。但是,一旦装载了mathjax,mathjax就会更改 MathJax 变量以包含控制mathjax所需的各种方法。您提供的初始配置将移动到 MathJax.config 属性,以便其内容与中提供的新值不冲突。 MathJax . 当您请求的mathjax组件被加载时(在 ready() 函数被调用)。

一旦mathjax创建了所需的对象(如输入和输出jax),对配置的更改可能不会产生任何影响,因为在创建对象期间使用了配置值,而且这已经完成。大多数对象从原始对象中复制其配置 MathJax 对象,因此更改 MathJax.config 创建对象后不会更改其配置。(你可以改变 MathJax.config 尚未创建的对象的值,但尚未创建的对象的值除外。)

对于某些对象,如输入和输出jax、文档处理程序和数学文档,配置设置的本地副本存储在 options 对象的属性,您可以在其中设置值。例如, MathJax.startup.output.options.scale 是输出的缩放值,您可以随时设置该值以影响任何后续的排版调用。

请注意,在创建主对象时,某些选项将移动到子对象。例如,对于tex输入jax, inlineMath 类似的选项用于创建 FindTeX 存储在 MathJax.startup.input[0].findTeX ;但在这种情况下, FindTeX 对象在创建时使用一次配置,因此更改 MathJax.startup.input[0].findTeX.options 不会影响它。(有一个 getPatterns() 方法如果 FindTeX 但是,如果更改了选项,则可用于刷新对象的对象。)

如果需要更改对象的配置,而该对象的选项在创建后无法更改,则需要在更改配置后创建该对象的新版本。例如,如果您更改 MathJax.config.tex.inlineMath 在mathjax启动之后,这将不会影响tex输入jax,如上所述。在这种情况下,你可以打电话给 MathJax.startup.getComponents() 要求mathjax重新创建所有内部对象(如 MathJax.startup.input )这将导致使用新的配置选项创建它们。但是,请注意,mathjax将不再知道已经排版的任何数学,因为该数据存储在创建新数据时丢弃的对象中。