6 个版本
0.2.1 | 2022 年 10 月 20 日 |
---|---|
0.2.0 | 2022 年 10 月 19 日 |
0.1.3 | 2022 年 6 月 21 日 |
2053 在 命令行工具
7.5MB
10K SLoC
包含 (压缩文件,205KB) dimensions.numbers
just-latex
如何在网页上渲染 LaTeX 片段? MathJaX? KaTeX?为什么不……直接使用 LaTeX 呢?
Just-latex 是一个简单的 Pandoc 过滤器,它串联了 TeX 生态系统中的多个现有工具,以便在将文档转换为 HTML 时使用实际的 LaTeX 引擎来渲染 LaTeX 片段。它旨在填补市场空白,为受 MathJaX 或 KaTeX 限制的用户提供一种新选择。
特性
- 完全兼容 TeX/LaTeX,因为我们只是在底层调用它们。这意味着您可以定义宏、更改字体、使用
tikz
等。——就像您在 LaTeX 文档中所做的那样。 - 使用 Pandoc,因此它支持广泛的输入格式,并且可以相对容易地嵌入到各种工作流程中,例如,如果您使用 Hexo 运行的博客(像我一样),则可以使用
hexo-renderer-pandoc
。 - 片段被转换为 SVG 图像,无论缩放如何,看起来都很好。
- 压缩 SVG,以确保生成的页面不会因体积过大而膨胀。
演示
请参阅 examples/demo.md
和 examples/demo.html
以展示此程序。演示功能使用 cmbright
包更改字体,使用 tikz
创建图表,以及使用 algpseudocode
排版伪代码。生成 demo.html
的命令是(在 examples/
下运行)
pandoc demo.md --filter ../target/debug/just-latex -o demo.html
(假设您有一个调试构建) 演示部分改编自 此处。
另一个演示 examples/fwht.md
实际上是多年前我写的 博客文章。它包含更多的数学内容,应该被视为此程序的典型用例。
在 examples
文件夹中还包括一个示例配置文件。
注意:出于安全原因,GitHub 限制了托管 HTML 文件的预览。如果您想检查 htmls,您可以使用类似 https://htmlpreview.github.io 的服务。 演示页面链接。
与 ... 的比较
MathJaX 和 KaTeX
我创建这个程序的目标与MathJaX和KaTeX不同。后者在其舒适区表现良好,但本质上它们仍然是TeX的JS部分移植,因此两者都存在局限性。
例如,作为衬线字体,Computer Modern系列实际上在屏幕上看起来并不好,MathJaX 3和KaTeX也没有提供其他选项(尽管MathJaX对它们使用的CM字体进行了微调)。在LaTeX中,我们可以自由使用诸如cmbright
、arev
、beamer
之类的包,或者使用unicode-math
加载OTF数学字体来解决问题,不是很好奇我们能否在Web上做到这一点吗?
另一个例子是宏的使用。MathJaX和KaTeX可以处理宏,但如果你在其中一个块中定义了一个宏并在另一个块中使用它,事情可能会变得有点棘手。
这个项目最初是为像我这样的博客作者设计的,其中大部分内容都是静态创建的,并且可以静态渲染。在实时和动态渲染TeX方程式方面,MathJaX和KaTeX仍然是无敌的。
基本上,如果你对MathJaX和KaTeX感到满意,就使用它们。如果你想探索打破这些库强加的限制,请查看这个!
TeX4ht、LaTeXML、Tralics等。
这些程序将LaTeX文档转换为HTML,而just-latex处理Markdown或Org等格式的LaTeX片段。当然,你可以使用Pandoc将Markdown文档转换为LaTeX,然后调用这些工具将其转换为HTML,但这似乎有点复杂。这些工具也是大型系统,需要一些设置。此外,据我所知,LaTeXML和Tralics是TeX仿真器,因此可能存在兼容性问题。
此外,请注意,这些系统试图通过识别输入文档中的某些元素并以“网络方式”处理它们来变得聪明,例如,数学转换为MathML或传递给MathJaX,文本被提取出来以供浏览器重新排版。这本身似乎可能是一个问题来源。
相比之下,just-latex是小型、简单且愚笨的。它用Rust编写,大约有1000行代码,并使用TeX社区中成熟的库,因此你可以在10分钟内完全理解其工作原理(你将在下面看到),并且有99%的把握渲染结果将与你在PDF中看到的结果相同。
SwiftLaTeX
SwiftLaTeX是将整个TeX引擎编译成WebAssembly并在浏览器中运行的。它实际上不应该与这个程序比较,因为前者在客户端浏览器中运行,而后者在服务器端进行所有渲染。
工作原理
- Just-latex是Pandoc过滤器,因此Pandoc将处理输入文档的解析——无论是Markdown、RestructuredText、Org还是Pandoc支持的其他任何内容。
- 程序识别Pandoc提供的文档树中的
MathInline
元素。 - 然后按照它们出现的顺序(进行一些去重)将这些片段连接起来,用用户定义的前置和后置文包围结果,并将结果写入临时目录中的
.tex
文件。例如,前置文可能是
后置文\documentclass[12pt]{article} \usepackage{amsmath, amssymb, amsthm, bm} \begin{document}
\end{document}
- 它调用(La)TeX(可以是pdfTeX、XeTeX或LuaTeX)将那个
.tex
编译成PDF文件。 - 然后调用dvisvgm将PDF转换为SVG。Dvisvgm包含在现代TeX发行版中。
- 对于每个片段,程序使用 SyncTeX 库来计算它在 PDF 和 SVG 中的位置。SyncTeX 已经集成在现代 TeX 引擎中多年,并且是几乎所有 TeX 编辑器用来实现源代码与输出同步的库。
- 通过查看实际路径,使用 usvg 库对区域进行细化。
MathInline
节点被替换为带有正确样式的RawInline
节点和<img>
,以显示 SVG 的计算区域。例如:
对于内联片段,将注意将图像的基线与周围文本的基线对齐。<img src="...#svgView(viewBox(0.42,-15567.08,23.07,11.62))" class="svg-math" style="width:23.07pt;height:11.62pt; top:2.66pt;position:relative;">
- SVG 本身是 LZMA 压缩的,然后使用 base64 编码,然后嵌入到一个短的 JavaScript 代码中,该代码在页面加载时解压缩 SVG,生成对象 URL 并填充上述
...
部分在<img>
标签中。此代码,以及加载 LZMA 解压缩器(大小为 7 KB)的<script>
代码,作为RawBlock
节点附加到文档树中。 - 程序将修改后的树返回给 Pandoc,Pandoc 完成工作并输出单个 HTML 文件。当页面加载时,您将看到渲染的片段与在 PDF 中显示的完全一样。
就是这样。10 步,1 个输入文件,1 个输出文件。
依赖关系和构建
要运行此程序,您将需要 Pandoc 和一个 TeX 发行版。要构建它,您还需要 Rust 工具链和 C 工具链。克隆此存储库(确保使用 git clone --recurse-submodules
以克隆 synctex
代码),然后运行 cargo build
。
配置
Pandoc 过滤器不能直接从命令行获取参数,所以 just-latex 从不同位置的文件读取配置。
- 它首先会在可执行文件相同的目录下寻找
jlconfig.toml
(当涉及符号链接时可能会 产生歧义),并将其作为配置文件加载。 - 然后,它会在工作目录下寻找
jlconfig.toml
,如果存在则加载它。
配置文件不需要指定所有配置项,因为它只是覆盖先前加载的配置项。
从 0.1.3 版本开始,您还可以在文档的 Front Matter YAML 中按文档配置 just-latex。例如:
---
jlconfig:
latex: lualatex
---
这告诉 just-latex 使用 LuaLaTeX。或者,您也可以将 jlconfig.latex: lualatex
作为缩写。由于 Pandoc 处理元数据块的方式,just-latex 当前实现的文件内配置可能会出现错误。错误报告总是受欢迎的!
所有配置项都在 config.rs
中定义,并具有默认值。
模式
Just-latex 可以在 PDF 或 DVI/XDV 模式下运行,PDF 模式是默认模式。速度相似。这些模式的不同之处在于使用的中间格式。
在PDF模式下,just-latex指示LaTeX引擎生成PDF文件,dvisvgm将PDF文件转换为SVG。一切运行良好,除了dvisvgm将所有文本转换为SVG路径,使用PDF输入。因此,SVG文件变得庞大,文本不可选择。just-latex的内部优化器专门针对这个痛点设计,当SVG文件未压缩时可以大大减轻这个问题,但在它们压缩之后效果并不明显。
在DVI/XDV模式下,dvisvgm可以保留文本并高效地嵌入子集化的字体,生成更精简的SVG文件和更快的加载时间。(不幸的是,由于使用了片段标识符,文本仍然不可选择。这个问题正在解决。)此外,浏览器将以与body文本相同的文本渲染堆栈渲染片段中的文本,因此希望渲染将更加一致和快速。然而,需要注意的是,DVI和XDV几乎已经废弃的格式,因此某些包(尤其在某些场景下的TikZ)可能需要特殊的配置才能正确使用。由于usvg的工作方式,just-latex的内部SVG优化器与DVI/XDV模式不兼容,因此必须禁用。
要切换模式,请在您的配置文件中设置mode = "pdf"
或mode = "dvi"
或mode = "xdv"
。DVI模式仅适用于pdfLaTeX,XDV模式仅适用于XeLaTeX,因此请确保模式与您选择的引擎匹配。由于dvilualatex
在大多数情况下不是很有用,因此just-latex不支持LuaLaTeX的类似模式。如果必须使用LuaLaTeX,请使用PDF模式。(通常,LuaLaTeX不是一个好的选择,因为它本质上较慢,当转换大量文档时尤其令人烦恼。)
技巧
在$$
中的所有内容都被Pandoc视为数学,而just-latex通常会将其用[
和]
括起来。要写出不被括在数学环境中的LaTeX,您可以
- 在
$$
的开始处使用%raw
。程序将检测到这一点。或者, - 使用Pandoc的扩展原始属性语法
您不需要在这里键入```{=tex} % Your code here. ```
%raw
。
请注意,如果您在$$
块中写入复杂非数学内容(更新:这似乎是带有空行的块),那么有时Pandoc会尝试聪明地识别您的代码为原始TeX块,但周围的$$
将变成普通可见文本。因此,如果您确实要写入非数学内容,建议使用第二种格式(它还不会让试图用MathJaX渲染您的Markdown的编辑器感到不安,例如Typora)。
或者,有时您可能想要一个仅用于宏定义或更改内部TeX变量的块。这是一个问题,因为当just-latex询问SyncTeX这些代码在PDF中的位置时,它会变得困惑——这样的代码本身不产生任何内容!SyncTeX沮丧地返回下一个片段的边界框,这是错误的。在这种情况下,您必须以%dontshow
开始这样的块,无论是$$
块还是{=tex}
块。这会通知just-latex仅将其包含在中间TeX文件中,而不要调用SyncTeX。您可以在示例文件中看到这一点。
请注意,您不能再使用 \TeX
和 \LaTeX
。这不是错误,因为在实际的 LaTeX 中这两个命令在数学模式下是无法使用的 -- MathJaX 让我们误以为可以! 您应该使用 \text{\TeX}
,或者类似的东西。
\let\oTeX=\TeX
\def\TeX{\text{\oTeX}}
同样,您不能在数学模式下使用如 align
这样的环境(您必须使用 aligned
)。
从 0.1.2 版本开始支持多页中间 PDF。但仍然建议将所有内容都放在一页上,因为跨页的 SyncTeX 可能会产生意外的结果(由于 TeX 的页面分页器工作方式)。Just-latex 现在采用一些启发式方法来处理这个问题。无论如何,请确保页面没有被页码/页眉/页脚装饰 -- 您可以通过在您的序言中添加 \pagestyle{empty}
来实现这一点(我的意思是,为什么一开始要添加页码呢?没有人会阅读中间 PDF)。此外,内联 LaTeX 片段不能跨页。多页意味着生成多个 SVG,这使得压缩效率降低,生成的 HTML 文件更大(尽管通过 web workers 可以并行解压缩)。您可以使用 \usepackage[paperheight=16000pt]{geometry}
来创建一个足够长的页面,以满足大多数情况。
限制
-
由于多种原因,渲染片段中的文本不可选择或复制。 这个问题正在解决中。
-
生成的 SVG 文件可能非常大,尽管这个程序为典型的 Markdown 文档(如博客文章)添加的压缩量不到 100 KB。 这个问题正在解决中。
-
TeX 很慢,dvisvgm 也是。尽管程序本身运行相当快,但转换一个文档仍然需要大约 1 秒。
-
您负责设置序言,使 LaTeX 片段的字体大小与 HTML 中周围文本的大小相匹配。例如,HTML 的默认文本大小为 12pt,因此您应该将
[12pt]
作为选项传递给\documentclass{article}
。同样,您应该配置页眉模板,使其与您的页眉大小相匹配。
贡献
请随时在问题部分报告任何错误或改进建议。PR 也非常受欢迎。
这有用吗?
是的。
依赖关系
~12–25MB
~392K SLoC