diff options
author | Karl Berry <karl@freefriends.org> | 2014-11-13 23:53:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-11-13 23:53:39 +0000 |
commit | e0056016e425d97e79d80fdee01acf4cd84c1d8d (patch) | |
tree | c6024370d669e546e6c66fca1784ec0a980e8694 /Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex | |
parent | c3397e2195329b400975b069f1f6e3b2092f84a8 (diff) |
impatient-cn (13nov14)
git-svn-id: svn://tug.org/texlive/trunk@35576 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex')
-rw-r--r-- | Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex | 1455 |
1 files changed, 1455 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex b/Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex new file mode 100644 index 00000000000..1ee49729615 --- /dev/null +++ b/Master/texmf-dist/doc/plain/impatient-cn/usermacs.tex @@ -0,0 +1,1455 @@ +% -*- coding: utf-8 -*- +% This is part of the book TeX for the Impatient. +% Copyright (C) 2003 Paul W. Abrahams, Kathryn A. Hargreaves, Karl Berry. +% See file fdl.tex for copying conditions. + +\input macros +%\chapter{A compendium \linebreak of useful macros} +\chapter{实用宏集概述} + +\chapterdef{eplain} + +%This section describes |eplain.tex|, a collection of macros and other +%definitions that extend plain \TeX. +%\bix^^|eplain.tex| +%The descriptions of the various macros explain their purposes, +%but usually do not explain how they +%work or provide explicit details on +%how to use them. That information is contained in the source files for +%|eplain.tex| and in the documentation that comes with it. +%See \headcit{Resources}{resources} for how to obtain |eplain.tex|. +这一章描述 |eplain.tex|,一组用于扩展 plain \TeX\ 的宏和其他定义。 +\bix^^|eplain.tex| +对各种宏的描述解释了它们的目的,但通常不解释它们的工作原理或给出如何使用它们的详情。 +那些信息包含在 |eplain.tex| 源码文件以及它的文档中。 +在\headcit{资源}{resources}中介绍了获取 |eplain.tex| 的方法。 + + +%\section{Preliminaries} +\section{预备定义} + +%We start with some macros for changing category codes and convenient +%definitions for two of the commonly used ones. +%^^{category codes//useful definitions for} +我们先介绍几个修改类别码及定义两种常用类别码的宏。 +^^{类别码//有用的类别码定义} + +%\pix^^|\makeactive| +%\pix^^|\letter| +%\pix^^|\other| +%\pix^^|\uncatcodespecials| +\pix^^|\makeactive| +\pix^^|\letter| +\pix^^|\other| +\pix^^|\uncatcodespecials| + +\csdisplay +\def\makeactive#1{\catcode`#1 = \active \ignorespaces}% +\chardef\letter = 11 \chardef\other = 12 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1 = \other}% + \dospecials}% Defined in plain. +| + +%In order to define `|^^M|' as an active character, you need to encase +%the definition in a group and invoke some extra machinery. +%\ttidxref{^^M} +%The \pix^|\letreturn| macro lets you define `|^^M|' without that +%extra machinery (which you can see in the definition below). +为了将 `|^^M|' 定义为活动字符,你需要将定义放在编组中,并借助某些额外机制。 +\ttidxref{^^M} +\pix^|\letreturn| 宏让你无需额外机制就可以定义 `|^^M|'(它的定义在下面可以看到)。 + +\csdisplay +{\makeactive\^^M \long\gdef\letreturn#1{\let^^M = #1}}% +| + +%These macros consume one, two, or three arguments. +这些宏用于吸收一个、两个或三个参量。 + +%\pix^^|\gobble| +%\pix^^|\gobbletwo| +%\pix^^|\gobblethree| +%\csdisplay +%\def\gobble#1{}\def\gobbletwo#1#2{}% +%\def\gobblethree#1#2#3{}% +%| +\pix^^|\gobble| +\pix^^|\gobbletwo| +\pix^^|\gobblethree| +\csdisplay +\def\gobble#1{}\def\gobbletwo#1#2{}% +\def\gobblethree#1#2#3{}% +| + +%Now we establish some conventions for reading the rest of the file. +%Within the file we allow ``private'' control sequences that contain +%`|@|' in their names. +%These control sequences aren't accessible outside of this file (unless +%you change the category code of `|@|' again). +%\xrdef{eplainconv} +现在我们建立一些惯例,用于读取这个文件的其他部分。 +在这个文件中我们允许名称带有 `|@|' 的``私有''控制序列。 +这些控制序列在这个文件之外无法使用(除非你再次修改 `|@|' 的类别码)。 +\xrdef{eplainconv} + +\csdisplay +\catcode`@ = \letter % Allow control sequences with @. +\let\@plainwlog = \wlog % Don't log register allocations. +\let\wlog = \gobble +\newlinechar = `^^J +| + +%The next two macros provide convenient forms of diagnostic output. +%\pix^|\loggingall| turns on all tracing, but causes the trace +%output to appear only in the log file and not at your terminal. +%\pix^|\tracingboxes| causes boxes to be displayed completely when +%they're traced. (\TeX\ normally shows only three levels of boxing +%and five items within each box.) +接下来两个宏提供了诊断输出的便捷方式。 +\pix^|\loggingall| 打开所有追踪, +但让追踪输出仅写在日志文件中,而不在终端上显示。 +\pix^|\tracingboxes| 使得盒子被追踪时其内容完全显示。% +(\TeX\ 通常只显示嵌套到三层的盒子,每个盒子显示五个项目。) + +\csdisplay +\def\loggingall{\tracingcommands\tw@\tracingstats\tw@ + \tracingpages\@ne\tracingoutput\@ne + \tracinglostchars\@ne\tracingmacros\tw@ + \tracingparagraphs\@ne\tracingrestores\@ne + \showboxbreadth\maxdimen\showboxdepth\maxdimen}% +\def\tracingboxes{\showboxbreadth = \maxdimen + \showboxdepth = \maxdimen}% +| + +%The default thickness of rules is $0.4$\pt. +%You can produce rules of any default thickness you choose by redefining +%|\vruledefaultwidth|, |\hruledefaultheight|, and |\hruledefaultdepth| +%and then using +%\pix^^|\ehrule| +%|\eh!-rule| +%and \pix^|\evrule| +%instead of |\hrule| and |\vrule|. (The `e' stands for +%``eplain''.) +%^^{rules//thickness of} +%If you give an explicit +%dimension (e.g., |\ehrule height 16pt|), \TeX\ will use it. +标线的默认厚度为 $0.4$\pt 。 +要生成默认厚度为任何值的标线, +你可以重新定义 |\vruledefaultwidth|、|\hruledefaultheight| 及 |\hrule!-defaultdepth|, +并将 |\hrule| 和 |\vrule| 换为 \pix^|\ehrule| 和 \pix^|\evrule|。% +(名称中的 `e' 代表 ``eplain''。)% +^^{标线//标线的厚度} +如果你显式给出尺寸(比如 |\ehrule height 16pt|),\TeX\ 将使用它。 + +\csdisplay +\newdimen\hruledefaultheight \hruledefaultheight = 0.4pt +\newdimen\hruledefaultdepth \hruledefaultdepth = 0.0pt +\newdimen\vruledefaultwidth \vruledefaultwidth = 0.4pt +\def\ehrule{\hrule height\hruledefaultheight + depth\hruledefaultdepth}% +\def\evrule{\vrule width\vruledefaultwidth}% +| + +%The |\%| convention for writing a `|%|' character doesn't work when you +%want to include that character in the token list of |\write|. +%^^|\write//writing \b\tt\%\e\ with| +%^^|%//writing out| +%You can use ^|\percentchar| to achieve this. +%We also redefine ^|^^L| to be nonouter so that you can use it in a +%macro definition or argument. +|\%| 通常用于写出 `|%|' 字符,但它无法包含在 |\write| 的记号列中。 +^^|\write//用它写出 \b\tt\%\e\| +%^^|%//写出该字符| +你可以用 ^|\percentchar| 达到此目的。 +我们还将 ^|^^L| 重新定义为非外部宏,因此你可以在宏定义或者参量中使用它。 + +\csdisplay +{\catcode`\% = \other \gdef\percentchar{%}}% + \def^^L{\par +}% +| + +%\pix^|\tokstostring| converts its argument into a list of ^{character +%tokens}. +%It uses only expansions that are handled in \TeX's gullet. +%This property is necessary +%for it to work with |\edef|. It is used by the cross-referencing +%macros (\xref{xrefs}). +\pix^|\tokstostring| 将它的参量转换为一列^{字符记号}。 +它仅用到在 \TeX\ 的食道中处理的展开。 +此特性是和 |\edef| 一起使用时所必需的。它用于宏的交叉引用(\xref{xrefs})。 + +%In order to split the argument up at spaces, we have to use two +%subsidiary macros. |\@ttsA| finds the spaces, and |\@ttsB| handles a +%token sequence without any spaces. Each space is replaced by the +%expansion of \pix^|\spacesub|. +为了将参量在空格处分开,我们要用到两个子宏。 +|\@ttsA| 用于寻找空格,而 |\@ttsB| 用于处理不带空格的控制序列。 +每个空格都被替换为 \pix^|\spacesub| 的展开。 + +\csdisplay +\def\tokstostring#1{\@ttsA#1 \ttsmarkA}% +\def\@ttsA#1 #2\ttsmarkA{\ifempty{#1}\else + \@ttsB #1\@ttsmarkB + \ifempty{#2}\else + \spacesub\@ttsA#2\ttsmarkA\fi\fi}% +\def\@ttsB#1{\ifx #1\@ttsmarkB\else + \string #1% + \expandafter\@ttsB\fi}% +\def\@ttsmarkB{\@ttsmarkB}% should never be expanded +\def\spacesub{+}% +| + +%\noindent +%\pix^|\ifempty| tests if its argument is empty. +\noindent +\pix^|\ifempty| 检测它的参量是否为空。 + +\csdisplay +\def\ifempty#1{\@ifempty #1\@emptymarkA\@emptymarkB}% +\def\@ifempty#1#2\@emptymarkB{\ifx #1\@emptymarkA}% +\def\@emptymarkA{\@emptymarkA}% +| + +%The ^|\for| macro implements a \TeX\ version of the ^{for loop} in +%traditional programming languages. These macros come directly from +%\LaTeX. +^|\for| 宏实现了其他传统编程语言中的^{for循环}的 \TeX\ 版本。 +这些宏直接取自 \LaTeX 。 + +\csdisplay +\def\for#1:=#2\do#3{\edef\@fortmp{#2}% + \ifx\@fortmp\empty \else + \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}\fi}% +\def\@nnil{\@nil}% +\def\@fornoop#1\@@#2#3{}% +\def\@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil + \else #5\def#4{#2} ifx #4\@nnil \else + #5\@iforloop #3\@@#4{#5}\fi\fi}% +\def\@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil + \let\@nextwhile=\@fornoop \else #4\relax + \let\@nextwhile=\@iforloop\fi + \@nextwhile#2\@@#3{#4}}% +| + +%\pix^|\obeywhitespace| is useful for reproducing line breaks, blank lines, +%and spaces in your input. It combines the effects of |\obey!-lines| and +%|\obey!-spaces|, +%^^|\obeylines| ^^|\obeyspaces| +%and also causes spaces at the start of a line to +%be printed. Tab characters are not affected by this; they still produce +%normal glue. +%\xrdef{ewhitesp} +%^^{space characters} +%^^|\fontdimen| +%^^|\font| +%^^|\letreturn| +\pix^|\obeywhitespace| 用于重新生成你的输入中的换行、空行和空格。 +它结合了|\obey!-lines| 和 |\obey!-spaces| 的效果, +^^|\obeylines| ^^|\obeyspaces| +并把行首的空格也打印出来。制表符不受它影响;它们仍然生成正常的粘连。 +\xrdef{ewhitesp} +^^{空格符} +^^|\fontdimen| +^^|\font| +^^|\letreturn| + +\csdisplay +\def\alwaysspace{\hglue\fontdimen2\the\font \relax}% +{\makeactive\^^M \makeactive\ % +\gdef\obeywhitespace{% +\makeactive\^^M\def^^M{\par\indent}% +\aftergroup\@removebox% Kill extra paragraph at end. +\makeactive\ \let =\alwaysspace}}% +\def\@removebox{\setbox0=\lastbox} +| + +%\pix^|\frac| is a good way to print fractions in text when you don't +%want to use |\over| and +%``1/2'' just doesn't look right. This macro is the answer to +%\knuth{Exercise~11.6}.^^{fractions//slashed form} +当你不想用 |\over|,而 ``1/2'' 看来又不够好时, +你最好用 \pix^|\frac| 在正文中打印分式。 +这个宏是\knuth{练习~11.6}的答案。^^{分式//斜线形式} + +\csdisplay +\def\frac#1/#2{\leavevmode + \kern.1em \raise .5ex \hbox{\the\scriptfont0 #1}% + \kern-.1em $/$% + \kern-.15em \lower .25ex \hbox{\the\scriptfont0 #2}}% +| + +%The following macros produce logos that are useful in the \TeX\ world. +%The \AMSTeX\ logo is from \knuth{page~420}. The \LaTeX\ logo is +%slightly modified from the one in |latex.tex| (we use a different font +%for the `A'); similarly, the \BibTeX\ logo uses |\sevenrm| instead of a +%true caps-and-small-caps font. The |.mf| source file for the \MF\ logo +%is given in the \MF\ manual: +%\smallskip +%{\narrower\noindent +%^{Knuth, Donald E.},{\sl The {\logosl METAFONT}book}. +% Reading, Mass.: Addison-Wesley, 1986.\par} +%\smallskip +%\pix^^|\LaTeX| +%\pix^^|\AMSTeX| +%\pix^^|\BibTeX| +%\pix^^|\MF| +下面这些宏生成 \TeX\ 圈中常用的标识。 +\AMSTeX\ 标识取自 \knuth{第~420~页}。 +\LaTeX\ 标识取自 |latex.tex| 并稍作修改(我们修改了 `A' 的字体); +类似地,\BibTeX\ 标识用 |\sevenrm| 字体代替真正的小型大写字体。 +\MF\ 标识的 |.mf| 源文件出现在 \MF\ 手册中: +\smallskip +{\narrower\noindent +^{Knuth, Donald E.},{\sl The {\logosl METAFONT}book}. + Reading, Mass.: Addison-Wesley, 1986.\par} +\smallskip +\pix^^|\LaTeX| +\pix^^|\AMSTeX| +\pix^^|\BibTeX| +\pix^^|\MF| + +\csdisplay +\def\LaTeX{L\kern-.26em \raise.6ex\hbox{\fiverm A}% + \kern-.15em TeX}% +\def\AMSTeX{$\cal A\kern-.1667em \lower.5ex\hbox{$\cal M$}% + \kern-.125em S$-\TeX}% +\def\BibTeX{{\rm B\kern-.05em {\sevenrm I\kern-.025em B}% + \kern-.08em T\kern-.1667em \lower.7ex\hbox{E}% + \kern-.125emX}}% +\font\mflogo = logo10 +\def\MF{{\mflogo META}{\tenrm \-}{\mflogo FONT}}% +| + +%The next two macros produce boxes. \pix^|\blackbox| produces a ``square +%bullet'', used in the list macros (\xref{listmacs}). +%\pix^|\makeblankbox| (from \knuth{page~311}) produces an unfilled +%rectangle, with the thickness of the border rules given by the +%arguments. +接下来的两个宏用于生成盒子。 +\pix^|\blackbox| 生成一个方块,它用在列表宏中(\xref{listmacs})。 +\pix^|\makeblankbox|(取自\knuth{第~311~页})生成一个空心矩形, +它的边框厚度由参量指定。 + +\csdisplay +\def\blackbox{\vrule height .8ex width .6ex depth -.2ex}% +\def\makeblankbox#1#2{% + \hbox{\lower\dp0\vbox{\hidehrule{#1}{#2}% + \kern -#1% overlap rules + \hbox to \wd0{\hidevrule{#1}{#2}% + \raise\ht0\vbox to #1{}% vrule height + \lower\dp0\vtop to #1{}% vrule depth + \hfil\hidevrule{#2}{#1}}% + \kern-#1\hidehrule{#2}{#1}}}}% +\def\hidehrule#1#2{\kern-#1\hrule height#1 depth#2 + \kern-#2}% +\def\hidevrule#1#2{\kern-#1{\dimen0 = #1 + \advance\dimen0 by #2 \vrule width\dimen0}\kern-#2}% +| + +%\pix^|\numbername| produces the written-out form of a number. (If the +%number is greater than ten, the macro just reproduces the numerals +%of its argument.) +\pix^|\numbername| 从数字生成其书面名称% +(若数字大于十,这个宏仅重新生成参量的数值。) + +\csdisplay +\def\numbername#1{\ifcase#1% + zero\or one\or two\or three\or four\or five% + \or six\or seven\or eight\or nine\or ten\or #1\fi}% +| + +%\pix^|\testfileexistence| determines whether a file |\jobname.#1| is +%non\-empty and sets |\if!-fileexists| appropriately. +%^^{files//testing for existence of} +%The file name in the argument need not end in a space token since +%the macro provides the space token. +\pix^|\testfileexistence| 判定文件 |\jobname.#1| 是否非空, +并相应地设定 |\if!-fileexists| 的值。 +^^{文件//检测文件是否存在} +参量中的文件名无需以空格记号结尾,因为这个宏已经提供了空格记号。 + +\csdisplay +\newif\iffileexists +\def\testfileexistence#1{\begingroup + \immediate\openin0 = \jobname.#1\space + \ifeof 0\global\fileexistsfalse + \else \global\fileexiststrue\fi + \immediate\closein0 + \endgroup}% +| + + +%\section Displays +\section 陈列公式 + +%By default, \TeX\ centers displayed material (the material between +%|$$|'s). ^^{displays, formatting} \pix^|\leftdisplays| causes displays +%to be left-justified by default. You can return to centered displays +%with \pix^|\centereddisplays|. +\TeX\ 默认将陈列公式(放在 |$$| 之间的公式)居中显示。 +^^{陈列公式//显示形式}\pix^|\leftdisplays| 让陈列公式默认为左对齐显示。 +你也可以用 \pix^|\centereddisplays| 命令恢复居中显示。 + +%The macros here are more general than they need to be just for doing +%left-justified displays. For every display, +%\pix^|\ifeqno| will be true if an |\eqno| occurred in the display. +%\pix^|\ifleqno| will be true if an |\leqno| occurred. If either +%kind of equation number occurred, \pix^|\eqn| produces the text of the +%equation number. \pix^|\eq| always produces the text of the +%equation itself. +这些宏提供让陈列公式左对齐显示之外的更多功能。 +对每个陈列公式,若 |\eqno| 存在则 \pix^|\ifeqno| 为真, +若 |\leqno| 存在则 \pix^|\ifleqno| 为真。 +如果其中一种公式编号存在,\pix^|\eqn| 将排印公式编号的内容。 +而 \pix^|\eq| 始终排印公式本身的内容。 + +%These macros are based on the code on \knuth{page~376}. +这些宏基于\knuth{第~376~页}中的代码。 + +\csdisplay +\newif\ifeqno \newif\ifleqno +\newtoks\@eqtoks \newtoks\@eqnotoks +\def\eq{\the\@eqtoks}\def\eqn{\the\@eqnotoks}% +\def\displaysetup#1$${% + \@displaytest#1\eqno\eqno\@displaytest}% +\def\@displaytest#1\eqno#2\eqno#3\@displaytest{% + \if !#3!% No \eqno, check for \leqno: + \@ldisplaytest#1\leqno\leqno\@ldisplaytest + \else + \eqnotrue \leqnofalse % Have \eqno, not \leqno. + \@eqnotoks = {#2}\@eqtoks = {#1}% + \fi + \generaldisplay$$}% +\def\@ldisplaytest#1\leqno#2\leqno#3\@ldisplaytest{% + \@eqtoks = {#1}% + \if !#3!% + \eqnofalse % No \leqno; we're done. + \else + \eqnotrue \leqnotrue % Have \leqno. + \@eqnotoks = {#2}% + \fi}% +| + +%You can format displays differently by defining your own macro, +%analogous to \pix^|\leftdisplays|. +%The macro definition must +%place a call on |\display!-setup| in |\every!-display| ^^|\everydisplay| +%so as to ensure +%that |\dis!-play!-setup| ^^|\displaysetup| is called at the start of +%every display. The macro definition must also include a definition of +%^|\generaldisplay|. +通过自己定义类似 \pix^|\leftdisplays| 的宏,你可以给陈列公式设定不同的形式。 +这个宏定义中必须在 |\every!-display| ^^|\everydisplay|中调用 |\display!-setup|, +以确保 |\dis!-play!-setup| ^^|\displaysetup|在每个陈列公式开始都被调用。 +这个宏定义必须也包含 ^|\generaldisplay| 的定义。 + +\csdisplay +\newtoks\previouseverydisplay +\def\leftdisplays{% + \previouseverydisplay = \everydisplay + \everydisplay = + {\the\previouseverydisplay \displaysetup}% + \def\generaldisplay{% + \leftline{% + \strut \indent \hskip\leftskip + \dimen0 = \parindent + \advance\dimen0 by \leftskip + \advance\displaywidth by -\dimen0 + \@redefinealignmentdisplays + \ifeqno \ifleqno + \kern-\dimen0 + \rlap{$\displaystyle\eqn$}% + \kern\dimen0 + \fi\fi + $\displaystyle{\eq}$% + \ifeqno \ifleqno\else + \hfill $\displaystyle{\eqn}$% + \fi\fi}}}% +\def\centereddisplays{\let\displaysetup = \relax}% +| + +%\filbreak +%\pix^|\leftdisplays| must go to some pains to make sure that +%|\dis!-play!-lines|, ^^|\displaylines| +%^|\eqalignno|, and ^|\leqalignno| still work properly. +%|\eq| is typeset in math mode, +%and |\halign| is illegal in math mode. +%^^|\halign//illegal in math mode| +%We use ^|\vcenter| to change the context so that |\halign| becomes +%legal again. We also remove the |\hfil| commands at the left of the template +%to obtain the flush left formatting. Other than those changes, the macros +%are the same as in |plain.tex|. +%\filbreak +\pix^|\leftdisplays| 必须历经辛苦地确保 |\dis!-play!-lines|^^|\displaylines|、 +^|\eqalignno| 和 ^|\leqalignno| 还能正常使用。 +|\eq| 在数学模式中排版,而 |\halign| 在数学模式中是不合法的。 +^^|\halign//在数学模式中不合法| +我们用 ^|\vcenter| 改变环境,以让 |\halign| 重新变成合法的。 +我们还去掉模板左边的 |\hfil| 命令以得到左对齐格式。 +除这些改变之外,这些宏与 |plain.tex| 中的相同。 + +\csdisplay +\def\@redefinealignmentdisplays{% + \def\displaylines##1{\displ@y + \vcenter{\halign{\hbox to\displaywidth{$\@lign + \displaystyle####\hfil$}\crcr##1\crcr}}}% + \def\eqalignno##1{\displ@y + \vcenter{\halign to\displaywidth{% + $\@lign\displaystyle{####}$\tabskip\z@skip + &$\@lign\displaystyle{{}####}$ + \hfil\tabskip\centering + &\llap{$\@lign####$}\tabskip\z@skip\crcr + ##1\crcr}}}% + \def\leqalignno##1{\displ@y + \vcenter{\halign to\displaywidth{% + $\@lign\displaystyle{####}$\tabskip\z@skip + &$\@lign\displaystyle{{}####} + $\hfil\tabskip\centering + &\kern-\displaywidth + \rlap{\kern-\parindent\kern-\leftskip$ + \@lign####$}% + \tabskip\displaywidth\crcr + ##1\crcr}}}}% +| + + +%\section Time of day +\section 日期时间 + +%When \TeX\ starts up, it sets the values of the +%^|\time|, ^|\day|, ^|\month|, and ^|\year| parameters. +%^^{time of day}^^{date} +%\pix^|\monthname| +%produces the name of the month, abbreviated to three letters. +%\pix^|\timestring| produces the current time, as in ``1:14\thinspace +%p.m.''. \pix^|\timestamp| produces the text of the complete date, as +%in ``23 Apr 1964\quad 1:14\thinspace p.m.''. +\TeX\ 开始运行时设定了 ^|\time|、^|\day|、^|\month| 和 ^|\year| 参数的值。 +^^{日期时间}^^{日期} +\pix^|\monthname| 排印月份名称的三字母缩写。 +\pix^|\timestring| 排印类似当前时间,类似于 ``1:14\thinspace p.m.''。 +\pix^|\timestamp| 排印完整日期文本,类似于 ``23 Apr 1964\quad 1:14\thinspace p.m.''。 + +\csdisplay +\def\monthname{% + \ifcase\month + \or Jan\or Feb\or Mar\or Apr\or May\or Jun% + \or Jul\or Aug\or Sep\or Oct\or Nov\or Dec% + \fi}% +\def\timestring{\begingroup + \count0 = \time \divide\count0 by 60 + \count2 = \count0 % The hour. + \count4 = \time \multiply\count0 by 60 + \advance\count4 by -\count0 % The minute. + \ifnum\count4<10 \toks1 = {0}% Get a leading zero. + \else \toks1 = {}% + \fi + \ifnum\count2<12 \toks0 = {a.m.}% + \else \toks0 = {p.m.}% + \advance\count2 by -12 + \fi + \ifnum\count2=0 \count2 = 12 \fi % Make midnight `12'. + \number\count2:\the\toks1 \number\count4 + \thinspace \the\toks0 +\endgroup}% +\def\timestamp{\number\day\space\monthname\space + \number\year\quad\timestring}% +| + + +%\section Lists +\section 列表 + +%\null +%\xrdef{listmacs} +%\bix^^{itemized lists} +%\bix^^{enumerations} +%\pix^|\numberedlist| produces numbered lists; |\endnumberedlist| ends +%them. +%\pix^|\unorderedlist| is analogous. +%For either of these, items inside the lists begin +%with \pix^|\li| (``list item''). You can put \pix^|\listcompact| +%at the beginning of a list if +%you don't want any additional space between the items of that list. +%Lists can be nested arbitrarily. +\null +\xrdef{listmacs} +\bix^^{编号列表} +\bix^^{列举} +\pix^|\numberedlist| 排印编号列表;|\endnumberedlist| 结束该列表。 +类似地,\pix^|\unorderedlist| 排印无序列表。 +这两种列表中的项目以 \pix^|\li|(``list item'')开头。 +如果不需要列表项目间的额外间隔,你可以在列表开始处加上 \pix^|\listcompact|。 +列表可以任意嵌套。 + +%You can control the spacing between the items more generally by +%assigning values to the registers listed below. If the items in +%your lists tend to be long, you might want to make |\interitemskip| +%nonzero. +%The left indentation of each list item is given by |\par!-indent| plus +%|\list!-left!-indent|; the right indentation of each list item +%is given by |\list!-right!-indent|. +更一般地,你可以通过改变下列寄存器的值控制列表项目间的间隔。 +如果列表项目经常比较长,你也许希望设定非零的 |\interitemskip|。 +各列表项目的左缩进量等于 |\par!-indent| 加 |\list!-left!-indent|; +各列表项目的右缩进量等于 |\list!-right!-indent|。 + +\csdisplay +\newskip\abovelistskip \abovelistskip = .5\baselineskip +\newskip\interitemskip \interitemskip = 0pt +\newskip\belowlistskip \belowlistskip = .5\baselineskip +\newdimen\listleftindent \listleftindent = \parindent +\newdimen\listrightindent \listrightindent = 0pt +\def\listcompact{\interitemskip = 0pt \relax}% +| + +%Both numbered and unnumbered lists use the macros that follow. +%We don't change |\parindent|, since many existing macros, e.g., +%|\footnote|, depend on |\parindent|. +%We must account for the +%possibility that items are more than one paragraph long. In this case, all +%paragraphs after the first will be indented. +%We use +%|\leftskip| and |\rightskip| to indent the list items. +%Indentation of displays is accounted for by changes to |\every!-dis!-play|. +%^^|\everydisplay| +编号列表和无序列表都使用下面这些宏。 +我们并不改变 |\parindent| 的值, +因为很多现有的宏比如 |\footnote| 依赖于 |\parindent|。 +我们必须考虑到项目包含不止一个段落的可能性。 +在这种情形中,除第一个之外的所有段落都将被缩进。 +我们用 |\leftskip| 和 |\rightskip| 缩进列表项目。 +我们通过改变 |\every!-dis!-play| 设定陈列公式的缩进。 +^^|\everydisplay| + +\csdisplay +\newdimen\@listindent +\def\beginlist{% + \@listindent = \parindent + \advance\@listindent by \listleftindent + \everydisplay = \expandafter{\the\everydisplay + % Don't lose user's \everydisplay: + \advance\displayindent by \@listindent + \advance\displaywidth by -\@listindent + \advance\displaywidth by -\listrightindent}% + \nobreak\vskip\abovelistskip + \parskip = 0pt + % \leftskip shifts nested lists to the right on the page. + \advance\leftskip by \@listindent + \advance\rightskip by \listrightindent}% +\def\printitem{\par\noindent + \llap{\hskip-\listleftindent \marker \enspace}}% +\def\endlist{\vskip\belowlistskip}% +| + +%\noindent +%You can change the way the item labels are typeset by +%redefining the |\numbered!-marker| macro. +%\pix^^|\numberedmarker| +\noindent +通常重新定义 |\numbered!-marker| 宏,你可以改变项目标签的样式。 +\pix^^|\numberedmarker| + +\csdisplay +\newcount\numberedlistdepth \newcount\itemnumber +\newcount\itemletter +\def\numberedmarker{% + \ifcase\numberedlistdepth + (impossible)% + \or \itemnumberout)% + \or \itemletterout)% + \else *% + \fi}% +| + +%\noindent Here are the definitions of |\numberedlist| and +%|\unorderedlist|. +%Both definitions have the same structure. +\noindent 这里是 |\numberedlist| 和 |\unorderedlist| 的定义。 +这两个定义的结构是相同的。 + +\csdisplay +\def\numberedlist{\environment{@numbered-list}% + \advance\numberedlistdepth by 1 + \itemnumber = 1 \itemletter = `a + \beginlist \let\marker = \numberedmarker + \def\li{% + \ifnum\itemnumber=1\else \vskip\interitemskip \fi + \printitem + \advance\itemnumber by 1 \advance\itemletter by 1 + }}% +\def\itemnumberout{\number\itemnumber}% +\def\itemletterout{\char\itemletter}% +\def\endnumberedlist{\par + \endenvironment{@numbered-list}\endlist}% +!bigskip +\newcount\unorderedlistdepth +\def\unorderedmarker{% + \ifcase\unorderedlistdepth + (impossible)% + \or \blackbox + \or ---% + \else *% + \fi}% +\def\unorderedlist{\environment{@unordered-list}% + \advance\unorderedlistdepth by 1 + \beginlist \itemnumber = 1 + \let\marker = \unorderedmarker + \def\li{% + \ifnum\itemnumber=1\else \vskip\interitemskip \fi + \printitem \advance\itemnumber by 1 + }}% +\def\endunorderedlist{\par + \endenvironment{@unordered-list}\endlist}% +| + +%\eix^^{itemized lists} +%\eix^^{enumerations} +\eix^^{编号列表} +\eix^^{列举} + + +%\section Verbatim listing +\section 原文呈现 + +%The \pix^|\listing| macro produces a verbatim listing of a specified +%file in the |\tt| font. +%It is based on the code on \knuth{page~380}. +%Tabs produce a fixed amount of space, and form +%feeds produce a page break. Other control characters produce whatever +%happens to be at that font position, which is generally not very useful. +%By redefining |\setup!-listing!-hook|, +%\pix^^|\setuplistinghook| +%you can take additional actions that are appropriate for your particular +%fonts and\slash or environment before the file is read in. +\pix^|\listing| 宏用 |\tt| 字体排印指定文件的原文呈现。 +它基于\knuth{第~380~页}中的代码。 +制表符生成固定大小的间隔,而换页符生成一个分页。 +其他控制字符生成该字体所在位置的字符,这通常不太有用。 +通过重新定义 |\setup!-listing!-hook|\pix^^|\setuplistinghook|, +你可以在读入文件前针对特别字体和\slash 或使用环境作额外定制。 + +\csdisplay +\def\listing#1{% + \par \begingroup \@setuplisting \setuplistinghook + \input #1 \endgroup}% +\let\setuplistinghook = \empty +\def\@setuplisting{% + \uncatcodespecials + \obeywhitespace \makeactive\` \makeactive\^^I + \def^^L{\vfill\eject}\tt}% +{\makeactive\` \gdef`{\relax\lq}}% Defeat ligatures. +{\makeactive\^^I\gdef^^I{\hskip8\fontdimen2\tt \relax}}% +| + + +%\section Tables of contents +\section 目录 + +%\null ^^{table of contents} +%The macro \pix^|\writetocentry| writes a macro call to the file +%|\jobname.toc|. The first argument of |\writetocentry|, e.g., +%``chapter'', is used to compose the name of the called macro. The second +%argument is the text to appear in the table of contents entry. +%|\writetocentry| appends the page number to the macro call. For +%example: +\null ^^{目录} +\pix^|\writetocentry| 宏在 |\jobname.toc| 文件中写入一个宏调用。 +|\write!-tocentry| 的第一个参量,比如``chapter'',用于构成所调用的宏的名称。 +第二个参量是显示在目录项中的文本。 +|\writetocentry| 添加页码到宏调用中。例如: +\csdisplay +\writetocentry{chapter}{Introduction} +| +%\noindent +%will produce the line: +\noindent +将生成下列这行: +\csdisplay +\tocchapterentry{Introduction}{2} +| +%\noindent in the |.toc| file, indicating +%that `Introduction' started on page 2. +\noindent 到 |.toc| 文件中,表示 `Introduction' 从第2页开始。 + +%You can use |\writenumberedtocentry| to provide a third parameter, such +%as a chapter number. For example: +利用 |\writenumberedtocentry| 你还可以提供第三个参数,比如章编号。例如: +\csdisplay +\writenumberedtocentry{chapter}{The second chapter}{2} +| +%\noindent will write a line: +\noindent 将写入这一行: +\csdisplay +\tocchapterentry{The second chapter}{2}{14} +| +%\noindent +%You can also |\write| to |\tocfile| yourself. +\noindent +你也可以自己用 |\write| 命令写入 |\tocfile|。% +\footnote{译注:原文的代码中遗漏 |\writetocentry| 的定义, +而将 |\writenumberedtocentry| 的定义重复写了两遍,译文已修正此问题。 +实际上,在本书所用的 |eplain.tex| 1.9 中, +|\writetocentry| 调用 |\writenumberedtocentry|, +并在后者中根据第三个参数是否非空写入不同的目录项。 +但在 |\writenumberedtocentry| 的定义中有问题, +导致写入 |tocfile| 文件的目录项始终有三个参数。 +在翻译时译者也同时修正 |eplain.tex| 中的这个错误。} + +\csdisplay +\newwrite\tocfile \newif\iftocfileopened +\def\opentocfile{\iftocfileopened\else + \tocfileopenedtrue + \immediate\openout\tocfile = \jobname.toc +\fi}% +\def\writetocentry#1#2{\ifrewritetocfile + \opentocfile + \write\tocfile{% + \expandafter\noexpand \csname toc#1entry\endcsname + {#2}{\folio}}% +\ignorespaces\fi}% +\def\writenumberedtocentry#1#2#3{\ifrewritetocfile + \opentocfile + \write\tocfile{% + \expandafter\noexpand \csname toc#1entry\endcsname + {#2}{#3}{\folio}}% +\ignorespaces\fi}% +| + +%To produce a table of contents, read the |.toc| file with +%\pix^|\readtocfile|. You should call |\read!-tocfile| before the first +%|\write!-toc!-entry|. When you're processing the table of contents +%without regenerating it, you should not rewrite +%the |.toc| file---if you do, its contents will be lost. +%The command +%|\rewrite!-tocfile!-false| will prevent the rewrite. +要排印出目录,只需用 \pix^|\readtocfile| 读取 |.toc| 文件。 +你应该在首次使用 |\write!-toc!-entry| 之前调用 |\read!-tocfile|。 +在处理目录且不想重新生成它时, +务必不要改写 |.toc| 文件——如果你这样做,文件内容将会丢失。 +命令 |\rewrite!-tocfile!-false| 将禁止这种改写。 + +\csdisplay +\newif\ifrewritetocfile \rewritetocfiletrue +\def\readtocfile{\testfileexistence{toc}% + \iffileexists + \input \jobname.toc + \ifrewritetocfile \opentocfile \fi + \fi}% +| + +%Here are some definitions of possible |\toc|\dots|entry| macros. These +%definitions are meant only as examples---running leaders across the line +%is usually not the best way to typeset a table of contents. +这里给出可能出现的 |\toc|\dots|entry| 宏的一些定义。 +这些定义只是作为例子而已——在目录中使用指引线通常不是最好的做法。 + +\csdisplay +\def\tocchapterentry#1#2{\line{\bf #1 \dotfill\ #2}}% +\def\tocsectionentry#1#2{% + \line{\quad\sl #1 \dotfill\ \rm #2}}% +\def\tocsubsectionentry#1#2{% + \line{\qquad\rm #1 \dotfill\ #2}}% +| + + +%\section Cross-references +\section 交叉引用 + +%\null ^^{cross-references} +%\xrdef{xrefs} +%The macros that follow provide symbolic +%cross-referencing, so that you can refer to something in another part of +%a document by name instead of by its actual page number. +%\pix^|\xrdef||{foo}| defines a label |foo| to be the current page +%number, and \pix^|\xrefn||{foo}| produces that page number, e.g., $77$. +%More often you'll want to say something like ``see p.\thinspace77'', so +%\pix^|\xref||{foo}| produces ``p.\thinspace 77''. If |foo| is not +%defined, a warning message will be given. |\xrefwarningfalse| +%suppresses the warning. +\null ^^{交叉引用} +\xrdef{xrefs} +接下来的宏提供了符号式的交叉引用, +让你可以在文档中通过名称而非实际页码提及其它部分的东西。 +\pix^|\xrdef||{foo}| 定义标签 |foo| 为当前页码, +而 \pix^|\xrefn||{foo}| 生成该页码,比如 $77$。 +你更常用的是类似 ``see p.\thinspace77'' 的写法, +因此 \pix^|\xref||{foo}| 生成 ``p.\thinspace 77''。 +如果 |foo| 未定义,就会得到一个警告信息。 +|\xrefwarningfalse| 取消这种警告。 + +%These macros provide no protection against duplicate definitions. You can +%check for duplicate definitions by sorting the cross-reference file and +%checking, either mechanically or by eye, for adjacent definitions of +%the same symbol. +这些宏没有提供对重复定义的保护。要检查重复定义, +你可以将交叉引用文件排序,并用工具或肉眼检查同一个符号的相邻定义。 + +\csdisplay +\newif\ifxrefwarning \xrefwarningtrue +\def\xrdef#1{\begingroup + \xrlabel{#1}% + \edef\@wr{\@writexrdef{\the\@xrlabeltoks}}% + \@wr + \endgroup \ignorespaces}% +\def\@writexrdef#1{\write\reffile{% + \string\gdef + \expandafter\string\csname#1\endcsname + {\noexpand\folio}\percentchar}}% +\def\xrefnumber#1{% + \xrlabel{#1}% + % \@xrlabeltoks now has the control sequence name. + \toks0 = + \expandafter{\csname\the\@xrlabeltoks\endcsname}% + \expandafter \ifx\the\toks0\relax + \ifxrefwarning \message{Undefined label + `\tokstostring{#1}'.}\fi + {\let\spacesub = \space + \expandafter\xdef\the\toks0 + {`{\tt \tokstostring{#1}}'}}\fi + \the\toks0}% +\def\xref#1{p.\thinspace\xrefnumber{#1}}% +\def\xrefn#1{\xrefnumber{#1}}% +| + +%This macro turns a label into a list of character tokens in the token +%register |\labeltoks|. A label can include blanks and control sequences in +%it as well as normal characters, but it can't include braces. +这个宏将一个标签转换为一列字符记号,并放在寄存器 |\labeltoks| 中。 +除了普通字符之外,标签还可以包含空格和控制序列,但不能包含花括号。 + +\csdisplay +\newtoks\@xrlabeltoks +\def\xrlabel#1{\begingroup + \escapechar = `\_ \edef\tts{\tokstostring{#1_}}% + \global\@xrlabeltoks = \expandafter{\tts}% + \endgroup}% +| + +%It takes two passes to get the cross-references right, since the +%definitions are written out to the auxiliary file |\jobname.aux|. +%\pix^|\readreffile| reads them back in. If you don't issue this command +%before the first definition, you'll lose all the definitions from the +%previous run. +需要运行两遍才能得到正确的交叉引用, +因为这些定义是写出到辅助文件|\jobname.aux| 里的。 +\pix^|\readreffile| 命令用于将它们读取回来。 +如果你不在第一个定义之前执行此命令,你将丢失上一遍运行得到的定义。 + +\csdisplay +\newwrite\reffile \newif\ifreffileopened +\def\openreffile{\ifreffileopened\else + \reffileopenedtrue + \immediate\openout\reffile = \jobname.aux + \fi}% +\def\readreffile{% + \testfileexistence{aux}% + \iffileexists + \begingroup + \@setletters + \input \jobname.aux + \endgroup + \else + \message{No cross-reference file; I won't give you + warnings about undefined labels.}% + \xrefwarningfalse + \fi + \openreffile}% +\def\@setletters{% + \catcode`_ = \letter \catcode`+ = \letter + \catcode`- = \letter \catcode`@ = \letter + \catcode`0 = \letter \catcode`1 = \letter + \catcode`2 = \letter \catcode`3 = \letter + \catcode`4 = \letter \catcode`5 = \letter + \catcode`6 = \letter \catcode`7 = \letter + \catcode`8 = \letter \catcode`9 = \letter + \catcode`( = \letter \catcode`) = \letter}% +| + +%^^{equations, labelling} +%You can give symbolic names to equations in a similar way, using +%\pix^|\eqdef| and \pix^|\eqref|. |\eqdef| inserts its own |\eqno| +%command, so it must be invoked in a place where |\eqno| is legal. +^^{公式编号} +按同样的方式,你可以用 \pix^|\eqdef| 和 \pix^|\eqref| 给出公式的符号式名称。 +|\eqdef| 插入自己的 |\eqno| 命令,因此它必须用在能用 |\eqno| 的地方。 + +\csdisplay +\newcount\eqnumber +\def\eqdef#1{\global\advance\eqnumber by 1 + \expandafter\xdef + \csname#1eqref\endcsname{\the\eqnumber}% + \immediate\write\reffile{\string\def + \expandafter\string\csname#1eqref\endcsname + {\the\eqnumber}}% + \eqno + \eqprint{\the\eqnumber}}% +| + +%|\eqref| produces ``(equation number)''. You can handle fancier +%formatting by redefining \pix^|\eqprint|. For example, you could redefine +%it so that the equation numbers include +%the chapter number. +|\eqref| 生成``(公式编号)''。 +通过重新定义 \pix^|\eqprint|,你可以实现更加复杂的格式。 +举个例子,你可以重新定义它,使得公式编号中包含章编号。 + +\csdisplay +\def\eqref#1{% + \expandafter \ifx \csname#1eqref\endcsname \relax + \ifxrefwarning \message{Undefined equation label + `#1'.}\fi + \expandafter\def\csname#1eqref\endcsname{00}% + \else \eqprint{\csname#1eqref\endcsname}% + \fi}% +\def\eqprint#1{(#1)}% +| + + +%\section Environments +\section 环境 + +%\null ^^{environments} These macros let you define your own named groups +%(environments) for parts of your manuscript. Like \TeX\ groups, these +%groups can be nested, and in fact their nesting can be intertwined with +%the nesting of \TeX\ groups. If the names at the beginning and end of +%an environment don't match, you'll get an error message. The macros are +%designed so that the message you get when such an error occurs will give +%you a good chance of localizing the cause of the error easily. +\null ^^{环境}这些宏让你可以将手稿的一部分定义为命名编组(环境)。 +类似 \TeX\ 的编组,这些编组也可以嵌套, +而且实际上它们的嵌套可以与 \TeX\ 编组的嵌套相互交织。 +如果开始的名称和结束的名称不匹配,你将得到一个错误信息。 +这些宏如此设计,使得当你得到这种错误信息时,你有机会方便地定位错误的来源。 + +%You begin an environment with +%\pix^^|\environment| +%|\envi!-ron!-ment| |{foo}| and end it with |\endenvironment{foo}|, where +%|foo| is the name of the environment. Our macros slightly improve on +%the answer to Exercise~5.7 of \texbook, by doing some checks on +%|\begingroup| and |\endgroup| pairs, as well as making sure +%|\environment| and |\endenvironment| pairs match. +用 \pix^^|\environment||\envi!-ron!-ment| |{foo}| 开始一个环境, +用 |\endenvironment{foo}| 结束该环境,其中 |foo| 是该环境的名称。 +我们的宏稍微改进了 \texbook\ 练习~5.7, +添加对 |\begingroup| 和 |\endgroup| 是否配对的检查, +并确保 |\environment| 和 |\endenvironment| 能够匹配。 + +\csdisplay +\def\environment#1{\ifx\@groupname\undefined\else + \errhelp = \@unnamedendgrouphelp + \errmessage{`\@groupname' was not closed by + \string\endenvironment}\fi + \def\@groupname{#1}% + \begingroup + \let\@groupname = \undefined \ignorespaces}% +\def\endenvironment#1{\endgroup + \def\@thearg{#1}% + \ifx\@groupname\@thearg + \else + \ifx\@groupname\undefined + \errhelp = \@isolatedendenvironmenthelp + \errmessage{Isolated + \string\endenvironment\space for `#1'}% + \else + \errhelp = \@mismatchedenvironmenthelp + \errmessage{Environment `#1' ended, + but `\@groupname' started}% + \endgroup % Probably a typo in the names. + \fi + \fi + \let\@groupname = \undefined \ignorespaces}% +| + +%We also define help messages for each of the errors above. +%^^|\newhelp| +你也可以给上述这些错误定义它们各自的帮助信息。 +^^|\newhelp| + +\csdisplay +\newhelp\@unnamedendgrouphelp{% + Most likely, you just forgot an^^J% + \string\endenvironment. + Maybe you should try inserting another^^J% + \string\endgroup to recover.}% +\newhelp\@isolatedendenvironmenthelp{% + You ended an environment X, but^^J% + no \string\environment\space to start it + is anywhere in sight.^^J% + You might also be at an + \string\endenvironment\space that would match^^J% + a \string\begingroup, i.e., you forgot an + \string\endgroup.}% +\newhelp\@mismatchedenvironmenthelp{% + You started an environment X, but^^J% + you ended it with Y. Maybe you made a typo + in one or the other^^J% + of the names.}% +| + +%Some environments should not be allowed to occur within +%another environment. Let's call these environments +%``outer environments''. |\check!-env| checks that no outer environment +%is currently in effect and complains if one is. To use |\check!-env|, you +%must issue the command |\environment!-true| at the beginning of every +%outer environment. +某些环境应当不允许出现在其他环境内部。我们称这些环境为``外部环境''。 +|\check!-env| 检测是否不存在当前有效的外部环境,若存在的话给出警告信息。 +要使用 |\checkenv|,你必须在每个外部环境开头处执行 |\environment!-true| 命令。 + +\csdisplay +\newif\ifenvironment +\def\checkenv{% + \ifenvironment + \errhelp = \@interwovenenvhelp + \errmessage{Interwoven environments}% + \endgroup + \fi}% +\newhelp\@interwovenenvhelp{% + Perhaps you forgot to end the previous^^J% + environment? I'm finishing off the current group,^^J% + hoping that will fix it.}% +| + + +%\section Justification +\section 对齐 + +%\bix^^{flush left} +%\bix^^{flush right} +%\bix^^{centered text} +%The three macros \pix^|\flushleft|, \pix^|\flushright|, and +%\xrdef{eplaincenter} +%\pix^|\center| justify the text on the following lines in the indicated way. +%The command should appear on a line by itself. +%Both the command and the text should be enclosed in a group---% +%the end of the group indicates the end of the text. +%The entire group is set as a single paragraph, with lines filled out +%on one side or another as appropriate. Blank lines are reproduced. +\bix^^{居左对齐} +\bix^^{居右对齐} +\bix^^{居中文本} +这三个宏 \pix^|\flushleft|、\pix^|\flushright| 和 +\xrdef{eplaincenter}\pix^|\center| 将后面各行文本以指定方式对齐。 +这种命令必须单独写在一行中。 +命令和文本应该包含在一个编组中——编组的结束就表示文本的结束。 +整个编组作为一个段落排版,各行视情况在一边或两边用空白填充。 +空行依原样显示。 + +\csdisplay +\begingroup + \catcode `\^^M = \active + \globaldefs = 1 % + \def\flushleft{\beforejustify % + \aftergroup\@endflushleft % + \def^^M{\null\hfil\break}% + \def\@eateol^^M{}\@eateol}% + \def\flushright{\beforejustify % + \aftergroup\@endflushright % + \def^^M{\break\null\hfil}% + \def\@eateol^^M{\hfil\null}\@eateol}% + \def\center {\beforejustify % + \aftergroup\@endcenter % + \def^^M{\hfil\break\null\hfil}% + \def\@eateol^^M{\hfil\null}\@eateol}% +\endgroup +| + +%The following commands are called as a result of the |\after!-group| +%^^|\aftergroup| +%in the definitions of |\flush!-left|, |\flush!-right|, and |\center|. +%They perform the necessary cleanup operations. +在 |\flush!-left|、|\flush!-right| 和 |\center| 的定义中, +下述这些命令出现在 ^|\aftergroup| 的后面; +它们在编组结束后被调用,以执行一些必需的清理工作。 + +\csdisplay +\def\@endflushleft{\unpenalty + {\parfillskip = 0pt plus 1 fil\par}% + \ignorespaces}% +\def\@endflushright{% + % Remove the \hfil\null\break we just put on. + \unskip \setbox0=\lastbox \unpenalty + % We have fil glue at the left of the line; + % \parfillskip shouldn't affect that. + {\parfillskip = 0pt \par}\ignorespaces}% +\def\@endcenter{% + % Remove the \hfil\null\break we just put on. + \unskip \setbox0=\lastbox \unpenalty + % We have fil glue at the left of the line; + % \parfillskip must balance it. + {\parfillskip = 0pt plus 1fil \par}\ignorespaces}% +\def\beforejustify{% + \par\noindent + \catcode`\^^M = \active + \checkenv \environmenttrue}% +| + +%\eix^^{flush left} +%\eix^^{flush right} +%\eix^^{centered text} +\eix^^{居左对齐} +\eix^^{居右对齐} +\eix^^{居中文本} + + +%\section Tables +\section 表格 + +%The \pix^|\makecolumns| macro enables you to give all the entries in a +%table without having to worry about where the columns break. For +%example, if you're typing a long alphabetical list that will be +%formatted in several columns, you usually won't know in advance where +%one column ends and the next begins. Moreover, if another item gets +%added, the column breaks will change. +\pix^|\makecolumns| 宏允许你给出表格的所有元素,而无需担心如何分栏。 +例如,在输入一个冗长的按字母排序的名单,并分多栏显示时, +你通常不知道在何处结束一栏开始下一栏。 +另外,如果添加了另一项,各栏的划分将会改变。 + +%|\makecolumns| takes two (delimited) arguments: the total number of +%entries in the table and the number of columns in the table. For +%example, `|\makecolumns 37/3:|' specifies a three-column table whose +%entries are the next $37$ lines. You can adjust the positioning of the +%table on the page by changing |\parindent|, which determines the space +%to the left, and |\hsize|, which determines the space from the left +%margin of the page to the right of the block. You can allow a page +%break above the |\valign| +%^^|\valign//used in {\tt\\makecolumns}| +%by changing +%\pix^|\abovecolumnspenalty|. +|\makecolumns| 有两个(定界)参量:表格元素的总数以及表格的栏数。 +例如,`|\makecolumns 37/3:|' 指定一个三栏表格,其元素为接下来的 $37$ 行。 +要调整表格在页面上的位置,你可以修改 |\parindent| 以确定表格左侧的空白, +以及 |\hsize| 以确定从页面左边缘到表格右侧的距离。 +要允许在 |\valign| ^^|\valign//用于 {\tt\\makecolumns}| 之前分页, +你可以修改 \pix^|\abovecolumnspenalty|。 + +\csdisplay +\newcount\abovecolumnspenalty +\abovecolumnspenalty = 10000 +\newcount\@linestogo % Lines remaining to process. +\newcount\@linestogoincolumn % Lines remaining in column. +\newcount\@columndepth % Number of lines in a column. +\newdimen\@columnwidth % Width of each column. +\newtoks\crtok \crtok = {\cr}% +\def\makecolumns#1/#2: {\par \begingroup + \@columndepth = #1 \advance\@columndepth by #2 + \advance\@columndepth by -1 + \divide \@columndepth by #2 + \@linestogoincolumn = \@columndepth \@linestogo = #1 + \def\@endcolumnactions{% + \ifnum \@linestogo<2 + \the\crtok \egroup \endgroup \par + % End \valign and \makecolumns. + \else + \global\advance\@linestogo by -1 + \ifnum\@linestogoincolumn<2 + \global\@linestogoincolumn = \@columndepth + \the\crtok + \else &\global\advance\@linestogoincolumn by -1 + \fi + \fi}% + \makeactive\^^M\letreturn\@endcolumnactions + \@columnwidth = \hsize + \advance\@columnwidth by -\parindent + \divide\@columnwidth by #2 + \penalty\abovecolumnspenalty + \noindent % It's not a paragraph (usually). + \valign\bgroup + &\hbox to \@columnwidth{\strut ##\hfil}\cr +}% The next end-of-line starts everything going. +| + + +%\section Footnotes +\section 脚注 + +%\null ^^{footnotes} +%Footnotes are most commonly typeset by using a raised number as the +%reference mark. We define the \pix^|\numberedfootnote| macro to do +%this. It also redefines ^|\vfootnote| to allow slightly more general +%formatting of footnotes than \plainTeX\ does. The dimension register +%\pix^^|\footnotemarkseparation| |\foot!-note!-mark!-sepa!-ra!-tion| +%controls the space between the footnote mark (e.g., the number) and the +%beginning of the text. The \pix^|\everyfootnote| tokens are inserted +%before producing the footnote. +\null ^^{脚注} +脚注通常用升高的数字作为参考符号。 +我们定义的 \pix^|\numberedfootnote| 宏就是这样的。 +它还重新定义了 ^|\vfootnote|,以支持比 \plainTeX\ 更一般的脚注格式。 +尺寸寄存器 \pix^^|\footnotemarkseparation| |\foot!-note!-mark!-sepa!-ra!-tion| +控制脚注符号(比如数字)与脚注文本之间的间隔。 +\pix^|\everyfootnote| 记号在每个脚注之前插入。 + +%The \plainTeX\ definitions of |\footnote| and |\vfootnote| are +%preserved in |\@plain!-footnote| and |\@plain!-vfootnote| in case you should +%need them. +\PlainTeX\ 中的 |\footnote| 和 |\vfootnote| 定义保留在 +|\@plain!-footnote| 和 |\@plain!-vfootnote| 中,以备不时之需。 + +\csdisplay +\newcount\footnotenumber \newtoks\everyfootnote +\newdimen\footnotemarkseparation +\footnotemarkseparation = .5em +\let\@plainfootnote = \footnote +\let\@plainvfootnote = \vfootnote +\def\vfootnote#1{\insert\footins\bgroup + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip + \xspaceskip\z@skip + \everypar = {}% + \the\everyfootnote + \indent\llap{#1\kern\footnotemarkseparation}\footstrut + \futurelet\next\fo@t}% +\def\numberedfootnote{\global\advance\footnotenumber by 1 + \@plainfootnote{$^{\number\footnotenumber}$}}% +| + + +%\section Double columns +\section 双栏 + +%\null ^^{double columns} The |\doublecolumns| command begins +%double-column output, while the |\single!-column| +%\pix^^|\singlecolumn| +%command restores +%single-column output. You can switch back and forth between them +%on a single page. +%The glue specified by |\above!-double!-column!-skip| and +%|\below!-double!-column!-skip| is inserted before and after the +%double-column material. +\null ^^{双栏} |\doublecolumns| 命令开始双栏输出, +而 |\single!-column| \pix^^|\singlecolumn| 命令恢复单栏输出。 +两者可以在同个页面上相互切换。 +用 |\above!-double!-column!-skip| 和 |\below!-double!-column!-skip| +指定的粘连插入到双栏素材的前面和后面。 + +%The approach is derived from \knuth{page~417}. +它们的实现方式来源于\knuth{第~417~页}。 + +\csdisplay +\newskip\abovedoublecolumnskip +\newskip\belowdoublecolumnskip +\abovedoublecolumnskip = \bigskipamount +\belowdoublecolumnskip = \bigskipamount +\newdimen\gutter \gutter = 2pc +\newdimen\doublecolumnhsize \doublecolumnhsize = \hsize +\newbox\@partialpage \newdimen\singlecolumnhsize +\newdimen\singlecolumnvsize \newtoks\previousoutput +\def\doublecolumns{\par % Don't start in horizontal mode. + \previousoutput = \expandafter{\the\output} + \advance\doublecolumnhsize by -\gutter + \divide\doublecolumnhsize by 2 + \output = {\global\setbox\@partialpage = + \vbox{\unvbox255\vskip\abovedoublecolumnskip}}% + \pagegoal = \pagetotal \break % Expands \output above. + \output = {\doublecolumnoutput}% + \singlecolumnhsize = \hsize + \singlecolumnvsize = \vsize + \hsize = \doublecolumnhsize \vsize = 2\vsize}% +| + +%The |\@double!-column!-split| macro does the actual splitting. +%Insertions are assumed to be single-column material. If you don't want +%this to be the case, you'll have to modify the output routine. After +%|\@double!-column!-split| has done its work, |\box255| will have the +%double-column material. The double-column material will be preceded by +%any single-column material that was typeset before |\doublecolumns| was +%invoked. |\box4| will have the material that didn't fit on the page. +|\@double!-column!-split| 宏执行实际的分栏。插入项被当作单栏素材; +如果这不是你想要的,你需要修改输出例行程序。 +在 |\@double!-column!-split| 完成之后,|\box255| 将包含双栏素材。 +双栏素材前面是调用 |\doublecolumns| 前的单栏素材。 +|\box4| 将包含无法放入该页面的素材。 + +\csdisplay +\def\@doublecolumnsplit{% + \splittopskip = \topskip \splitmaxdepth = \maxdepth + \dimen0 = \singlecolumnvsize + \advance\dimen0 by -\ht\@partialpage + \advance\dimen0 by -\ht\footins + \advance\dimen0 by -\skip\footins + \advance\dimen0 by -\ht\topins + \begingroup + \vbadness = 10000 + \global\setbox1=\vsplit255 to \dimen0 \wd1=\hsize + \global\setbox3=\vsplit255 to \dimen0 \wd3=\hsize + \endgroup + \global\setbox4=\vbox{\unvbox255 + \penalty\outputpenalty}% + \global\setbox255=\vbox{\unvbox\@partialpage + \hbox to \singlecolumnhsize{\box1\hfil\box3}% + \vfill}}% +| +%\needspace{.5in} +%|\double!-column!-out!-put| is the real output routine. We call the old +%|\output| to do the work of actually shipping out the box. +\needspace{.5in} +|\double!-column!-out!-put| 是真正的输出例行程序。 +我们调用 |\output| 执行实际的盒子送出工作。 + +\csdisplay +\def\doublecolumnoutput{\@doublecolumnsplit + \hsize = \singlecolumnhsize \vsize = \singlecolumnvsize + \previousoutput \unvbox4}% +| + +%|\singlecolumn| resumes typesetting in one column. It assumes that +%|\doublecolumns| has been called. +|\singlecolumn| 恢复单栏排版。它假定已调用了 |\doublecolumns|。 + +\csdisplay +\def\singlecolumn{\par % Don't start in horizontal mode. + \output = {\global\setbox1 = + \vbox{\unvbox255\vskip\abovedoublecolumnskip}}% + \pagegoal = \pagetotal \break \setbox255 = \box1 + {\singlecolumnvsize = \ht255 + \divide\singlecolumnvsize by 2 + \advance\singlecolumnvsize by +\ht\@partialpage + \advance\singlecolumnvsize by +\ht\footins + \advance\singlecolumnvsize by +\skip\footins + \advance\singlecolumnvsize by +\ht\topins + \@doublecolumnsplit}% + \hsize = \singlecolumnhsize + \vsize = \singlecolumnvsize + \output = \expandafter{\the\previousoutput}% + \unvbox255}% +| + +%\margin{`Sensible paragraph skips' section deleted} +\margin{`Sensible paragraph skips' section deleted} + + +%\section Finishing up +\section 收尾 + +%We now must undo the changes that we made when we started (see +%\xref{eplainconv}). We also give a version identification, which is +%subsequently available in |\fmt!-name| and |\fmt!-version|. +现在我们必须撤销开始的修改(见\xref{eplainconv})。 +我们还给出版本标识,它可以在 |\fmt!-name| 和 |\fmt!-version| 中得到。 + +\csdisplay +\let\wlog = \@plainwlog \catcode`@ = \other +\def\fmtname{eplain}% +{\edef\plainversion{\fmtversion}% + \xdef\fmtversion{1.0: 15 May 1990 + (and plain \plainversion)}% +}% +| + +%\eix^^|eplain.tex| +\eix^^|eplain.tex| + +\ifoldeplain\else\ifcompletebook\else +\vskip4em{\sectionfonts\leftline{本章索引}} +\readindexfile{i} +\fi\fi + +\endchapter +\byebye |