兴趣与特殊文档

LaTeX 不只属于论文。把国际象棋棋谱照 PGN 原样写下,棋盘图就会自动跟上;填字、数独、编织图解、家谱,CTAN 上都有专门的宏包。不过这一角有个特别的坑:网上推荐的宏包相当常见地并不在 TeX Live 里。围棋的 psgo 确实收录了,却无法在 pdflatex 下运行,而 kpsewhich shogi.sty 什么也没返回。因此下面每一个宏包,都是先用 kpsewhich 确认存在、再实际编译过才写进来的。凡是跑不通的,本页就照实说。

用 PGN 写国际象棋棋谱 —— skak / xskak / chessboard

国际象棋是 LaTeX 里配套最完善的爱好领域。加载 \usepackage{xskak},用 \newchessgame 开局,再照 PGN 原样\mainline{1. e4 e5 2. Nf3 Nc6 3. Bb5 a6}:着法会被排版,而放 \chessboard 的地方就会出现那一时刻的局面图。关键在于这个宏包内部持有一副棋盘,并真的把着法走了一遍。因此图与谱不会脱节。与手工输入坐标画图的方式不同,在中途插入一着,之后所有的图都会跟着更新。

latex
\documentclass{article}
\usepackage{xskak}   % loads skak and chessboard
\begin{document}
\newchessgame
\mainline{1. e4 e5 2. Nf3 Nc6 3. Bb5 a6}
\chessboard

% the shortest possible loss, in four plies
\newchessgame
\mainline{1. f3 e5 2. g4 Qh4#}
\chessboard[showmover=false]
\end{document}

这三个宏包分工清晰。skak 是根基:解析棋谱、维护内部棋盘,并提供以字形表示棋子的字体。xskak 叠在其上,支持变着与多局并行,同时也会加载 chessboard。图的精细控制归 chessboard:像 \chessboard[showmover=false] 这样的键可关掉行棋方标记,你也可以只截取棋盘的一部分,或给个别格子上色、加标记。既然一行 \usepackage{xskak} 就把三层都带齐,拿不准时写这一句便是。

来历也值得一提。skak 是丹麦语的「国际象棋」——README 里就是这么写的。作者是 Torben Hoffmann,TeX Live 2024 同捆的是 v1.5.3(2018 年 1 月 8 日)。据 TeX Live 自身的目录条目,这个宏包建立在 Piet Tutelaers 的工作之上,其新意在于用 PGN 而非坐标记法作为输入:g1f3 变成更易读的 Nf3xskak(v1.5,2019 年 6 月 23 日)与 chessboard(v1.9,2020 年 11 月 1 日)均出自 Ulrike Fischer 之手,而 skak 自己的致谢里也感谢了她在字体处理上的工作。

围棋有 psgo,将棋没有 —— 以及 psgo 为何跑不了 pdflatex

画围棋图的宏包,TeX Live 2024 确实收有 psgo(v0.17)——但正如其名,它用 PSTricks 绘图,因此在 pdflatex 下无法使用。实际把 \begin{psgoboard} 送进去,报出 ! Undefined control sequence.,其展开处是 \c@lor@to@ps ->\PSTricks _Not_Configured_For_This_Format:PSTricks 自己宣布「未为此格式配置」。有趣的是,只写 \usepackage{psgo} 是能通过的;崩掉的是真正开始画盘的那一刻。出路是走 latexdvipsps2pdf,或者夹进 auto-pst-pdf(TeX Live 2024 中有收录)。前者实测输出了一页 PDF。

关于将棋,把话说明白:TeX Live 2024 里没有将棋宏包。 kpsewhich shogi.stykpsewhich igo.stykpsewhich gochess.sty 全都没有返回,在 /usr/local/texlive/2024 下搜索 shogi 也找不到相应文件。要排将棋棋谱或局面,只能自己装 CTAN 之外的东西,或者用 TikZ 画盘。与其凭「多年前用过某个宏包」的记忆行事,不如先敲一遍 kpsewhich——在 LaTeX 的这一角,这是最短的路。

填字与数独 —— cwpuzzle 与 sudoku

填字用 cwpuzzle,数独用 sudoku。两者都像在写表格:格子在一行里用 | 分隔。在 cwpuzzlePuzzle 环境里,|[1]T 表示「编号为 1、内容为 T 的格」,|* 表示黑格,|. 结束一行。编号与外框都是自动的;PuzzleClues 环境配合 \Clue{编号}{答案}{提示} 可以另排提示,因而同一份源文件既能出空白题目也能出填好的答案。有一处要留心:文件名与发行名不一致。加载的是 \usepackage{cwpuzzle},但在 TeX Live 上这个宏包以 crossword 之名发行,版本 v1.11(2022 年 9 月 13 日)。用 tlmgr 查找时请用后者。

latex
\usepackage{cwpuzzle}   % distributed on TeX Live under the name "crossword"
\usepackage{sudoku}
% ...
\begin{Puzzle}{5}{5}%
|[1]T|[2]E|[3]X |*  |*  |.
|E   |*   |E    |*  |*  |.
|[4]X|*   |X    |*  |*  |.
|*   |*   |*    |*  |*  |.
|*   |*   |*    |*  |*  |.
\end{Puzzle}
\begin{PuzzleClues}{\textbf{Across}}
\Clue{1}{TEX}{A typesetting system}
\end{PuzzleClues}

\begin{sudoku}
|2| | |6| |7| | |1|.
| |8| | | | | |5| |.
| | |6| |3| |4| | |.
| | |9| | | |8| | |.
|5| | |1| |4| | |2|.
| | |3| | | |7| | |.
| | |4| |6| |1| | |.
| |7| | | | | |3| |.
|9| | |2| |8| | |4|.
\end{sudoku}

sudoku(v1.0)要求正好九行;空格写成 | |(中间留空),每行以 |. 结束。上面两个例子在 TeX Live 2024 上都无错通过——cwpuzzle 排出了外框与编号,sudoku 排出了带 3×3 粗线的棋盘。顺带一提,cwpuzzle 虽名为填字,也能排数独与方阵(Kakuro)。若打算排一整本谜题书,索性统一到它上面也是个办法。

排编织图解 —— knitting 宏包与符号表在哪里

knitting(v3.0,2019 年 4 月 3 日,Ariel Barton 作)提供绳编与蕾丝编织图解所需的符号字体与命令。它的用法很有特色:符号是用普通字母敲出来的,如 \textknit{kpkp}——k 是下针、p 是上针,键盘上的一个字符对应一个针目符号。带方格的图解用 \chart[right]{...} 排,这里有个坑:chart命令而非环境,正文要放进花括号。写 \begin{chart} 不报错、退出码也是 0,但用相同内容对比两种写法,命令式排出了针目符号与行号,环境式却把 kpkpkp 这几个字母原样印了出来。方格的有无由 \knitgrid\knitnogrid 切换。像老宏包一样,它在 Plain TeX 与 LaTeX 下都能用。

latex
\usepackage{knitting}
% ...
\textknit{kpkpkp}   % symbols are typed as ordinary letters

\knitgrid           % draw the grid; \knitnogrid for a chart without one
% \chart is a COMMAND taking a braced body -- not a "chart" environment.
\chart[right]{
kpkpkp
pkpkpk
}

哪一个字母对应哪一种针目,一览表在 knitkey 里——但它并不是一个要加载的宏包。kpsewhich knitkey.sty 什么都不返回;真正的东西是一份文档,位于 texmf-dist/doc/fonts/knitting/knitkey.pdf。要在本地打开,texdoc knitkey 最快。同一目录下还有 knitexamples.pdf。另外 TeX Live 里还另有一个名为 knittingpattern 的宏包,它排的是文字版编织说明,而非图解。

家谱、菜谱与日程表 —— genealogytree / cooking / termcal

家谱交给 genealogytree(v2.3.0)。它建立在 TikZ 之上,在 pdflatex 下即可运行。在 \begin{genealogypicture}把亲属关系照样写成嵌套,如 parent{ g{子} p{父} p{母} },布局便会自动算好。template= 用来挑选外观样式,起步时选 signpost 就不错。这个宏包的严肃之处在于它区分血缘与婚姻,因而图在谱系意义上是正确的,而不只是一幅画。

latex
\usepackage[all]{genealogytree}
\usepackage{cooking}
% ...
\begin{genealogypicture}[template=signpost]
parent{
  g{Child}
  p{Father}
  p{Mother}
}
\end{genealogypicture}

\pagestyle{recipe}
\begin{recipe}{Pancakes (serves 4)}
\ingredient{200\,g flour} sift into a bowl.
\ingredient{2 eggs}
\ingredient{300\,ml milk} whisk in until smooth.
\end{recipe}

菜谱有 cooking(v0.9b,1999 年 6 月 24 日,Axel Reichert 作)。年头久,设计反倒干脆:\ingredient{...} 只接受一个参数——分量与材料名一起写进去——紧随其后就是步骤句子。排出来便是常见的食谱版式:材料在左栏右对齐,做法向右流淌。TeX Live 里还有另外两个同类宏包,cuisine(v0.7)与 xcookybooky(v1.5),后者已现代到能放照片与烹饪时间。要排日程表,则 termcal(v1.8)接受起始日期与周数,替你排出课程日历。

推荐之前先 kpsewhich —— 什么收录了,什么没有

在 LaTeX 的这一角,旧文章里提到的宏包未必还在你机器上。核实只需一秒:敲 kpsewhich 宏包名.sty,有就返回路径,没有就什么都不返回。不知道文件名时,tlmgr info 名称 会连同说明一起告诉你。下表就是写这一页时实际敲出来的结果——在你写下任何 \usepackage 之前,同样的命令自己也能敲。

宏包在 TeX Live 2024 中的状态注意事项
skak / xskak / chessboard三者均收录:v1.5.3 / v1.5 / v1.9一行 \usepackage{xskak} 就把三个都带进来
psgo已收录(v0.17)依赖 PSTricks;在 pdflatex 下一画盘就崩
shogi.sty不存在kpsewhich 为空;igo.stygochess.sty 同样没有
cwpuzzle已收录,v1.11(2022 年 9 月 13 日)在 TeX Live 上的发行名是 crossword;也能排数独与 Kakuro
sudoku已收录(v1.0)需要正好九行;空格写成 | |,中间留空
knitting已收录(v3.0,2019 年 4 月 3 日)符号表 knitkey 是 PDF 而非宏包;用 texdoc knitkey 阅读
genealogytree已收录(v2.3.0)基于 TikZ;在 pdflatex 下直接可用
cooking已收录(v0.9b,1999 年 6 月 24 日)\ingredient 只接受一个参数;cuisinexcookybooky 亦有收录
termcal已收录(v1.8)由起始日期与周数排出课程日历

最后说一件本页不涉及的事:乐谱。音乐排版另有专页,那里实测过 LilyPond 并未随 TeX Live 分发,以及 MusiXTeX 需要 etexmusixflxetex 三遍处理。在这些爱好类排版里,成果的全部就是「图对不对」,所以别满足于编译无错——务必打开 PDF 用眼睛确认。棋盘图上哪怕有一子放错了格,TeX 也不会吭一声。