\chapter{表格} \ConTeXt\ 提供了多种表格形式,我们不需要全都学会,可以先学会最为简单的形式 Tabulate,等到将它用到山穷水尽也无法表达你想要的表格时,再考虑其他形式是否够用。简单的未必不好,强大的未必更好,既简单又符合自己需求的,永远都是最好的。 \section{基本用法} 首先,构造一个 2 行 3 列的表格,第 1 行的内容是 \type{1 2 3},第二行的内容是 \type{4 5 6},排版代码和结果如下: \startsample \starttabulate \NC 1 \NC 2 \NC 3\NC\NR \NC 4 \NC 5 \NC 6\NC\NR \stoptabulate \stopsample \simplesample[option=TEX]{\null} \getsample \noindent 结果第 3 列跑到版面最右侧了。这是因为我们尚未定义表格各列的对齐方式。对齐方式不外乎三种,左、中、右,Tabulate 分别使用缩写 \type{l},\type{c} 和 \type{r} 指代它们。例如,若令表格第 1 列居左,第 2 列居中,第 3 列居右,只需 \startsample \starttabulate[|l|c|r|] \NC 1 \NC 2 \NC 3\NC\NR \NC 4 \NC 5 \NC 6\NC\NR \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} \noindent 现在看上去像表格了,但是由于表格尚无边框线,无法看出表格各列内容的对齐状态。 想必你已经猜测出了,\type{\NC} 用于在表格的某一行构造一个单元格,上述示例中,表格内容的每一行最后一个 \type{\NC} 实际上是多余的,\ConTeXt\ 会忽略它,但是你可以将它理解为表格的单元格的边界。\type{\NR} 用于构造一个新行,即下一行。上述示例里,表格只有两行,实际上第 2 个 \type{\NR} 也是多余的,只是为了形式上更整齐而保留,\ConTeXt\ 会忽略它,你可以将它理解为表格一行的结束。 现在,将 \type{\NC} 替换为 \type{\VL},便可画出单元格的左右边界线,即 \startsample \starttabulate[|l|c|r|] \VL 1 \VL 2 \VL 3\VL\NR \VL 4 \VL 5 \VL 6\VL\NR \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} \noindent 在表格每一行的开始放上 \type{\HL},可画出表格各行横线,即 \startsample \starttabulate[|l|c|r|] \HL \VL 1 \VL 2 \VL 3\VL\NR \HL \VL 4 \VL 5 \VL 6\VL\NR \HL \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} \noindent 可能你已经发现了,表格的竖线将被横线截断了。不必担心是你的问题,而是 Tabulate 主要用于排版横线表,例如图 \in[three-line table] 所示的在科技论文中常用的三线表。 \placefigure[force][three-line table]{三线表}{\externalfigure[09/three-line-table.pdf]} 让表格的横线和竖线完全相交并不困难,只需将单元格之间的纵向间距参数 \type{distance} 设为 \type{0pt} 或 \type{none}: \startsample \starttabulate[|l|c|r|][distance=none] \HL \VL 1 \VL 2 \VL 3\VL\NR \HL \VL 4 \VL 5 \VL 6\VL\NR \HL \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} \section{间距调整} 若希望单元格的宽度更宽一些,需要在列格式中设定 \type{w} 参数,例如令单元格宽度为 1 cm,只需 \type{w(1cm)} 即可。例如 \startsample \starttabulate[|lw(1cm)|cw(1cm)|rw(1cm)|][distance=none] \HL \VL 1 \VL 2 \VL 3\VL\NR \HL \VL 4 \VL 5 \VL 6\VL\NR \HL \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} 若希望文档中所有表格实例的 \type{distance} 参数皆为 \type{none},可用 \type{\setuptabulate} 进行设定: \starttyping[option=TEX] \setuptabulate[distance=none] \stoptyping 若想加大单元格的竖向间距,可用 \type{\TB} 命令插入空行予以调整。例如插入 2mm 高的空格, \startsample \starttabulate[|lw(1cm)|cw(1cm)|rw(1cm)|][distance=none] \HL \VL 1 \VL 2 \VL 3\VL\NR \HL \TB[2mm] \HL \VL 4 \VL 5 \VL 6\VL\NR \HL \stoptabulate \stopsample \simplesample[option=TEX]{\getsample} \noindent \type{\TB} 也可以使用相对尺寸,例如 \type{2*line},\type{line},\type{halfline} 和 \type{quarterline} 分别为一行文字的高度的 2 倍,1 倍,1/2 倍和 1/4 倍。 由于插图不过是个头较大的文字,因此基于表格理应能实现 \in[figure-matrix] 节所述的排版插图阵列。的确可以如此,例如 \starttyping[option=TEX] \def\figA{\externalfigure[ctxnotes.png][height=3cm]} \def\figB{\externalfigure[ctxnotes-2.png][height=3cm]} \placefigure{}{ \starttabulate[|cw(6cm)|cw(6cm)|] \NC \figA \NC \figB \NC\NR \NC a \NC b\NC\NR \stoptabulate } \stoptyping \midaligned{\externalfigure[09/01.pdf]} \section{\type{\placetable}} 类似于插图,表格也有一个放置命令 \type{\placetable},其用法与 \type{\placefigure} 相似。例如 \starttyping[option=TEX] \placetable[here][表格示例]{简单的表格}{ \starttabulate[|cw(2cm)|cw(2cm)|cw(2cm)|][distance=none] \HL \VL 1 \VL 2 \VL 3\VL\NR \HL \VL 4 \VL 5 \VL 6\VL\NR \HL \stoptabulate } \stoptyping \midaligned{\externalfigure[09/02.pdf]} 对于中文排版,表格的标题,默认的设置并不符合我们的习惯,需要作一些定制。首先,将表格编号前缀设定为 \starttyping[option=TEX,space=on] \setuplabeltext[en][table={表 }] \stoptyping \noindent 然后,将表格标题编号设为正体,字号比正文字号小一级,放置于表格上方,并居中对齐: \starttyping[option=TEX] \setupcaption [table] [headstyle=\tf,style=\tfx,location=top,align=center] \stoptyping \blank[line] \midaligned{\externalfigure[09/03.pdf]} \section{不传之秘} 在绘制表格的横线和竖线时,线条粗度可通过参数 \type{rulethickness} 进行设定。例如,将线条粗度设为 2 pt: \startsample \starttabulate[|c|c|c|c|c|][rulethickness=2pt] \HL \NC 一 \NC 二 \NC 三 \NC 四 \NC 五 \NC\NR \HL \NC one \NC two \NC three \NC four \NC five \NC\NR \NC 1 \NC 2 \NC 3 \NC 4 \NC 5 \NC\NR \HL \stoptabulate \stopsample \simplesample[option=TEX]{\externalfigure[09/04.pdf]} \noindent 但是,如果我们只想让表格的顶线和底线是粗度 2 pt,中间那条横线让它是 Tabulate 的默认粗度,该如何实现呢? 对于该问题,也许你翻遍 \ConTeXt\ 的 Wiki 或手册,都找不到答案,因为答案在 \ConTeXt\ 的 tabl-tbl.mkxl 文件里。使用以下命令可搜索该文件: \starttyping $ mtxrun --script base --search tabl-tbl.mkxl \stoptyping \noindent 需要注意的是,该文件中关于 \type{\TL},\type{\LL} 和 \type{\BL} 的注释应该是错的。要解决上述问题,需要先了解以下细节: \startitemize[packed] \item 表格线粗度默认大概是 0.4 pt; \item 横线 \type{\HL} 有着细致的类别划分,从表格的顶线到底线,依次为顶线 \type{\TL},第一条横线 \type{\FL},中间的横线 \type{\ML},最后一条横线 \type{LL},底线 \type{\BL}; \item 若要设定表格横线的不同粗度,则横线必须按照类别使用,不可使用 \type{\HL}; \item \type{\HL}\footnote{包括 \type{\TL},\type{\FL},……,\type{\BL}。}和 \type{\VL} 可以接受两个参数,一个是表格线既定粗度的倍数,另一个是表格线颜色。 \stopitemize \noindent 然后,将上述示例修改为 \starttyping[option=TEX] \starttabulate[|c|c|c|c|c|][rulethickness=2pt] \TL \NC 一 \NC 二 \NC 三 \NC 四 \NC 五 \NC\NR \FL \NC one \NC two \NC three \NC four \NC five \NC\NR \NC 1 \NC 2 \NC 3 \NC 4 \NC 5 \NC\NR \BL \stoptabulate \stoptyping \noindent 由于该表格内容只有三行,因此只有顶线,第一条横线和底线,亦即无中间横线和最后一条横线。为了更加充分演示问题是如何解决的,可以让该表格的内容再丰富一些: \starttyping[option=TEX] \starttabulate[|c|c|c|c|c|][rulethickness=2pt] \TL \NC 一 \NC 二 \NC 三 \NC 四 \NC 五 \NC\NR \FL \NC 甲 \NC 乙 \NC 丙 \NC 丁 \NC 戊 \NC\NR \ML \NC one \NC two \NC three \NC four \NC five \NC\NR \LL \NC 1 \NC 2 \NC 3 \NC 4 \NC 5 \NC\NR \BL \stoptabulate \stoptyping 现在要保持 \type{\TL} 和 \type{\BL} 为既定粗度 2 pt,将 \type{\FL},\type{\ML} 和 \type{\LL} 的粗度设置为 0.2 倍的既定粗度,及 0.4 pt,顺便试验一下颜色是否真的可用,见示例 \in[HL example] 对应的代码,结果只有 \type{\ML} 变成了双线,其他皆符合预期。 为何 \type{\ML} 如此不配合呢?我猜也许它本来就是在绘制双线,因为 Tabulate 支持表格分页断开,即一个表格若处于页面底部且不能完全被当前页面容纳时,\ConTeXt\ 可将其断开,一部分在当前页面,另一部分在下一页面。为了让断开后的表格完整,\type{\ML} 必须是双线。若将示例 \in[HL example] 中的 \type{\ML} 换成 \type{\HL},结果同样是双线。若不需要双线,可将 \type{\ML} 皆换为 \type{\FL} 或 \type{\LL}。 为了避免上述莫名其妙的问题,若只是令表格顶线和底线变粗,不必设定 \type{rulethickness} 参数,而是修改顶线和底线的粗度,令其他表格线的粗度皆为默认值。 \startsample \starttabulate[|c|c|c|c|c|][rulethickness=2pt] \TL \NC 一 \NC 二 \NC 三 \NC 四 \NC 五 \NC\NR \FL[0.2,red] \NC 甲 \NC 乙 \NC 丙 \NC 丁 \NC 戊 \NC\NR \ML[0.2,blue] \NC one \NC two \NC three \NC four \NC five \NC\NR \LL[0.2,magenta] \NC 1 \NC 2 \NC 3 \NC 4 \NC 5 \NC\NR \BL \stoptabulate \stopsample \sample[option=TEX][HL example]{修改表格线粗度和颜色}{\getsample} \section{小结} 除了在设定表格线粗度时不尽人意之外,Tabulate 堪当日常之用。它还有一些功能,本章尚未涉及,诸如跨栏,分页,段落等,这部分功能在后续章节介绍其他排版元素时,将作为搭配示例予以介绍。 待到 Tabulate 用至捉襟见肘之时,可使用「终极表格」,其文档在你的 \ConTeXt\ 环境里,可通过以下命令搜索: \starttyping $ mtxrun --script base --search xtables-mkiv.pdf \stoptyping