《Lua in ConTeXt》13:畫布

構造一個框框,令它在正文區域的水平和豎直方向皆居中,此事略有些複雜,但是倘若使用 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]

結果非常理想:

爲何將 \canvaslocation 設爲 lohi 就能解決問題?很抱歉,我不知道。許多年前,我是從 \setupframedlocation 參數的衆多可取的值裏經過試驗,確定了 lohi 能解決問題。

現在,可以從 ConTeXt 源文件裏去掉 \showframe 了,然後爲 \canvas 增加兩個參數,rulethicknessempty,前者用於設定框框的線寬,後者用於隱沒框框內的文字,然後將框框的顏色修改爲暗紅色:

\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

上述的繪圖代碼,雖然的確是我寫的,但是現在我也看不懂。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章