构造一个框框,令它在正文区域的水平和竖直方向皆居中,此事略有些复杂,但是倘若使用 makeup 会容易很多。
makeup 是什么?我也不知道,ConTeXt wiki 上给出的解释是:
A makeup is a separate page, like a title page or colofon. There is one standard makeup page, but you can define more if needed. ——From a mail by Taco:
ConTeXt Reference 给出的解释是:
A document may have a titlepage, a colofon and some pages that are not directly related to the main part of the document. Mostly these pages are not numbered and can do without headers and footers. Because their layout needs extra attention we prefer the word makeup for defining their specific layout.
makeup 这个词有「化妆品」,「天性」,「组成」之意,顾上述引文之名而思其意,在 ConTeXt 世界里应该是化妆品的意思。Hans 和 Taco 皆是荷兰人,他们用的英文单词居然用了修辞。
根据上述引文,可知有个 standardmakeup,标准的 makeup……标准的,应该很好,试一试:
\environment card-env
\starttext
\startstandardmakeup
... some text ...
\stopstandardmakeup
\stoptext
结果为

成功了一半。水平方向未居中,试试 align
参数:
\startstandardmakeup[align=middle]
... some text ...
\stopstandardmakeup
结果为

成功。将 ... some text ...
换成框框吧,
\startstandardmakeup[align=middle]
\framed{... some text ...}
\stopstandardmakeup
结果表现了命途多舛:

不过,这个结果能够证明,框框跟普通的文字内容是不一样的。如果在框框两侧添加一些普通文字,是否可以欺骗 TeX 编译器呢?试试看,
\startstandardmakeup[align=middle]
... \framed{... some text ...} ...
\stopstandardmakeup
结果的确可以,如下图:

现在,只需将框框两侧的文字换成有高度但没宽度的 \strut
即可实现框框的水平居中,即
\startstandardmakeup[align=middle]
\strut\framed{... some text ...}\strut
\stopstandardmakeup
阴谋得逞:

现在,将框框的宽度设为 \textwidth
,高度设为 \textheight
,
\framed[width=\textwidth,height=\textheight]{... some text ...}
结果为

ConTeXt 允许用户定义自己的框框,例如:
\environment card-env
\defineframed
[canvas]
[width=\textwidth,height=\textheight]
\starttext
\startstandardmakeup[align=middle]
\strut\canvas{... some text ...}\strut
\stopstandardmakeup
\stoptext
上述我定义的框框叫 \canvas
,它的排版结果与上面最后的排版结果相同。
但是,上面最后的排版结果,还是经不起认真观察,框框的位置在竖直方向上并不居中,而是略微向上偏移。若不确定,可使用 \showframe
,并将框框的颜色设为红色,
\environment card-env
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=red]
\showframe
\starttext
\startstandardmakeup[align=middle]
\strut\canvas{... some text ...}\strut
\stopstandardmakeup
\stoptext
则真相立现:

红色的框框略微向上偏移了微小的距离。我有些佩服我的眼力了。
若令 \canvas
达到理想化的竖向居中,就需要消除它的偏移。该问题的解决方案是,将框框的 location
参数设为 lohi
:
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=red,
location=lohi]
结果非常理想:

为何将 \canvas
的 location
设为 lohi
就能解决问题?很抱歉,我不知道。许多年前,我是从 \setupframed
的 location
参数的众多可取的值里经过试验,确定了 lohi
能解决问题。
现在,可以从 ConTeXt 源文件里去掉 \showframe
了,然后为 \canvas
增加两个参数,rulethickness
和 empty
,前者用于设定框框的线宽,后者用于隐没框框内的文字,然后将框框的颜色修改为暗红色:
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=darkred,
rulethickness=.25em,
location=lohi,
empty=yes]
现在,框框的样子如下图所示:

我煞费苦心,创造这个暗红色的框框,做什么用呢?画画。接下来,还需要再对这个框框动一些手脚,令它成为我的卡片上的一小块画布。
框框有个好兄弟,叫 overlay。这个单词,我也不知道怎么翻译会比较准确。倘若不知如何言传,那就努力意会:
\defineoverlay[foo][... some object ...]
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=darkred,
rulethickness=.25em,
location=lohi,
empty=yes,
background=foo]
排版结果如下:

从上述示例里,可意会的事情是,我定义了一个名字叫作 foo
的 overlay,在其中「画」了几个字,然后将这个 overlay 作为框框的背景。
在 overlay 里能画画吗?不能。但 overlay 里能够存放图片。例如,将上文最后一幅图片保存到 ConTeXt 源文件所在目录并命名为 foo.png,然后重新定义 overlay:
\defineoverlay
[foo]
[{\externalfigure[foo.png][width=\overlaywidth,height=\overlayheight]}]
结果为

是不是很奇妙?因为似乎有递归的影子。不过,这并不重要。overlay 能存放图片,它也能存放一种叫作 MetaPost 的绘图语言的代码:
\defineoverlay
[foo]
[\uniqueMPgraphic{绘图代码}]
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=darkred,
rulethickness=.25em,
location=lohi,
empty=yes,
background=foo]
\startuniqueMPgraphic{绘图代码}
... ... MetaPost 代码 ... ...
\stopuniqueMPgraphic
接下来,我给一个完整且具体的例子,但是因为代码有点长,还是先图夺人更友好一些:

这是我多年前的作品,名字叫「颤动的希尔伯特曲线」……它的所有代码如下:
\environment card-env
\defineoverlay
[foo]
[\uniqueMPgraphic{绘图代码}]
\defineframed
[canvas]
[width=\textwidth,
height=\textheight,
framecolor=darkred,
rulethickness=.25em,
location=lohi,
empty=yes,
background=foo]
\startuniqueMPgraphic{绘图代码}
vardef hilbert(expr sidelength, n) =
numeric u; u := 0.5sidelength;
pair a, b, c, d;
a := (-0.5, -0.5) * u;
b := (-0.5, 0.5) * u;
c := (0.5, 0.5) * u;
d := (0.5, -0.5) * u;
path p;
p := a -- b -- c -- d;
transform sw, nw, ne, se;
sw := identity
scaled 0.5
reflectedabout ((0, 0), (1, 1))
shifted (-0.5u, -0.5u);
nw := identity
scaled 0.5
shifted (-0.5u, 0.5u);
ne := identity
scaled 0.5
shifted (0.5u, 0.5u);
se := identity
scaled 0.5
reflectedabout ((0, 0), (1, -1))
shifted (0.5u, -0.5u);
for i := 2 upto n:
p := p transformed sw for j := nw, ne, se: -- p transformed j endfor;
endfor;
p
enddef;
path p; p := hilbert(OverlayWidth, 3) randomized 5mm;
drawpath p yscaled(OverlayHeight / OverlayWidth);
drawpoints p yscaled(OverlayHeight / OverlayWidth);
\stopuniqueMPgraphic
\starttext
\startstandardmakeup[align=middle]
\strut\canvas{... some text ...}\strut
\stopstandardmakeup
\stoptext
上述的绘图代码,虽然的确是我写的,但是现在我也看不懂。
网友评论