<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% -*- 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|.
è¿™ä¸€ç«&nbsp;æè¿° |eplain.tex|ï¼Œä¸€ç»„ç”¨äºŽæ‰©å±• plain \TeX\ çš„å®å’Œå…¶ä»–å®šä¹‰ã€‚
\bix^^|eplain.tex|
å¯¹å„ç§å®çš„æè¿°è§£é‡Šäº†å®ƒä»¬çš„ç›®çš„ï¼Œä½†é€šå¸¸ä¸è§£é‡Šå®ƒä»¬çš„å·¥ä½œåŽŸç†æˆ–ç»™å‡ºå¦‚ä½•ä½¿ç”¨å®ƒä»¬çš„è¯¦æƒ…ã€‚
é‚£äº›ä¿¡æ¯åŒ…å«åœ¨ |eplain.tex| æºç&nbsp;æ–‡ä»¶ä»¥åŠå®ƒçš„æ–‡æ¡£ä¸­ã€‚
åœ¨\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}
æˆ‘ä»¬å…ˆä»‹ç»å‡&nbsp;ä¸ªä¿®æ”¹ç±»åˆ«ç&nbsp;åŠå®šä¹‰ä¸¤ç§å¸¸ç”¨ç±»åˆ«ç&nbsp;çš„å®ã€‚
^^{ç±»åˆ«ç&nbsp;//æœ‰ç”¨çš„ç±»åˆ«ç&nbsp;å®šä¹‰}

%\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|' å®šä¹‰ä¸ºæ´»åŠ¨å­—ç¬¦ï¼Œä½&nbsp;éœ€è¦å°†å®šä¹‰æ”¾åœ¨ç¼–ç»„ä¸­ï¼Œå¹¶å€ŸåŠ©æŸäº›é¢å¤–æœºåˆ¶ã€‚
\ttidxref{^^M}
\pix^|\letreturn| å®è®©ä½&nbsp;æ—&nbsp;éœ€é¢å¤–æœºåˆ¶å°±å¯ä»¥å®šä¹‰ `|^^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}
çŽ°åœ¨æˆ‘ä»¬å»ºç«‹ä¸€äº›æƒ¯ä¾‹ï¼Œç”¨äºŽè¯»å–è¿™ä¸ªæ–‡ä»¶çš„å…¶ä»–éƒ¨åˆ†ã€‚
åœ¨è¿™ä¸ªæ–‡ä»¶ä¸­æˆ‘ä»¬å…è®¸åç§°å¸¦æœ‰ `|@|' çš„``ç§æœ‰''æŽ§åˆ¶åºåˆ—ã€‚
è¿™äº›æŽ§åˆ¶åºåˆ—åœ¨è¿™ä¸ªæ–‡ä»¶ä¹‹å¤–æ—&nbsp;æ³•ä½¿ç”¨ï¼ˆé™¤éžä½&nbsp;å†æ¬¡ä¿®æ”¹ `|@|' çš„ç±»åˆ«ç&nbsp;ï¼‰ã€‚
\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.
æ&nbsp;‡çº¿çš„é»˜è®¤åŽšåº¦ä¸º $0.4$\pt ã€‚
è¦ç”Ÿæˆé»˜è®¤åŽšåº¦ä¸ºä»»ä½•å€¼çš„æ&nbsp;‡çº¿ï¼Œ
ä½&nbsp;å¯ä»¥é‡æ–°å®šä¹‰ |\vruledefaultwidth|ã€|\hruledefaultheight| åŠ |\hrule!-defaultdepth|ï¼Œ
å¹¶å°† |\hrule| å’Œ |\vrule| æ¢ä¸º \pix^|\ehrule| å’Œ \pix^|\evrule|ã€‚%
ï¼ˆåç§°ä¸­çš„ `e' ä»£è¡¨ ``eplain''ã€‚ï¼‰%
^^{æ&nbsp;‡çº¿//æ&nbsp;‡çº¿çš„åŽšåº¦}
å¦‚æžœä½&nbsp;æ˜¾å¼ç»™å‡ºå°ºå¯¸ï¼ˆæ¯”å¦‚ |\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.
|\%| é€šå¸¸ç”¨äºŽå†™å‡º `|%|' å­—ç¬¦ï¼Œä½†å®ƒæ—&nbsp;æ³•åŒ…å«åœ¨ |\write| çš„è®°å·åˆ—ä¸­ã€‚
^^|\write//ç”¨å®ƒå†™å‡º \b\tt\%\e\|
%^^|%//å†™å‡ºè¯¥å­—ç¬¦|
ä½&nbsp;å¯ä»¥ç”¨ ^|\percentchar| è¾¾åˆ°æ­¤ç›®çš„ã€‚
æˆ‘ä»¬è¿˜å°† ^|^^L| é‡æ–°å®šä¹‰ä¸ºéžå¤–éƒ¨å®ï¼Œå›&nbsp;æ­¤ä½&nbsp;å¯ä»¥åœ¨å®å®šä¹‰æˆ–è€…å‚é‡ä¸­ä½¿ç”¨å®ƒã€‚

\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|.
ä¸ºäº†å°†å‚é‡åœ¨ç©ºæ&nbsp;¼å¤„åˆ†å¼€ï¼Œæˆ‘ä»¬è¦ç”¨åˆ°ä¸¤ä¸ªå­å®ã€‚
|\@ttsA| ç”¨äºŽå¯»æ‰¾ç©ºæ&nbsp;¼ï¼Œè€Œ |\@ttsB| ç”¨äºŽå¤„ç†ä¸å¸¦ç©ºæ&nbsp;¼çš„æŽ§åˆ¶åºåˆ—ã€‚
æ¯ä¸ªç©ºæ&nbsp;¼éƒ½è¢«æ›¿æ¢ä¸º \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| å®å®žçŽ°äº†å…¶ä»–ä¼&nbsp;ç»Ÿç¼–ç¨‹è¯­è¨€ä¸­çš„^{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| ç”¨äºŽé‡æ–°ç”Ÿæˆä½&nbsp;çš„è¾“å…¥ä¸­çš„æ¢è¡Œã€ç©ºè¡Œå’Œç©ºæ&nbsp;¼ã€‚
å®ƒç»“åˆäº†|\obey!-lines| å’Œ |\obey!-spaces| çš„æ•ˆæžœï¼Œ
^^|\obeylines| ^^|\obeyspaces|
å¹¶æŠŠè¡Œé¦–çš„ç©ºæ&nbsp;¼ä¹Ÿæ‰“å°å‡ºæ¥ã€‚åˆ¶è¡¨ç¬¦ä¸å—å®ƒå½±å“ï¼›å®ƒä»¬ä»ç„¶ç”Ÿæˆæ­£å¸¸çš„ç²˜è¿žã€‚
\xrdef{ewhitesp}
^^{ç©ºæ&nbsp;¼ç¬¦}
^^|\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}
å½“ä½&nbsp;ä¸æƒ³ç”¨ |\over|ï¼Œè€Œ ``1/2'' çœ‹æ¥åˆä¸å¤Ÿå¥½æ—¶ï¼Œ
ä½&nbsp;æœ€å¥½ç”¨ \pix^|\frac| åœ¨æ­£æ–‡ä¸­æ‰“å°åˆ†å¼ã€‚
è¿™ä¸ªå®æ˜¯\knuth{ç»ƒä¹&nbsp;~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\ åœˆä¸­å¸¸ç”¨çš„æ&nbsp;‡è¯†ã€‚
\AMSTeX\ æ&nbsp;‡è¯†å–è‡ª \knuth{ç¬¬~420~é¡µ}ã€‚
\LaTeX\ æ&nbsp;‡è¯†å–è‡ª |latex.tex| å¹¶ç¨ä½œä¿®æ”¹ï¼ˆæˆ‘ä»¬ä¿®æ”¹äº† `A' çš„å­—ä½“ï¼‰ï¼›
ç±»ä¼¼åœ°ï¼Œ\BibTeX\ æ&nbsp;‡è¯†ç”¨ |\sevenrm| å­—ä½“ä»£æ›¿çœŸæ­£çš„å°åž‹å¤§å†™å­—ä½“ã€‚
\MF\ æ&nbsp;‡è¯†çš„ |.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| çš„å€¼ã€‚
^^{æ–‡ä»¶//æ£€æµ‹æ–‡ä»¶æ˜¯å¦å­˜åœ¨}
å‚é‡ä¸­çš„æ–‡ä»¶åæ—&nbsp;éœ€ä»¥ç©ºæ&nbsp;¼è®°å·ç»“å°¾ï¼Œå›&nbsp;ä¸ºè¿™ä¸ªå®å·²ç»æä¾›äº†ç©ºæ&nbsp;¼è®°å·ã€‚

\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| è®©é™ˆåˆ—å…¬å¼é»˜è®¤ä¸ºå·¦å¯¹é½æ˜¾ç¤ºã€‚
ä½&nbsp;ä¹Ÿå¯ä»¥ç”¨ \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~é¡µ}ä¸­çš„ä»£ç&nbsp;ã€‚

\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| çš„å®ï¼Œä½&nbsp;å¯ä»¥ç»™é™ˆåˆ—å…¬å¼è®¾å®šä¸åŒçš„å½¢å¼ã€‚
è¿™ä¸ªå®å®šä¹‰ä¸­å¿…é¡»åœ¨ |\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| å‘½ä»¤ä»¥å¾—åˆ°å·¦å¯¹é½æ&nbsp;¼å¼ã€‚
é™¤è¿™äº›æ”¹å˜ä¹‹å¤–ï¼Œè¿™äº›å®ä¸Ž |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
            &amp;$\@lign\displaystyle{{}####}$
               \hfil\tabskip\centering
            &amp;\llap{$\@lign####$}\tabskip\z@skip\crcr
            ##1\crcr}}}%
   \def\leqalignno##1{\displ@y
      \vcenter{\halign to\displaywidth{%
             $\@lign\displaystyle{####}$\tabskip\z@skip
            &amp;$\@lign\displaystyle{{}####}
               $\hfil\tabskip\centering
            &amp;\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&lt;10 \toks1 = {0}% Get a leading zero.
   \else            \toks1 = {}%
   \fi
   \ifnum\count2&lt;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| æŽ’å°æ—&nbsp;åºåˆ—è¡¨ã€‚
è¿™ä¸¤ç§åˆ—è¡¨ä¸­çš„é¡¹ç›®ä»¥ \pix^|\li|ï¼ˆ``list item''ï¼‰å¼€å¤´ã€‚
å¦‚æžœä¸éœ€è¦åˆ—è¡¨é¡¹ç›®é—´çš„é¢å¤–é—´éš”ï¼Œä½&nbsp;å¯ä»¥åœ¨åˆ—è¡¨å¼€å§‹å¤„åŠ&nbsp;ä¸Š \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|.
æ›´ä¸€èˆ¬åœ°ï¼Œä½&nbsp;å¯ä»¥é€šè¿‡æ”¹å˜ä¸‹åˆ—å¯„å­˜å™¨çš„å€¼æŽ§åˆ¶åˆ—è¡¨é¡¹ç›®é—´çš„é—´éš”ã€‚
å¦‚æžœåˆ—è¡¨é¡¹ç›®ç»å¸¸æ¯”è¾ƒé•¿ï¼Œä½&nbsp;ä¹Ÿè®¸å¸Œæœ›è®¾å®šéžé›¶çš„ |\interitemskip|ã€‚
å„åˆ—è¡¨é¡¹ç›®çš„å·¦ç¼©è¿›é‡ç­‰äºŽ |\par!-indent| åŠ&nbsp; |\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|
ç¼–å·åˆ—è¡¨å’Œæ—&nbsp;åºåˆ—è¡¨éƒ½ä½¿ç”¨ä¸‹é¢è¿™äº›å®ã€‚
æˆ‘ä»¬å¹¶ä¸æ”¹å˜ |\parindent| çš„å€¼ï¼Œ
å›&nbsp;ä¸ºå¾ˆå¤šçŽ°æœ‰çš„å®æ¯”å¦‚ |\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| å®ï¼Œä½&nbsp;å¯ä»¥æ”¹å˜é¡¹ç›®æ&nbsp;‡ç­¾çš„æ&nbsp;·å¼ã€‚
\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~é¡µ}ä¸­çš„ä»£ç&nbsp;ã€‚
åˆ¶è¡¨ç¬¦ç”Ÿæˆå›ºå®šå¤§å°çš„é—´éš”ï¼Œè€Œæ¢é¡µç¬¦ç”Ÿæˆä¸€ä¸ªåˆ†é¡µã€‚
å…¶ä»–æŽ§åˆ¶å­—ç¬¦ç”Ÿæˆè¯¥å­—ä½“æ‰€åœ¨ä½ç½®çš„å­—ç¬¦ï¼Œè¿™é€šå¸¸ä¸å¤ªæœ‰ç”¨ã€‚
é€šè¿‡é‡æ–°å®šä¹‰ |\setup!-listing!-hook|\pix^^|\setuplistinghook|ï¼Œ
ä½&nbsp;å¯ä»¥åœ¨è¯»å…¥æ–‡ä»¶å‰é’ˆå¯¹ç‰¹åˆ«å­—ä½“å’Œ\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| æ·»åŠ&nbsp;é¡µç&nbsp;åˆ°å®è°ƒç”¨ä¸­ã€‚ä¾‹å¦‚ï¼š
\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| ä½&nbsp;è¿˜å¯ä»¥æä¾›ç¬¬ä¸‰ä¸ªå‚æ•°ï¼Œæ¯”å¦‚ç«&nbsp;ç¼–å·ã€‚ä¾‹å¦‚ï¼š
\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
ä½&nbsp;ä¹Ÿå¯ä»¥è‡ªå·±ç”¨ |\write| å‘½ä»¤å†™å…¥ |\tocfile|ã€‚%
\footnote{è¯‘æ³¨ï¼šåŽŸæ–‡çš„ä»£ç&nbsp;ä¸­é—æ¼ |\writetocentry| çš„å®šä¹‰ï¼Œ
è€Œå°† |\writenumberedtocentry| çš„å®šä¹‰é‡å¤å†™äº†ä¸¤éï¼Œè¯‘æ–‡å·²ä¿®æ­£æ­¤é—®é¢˜ã€‚
å®žé™…ä¸Šï¼Œåœ¨æœ¬ä¹¦æ‰€ç”¨çš„ |eplain.tex| 1.9 ä¸­ï¼Œ
|\writetocentry| è°ƒç”¨ |\writenumberedtocentry|ï¼Œ
å¹¶åœ¨åŽè€…ä¸­æ&nbsp;¹æ®ç¬¬ä¸‰ä¸ªå‚æ•°æ˜¯å¦éžç©ºå†™å…¥ä¸åŒçš„ç›®å½•é¡¹ã€‚
ä½†åœ¨ |\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| æ–‡ä»¶ã€‚
ä½&nbsp;åº”è¯¥åœ¨é¦–æ¬¡ä½¿ç”¨ |\write!-toc!-entry| ä¹‹å‰è°ƒç”¨ |\read!-tocfile|ã€‚
åœ¨å¤„ç†ç›®å½•ä¸”ä¸æƒ³é‡æ–°ç”Ÿæˆå®ƒæ—¶ï¼Œ
åŠ¡å¿…ä¸è¦æ”¹å†™ |.toc| æ–‡ä»¶â€”â€”å¦‚æžœä½&nbsp;è¿™æ&nbsp;·åšï¼Œæ–‡ä»¶å†…å®¹å°†ä¼šä¸¢å¤±ã€‚
å‘½ä»¤ |\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}
æŽ¥ä¸‹æ¥çš„å®æä¾›äº†ç¬¦å·å¼çš„äº¤å‰å¼•ç”¨ï¼Œ
è®©ä½&nbsp;å¯ä»¥åœ¨æ–‡æ¡£ä¸­é€šè¿‡åç§°è€Œéžå®žé™…é¡µç&nbsp;æåŠå…¶å®ƒéƒ¨åˆ†çš„ä¸œè¥¿ã€‚
\pix^|\xrdef||{foo}| å®šä¹‰æ&nbsp;‡ç­¾ |foo| ä¸ºå½“å‰é¡µç&nbsp;ï¼Œ
è€Œ \pix^|\xrefn||{foo}| ç”Ÿæˆè¯¥é¡µç&nbsp;ï¼Œæ¯”å¦‚ $77$ã€‚
ä½&nbsp;æ›´å¸¸ç”¨çš„æ˜¯ç±»ä¼¼ ``see p.\thinspace77'' çš„å†™æ³•ï¼Œ
å›&nbsp;æ­¤ \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.
è¿™äº›å®æ²¡æœ‰æä¾›å¯¹é‡å¤å®šä¹‰çš„ä¿æŠ¤ã€‚è¦æ£€æŸ¥é‡å¤å®šä¹‰ï¼Œ
ä½&nbsp;å¯ä»¥å°†äº¤å‰å¼•ç”¨æ–‡ä»¶æŽ’åºï¼Œå¹¶ç”¨å·¥å…·æˆ–è‚‰çœ¼æ£€æŸ¥åŒä¸€ä¸ªç¬¦å·çš„ç›¸é‚»å®šä¹‰ã€‚

\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.
è¿™ä¸ªå®å°†ä¸€ä¸ªæ&nbsp;‡ç­¾è½¬æ¢ä¸ºä¸€åˆ—å­—ç¬¦è®°å·ï¼Œå¹¶æ”¾åœ¨å¯„å­˜å™¨ |\labeltoks| ä¸­ã€‚
é™¤äº†æ™®é€šå­—ç¬¦ä¹‹å¤–ï¼Œæ&nbsp;‡ç­¾è¿˜å¯ä»¥åŒ…å«ç©ºæ&nbsp;¼å’ŒæŽ§åˆ¶åºåˆ—ï¼Œä½†ä¸èƒ½åŒ…å«èŠ±æ‹¬å·ã€‚

\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.
éœ€è¦è¿è¡Œä¸¤éæ‰èƒ½å¾—åˆ°æ­£ç¡®çš„äº¤å‰å¼•ç”¨ï¼Œ
å›&nbsp;ä¸ºè¿™äº›å®šä¹‰æ˜¯å†™å‡ºåˆ°è¾…åŠ©æ–‡ä»¶|\jobname.aux| é‡Œçš„ã€‚
\pix^|\readreffile| å‘½ä»¤ç”¨äºŽå°†å®ƒä»¬è¯»å–å›žæ¥ã€‚
å¦‚æžœä½&nbsp;ä¸åœ¨ç¬¬ä¸€ä¸ªå®šä¹‰ä¹‹å‰æ‰§è¡Œæ­¤å‘½ä»¤ï¼Œä½&nbsp;å°†ä¸¢å¤±ä¸Šä¸€éè¿è¡Œå¾—åˆ°çš„å®šä¹‰ã€‚

\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.
^^{å…¬å¼ç¼–å·}
æŒ‰åŒæ&nbsp;·çš„æ–¹å¼ï¼Œä½&nbsp;å¯ä»¥ç”¨ \pix^|\eqdef| å’Œ \pix^|\eqref| ç»™å‡ºå…¬å¼çš„ç¬¦å·å¼åç§°ã€‚
|\eqdef| æ’å…¥è‡ªå·±çš„ |\eqno| å‘½ä»¤ï¼Œå›&nbsp;æ­¤å®ƒå¿…é¡»ç”¨åœ¨èƒ½ç”¨ |\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|ï¼Œä½&nbsp;å¯ä»¥å®žçŽ°æ›´åŠ&nbsp;å¤æ‚çš„æ&nbsp;¼å¼ã€‚
ä¸¾ä¸ªä¾‹å­ï¼Œä½&nbsp;å¯ä»¥é‡æ–°å®šä¹‰å®ƒï¼Œä½¿å¾—å…¬å¼ç¼–å·ä¸­åŒ…å«ç«&nbsp;ç¼–å·ã€‚

\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 ^^{çŽ¯å¢ƒ}è¿™äº›å®è®©ä½&nbsp;å¯ä»¥å°†æ‰‹ç¨¿çš„ä¸€éƒ¨åˆ†å®šä¹‰ä¸ºå‘½åç¼–ç»„ï¼ˆçŽ¯å¢ƒï¼‰ã€‚
ç±»ä¼¼ \TeX\ çš„ç¼–ç»„ï¼Œè¿™äº›ç¼–ç»„ä¹Ÿå¯ä»¥åµŒå¥—ï¼Œ
è€Œä¸”å®žé™…ä¸Šå®ƒä»¬çš„åµŒå¥—å¯ä»¥ä¸Ž \TeX\ ç¼–ç»„çš„åµŒå¥—ç›¸äº’äº¤ç»‡ã€‚
å¦‚æžœå¼€å§‹çš„åç§°å’Œç»“æŸçš„åç§°ä¸åŒ¹é…ï¼Œä½&nbsp;å°†å¾—åˆ°ä¸€ä¸ªé”™è¯¯ä¿¡æ¯ã€‚
è¿™äº›å®å¦‚æ­¤è®¾è®¡ï¼Œä½¿å¾—å½“ä½&nbsp;å¾—åˆ°è¿™ç§é”™è¯¯ä¿¡æ¯æ—¶ï¼Œä½&nbsp;æœ‰æœºä¼šæ–¹ä¾¿åœ°å®šä½é”™è¯¯çš„æ¥æºã€‚

%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\ ç»ƒä¹&nbsp;~5.7ï¼Œ
æ·»åŠ&nbsp;å¯¹ |\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|
ä½&nbsp;ä¹Ÿå¯ä»¥ç»™ä¸Šè¿°è¿™äº›é”™è¯¯å®šä¹‰å®ƒä»¬å„è‡ªçš„å¸®åŠ©ä¿¡æ¯ã€‚
^^|\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|ï¼Œä½&nbsp;å¿…é¡»åœ¨æ¯ä¸ªå¤–éƒ¨çŽ¯å¢ƒå¼€å¤´å¤„æ‰§è¡Œ |\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| å°†åŽé¢å„è¡Œæ–‡æœ¬ä»¥æŒ‡å®šæ–¹å¼å¯¹é½ã€‚
è¿™ç§å‘½ä»¤å¿…é¡»å•ç‹¬å†™åœ¨ä¸€è¡Œä¸­ã€‚
å‘½ä»¤å’Œæ–‡æœ¬åº”è¯¥åŒ…å«åœ¨ä¸€ä¸ªç¼–ç»„ä¸­â€”â€”ç¼–ç»„çš„ç»“æŸå°±è¡¨ç¤ºæ–‡æœ¬çš„ç»“æŸã€‚
æ•´ä¸ªç¼–ç»„ä½œä¸ºä¸€ä¸ªæ®µè½æŽ’ç‰ˆï¼Œå„è¡Œè§†æƒ…å†µåœ¨ä¸€è¾¹æˆ–ä¸¤è¾¹ç”¨ç©ºç™½å¡«å……ã€‚
ç©ºè¡Œä¾åŽŸæ&nbsp;·æ˜¾ç¤ºã€‚

\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 è¡¨æ&nbsp;¼

%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| å®å…è®¸ä½&nbsp;ç»™å‡ºè¡¨æ&nbsp;¼çš„æ‰€æœ‰å…ƒç´&nbsp;ï¼Œè€Œæ—&nbsp;éœ€æ‹…å¿ƒå¦‚ä½•åˆ†æ&nbsp;ã€‚
ä¾‹å¦‚ï¼Œåœ¨è¾“å…¥ä¸€ä¸ªå†—é•¿çš„æŒ‰å­—æ¯æŽ’åºçš„åå•ï¼Œå¹¶åˆ†å¤šæ&nbsp;æ˜¾ç¤ºæ—¶ï¼Œ
ä½&nbsp;é€šå¸¸ä¸çŸ¥é“åœ¨ä½•å¤„ç»“æŸä¸€æ&nbsp;å¼€å§‹ä¸‹ä¸€æ&nbsp;ã€‚
å¦å¤–ï¼Œå¦‚æžœæ·»åŠ&nbsp;äº†å¦ä¸€é¡¹ï¼Œå„æ&nbsp;çš„åˆ’åˆ†å°†ä¼šæ”¹å˜ã€‚

%|\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| æœ‰ä¸¤ä¸ªï¼ˆå®šç•Œï¼‰å‚é‡ï¼šè¡¨æ&nbsp;¼å…ƒç´&nbsp;çš„æ€»æ•°ä»¥åŠè¡¨æ&nbsp;¼çš„æ&nbsp;æ•°ã€‚
ä¾‹å¦‚ï¼Œ`|\makecolumns 37/3:|' æŒ‡å®šä¸€ä¸ªä¸‰æ&nbsp;è¡¨æ&nbsp;¼ï¼Œå…¶å…ƒç´&nbsp;ä¸ºæŽ¥ä¸‹æ¥çš„ $37$ è¡Œã€‚
è¦è°ƒæ•´è¡¨æ&nbsp;¼åœ¨é¡µé¢ä¸Šçš„ä½ç½®ï¼Œä½&nbsp;å¯ä»¥ä¿®æ”¹ |\parindent| ä»¥ç¡®å®šè¡¨æ&nbsp;¼å·¦ä¾§çš„ç©ºç™½ï¼Œ
ä»¥åŠ |\hsize| ä»¥ç¡®å®šä»Žé¡µé¢å·¦è¾¹ç¼˜åˆ°è¡¨æ&nbsp;¼å³ä¾§çš„è·ç¦»ã€‚
è¦å…è®¸åœ¨ |\valign| ^^|\valign//ç”¨äºŽ {\tt\\makecolumns}| ä¹‹å‰åˆ†é¡µï¼Œ
ä½&nbsp;å¯ä»¥ä¿®æ”¹ \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&lt;2
         \the\crtok \egroup \endgroup \par
            % End \valign and \makecolumns.
      \else
         \global\advance\@linestogo by -1
         \ifnum\@linestogoincolumn&lt;2
            \global\@linestogoincolumn = \@columndepth
            \the\crtok
         \else &amp;\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
      &amp;\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| å®å°±æ˜¯è¿™æ&nbsp;·çš„ã€‚
å®ƒè¿˜é‡æ–°å®šä¹‰äº† ^|\vfootnote|ï¼Œä»¥æ”¯æŒæ¯” \plainTeX\ æ›´ä¸€èˆ¬çš„è„šæ³¨æ&nbsp;¼å¼ã€‚
å°ºå¯¸å¯„å­˜å™¨ \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 åŒæ&nbsp;

%\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 ^^{åŒæ&nbsp;} |\doublecolumns| å‘½ä»¤å¼€å§‹åŒæ&nbsp;è¾“å‡ºï¼Œ
è€Œ |\single!-column| \pix^^|\singlecolumn| å‘½ä»¤æ¢å¤å•æ&nbsp;è¾“å‡ºã€‚
ä¸¤è€…å¯ä»¥åœ¨åŒä¸ªé¡µé¢ä¸Šç›¸äº’åˆ‡æ¢ã€‚
ç”¨ |\above!-double!-column!-skip| å’Œ |\below!-double!-column!-skip|
æŒ‡å®šçš„ç²˜è¿žæ’å…¥åˆ°åŒæ&nbsp;ç´&nbsp;æçš„å‰é¢å’ŒåŽé¢ã€‚

%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| å®æ‰§è¡Œå®žé™…çš„åˆ†æ&nbsp;ã€‚æ’å…¥é¡¹è¢«å½“ä½œå•æ&nbsp;ç´&nbsp;æï¼›
å¦‚æžœè¿™ä¸æ˜¯ä½&nbsp;æƒ³è¦çš„ï¼Œä½&nbsp;éœ€è¦ä¿®æ”¹è¾“å‡ºä¾‹è¡Œç¨‹åºã€‚
åœ¨ |\@double!-column!-split| å®Œæˆä¹‹åŽï¼Œ|\box255| å°†åŒ…å«åŒæ&nbsp;ç´&nbsp;æã€‚
åŒæ&nbsp;ç´&nbsp;æå‰é¢æ˜¯è°ƒç”¨ |\doublecolumns| å‰çš„å•æ&nbsp;ç´&nbsp;æã€‚
|\box4| å°†åŒ…å«æ—&nbsp;æ³•æ”¾å…¥è¯¥é¡µé¢çš„ç´&nbsp;æã€‚

\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| æ¢å¤å•æ&nbsp;æŽ’ç‰ˆã€‚å®ƒå‡å®šå·²è°ƒç”¨äº† |\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}ï¼‰ã€‚
æˆ‘ä»¬è¿˜ç»™å‡ºç‰ˆæœ¬æ&nbsp;‡è¯†ï¼Œå®ƒå¯ä»¥åœ¨ |\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{æœ¬ç«&nbsp;ç´¢å¼•}}
\readindexfile{i}
\fi\fi

\endchapter
\byebye
</pre></body></html>