jlreq

jlreq 大概是唯一一个会在排版过程中告诉你「行距超出规范建议范围」的 LaTeX 文档类。它由阿部纪行于 2017 年发布,是把 W3C 技术文档 《日本語組版処理の要件》(JLReq / Requirements for Japanese Text Layout) 在 LaTeX 中实现的尝试,名字也由此而来。它的源码里有三十多处注释直接引用了要件的条款编号;加上 jlreq_notes 选项,这些带条款号的建议就会出现在日志里。本页要讲的是 jlreq 与 js 系 class 的分歧在哪里、如何用数值设计版面,以及竖排、行首括号位置这类日文特有设定该怎么处理。

JLReq 是什么,class 又如何实现它

JLReq 是 W3C 编写的技术文档,说明正确排日文需要什么。它以日本工业标准 JIS X 4051(日文文档排版方法)为基础,逐条列出 CSS、电子书等技术应当遵守的规则:哪些字符不能出现在行首行尾、和文与西文之间的空隙、注与标题的处理方式、版面如何确定。jlreq class 文件开头明确写出了它所依据的版本——2020 年 8 月 11 日的 W3C Note。准确的说法是:一份规范被翻译成了一个文档类。

实现有多深,从这个类自带和文字体度量(JFM) 就看得出来。jsclasses 借用 JIS 度量,而 jlreq 发布专用的 TFM,如 jlreq.tfmjlreqg-v.tfmjlreq-jidori.tfm,以及供 LuaTeX-ja 使用的 jfm-jlreq.luajfm-jlreqv.lua。标点和括号周围的空隙是在度量内部决定的,而不是靠 class 的宏——也就是说,要件被嵌进了排版引擎的最底层。当前用的是 pLaTeX、upLaTeX 还是 LuaLaTeX,class 会自动判定并写进日志,例如 jlreq guessed engine: uplatex(不支持 XeLaTeX)。若要强制指定,可把 platexuplatexlualatex 作为 class 选项传入。

jlreq 与 jsclasses 的区别

一句话概括:jsclasses 交给你一套做好的体裁,jlreq 交给你做体裁用的刻度。 奥村晴彦的 jsarticle 围绕精心调好的默认值设计,什么都不用想就能得到可读的日文文档。jlreq 的思路正相反:它假定你会 自己给出数值——正文多少磅、每行多少字、每页多少行、行距多少,以及天头、地脚、订口、切口的边距。所以二者并不冲突。急着把论文排整齐就用 jsclasses;开本和字数在动笔前就已定好,就用 jlreq。

另一个区别是,为符合规范所需的细微判断都被做成了明确的选项。例如加上 narrow_kanjiskip,和文字符之间的空隙(kanjiskip)就会退回 jsarticle 的设定。当你觉得「换到 jlreq 之后字面的疏密变了」,这个选项就是最短的答案。默认 JFM 采用要件规定的空隙,所以把 jsclasses 排的稿子原样搬到 jlreq,即使每行字数相同,行的观感也会略有不同。要迁移的话,先比较一页,再动整篇正文。

基本选项——文档类型、纸张、字号

jlreq 只有一个 class。文档类型通过方括号选项切换:默认相当于 article,传 report 得到带 \chapter 的报告,传 book 得到书籍。注意它不像 jsclasses 那样按类型分成不同 class 名。要竖排就加 tate。此外,标准 class 里熟悉的写法可以原样使用:twocolumntwosidetitlepagelandscapedraftopenright / openanydisablejfam

纸张用 paper= 指定。除了 paper=a4paper=a5,也可以直接写宽高,如 paper={148mm,210mm}。这里有一个陷阱:paper=b5 指的是 ISO 的 B5(176×250 mm),而不是日本所说的 B5,即 JIS 的 182×257 mm。 class 不会悄悄放过,它会警告 Class jlreq Warning: The option 'b5' means the papersize in the ISO B-series, not in the JIS B-series. This behavior was changed from jlreq version 2021-11-05. Use 'paper=b5j' for the JIS-B-series.。做同人志或送日本印厂时,几乎可以肯定 paper=b5j 才是正确答案。

字号要把西文和日文分开考虑。fontsize= 是西文基准字号(默认 10pt),jafontsize= 是日文字号,jafontscale= 则直接给出两者的比值(默认 1,即同尺寸)。jlreq 接受出版用的 级(Q)和齿(H) 作为长度单位,因此可以照原样写成 fontsize=13Q(1 Q = 1 H = 0.25 mm)。日文原稿的规格几乎都以级给出,能不换算直接抄写,在实务上作用不小。

选项含义默认值
article / report / book切换文档类型(有无章、体裁)相当于 article
tate改为竖排横排
platex / uplatex / lualatex显式指定引擎;不写时 class 会自行判定并写入日志自动判定
paper=纸张:a4a5b5j(JIS B5)、{宽,高}。裸写 b5 是 ISO B5a4
fontsize= / jafontsize=西文/日文基准字号;除 pt 外也可用 QH10pt / 与西文同尺寸
jlreq_notes当设置偏离要件时,在日志中输出带条款号的建议off

用数值设计版面

版面——正文所在的矩形区域——可以由内向外由外向内来确定。由内向外,是给出一行长度 line_length=、每页行数 number_of_lines= 和行距 baselineskip=,余下的自然成为边距。由外向内,是给出天头 head_space=、地脚 foot_space=、订口 gutter=、切口 fore_edge=(也可写 fore-edge=),余下的成为版面。如果规格是「每行 38 字、每页 18 行」,就从内向外写;如果是「天头 20 mm、订口 18 mm」,就从外向内写,中途不必混用。

这里可以使用专用单位。zw 是一个全角字符的宽度,zh 是其高度,因此字数和行距可以照「几个字」来写。line_length=40zw 即一行 40 字,baselineskip=1.75zw 即 1.75 个全角字符的行距。行距也可以用 linegap= 给出,它按「一个全角字符加上你指定的空隙」计算。若不指定,line_length 为纸张字符方向长度的 0.75 倍number_of_lines 为行方向 0.75 倍范围内可容纳的行数,baselineskip 为日文字号的 1.7 倍,栏间距 column_gap2zw。省略 head_spacefoot_space 时,版面在天地方向居中。

选项含义默认值
line_length=一行的长度(字数)纸张字符方向长度的 0.75 倍
number_of_lines=每页行数行方向 0.75 倍范围内可容纳的行数
baselineskip= / linegap=行距;linegap= 按「一个全角字符加上此空隙」计算日文字号的 1.7 倍
gutter= / fore_edge=订口(装订侧)与切口(对侧)的边距
head_space= / foot_space=天头与地脚的边距省略时上下居中
column_gap=双栏时的栏间距2zw

日文特有的设定:括号位置、悬挂标点、纵中横

这里是 jlreq 最有特色的领域。open_bracket_pos= 决定行首出现起始括号时的摆放方式(JLReq 3.1.5)。三个取值是 zenkaku_tentsuki(默认)、zenkakunibu_nibunibu_tentsuki,用来选择括号是以全角顶到行首,还是收进二分(半个字宽)。加上 hanging_punctuation,行末的句读点就会悬挂到版面之外(3.8.2 注 1)。这两件事在网页和 DTP 领域都是常被讨论的选项,但能用一个 class 选项直接切换的,大概只有 jlreq。

正文一侧的日文工具也很齐全:把数字直立排入竖排文中的 \tatechuyoko、把文字排进固定字数格位的 \jidori、在正文行中插入两行小注的 \warichu、旁注 \sidenote、尾注 \endnote,以及临时加宽和文字距的 \akigumi。日期也有讲究:声明 \和暦 后再写 \today,日期就会带上年号,竖排时数字还会用汉数字排出。class 把昭和、平成、令和的分界(1989 年 1 月 8 日与 2019 年 5 月 1 日)写进了自己的代码,改元那次的更新记录里就直接写着「新年号」。

竖排示例与引擎的选择

下面是一个 A5 竖排文档,版面由内向外设计:tate 设为竖排,paper=a5 决定开本,其余用数值给出版面——日文 13 级、一行 40 字、每页 17 行、行距 1.75 个全角字符。正文什么都不用加,仅这一行就定下了出版物的体裁。同一行 \documentclass 两条路都能走:用 upLaTeX 会经由 DVI,用 LuaLaTeX 则使用系统字体直接输出 PDF。想改横排,去掉 tate 即可。

latex
\documentclass[
  tate,                 % vertical writing
  paper=a5,
  fontsize=13Q,         % 1 Q = 0.25 mm
  line_length=40zw,     % 40 characters per line
  number_of_lines=17,
  baselineskip=1.75zw,
]{jlreq}
\begin{document}
\title{雪国}
\author{川端康成}
\maketitle
国境の長いトンネルを抜けると雪国であった。
\end{document}

这里有一个只在 DVI 路线上出现的陷阱:jlreq 不会把纸张尺寸作为 \special 写进 DVI。 因此写了 paper=a5 的原稿用 upLaTeX 排好交给 dvipdfmx 时,PDF 会以 dvipdfmx 的默认纸张输出(在 TeX Live 的标准配置下是 A4)。解决办法有两个:在导言区加 \usepackage{bxpapersize},或者在转换端指定,如 dvipdfmx -p a5。用 LuaLaTeX 时页面尺寸会直接写入 PDF,不会遇到这个问题。

让 class 帮你验算设计(jlreq_notes)

在 class 选项里加上 jlreq_notes,jlreq 就会把你给的数值与要件对照,把越界的项写进日志。比如设为 baselineskip=1.2zw,日志中就会出现一条带 JLReq 抬头的提示,说明行间宜在二分以上、全角以下(2.4.2.d 注 3)。当旁注的行长过短,或竖排时版面与书眉之间空隙不足时,它也会分别附上对应的条款号告诉你。排版本身不会停下——这些是建议而非强制。只有物理上不成立时才会中断:行距小于字号会以 ! Class jlreq Error: The baselineskip is less than fontsize. 停下。

用 \jlreqsetup 打磨标题与注

版面尺寸由 class 选项决定,但注、引用、列表、标题的 细节 则在导言区通过 \jlreqsetup{...} 里的 key=value 来调整:脚注、旁注、割注、尾注的排法,引用的缩进(quote_indent=),标题占行等等。想重新设计标题本身,就用 \NewBlockHeading\ModifyHeading。这种分工是有意为之的——版面是读者翻开一页时立刻看到的尺寸,而 \jlreqsetup 管的是各个元素的行为方式。不必一次全记住:先在 \documentclass 里定好开本、字数和行数,再按需要往 \jlreqsetup 里添加即可。权威的完整列表在随附手册(阿部所著日文文档)里,用 texdoc jlreq 打开。

定好版面后先检查一页

jlreq 的设置很强大,因此即使数值写错,PDF 照样会生成。在写正文之前,先用一页假文加上标题、脚注、引用和一个小图表构建一次,然后实际测量每行字数、行数以及订口和切口的边距。尤其是竖排时,纸面上的「行的方向」和「字进的方向」与横排互换,所以首先要确认 line_lengthnumber_of_lines 没有弄反。若需要裁切标记,请使用 jlreq-trimmarks 宏包而不是 class 选项;传入 tombow 会给出警告 The option 'tombow' is not supported by jlreq class. Please use the jlreq-trimmarks package

  • 每行字数 — 在正文里数全角字符,不要只看标点落在哪里。
  • 行数 — 在普通页面和带标题的页面上分别数正文行。
  • 边距 — 要装订的稿子给订口留宽些;只交 PDF 时避免过大的装订余量。
  • 纸张 — 走 DVI 路线时要量成品 PDF。忘了 bxpapersizedvipdfmx -p 就会出成 A4。
  • 引擎 — 若 upLaTeX 与 LuaLaTeX 用的字体不同,只把所选路线的 PDF 当作准本。