\chapter{幻灯片}

现在你已经领略甚至可能全部掌握了 \ConTeXt\ 常用的的排版元素，若不使用它们而是依然使用 Microsoft PowerPoint 制作幻灯片甚为可惜。如果你已决意使用 \ConTeXt\ 制作幻灯片，你会发现，你几乎不需要再学习多少新的 \ConTeXt\ 命令便可随心所欲地制作清新质朴的幻灯片了。

\section{纸面尺寸}

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

\starttyping[option=TEX]
\setuppapersize[A5]
\stoptyping

制作幻灯片通常不需要太大的纸面尺寸。\ConTeXt\ 提供了 S4 尺寸（$400\,{\rm pt}\times 300\,{\rm pt}$），可将其作为幻灯片的纸面尺寸。也可以自己定义纸面尺寸并使用，例如

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

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

\starttyping[option=TEX]
\definepapersize[foo][width=640pt,height=360pt]
\setuppapersize[foo]
\stoptyping

现在，我们可以制作幻灯片的最原始的形式：

\starttyping[option=TEX]
\usemodule[visual]
\definepapersize[foo][width=640pt,height=360pt]
\setuppapersize[foo]
\starttext
\title{\fakewords{3}{5}}
\fakewords{50}{100}
\stoptext
\stoptyping
\midaligned{\externalfigure[13/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[13/layout-1.pdf][width=.6\textwidth]}

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

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

\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{tospace} 的值是 \type{top} + \type{topdistance}，但是在 \type{\setuplayout} 中只对后者进行设定是无效的，必须先设定 \type{tospace}，然后再将其值分配给 \type{top} 和 \type{topdistance}，或让 \ConTeXt\ 自动分配。

对于页面纵向布局参数，我要去掉页面顶部和底部留白，只需作以下设定

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

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

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

完成页面布局设定后，别忘记去掉 \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 倍，即 $1.75\times 16\,{\rm pt}$：

\starttyping[option=TEX]
\setupinterlinespace[line=28pt]
\stoptyping

以下代码设置了了第 1 级列表样式，（1）定义一个新的列表项符号，将其设置列表项默认符号；（2）消除列表项之间的额外间距；（3）列表项的符号和内容之间插入 .5em 的间距；（4）列表前后各空 1/4 行，因为在幻灯片中，纵向空间颇为珍贵。

\starttyping[option=MP]
\startuseMPgraphic{square}
  path a, b;
  a := (-.5, 0) -- (-.5, .5) -- (.5, .5);
  b := (-.5, -.5) -- (.5, -.5) -- (.5, 0);
  for i = a, b:
    draw i scaled 10pt withpen pencircle scaled 2pt withcolor darkred;
  endfor;
  draw (0, 0) withpen pensquare scaled 4pt withcolor darkred;
\stopuseMPgraphic
\stoptyping
\starttyping[option=TEX]
\definesymbol[10][{\lower.15ex\hbox{\useMPgraphic{square}}}]
\setupitemize
  [1][10,packed]
  [distance=0.4em,
   before={\blank[quarterline]},after={\blank[quarterline]}]
\stoptyping
\noindent 如果你还需要二级、三级列表，可参照上述设定制作适合的样式。

将幻灯片一级无编号标题和有编号标题均设置为居中对齐，字号级别为 \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 初六，发蒙，利用刑人，用说桎梏；以往吝。
\item 九二，包蒙，吉。纳妇，吉；子克家。
\item 六三，勿用取女，见金夫，不有躬，无攸利。
\item 六四，困蒙，吝。
\item 六五，童蒙，吉。
\item 上九，击蒙，不利为寇，利御寇。
\stopitemize
\stopbuffer
\dorecurse{10}{\getbuffer[foo]}
\stoptext
\stoptyping
\midaligned{\externalfigure[13/slides-2.pdf][width=.6\textwidth,frame=on]}

\noindent 上述代码使用了 \ConTeXt\ 的 \type{buffer} 环境和循环宏 \type{\dorecurse}。所谓 \type{buff}，是一个可以设定名字的缓存，它可以包含 \ConTeXt\ 排版代码。\type{\getbuffer} 可获得指定名字的缓存中所包含的全部代码。\type{\dorecurse} 可以将其所含内容重复指定次数。上述代码所产生的效果是生成十页内容相同的幻灯片。

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

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

\noindent 如果你还需要二级、三级标题，可参照上述设定制作适合的样式。

\section{页脚}

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

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

\starttyping[option=TEX]
\showframe
\setupfooter[style=small,color=darkred]
% 页脚左侧区域为空，右侧区域放置用于表示进度的页码
\setupfootertexts[margin][][\hss\userpagenumber/\lastuserpage]
\stoptyping
\noindent 结果如图 \in[页码进度] 所示。
\placefigure[here][页码进度]{第 4 页幻灯片}{\externalfigure[13/slides-4.pdf][page=4,width=.6\textwidth,frame=on]}

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

\section{进度条}

现在，我们放弃使用当前页码除以总页数的方式表示进度，而是颇为用心地用 \METAPOST\ 在页面底部绘制一个进度条。实际上，用不了几行代码便可实现：

\starttyping[option=MP]
\startuseMPgraphic{processbar}
numeric w, n, s, t;
w := \overlaywidth; n := \lastuserpage;
s := .5w / (n + 2); t := \userpagenumber - 1;
path p; p := (fullsquare scaled \overlayheight);
pickup pencircle scaled 2pt;
picture q;
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=\makeupwidth,height=.8em,
                           background=process,empty=yes]{}}]
\stoptyping

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

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

\section{封面和致谢}

幻灯片的封面和最后的致谢页皆可使用 \type{sandardmakeup} 环境制作。例如

\starttyping[option=TEX]
\startstandardmakeup[align=center]
\ssd \color[darkred]{如何用 \ConTeXt\ 制作幻灯片}
\blank[2*line]
\ssb 李某人
\blank[line]
2023 年 3 月 28 日
\stopstandardmakeup
\stoptyping
\noindent 结果如图 \in[cover] 所示。

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

\section{不要太刺眼}

白色背景，往往过于刺眼。我们可将幻灯片背景色设置为浅灰色：

\starttyping[option=TEX]
\setupbackgrounds[page][backgroundcolor=lightgray,background=color]
\stoptyping
\noindent 结果如图 \in[slide-background] 所示。
\placefigure[here][slide-background]{浅灰色背景}{\externalfigure[13/slides-finished.pdf][width=.6\textwidth,page=1,frame=on]}

\section{小结}

本章仅介绍了非常基本的幻灯片制作过程。一份精致的幻灯片样式，值得你用心设计，但是切记，不要喧宾夺主。质胜文则野，文胜质则史。孔子说，好的幻灯片样式，总是是文质彬彬的。本文制作的幻灯片示例，路数偏野。
