Typst:TeX和LaTeX的有力替代方案
Typst是一种简单强大、基于标记的语言,用于创建技术文档和书籍,是TeX和LaTeX的有力替代方案。
文档的分类与排版语言
当谈及文档时,通常分为两类。一类是商务文档,通常使用Microsoft Word或Google Docs等办公软件来撰写;另一类是项目文档,往往借助Sphinx或Pandoc等工具从项目中半自动生成。不过,还有第三类文档,它可能与前两类有所重叠,这就是通过排版语言生成的文档。排版语言结合了标记和编程语言,用于制作书籍、教科书、学术期刊、科研论文、技术手册等对格式和布局要求极高的文档。借助排版语言,可创建一份方便且易于阅读的文档,它既可以作为唯一的事实来源,也能作为输出为印刷版、网页版、电子书等格式的基础。
开源项目Typst崭露头角
近年来,一个开源项目Typst(发音为 “typist”)逐渐崭露头角,成为满足上述所有需求的强大选择。
TeX、LaTeX与Typst对比
几十年来,TeX一直是卓越的排版语言,其更知名的衍生版LaTeX更是广为人知。TeX由Donald Knuth于1978年创建,LaTeX则在1984年问世。TeX和LaTeX应用广泛,几乎得到了普遍支持和认可。然而,它们存在两个长期的重大问题。其一,它们诞生已久,是为完全不同的计算环境而设计的,其陈旧之处体现在繁琐的语法和管理上;其二,使用这两种语言的总体复杂度较高。实际上,LaTeX最初就是为简化TeX的使用而创建的,但TeX底层的复杂性难以掩盖。Typst则是为解决TeX和LaTeX的问题与局限而全新设计的。它与前两者有许多相似的理念,例如,Typst可以使用类似于编程语言中表达数学公式的语法来排版数学公式。不过,它并不试图与TeX语法兼容(尽管可以使用第三方工具将TeX公式转换为Typst格式)。
Typst的使用方式
Typst有多种使用方式:它可以作为独立的命令行程序(开源的Typst编译器),也有托管的网页编辑器(Typst应用),还能作为Visual Studio Code的扩展(Tinymist Typst是最受欢迎的扩展)。网页编辑器能让使用者最快上手:只需开始输入内容,就能看到实时预览(VS Code的Tinymist扩展也能显示预览)。Typst的网页编辑器会在输入时实时预览所有内容。当前的导出模式为PDF,能精确保留内容的位置和格式。
Typst的基础使用方法
对于大多数基础文档,Typst无需太多额外的语法。可以直接输入Markdown风格的文本,它会按照预期进行格式化。例如,下划线和星号可用于强调或加粗文本,行首使用等号可设置章节标题等。当想对文档的默认展示效果进行修改时,Typst的编程功能就派上用场了。比如,若要设置页面大小、边距、字体和段落格式,可以使用如下声明:
#set page(width:5.25in, height:8in, margin: .5in)
#set text(size: 11pt, font: "Libre Baskerville")
#set par(first - line - indent: 1.75em,justify: true)
`#set`命令会从文档中的该位置起生效。若将这些命令放在文档开头,它们将影响下面的所有内容。不过,也可以在后面使用其他`#set`命令来覆盖这些设置,例如从单栏文本切换为双栏文本时。
Typst代码模式解析
在Typst中,井号(#)(除非用反斜杠转义)用于表示从普通文本(标记模式)切换到Typst命令(代码模式)。这些命令可以跨越多行,直到Typst代码块或表达式结束,例如:
这是普通文本。
#let inline_image(img) = {
box(height: 8em,
place(top+left, dx: 5pt,
square(
image(img, height:100%, fit:"cover")
)
)
)
}
这又是普通文本了。
这里,使用`#let`定义了一个接受一个参数(图像名称)的函数,并将其插入到一个内联框中。花括号表示函数体,与Python类似,每行以换行符结尾,而非像JavaScript那样以分号结尾。Typst可以导出为多种格式,如PDF、图像和HTML,不过它针对PDF和图像的静态布局进行了优化。由于Typst无法保证某些格式在HTML模式下的可靠渲染(例如HTML中不存在的页眉和页脚),所以有些格式在HTML模式下默认不会渲染。可以通过`target()`函数确定当前的导出目标,并据此采取相应操作,例如:
#let sectionbreak(txt) = {
context(
if target()=="html" {
html.elem("div", attrs:(class:"section - break"))[]
return
} else {
divider()
}
)
}
在这个例子中,创建了一个`sectionbreak()`函数,它有两种行为。对于HTML目标,它会插入一个带有CSS类的空div标签,可以用样式表对其进行样式设置;对于其他目标,它默认使用内置的`divider()`函数。Typst代码中可以访问文档的所有属性。`query`函数使用类似于JavaScript元素查询系统的语法,例如:
query(
heading.where(
level: 1,
)
)
这将返回文档中所有一级标题,然后可以对它们进行迭代、操作内容、执行其他检查等。Typst还有自己的包管理器和包目录。包无需从目录中正式安装,只需在Typst程序中使用`import`语句引用它们,它们就会被包含进来。
Typst数学模式特点
Typst的数学块借鉴了TeX的模式,但不能完全替代TeX。不过,有一定编程经验的人应该能够轻松掌握Typst数学模式的使用方法。数学公式用美元符号与文本分隔,例如:
$ sum_(k = 1)^n k = (n(n + 1)) / 2 $
这个代码块会渲染为相应的方程。与井号一样,如果需要在文本中使用美元符号,可以用反斜杠进行转义。如果有大量用TeX编写的现有材料,可以使用第三方工具将其转换为Typst格式。MiTex包可以对单个公式或整个TeX文档进行内联转换。
自动化Typst的方法与现状
Typst语言及其生态系统相对较新,该语言存在一些局限性。有些只是需要进一步开发功能,而有些则是设计上的限制,例如对导入路径或读取数据的严格限制。绕过Typst局限性的一种方法是将其封装在另一种编程语言中。Python是一个不错的选择,`typst` Python库提供了一种高级方式来驱动Typst编译器。这使使用者能够编排涉及多个文件的复杂工作流程、读取项目根目录之外的数据,或执行Typst查询以读取文档数据。随着时间的推移,一些现在需要通过这种方式实现的功能可能会成为Typst的原生特性。Typst社区已经相当活跃(已有超过一千个可用的包),并且会定期发布新版本。
Typst的分类
分类:编程语言、软件开发