\chapter{幻灯片}

现在你已经领略甚至可能全部掌握了 \CONTEXT\ 常用的的排版元素，若不使用它们而是依然使用 Microsoft PowerPoint 或 WPS 之类的软件制作幻灯片则甚为可惜。现在若是用 \CONTEXT，只需要再掌握寥寥几条排版命令便可制作出独具风格的幻灯片了。

\section{纸面尺寸}

纸面尺寸是页面的打印尺寸。至此为止，本文档之前所有的示例，在 \type{TEXpage} 环境里的，纸面尺寸取决于文档内容的多少，而在 \type{text} 环境里的，纸面尺寸默认是 A4，即 $21\,{\rm cm}\times 29.7\,{\rm cm}$。如果你需要将纸面尺寸换成 A5，只需在样式文件中作以下设定\cmdindex{setuppapersize}

\cmdindex{setuppapersize}
\starttyping[option=TEX]
\setuppapersize[A5]
\stoptyping

制作幻灯片通常不需要太大的纸面尺寸。\CONTEXT\ 提供了 S4 尺寸（$400\,{\rm pt}\times 300\,{\rm pt}$），可将其作为幻灯片的纸面尺寸，或者你根据自身需求定义一个纸面尺寸来用\cmdindex{definepapersize}，例如

\starttyping[option=TEX]
\definepapersize[slidesize][width=640pt,height=480pt]
\setuppapersize[slidesize]
\stoptyping

实际上，纸面尺寸仅对排版结果的打印很重要，倘若只是在计算机（或投影仪）屏幕上观看排版结果，我们总是可以通过调整正文字体大小去应对过大或过小的纸面尺寸，但是纸面尺寸的宽高比例，对于屏幕非常重要。通常，幻灯片的宽高比应当与屏幕的分辨率相适应为最佳。例如，我的屏幕分辨率是 $1600\times 900$，那么我要制作的幻灯片页面的宽高比也应当是 $16:9$，故而纸面尺寸可设定为

\cmdindex{definepapersize}
\starttyping[option=TEX]
\definepapersize[slidesize][width=640pt,height=360pt]
\setuppapersize[slidesize]
\stoptyping

现在，我们可以制作幻灯片的最原始的形式了，见下例。

\starttyping[option=TEX]
\usemodule[visual]
\definepapersize[slidesize][width=640pt,height=360pt]
\setuppapersize[slidesize]

\starttext
\title{\fakewords{3}{5}}
\fakewords{50}{100}
\stoptext
\stoptyping
\midaligned{\externalfigure[12/slides-1.pdf][width=.6\textwidth,frame=on]}

\section{页面布局}

在 \type{text} 环境之前添加以下代码：

\starttyping[option=TEX]
\showframe
\stoptyping

\noindent 可在页面上显示当前的页面布局，结果如图 \in[12-layout-1] 所示。可根据图 \in[ConTeXt-layout] 理解页面布局中各区域名称和尺寸参数名称。

\placefigure[here][12-layout-1]{\CONTEXT\ 默认的页面布局}{\externalfigure[12/layout-1.pdf][width=.6\textwidth]}

\placefigure[here][ConTeXt-layout]{页面布局注解}{\externalfigure[12/ConTeXt-layout.svg][width=.8\textwidth]}

使用 \type{\setlayout}\cmdindex{setlayout} 可对各区域尺寸进行调整，例如让版心居中，即图 \in[ConTeXt-layout] 所示的 \type{width} 和 \type{textheight} 确定的区域居中，因为在默认情况下，它有些偏左。我们已经知道，页面的横向尺寸是 640pt，按以下设定即可令版心居中。

\cmdindex{setuplayout}
\starttyping[option=TEX]
\setuplayout
  [leftedge=0pt,leftedgedistance=0pt,
   leftmargin=80pt,leftmargindistance=10pt,
   backspace=90pt,
   rightedge=0pt,rightedgedistance=0pt,
   rightmargin=80pt,rightmargindistance=10pt,
   width=460pt]
\stoptyping

\noindent 上述设定，实现了页面布局中页面总宽度值 640 pt 的分配，但是要注意一点，\type{backspace} 的值等于 4 个以 \type{left} 为前缀的参数值之和，虽然在设定了它的各个分量后，但 \CONTEXT\ 在遇到默认的 \type{backspace} 值与实际的 \type{left...} 参数值之和不符时，会根据 \type{backspace} 值进行页面布局。倘若我们不关心 \type{left...} 参数，即 \CONTEXT\ 默认对页面左侧留白区域默认如何分配，仅需要让 \CONTEXT\ 知道 \type{backspace=90pt}，则上述代码可简化为

\starttyping[option=TEX]
\setuplayout
  [backspace=90pt,
   rightedge=0pt,rightedgedistance=0pt,
   rightmargin=80pt,rightmargindistance=10pt,
   width=460pt]
\stoptyping

\noindent 还可以进一步简化，因为 \CONTEXT\ 对 \type{rightedge} 和 \type{rightedgedistance} 赋予的默认值原本就是 0，因此有

\starttyping[option=TEX]
\setuplayout
  [backspace=90pt,
   rightmargin=80pt,rightmargindistance=10pt,
   width=460pt]
\stoptyping

如果我们只关心版心的横向居中问题，并不关心左右留白区域的尺寸，最为简单的布局方式是

\starttyping[option=TEX]
\setuplayout[width=middle]
\stoptyping

以上设置的是页面横向布局。对于纵向布局，存在与 \type{backspace} 类似的问题，即 \type{topspace} 的设定。\type{topspace} 的值是 \type{top} + \type{topdistance}，但是在 \type{\setuplayout} 中只对后者进行设定是无效的，必须先设定 \type{topspace}，然后再将其值分配给 \type{top} 和 \type{topdistance}，或让 \CONTEXT\ 自动分配。

制作幻灯片时，除了纵向居中，可以需要去掉页面顶部和底部留白从而节省一些纵向空间，脚注区域可以保留，故而纵向参数可设定为

\starttyping[option=TEX]
height=middle,topspace=0pt,bottom=0pt,footer=40pt
\stoptyping

\noindent 现在全部的页面布局设定如下：

\starttyping[option=TEX]
\setuplayout[width=middle,height=middle,topspace=0pt,bottom=0pt,footer=40pt]
\stoptyping
\midaligned{\externalfigure[12/layout-2.pdf][width=.6\textwidth,frame=on]}

完成页面布局设定后，别忘记去掉 \type{text} 环境之前的 \type{\showframe} 语句。此外，我建议你在 \type{text} 环境里动手试验一番 \type{\showlayout}。

\section[slide-fonts]{字体}

在 \CONTEXT\ 使用汉字字体，对此估计你已经颇为熟悉了。在幻灯片中，我对字体作以下设定：

\starttyping[option=TEX]
\definefallbackfamily
  [myfonts][ss][latinmodernsans][range={0x0000-0x0400},force=yes]
\definefontfamily[myfonts][ss][simhei][bf=simhei,it=kaiti,bi=simhei]
\setscript[hanzi]
\setupbodyfont[myfonts,ss,16pt]
\stoptyping

\noindent 上述字体设定并不完整，尚未设定衬线字族和等宽字族，这些字族可在需要时再予以设定。

\section[regular-style]{常规样式}

首先，消除 \CONTEXT\ 默认在页面顶部设置的页码：

\starttyping[option=TEX]
\setuppagenumbering[location=]
\stoptyping

\noindent 幻灯片通常不需要页码，即使需要页码，默认的页码出现的位置和字号皆不合适。

设置行间距为 1.75 倍：

\starttyping[option=TEX]
\setupinterlinespace[line=1.75\bodyfontsize]
\stoptyping

下例设置了列表的第 1 级样式，具体为 (1) 将 \in[drawing-sym] 节实现的列表项符号作为默认列表项符号，只是正方形的阴影颜色略加修改，\type{.75white} 等价于 rgb 三元组 \type{(0.75, 0.75, 0.75)}；(2) 消除列表项的间距；（3） 在列表项的符号和内容之间插入 .5em 的间距；(4) 让列表前后各空 1/4 行。

\starttyping[option=MP]
\startuseMPgraphic{square}
numeric u; path p;
u := BodyFontSize; 
p := fullsquare scaled .8u;
fill p shifted (.2u, -.2u) withcolor .75white;
fill p withcolor .5[blue, white];
\stopuseMPgraphic
\stoptyping
\starttyping[option=TEX]
\definesymbol[10][{\lower.2\bodyfontsize\hbox{\useMPgraphic{square}}}]
\setupitemize[1] % 列表第 1 级样式
             [10,packed]
             [distance=.5em,
               before={\blank[quarterline]},
               after={\blank[quarterline]}]
\stoptyping
\noindent 如果你还需要二级、三级列表，只需将 \tex{setupitemize} 的第 1 个参数换成 2、3，然后参照上例设定其样式。

然后将幻灯片一级标题设置为居中对齐，字号级别为 \type{b}，颜色为 \type{darkred}，前后各空半行：

\starttyping[option=TEX]
\setuphead
  [title,chapter]
  [align=center,style=\ssb,color=darkred,
   before={\blank[halfline]},after={\blank[halfline]}]
\stoptyping

现在，在 \type{text} 环境中随便写点什么，察验上述设定是否起效。

\starttyping[option=TEX]
\starttext
\startbuffer[foo]
\chapter{蒙卦}
亨。匪我求童蒙，童蒙求我；初筮告，再三渎，渎则不告。利贞。
\startitemize
\item 初六，发蒙，利用刑人，用说桎梏；以往吝。
\stoptyping
\starttyping[option=TEX]
\item 九二，包蒙，吉。纳妇，吉；子克家。
\item 六三，勿用取女，见金夫，不有躬，无攸利。
\item 六四，困蒙，吝。
\item 六五，童蒙，吉。
\item 上九，击蒙，不利为寇，利御寇。
\stopitemize
\stopbuffer
\dorecurse{3}{\getbuffer[foo]}
\stoptext
\stoptyping
\midaligned{\externalfigure[12/slides-2.pdf][width=.6\textwidth,frame=on]}

\noindent 上述代码使用了 \CONTEXT\ 的 \type{buffer} 环境\index[buffer]{\type{buffer} 环境}。所谓 \type{buffer}，是可以设定名字的缓存，它可以包含 \CONTEXT\ 排版代码。\type{\getbuffer} 用于获取缓存内容。

截止至此，我们第一次在示例中使用有编号标题。对于 \type{\chapter} 建议在幻灯片样式中将数字编号更改为中文编号，另外设置编号的样式为 \type{inmargin}，表示编号不参与居中对齐，只有标题内容参与对齐，见下例。

\starttyping[option=TEX]
\setuphead[chapter][conversion=chinesenumerals,alternative=inmargin]
\stoptyping
\midaligned{\externalfigure[12/slides-3.pdf][width=.6\textwidth,frame=on]}
\blank

\noindent 如果你还需要二级、三级标题，可参照上述设定，依法炮制。

\section[footer]{页脚}

在 \in[regular-style] 节中，我关闭了 \CONTEXT\ 好意提供的页码。因为我希望页码出现在页面的右下角，且除以总页数，以便清楚幻灯片的进度。

\CONTEXT\ 提供了 \type{\setupfootertexts} 命令\cmdindex{setupfootertexts}，可以在页脚左、右区域放入文字、盒子或图形等内容，同时提供了 \type{\setupfooter} 用于设定页脚区域的文字样式。另外，\type{\userpagenumber}\cmdindex{userpagenumber} 和 \type{\lastuserpage}\cmdindex{lastuserpage} 可分别用于获取当前页的页码和最后一页的页码。基于这些命令，便可实现能够表示进度的页码。例如

\cmdindex{setupfootertexts}
\starttyping[option=TEX]
\setupfooter[style=small,color=darkred]
% 令页脚左侧区域为空，右侧区域放置用于表示进度的页码
\setupfootertexts[margin][][\hss\userpagenumber/\lastuserpage]
\stoptyping

\noindent 结果如图 \in[页码进度] 所示。
\placefigure[here][页码进度]{第 4 页幻灯片}{\externalfigure[12/slides-4.pdf][page=4,width=.6\textwidth,frame=on]}

现在，我们已经有了一个基本可用的幻灯片样式了。倘若使用刚学过的 \METAPOST\ 语言，琢磨一下，给幻灯片增加些许不庸俗又实用的装饰，也许会让人觉得你的幻灯片颇为用心。

\section{进度条}

现在，我们放弃使用当前页码除以总页数的方式表示进度，而是用 \METAPOST\ 画一个进度条，见以下代码。

\starttyping[option=MP]
\startuseMPgraphic{processbar}
numeric w, n, s, t; path p; picture q;
w := \overlaywidth; n := \lastuserpage;
s := .5w / (n + 2); t := \userpagenumber - 1;
p := (fullsquare scaled \overlayheight);
pickup pencircle scaled 2pt;
q := image(for i = 0 upto n - 1:
             p := (p shifted (2s, 0)) randomized .5pt;
             if t = i: fill p withcolor darkgreen; fi;
             draw p withcolor transparent(1, 0.5, darkgray);
           endfor;);
draw q xsized w;
\stopuseMPgraphic
\stoptyping

\starttyping[option=TEX]
\defineoverlay[process][\useMPgraphic{processbar}]
\setupfootertexts[{\framed[frame=off,offset=0pt,
                           width=\textwidth,height=.8em,
                           background=process,empty=yes]{}}]
\stoptyping

\noindent 上述代码唯一需要解释之处是，当 \type{\setupfootertexts} 只有一个参数时，该参数的值会被安置在页脚的中间区域。上述代码构造的进度条效果如图 \in[processbar] 所示。

\placefigure[here][processbar]{第 2 页幻灯片}{\externalfigure[12/slides-finished.pdf][width=.6\textwidth,page=3,frame=on]}

\section{封面和致谢}

\index[standardmakeup]{\type{standardmakeup} 环境}
幻灯片的封面皆可使用 \type{sandardmakeup} 环境制作，见下例。

\index[standardmakeup]{standard makeup}
\starttyping[option=TEX]
\startstandardmakeup[align=center]
\ssd\color[darkred]{如何用 \CONTEXT\ 制作幻灯片}
\blank[2*line]
\ssb\darkred{李某人}
\blank[3*line]
\darkred{2025 年 09 月 01 日}
\stopstandardmakeup
\stoptyping

之所以用 \type{standardmakeup} 环境制作封面，是因为它能构造完全空白的单页，且该页不参与页码计数。
\placefigure[here][cover]{封面}{\externalfigure[12/slides.pdf][width=.6\textwidth,page=1,frame=on]}

若想让封面赏心悦目，最好的办法是制作一幅与幻灯片所讲主题相适且比例与幻灯片页面相同的图片，将其设为封面背景。假设背景图片为 foo.png，将其设定为封面背景的方法如下：

\starttyping[option=TEX]
\definelayer[cover][width=\paperwidth,height=\paperheight]
\setlayer[cover][preset=lefttop]
         {\externalfigure[foo.png][width=\paperwidth,height=\paperheight]}
\setupbackgrounds[page][background=cover]
\startstandardmakeup[align=center]
... 省略封面内容 ...
\stopstandardmakeup
\stoptyping
\placefigure[force][slide-background]{全页插图背景}{\externalfigure[12/slides-finished.pdf][width=.6\textwidth,page=1]}

你也可以不断尝试用 \METAPOST\ 语言画一些图形作为封面背景。这份文档的封面上像迷宫一样的线条便是用 \METAPOST\ 代码画出的。

至于幻灯片最后的致谢页，依然可以用 \type{makeup} 环境制作。

\subject{结语}

一份精致的幻灯片样式，值得你用心设计，但是切记，不要喧宾夺主。质胜文则野，文胜质则史。孔子说，好的幻灯片样式，应该是文质彬彬的。你可以将自己亲手制作的幻灯片样式保存下来，以后可重复使用，也可以分享给他人。不过，制作幻灯片只是帮助你学会页面布局的掌控方法，后者能够帮助你排版更多类型的文档。
