页面布局控制
声明:可转载,可修改,也可以不注明作者和出处。
本篇介绍如何使用 ConTeXt 产生我们所期望的页面布局。
前面还有一系列文章:
第一篇:序幕有点长
第二篇:这就是 ConTeXt Minimals
第三篇:不仅仅是为了中文
第四篇:那年挖的坑,今年开始填
第五篇:ConTeXt 文稿的物理结构
第六篇:ConTeXt 文稿的逻辑结构
什么是页面布局
所谓排版,很多人说它是一门艺术,而我一直都是很庸俗的把它理解为在一个矩形的空白区域里有规则的安置文本和图片(网页排版,还会涉及音像媒介)。所谓“页面布局”,就是对那个矩形的空白区域进行一些常规的划分。ConTeXt 所提供的页面布局如下图所示。
如果经常使用 ConTeXt 排版文档,建议将上图打印出来,放于案侧随时查阅。
页面布局的尺寸参数
上 面那幅蔚为壮观的页面布局图,也许你可以从中看出 ConTeXt 的页面布局是通过 22 个尺度参数(其中有 20 个参数是有编号的,2 个是没编号的)进行控制的,感觉有点恐怖,不过比钢琴的 88 个按键少多了。也许人类所谓的艺术,无非就是与那些参数众多的物件过不去,非要搞定它们不成。
如果我们从页面的横向与纵向来观察 ConTeXt 页面布局的 22 个尺度参数,很容易就可以发现它们变成了 11 + 11 个参数,如下表所示。
页面布局的尺度参数 | |
---|---|
横向尺度参数 | 纵向尺度参数 |
paperwidth | paperheight |
backspace | topspace |
leftedge | top |
leftedgedistance | topdistance |
leftmargin | header |
leftmargindistance | headerdistance |
width | height |
rightmargindistance | footerdistance |
rightmargin | footer |
rightedgedistance | bottomdistance |
rightedge | bottom |
这些尺度参数的名称虽然都可以找到中文的对应译名,但是我认为那样会将事情搞的更乱,我们干脆就将这组名称当作 ConTeXt 术语引入。
结合前面的页面布局图以及上面的页面布局尺度参数表,我们还可以分别从横向与纵向做进一步分解。
对 于横向的尺度参数,如果除去 paperwidth 与 backspace,那么剩下的尺度参数可以规划为边界(edge)、边距(margin)以及版心宽度(width)三个区域,其中 edge 与 margin 区域又分别呈左右对称分布于版心的两侧,这样就得到了如下面表格所示的横向尺度参数分布:
页面布局的横向尺度参数分布 | |||||||||
---|---|---|---|---|---|---|---|---|---|
左边界 | 左边距 |
版心 |
右边距 | 右边界 | |||||
leftedge | leftedgedistance | leftmargin | leftmargindistance | width | rightmargindistance | rightmargin | rightedgedistance | rightedge |
对于纵向的尺度参数,如果除去 paperheight 与 topspace,那么也可以按照横向尺度参数那样给出纵向的尺度参数分布:
页面布局的纵向尺度参数分布 | |||||||||
---|---|---|---|---|---|---|---|---|---|
上边界 | 页眉 | 版心高度 | 页脚 | 下边界 | |||||
top | topdistance | header | headerdistance | height | footerdistance | footer | bottomdistance | bottom |
要注意一点:纵向尺度参数的版心高度(height)包含着页眉(header)及页脚(footer)等尺度。版心宽度与高度参数之中暗含一点玄机,下文将单独拿出一个小节专门论述。
下 面,我们再来关注一下被忽略的 paperwidth、backspace、paperheight、topspace 这四个尺度参数,其中 paperwidth 与paperheight 分别表示页面宽度与高度,backspace 与 topspace 分别指版心左侧区域与上侧区域。
\setuplayout 与 \showlayout
上一节所讲述的众多页面布局的尺度参数中,除了 paperwidth 与 paperheight 这两个参数之外,其余参数皆可用 \setuplayout 控制序列进行设定。例如前面那幅页面布局图所显示的页面布局可采用下面这份 ConTeXt 文稿实现。
\setuplayout[ backspace=4.5cm, leftedge=0.5cm, leftedgedistance=0.5cm, rightedge=0.5cm, rightedgedistance=0.5cm, topspace=3cm, top=2cm, headerdistance=0.5cm, header=1cm, footerdistance=0.5cm, footer=1cm, topdistance=0.5cm, bottomspace=3cm, bottom=2cm, width=fit, height=fit] \starttext \showlayout \stoptext
\showlayout 控制序列可以可视化显示页面布局。下面这份 ConTeXt 文稿可以显示 ConTeXt 默认的页面布局:
\starttext \showlayout \stoptext
如果你不是很懒的话,也可以尝试使用 \showframe 这个控制序列替换 \showlayout 以观其效。
版心宽度与高度
版心,就是页面主要内容所在的区域。ConTeXt 使用 makeup 这个称谓来表示版心。在 \setuplayout 控制序列所设定的参数中,width 与 height 分别表示版心的宽度与高度。
可以使用控制序列 \makeupwidth 和 \makeupheight 获取版心的宽高尺度,例如:
\usemodule[zhfonts] \zhfonts[rm,11pt] \setuplayout[width=13cm, height=15cm] \starttext 版心宽度为 \the\makeupwidth 版心高度为 \the\makeupheight \stoptext
输出:
上 例 ConTeXt 文稿中版心宽度与高度是采用厘米(cm)为单位设定的,使用 \makeupwidth 与 \makeupheight 所获得的版心宽度与高度则是以 pt 为单位。在印刷排版行业中,pt 与 cm 的长度换算可基于 1pt = 1/72in,1in = 2.53cm 实现。
注意:上例为了在排版结果中显示 \makeupwidth 与 \makeupheight 的值,我们使用了控制序列 \the。如果你没有学习过 Plain TeX,那么 \the 的作用可能难以理解。暂时可以不用和它计较,仅需知道它可以从一些用于表示长度的控制序列的值提取出来,并作为普通文本排版输出。
ConTeXt 所定义的版心是由正文域(text)、页眉(header)和页脚(footer)构成。所谓正文域,可以理解为 ConTeXt 文稿的逻辑结构所营造的区域。
正 文域的宽度和高度,可分别使用 \textwidth 与 \textheight 获取。页眉和页角的宽度与版心宽度相同,其高度可分别使用 \headerheight 与 \footerheight 获取,此外页眉与版心的间距可使用 \headerdistance 获取,页脚与版心的间距可使用 \footerdistance 获取。例如:
\usemodule[zhfonts] \zhfonts[rm,11pt] \setupTABLE[frame=off,width=fit,rulethickness=1pt] \setupTABLE[row][odd,even][height=1.8em,align=lohi] \setupTABLE[row][first][topframe=on,height=2em,align={middle,lohi,broad}] \setupTABLE[row][2][topframe=on,rulethickness=0.5pt] \setupTABLE[row][last][bottomframe=on] \setupTABLE[column][1,2,3][offset=0pt,loffset=1em,roffset=1em,width=fit] \starttext \placetable{none} {\bTABLE \bTR\bTD\bf 控制序列\eTD \bTD\bf 含义\eTD \bTD\bf 值\eTD\eTR \bTR\bTD\tex{makeupwidth}\eTD \bTD 版心宽度\eTD \bTD\the\makeupwidth\eTD\eTR \bTR\bTD\tex{makeupheight}\eTD \bTD 版心高度\eTD \bTD\the\makeupheight\eTD\eTR \bTR\bTD\tex{textwidth}\eTD \bTD 正文域宽度\eTD \bTD\the\textwidth\eTD\eTR \bTR\bTD\tex{textheight}\eTD \bTD 正文域高度\eTD \bTD\the\textheight\eTD\eTR \bTR\bTD\tex{headerheight}\eTD \bTD 页眉高度\eTD \bTD\the\headerheight\eTD\eTR \bTR\bTD\tex{headerdistance}\eTD \bTD 页眉与版心间距\eTD \bTD\the\headerdistance\eTD\eTR \bTR\bTD\tex{footerheight}\eTD \bTD 页脚高度\eTD \bTD\the\footerheight\eTD\eTR \bTR\bTD\tex{footerdistance}\eTD \bTD页脚与版心间距\eTD \bTD\the\footerdistance\eTD\eTR \eTABLE} \stoptext
上例看上去貌似有些复杂,实际上它只是尽力排版了一个三线表格而已,暂且可不予理会(当然,你可以将这个例子作为 ConTeXt 表格示例),我们只关心它的输出结果:
认真观察从上例的输出结果,可以发现 \makeupwidth 的值于 \textwidth 相等。但是一定不要认为它们是真正的相等,因为它们只是在单栏排版的情况下是相等的,对于多栏排版,例如:
\starttext \startcolumns[rule=on,n=2] \tex{makeupwidth} = \the\makeupwidth \blank \tex{textwidth} = \the\textwidth \blank \input knuth \stopcolumns \stoptext
输出:
显然,此时 \makeupwidth 不仅不等于 \textwidth,反而是它的两倍还要多,因为此时:
\makeupwidth = (2 * \textwidth + 文本的栏间距)
继续观察前面的三线表格中的版心尺度控制序列的值,也许你会发现这样的等式:
\makeupheight = \headerheight + \headerdistance + \footerheight + \footerdistance
嗯,这次的观察结果是正确的。
页面尺度
对于页面布局的相关尺度参数,其含义、设定及参数值获取方法现在应该基本清楚了,现在需要拜访一下一直被一直被故意忽略的 paperwidth 和 paperheight 参数。
页 面布局控制是发生在矩形区域的页面空间中的,页面空间由 paperwidth 与 paperheight 参数界定,但是我们不需要直接设定这两个参数,因为 ConTeXt 提供了 \setuppapersize,并赠送了一组预定义的页面尺度。例如,如果采用 A4 纸作为页面空间,只需:
\setuppapersize[A4][A4]
如果你喜欢将页面横陈,只需:
\setuppapersize[A4,landscape][A4,landscape]
控制序列 \setuppapersize 接受 2 个参数,第一个参数是页面的尺度参数(宽度与高度),第二个参数是打印纸的尺度参数(宽度与高度)。一般,页面的尺度参数是等于打印纸的尺度参数的,但是也有例外的情况。
譬如,你将页面空间定义为 A3 纸的尺度,但是你身边的打印机只支持 A4 纸打印,此时只需将 \setuppapersize 的第 1 个参数设为 A3,而第 2 个参数设为 A4,即:
\setuppapersize[A3][A4]
将 A3 尺度的页面空间放置于 A4 纸上,这听起来有些不可思议,但是 ConTeXt 拍了拍胸脯,说你不要担心了,我会替你进行版面的全局缩放。
如果你认为 \setuppapersize 的第 2 个参数对你没有存在的意义,那么在定义页面尺度时,可以不需要再写它,例如:
\setuppapersize[A4]
此时,ConTeXt 就自作主张帮你将打印纸的尺度也设为 A4 了。
ConTeXt 预定义的页面尺度主要有 [A0, A9]、[B0, B9]、[C0, C9] 这些国际标准纸张尺度,此外还有 letter、legal、CD 等尺度,在此就不一而足了,详见 http://wiki.contextgarden.net/PaperSizes。
如果你没有在 ConTeXt 预定义的页面尺度集中找到符合需求的尺度,那么就需要使用 \definepapersize 自定义页面尺度并将其作为 \setuppapersize 的参数,例如:
\definepapersize[MyPaper][width=18.5cm,height=23cm] \setuppapersize[MyPaper]
上例所定义的 MyPaper 规格的页面与纸张尺寸,是近年来计算机技术书籍排版常用的页面尺度。
习惯的映射
前 面的内容一直围绕 ConTeXt 的 \setuplayout 与 \setuppapersize 这两个控制序列所能弹奏的参数——嗯,它不会弹钢琴——应该是它们能操作的参数,虽然那些参数不是全部,但是如果你理解了它们的功用,一般的页面布局都可 以游刃有余的去对付,毕竟那是 20 多号参数呢,爱因斯坦的质能方程也不过 2 个参数。
现在,我们来看一下我朝印刷排版业界对版面布局的定义。由于我不谙此道,所以只能浮光略影的写一点。若有谙于此道者,若另行著文阐释,吾辈幸甚。
我朝印刷排版业界对于版面布局有这样一套术语:版心、天头、地脚、订口、翻口。我们可以在 \setuplayout 找到这组术语的映射。
我朝印刷排版所关注的版心与 ConTeXt 的版心是对应的。这主要是因为我不知道该怎么翻译 ConTeXt 的 makeup 尺度参数,所以直接就套用了“版心”的概念。
天头,是指版心之上的区域,对应 ConTeXt 的页面布局纵向尺度参数中的 height 之上的区域,即 topspace。
地脚,是指版心之下的区域,对应 ConTeXt 的页面布局纵向尺度参数中的 height 之下的区域,即 (paperheight - topspace - height)。实际上 \setuplayout 有一个 bottomspace 等价于地脚,但是其用法另有玄机,后文会加以介绍。
订口,对于单面排版,是指版心之左的区域,而对于双面排版是指版心与书脊之间的区域,对应 ConTeXt 的页面布局纵向尺度参数中的 width 之左的区域,即 backspace。
翻口,对于单面排版,是指版心之右的区域,而对于双面排版是指版心与翻书位置之间的区域,对应 ConTeXt 的页面布局纵向尺度参数中的 width 之左的区域,即 (paperwidth - backspace - width)。实际上 \setuplayout 有一个 cutpace 等价于翻口,但是其用法另有玄机,后文会加以介绍。
这里必须要注意:对 于 ConTeXt 单面排版,我们使用版心之左来称谓 backspace 区域,使用版心之右来称谓 (paperwidth - backspace - width) 区域,而对其双面排版,我们依然可以如此称谓,因为 ConTeXt 认为双面排版的页面布局是单面排版时的页面布局镜像而成。这个问题,以后还需要在讲述 ConTeXt 单双面排版时再进一步阐释,在此便不作深究。
尺度约束
上一节中,我们说地脚与翻口在 ConTeXt 页面布局尺度所对应的参数设定另有玄机,这是因为 ConTeXt 为页面布局提供了尺度约束机制。
例如,翻口的尺度设定,我们可以有两种方案。第一种方案是隐式设定,如下:
\setuppapersize[A4] \setuplayout[backspace=4cm, width=13cm]
此时,由于 A4 的宽度为 21cm,即 paperwidth 为 21cm。那么翻口的尺度 ConTeXt 会按照 (paperwidth - backspace - width) 这个公式来计算,即 (21cm - 4cm - 13cm) = 4cm。
第二种方案是显式设定,如下:
\setuppapersize[A4] \setuplayout[backspace=4cm, width=middle, cutspace=5cm]
此 时,注意版心宽度对应的尺度参数 width 的值为 middle,并且订口(backspace)和翻口(cutspace)的尺度值已经显示给定,那么 ConTeXt 就会采用公式 (paperwidth - backspace - cutspace) 来计算 width 的值,即 (21cm - 4cm - 5cm) = 12cm。
对于地脚的尺度设定与翻口相似,这个可以作为课后习题来折腾,不复多言。
上述翻口尺度设定的两种方案,也可以从版心宽度的设定来理解,这又别有一番风味。例如,版心宽度的设定,我们有两种方案。第一种方案是显式设定,如下:
\setuppapersize[A4] \setuplayout[backspace=4cm, width=13cm]
第二种方案是隐式设定,如下:
\setuppapersize[A4] \setuplayout[backspace=4cm, width=fit, cutspace=5cm]
但是,对于版心宽度的设定,我们还有一种隐式设定方案,如下:
\setuppapersize[A4] \setuplayout[backspace=4cm, width=fit, cutspace=5cm]
此时,width 的值为 fit,解释会很罗嗦,下面是我直接从 ConTeXt Wiki 上拿来的流程(实际上是一块 lua 代码):
if cutspace == 0pt then cutspace = backspace end width = paperwidth-cutspace scratchdimen = backspace - leftedgewidth-leftedgedistance -leftmarginwidth-leftmargindistance if scratchdimen< 0pt then scratchdimen = 0pt end makeupwidth = makeupwidth - rightmargindistance-rightmarginwidth - rightedgedistance-rightedgewidth- scratchdimen
上例,如果感觉难以理解就罢了,对生活影响不大。
推荐阅读
这篇文章,有许多细节没有谈到。除了我在文中有过许诺以后会继续阐释的细节之外,其它我便不再关心了。想知道更多的内容,需要阅读 http://wiki.contextgarden.net/Layout。
预告
下一篇要写什么,我还没想好。
转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com
2011年1月20日 22:59
学习。
下一篇写页眉、页脚、页码等内容吧。
2011年2月09日 13:31
虽是latex用户,但是这篇还是非常有用的。
2011年2月12日 17:16
拜博客。
2011年4月23日 10:51
同拜博客^_^