summaryrefslogtreecommitdiff
path: root/web/web2w/ctex.tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/web2w/ctex.tex
Initial commit
Diffstat (limited to 'web/web2w/ctex.tex')
-rw-r--r--web/web2w/ctex.tex38140
1 files changed, 38140 insertions, 0 deletions
diff --git a/web/web2w/ctex.tex b/web/web2w/ctex.tex
new file mode 100644
index 0000000000..03e8cd6ad3
--- /dev/null
+++ b/web/web2w/ctex.tex
@@ -0,0 +1,38140 @@
+\input cwebmac
+% This program is copyright (C) 1982 by D. E. Knuth; all rights are reserved.
+% Copying of this file is authorized only if (1) you are D. E. Knuth, or if
+% (2) you make absolutely no changes to your copy. (The WEB system provides
+% for alterations via an auxiliary file; the master file should stay intact.)
+% See Appendix H of the WEB manual for hints on how to install this program.
+% And see Appendix A of the TRIP manual for details about how to validate it.
+
+% TeX is a trademark of the American Mathematical Society.
+% METAFONT is a trademark of Addison-Wesley Publishing Company.
+
+% Version 0 was released in September 1982 after it passed a variety of tests.
+% Version 1 was released in November 1983 after thorough testing.
+% Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
+% Version 1.2 allowed `0' in response to an error, et alia (October 1984).
+% Version 1.3 made memory allocation more flexible and local (November 1984).
+% Version 1.4 fixed accents right after line breaks, et alia (April 1985).
+% Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
+% Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
+% Version 2.1 corrected anomalies in discretionary breaks (January 1987).
+% Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
+% Version 2.3 avoided incomplete page in premature termination (August 1987).
+% Version 2.4 fixed \noaligned rules in indented displays (August 1987).
+% Version 2.5 saved cur_order when expanding tokens (September 1987).
+% Version 2.6 added 10sp slop when shipping leaders (November 1987).
+% Version 2.7 improved rounding of negative-width characters (November 1987).
+% Version 2.8 fixed weird bug if no \patterns are used (December 1987).
+% Version 2.9 made \csname\endcsname's "relax" local (December 1987).
+% Version 2.91 fixed \outer\def\a0{}\a\a bug (April 1988).
+% Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
+% Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
+% Version 2.94 kept open_log_file from calling fatal_error (November 1988).
+% Version 2.95 solved that problem a better way (December 1988).
+% Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
+% Version 2.97 corrected blunder in creating 2.95 (February 1989).
+% Version 2.98 omitted save_for_after at outer level (March 1989).
+% Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
+% Version 2.991 caught .5\ifdim.6... (June 1989).
+% Version 2.992 introduced major changes for 8-bit extensions (September 1989).
+% Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
+% Version 3.0 fixed unusual displays; was more \output robust (March 1990).
+% Version 3.1 fixed nullfont, disabled \write{\the\prevgraf} (September 1990).
+% Version 3.14 fixed unprintable font names and corrected typos (March 1991).
+% Version 3.141 more of same; reconstituted ligatures better (March 1992).
+% Version 3.1415 preserved nonexplicit kerns, tidied up (February 1993).
+% Version 3.14159 allowed fontmemsize to change; bulletproofing (March 1995).
+% Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002).
+% Version 3.1415926 was a general cleanup with minor fixes (February 2008).
+% Version 3.14159265 was similar (January 2014).
+
+% A reward of $327.68 will be paid to the first finder of any remaining bug.
+
+% Although considerable effort has been expended to make the TeX program
+% correct and reliable, no warranty is implied; the author disclaims any
+% obligation or liability for damages, including but not limited to
+% special, indirect, or consequential damages arising out of or in
+% connection with the use or performance of this software. This work has
+% been a ``labor of love'' and the author hopes that users enjoy it.
+
+% Here is TeX material that gets inserted after \input webmac
+\def\hang{\hangindent 3em\noindent\ignorespaces}
+\def\hangg#1 {\hang\hbox{#1 }}
+\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps for names like SAIL
+\def\PASCAL{Pascal}
+\def\ph{\hbox{Pascal-H}}
+\def\pct!{{\char`\%}} % percent sign in ordinary text
+\font\logo=logo10 % font used for the METAFONT logo
+\def\MF{{\logo META}\-{\logo FONT}}
+\def\<#1>{$\langle#1\rangle$}
+\def\section{\mathhexbox278}
+
+\def\(#1){} % this is used to make section names sort themselves better
+\def\9#1{} % this is used for sort keys in the index via @:sort key}{entry@>
+
+\let\?=\relax % we want to be able to \write a \?
+
+\def\title{\TeX82}
+\def\topofcontents{\hsize 5.5in
+ \vglue 0pt plus 1fil minus 1.5in
+ \def\?##1]{\hbox to 1in{\hfil##1.\ }}
+ }
+\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in}
+\pageno=3
+\def\glob{13} % this should be the section number of "<Global...>"
+\def\gglob{20, 26} % this should be the next two sections of "<Global...>"
+
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\'=\RQ % right quote in a string
+ \let\`=\LQ % left quote in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ #1\kern.05em}}
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+\def\LQ{{\tt\char'22}} % left quote in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\dotdot{\mathrel{.\,.}} % double dot, used only in math mode
+
+\N{1}{1}Introduction.
+This is \TeX, a document compiler intended to produce typesetting of high
+quality.
+The \PASCAL\ program that follows is the definition of \TeX82, a standard
+version of \TeX\ that is designed to be highly portable so that identical output
+will be obtainable on a great variety of computers.
+
+The main purpose of the following program is to explain the algorithms of \TeX\
+as clearly as possible. As a result, the program will not necessarily be very
+efficient when a particular \PASCAL\ compiler has translated it into a
+particular machine language. However, the program has been written so that it
+can be tuned to run efficiently in a wide variety of operating environments
+by making comparatively few changes. Such flexibility is possible because
+the documentation that follows is written in the \.{WEB} language, which is
+at a higher level than \PASCAL; the preprocessing step that converts \.{WEB}
+to \PASCAL\ is able to introduce most of the necessary refinements.
+Semi-automatic translation to other languages is also feasible, because the
+program below does not make extensive use of features that are peculiar to
+\PASCAL.
+
+A large piece of software like \TeX\ has inherent complexity that cannot
+be reduced below a certain level of difficulty, although each individual
+part is fairly simple by itself. The \.{WEB} language is intended to make
+the algorithms as readable as possible, by reflecting the way the
+individual program pieces fit together and by providing the
+cross-references that connect different parts. Detailed comments about
+what is going on, and about why things were done in certain ways, have
+been liberally sprinkled throughout the program. These comments explain
+features of the implementation, but they rarely attempt to explain the
+\TeX\ language itself, since the reader is supposed to be familiar with
+{\sl The \TeX book}.
+
+\fi
+
+\M{2}The present implementation has a long ancestry, beginning in the summer
+of~1977, when Michael~F. Plass and Frank~M. Liang designed and coded
+a prototype
+based on some specifications that the author had made in May of that year.
+This original proto\TeX\ included macro definitions and elementary
+manipulations on boxes and glue, but it did not have line-breaking,
+page-breaking, mathematical formulas, alignment routines, error recovery,
+or the present semantic nest; furthermore,
+it used character lists instead of token lists, so that a control sequence
+like \.{\\halign} was represented by a list of seven characters. A
+complete version of \TeX\ was designed and coded by the author in late
+1977 and early 1978; that program, like its prototype, was written in the
+{\mc SAIL} language, for which an excellent debugging system was
+available. Preliminary plans to convert the {\mc SAIL} code into a form
+somewhat like the present ``web'' were developed by Luis Trabb~Pardo and
+the author at the beginning of 1979, and a complete implementation was
+created by Ignacio~A. Zabala in 1979 and 1980. The \TeX82 program, which
+was written by the author during the latter part of 1981 and the early
+part of 1982, also incorporates ideas from the 1979 implementation of
+\TeX\ in {\mc MESA} that was written by Leonidas Guibas, Robert Sedgewick,
+and Douglas Wyatt at the Xerox Palo Alto Research Center. Several hundred
+refinements were introduced into \TeX82 based on the experiences gained with
+the original implementations, so that essentially every part of the system
+has been substantially improved. After the appearance of ``Version 0'' in
+September 1982, this program benefited greatly from the comments of
+many other people, notably David~R. Fuchs and Howard~W. Trickey.
+A final revision in September 1989 extended the input character set to
+eight-bit codes and introduced the ability to hyphenate words from
+different languages, based on some ideas of Michael~J. Ferguson.
+
+No doubt there still is plenty of room for improvement, but the author
+is firmly committed to keeping \TeX82 ``frozen'' from now on; stability
+and reliability are to be its main virtues.
+
+On the other hand, the \.{WEB} description can be extended without changing
+the core of \TeX82 itself, and the program has been designed so that such
+extensions are not extremely difficult to make.
+The \\{banner} string defined here should be changed whenever \TeX\
+undergoes any modifications, so that it will be clear which version of
+\TeX\ might be the guilty party when a problem arises.
+
+If this program is changed, the resulting system should not be called
+`\TeX'; the official name `\TeX' by itself is reserved
+for software systems that are fully compatible with each other.
+A special test suite called the ``\.{TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\TeX' [cf.~Stanford Computer Science report CS1027,
+November 1984].
+
+\Y\B\4\D$\\{banner}$ \5
+\.{"This\ is\ TeX,\ Versio}\)\.{n\ 3.14159265\ (HINT)"}\C{printed when \TeX\ starts}\par
+\fi
+
+\M{3}Different \PASCAL s have slightly different conventions, and the present
+program expresses \TeX\ in terms of the \PASCAL\ that was
+available to the author in 1982. Constructions that apply to
+this particular compiler, which we shall call \ph, should help the
+reader see how to make an appropriate interface for other systems
+if necessary. (\ph\ is Charles Hedrick's modification of a compiler
+for the DECsystem-10 that was originally developed at the University of
+Hamburg; cf.\ {\sl SOFTWARE---Practice \AM\ Experience \bf6} (1976),
+29--42. The \TeX\ program below is intended to be adaptable, without
+extensive changes, to most other versions of \PASCAL, so it does not fully
+use the admirable features of \ph. Indeed, a conscious effort has been
+made here to avoid using several idiosyncratic features of standard
+\PASCAL\ itself, so that most of the code can be translated mechanically
+into other high-level languages. For example, the `\&{with}' and `\\{new}'
+features are not used, nor are pointer types, set types, or enumerated
+scalar types; there are no `\&{var}' parameters, except in the case of files;
+there are no tag fields on variant records; there are no assignments
+\&{double} $\K$ \&{int}; no procedures are declared local to other procedures.)
+
+The portions of this program that involve system-dependent code, where
+changes might be necessary because of differences between \PASCAL\ compilers
+and/or differences between
+operating systems, can be identified by looking at the sections whose
+numbers are listed under `system dependencies' in the index. Furthermore,
+the index entries for `dirty \PASCAL' list all places where the restrictions
+of \PASCAL\ have not been followed perfectly, for one reason or another.
+
+Incidentally, \PASCAL's standard \\{round} function can be problematical,
+because it disagrees with the IEEE floating-point standard.
+Many implementors have
+therefore chosen to substitute their own home-grown rounding procedure.
+
+\fi
+
+\M{4}The program begins with a normal \PASCAL\ program heading, whose
+components will be filled in later, using the conventions of \.{WEB}.
+For example, the portion of the program called `\X\glob:Global
+variables\X' below will be replaced by a sequence of variable declarations
+that starts in $\section\glob$ of this documentation. In this way, we are able
+to define each individual global variable when we are prepared to
+understand what it means; we do not have to define all of the globals at
+once. Cross references in $\section\glob$, where it says ``See also
+sections \gglob, \dots,'' also make it possible to look at the set of
+all global variables, if desired. Similar remarks apply to the other
+portions of the program heading.
+
+Actually the heading shown here is not quite normal: The line
+does not mention any \\{output} file, because \ph\ would ask the \TeX\ user
+to specify a file name if \\{output} were specified here.
+
+\Y\B\F\\{type} \5
+\\{true}\C{but `\\{type}' will not be treated as a reserved word}\par
+\Y\B\hbox{\4}\X9:Compiler directives\X\C{all file names are defined dynamically}\6
+\X6:Labels in the outer block\X\6
+\X11:Constants in the outer block\X\6
+\X18:Types in the outer block\X\6
+\X13:Global variables\X\7
+\&{void} \\{initialize}(\&{void})\C{this procedure gets things started properly}\6
+${}\{{}$\5
+\1\X19:Local variables for initialization\X\6
+\X8:Initialize whatever \TeX\ might access\X;\6
+\4${}\}{}$\2\7
+\hbox{\4}\X57:Basic printing procedures\X\6
+\hbox{\4}\X78:Error handling procedures\X\par
+\fi
+
+\M{5}The overall \TeX\ program begins with the heading just shown, after which
+comes a bunch of procedure declarations and function declarations.
+Finally we will get to the main program, which begins with the
+comment `\\{start\_here}'. If you want to skip down to the
+main program now, you can look up `\\{start\_here}' in the index.
+But the author suggests that the best way to understand this program
+is to follow pretty much the order of \TeX's components as they appear in the
+\.{WEB} description you are now reading, since the present ordering is
+intended to combine the advantages of the ``bottom up'' and ``top down''
+approaches to the problem of understanding a somewhat complicated system.
+
+\fi
+
+\M{6}Three labels must be declared in the main program, so we give them
+symbolic names.
+
+\Y\B\4\X6:Labels in the outer block\X${}\E{}$\6
+\hbox{\hskip-2pt}\hbox{\hskip-2pt}\,\C{key control points}\par
+\U4.\fi
+
+\M{7}Some of the code below is intended to be used only when diagnosing the
+strange behavior that sometimes occurs when \TeX\ is being installed or
+when system wizards are fooling around with \TeX\ without quite knowing
+what they are doing. Such code will not normally be compiled; it is
+delimited by the codewords `$\\{debug}\ldots\\{debug}$', with apologies
+to people who wish to preserve the purity of English.
+
+Similarly, there is some conditional code delimited by
+`$\\{stat}\ldots\\{tats}$' that is intended for use when statistics are to be
+kept about \TeX's memory usage. The \\{stat} $\ldots$ \\{tats} code also
+implements diagnostic information for \.{\\tracingparagraphs} and
+\.{\\tracingpages}.
+
+\fi
+
+\M{8}This program has two important variations: (1) There is a long and slow
+version called \.{INITEX}, which does the extra calculations needed to
+initialize \TeX's internal tables; and (2)~there is a shorter and faster
+production version, which cuts the initialization to a bare minimum.
+Parts of the program that are needed in (1) but not in (2) are delimited by
+the codewords `$\\{init}\ldots\\{tini}$'.
+
+\Y\B\4\X8:Initialize whatever \TeX\ might access\X${}\E{}$\6
+\X21:Set initial values of key variables\X\6
+\8\#\&{ifdef} \.{INIT}\6
+\X164:Initialize table entries (done by \.{INITEX} only)\X\6
+\8\#\&{endif}\par
+\U4.\fi
+
+\M{9}If the first character of a \PASCAL\ comment is a dollar sign,
+\ph\ treats the comment as a list of ``compiler directives'' that will
+affect the translation of this program into machine language. The
+directives shown below specify full checking and inclusion of the \PASCAL\
+debugger when \TeX\ is being debugged, but they cause range checking and other
+redundant code to be eliminated when the production system is being generated.
+Arithmetic overflow will be detected in all cases.
+
+\Y\B\4\X9:Compiler directives\X${}\E{}$\6
+\8\#\&{include} \.{<stdint.h>}\6
+\8\#\&{include} \.{<stdbool.h>}\6
+\8\#\&{include} \.{<stdio.h>}\6
+\8\#\&{include} \.{<stdlib.h>}\6
+\8\#\&{include} \.{<string.h>}\6
+\8\#\&{include} \.{<math.h>}\6
+\8\#\&{define} \\{odd}(\|X) \5${}((\|X)\AND\T{1}){}$\6
+\8\#\&{define} \\{chr}(\|X) \5((\&{unsigned} \&{char})(\|X))\6
+\8\#\&{define} \\{ord}(\|X) \5((\&{int})(\|X))\6
+\8\#\&{if} ${}\.{\_\_SIZEOF\_FLOAT\_\_}\E\T{4}{}$\6
+\&{typedef} \&{float} \&{float32\_t};\6
+\8\#\&{else}\6
+\8\#\&{error} \&{float} \\{type}\\{must}\\{have}\\{size}\T{4} \6
+\8\#\&{endif}\6
+\ATH\par
+\A56.
+\U4.\fi
+
+\M{10}This \TeX\ implementation conforms to the rules of the {\sl Pascal User
+Manual} published by Jensen and Wirth in 1975, except where system-dependent
+code is necessary to make a useful system program, and except in another
+respect where such conformity would unnecessarily obscure the meaning
+and clutter up the code: We assume that \&{case} statements may include a
+default case that applies if no matching label is found. Thus, we shall use
+constructions like
+$$\vbox{\halign{\ignorespaces#\hfil\cr
+\&{case} \|x\cr
+1: $\langle\,$code for $x=1\,\rangle$;\cr
+3: $\langle\,$code for $x=3\,\rangle$;\cr
+\&{default}: $\langle\,$code for $\|x\I\T{1}$ and $\|x\I\T{3}$$\,\rangle$\cr
+$\}$\cr}}$$
+since most \PASCAL\ compilers have plugged this hole in the language by
+incorporating some sort of default mechanism. For example, the \ph\
+compiler allows `\&{default}::' as a default label, and other \PASCAL s allow
+syntaxes like `\&{else}' or `\&{otherwise}' or `\\{otherwise}:', etc. The
+definitions of \&{default}: and $\}$ should be changed to agree with
+local conventions. Note that no semicolon appears before $\}$ in
+this program, so the definition of $\}$ should include a semicolon
+if the compiler wants one. (Of course, if no default mechanism is
+available, the \&{case} statements of \TeX\ will have to be laboriously
+extended by listing all remaining cases. People who are stuck with such
+\PASCAL s have, in fact, done this, successfully but not happily!)
+
+\fi
+
+\M{11}The following parameters can be changed at compile time to extend or
+reduce \TeX's capacity. They may have different values in \.{INITEX} and
+in production versions of \TeX.
+
+\Y\B\4\X11:Constants in the outer block\X${}\E{}$\6
+\&{enum} ${}\{{}$\5
+\1${}\\{mem\_max}\K{}$\T{30000}\5
+\2${}\}{}$;\C{greatest index in \TeX's internal \\{mem} array; must be strictly less than \\{max\_halfword}; must be equal to \\{mem\_top} in \.{INITEX}, otherwise $\G$ \\{mem\_top}}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{mem\_min}\K{}$\T{0}\5
+\2${}\}{}$;\C{smallest index in \TeX's internal \\{mem} array; must be \\{min\_halfword} or more; must be equal to \\{mem\_bot} in \.{INITEX}, otherwise $\Z$ \\{mem\_bot}}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{buf\_size}\K{}$\T{500}\5
+\2${}\}{}$;\C{maximum number of characters simultaneously present in current lines of open files and in control sequences between \.{\\csname} and \.{\\endcsname}; must not exceed \\{max\_halfword}}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{error\_line}\K{}$\T{72}\5
+\2${}\}{}$;\C{width of context lines on terminal error messages}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{half\_error\_line}\K{}$\T{42}\5
+\2${}\}{}$;\C{width of first lines of contexts in terminal error messages; should be between 30 and $\\{error\_line}-\T{15}$}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{max\_print\_line}\K{}$\T{79}\5
+\2${}\}{}$;\C{width of longest text lines output; should be at least 60}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{stack\_size}\K{}$\T{200}\5
+\2${}\}{}$;\C{maximum number of simultaneous input sources}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{max\_in\_open}\K{}$\T{6}\5
+\2${}\}{}$;\C{maximum number of input files and error insertions that can be going on simultaneously}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{font\_max}\K{}$\T{75}\5
+\2${}\}{}$;\C{maximum internal font number; must not exceed \\{max\_quarterword} and must be at most $\\{font\_base}+\T{256}$}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{font\_mem\_size}\K{}$\T{20000}\5
+\2${}\}{}$;\C{number of words of \\{font\_info} for all fonts}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{param\_size}\K{}$\T{60}\5
+\2${}\}{}$;\C{maximum number of simultaneous macro parameters}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{nest\_size}\K{}$\T{40}\5
+\2${}\}{}$;\C{maximum number of semantic levels simultaneously active}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{max\_strings}\K{}$\T{3000}\5
+\2${}\}{}$;\C{maximum number of strings; must not exceed \\{max\_halfword}}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{string\_vacancies}\K{}$\T{8000}\5
+\2${}\}{}$;\C{the minimum number of characters that should be available for the user's control sequences and font names, after \TeX's own error messages are stored}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{pool\_size}\K{}$\T{32000}\5
+\2${}\}{}$;\C{maximum number of characters in strings, including all error messages and help texts, and the names of all fonts and control sequences; must exceed \\{string\_vacancies} by the total length of \TeX's own strings, which is currently
+about 23000}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{save\_size}\K{}$\T{600}\5
+\2${}\}{}$;\C{space for saving values outside of current group; must be at most \\{max\_halfword}}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{trie\_size}\K{}$\T{8000}\5
+\2${}\}{}$;\C{space for hyphenation patterns; should be larger for \.{INITEX} than it is in production versions of \TeX}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{trie\_op\_size}\K{}$\T{500}\5
+\2${}\}{}$;\C{space for ``opcodes'' in the hyphenation patterns}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{dvi\_buf\_size}\K{}$\T{800}\5
+\2${}\}{}$;\C{size of the output buffer; must be a multiple of 8}\6
+\&{enum} ${}\{{}$\5
+\1${}\\{file\_name\_size}\K{}$\T{40}\5
+\2${}\}{}$;\C{file names shouldn't be longer than this}\6
+\&{const} \&{char} ${}{*}\\{pool\_name}\K\.{"TeXformats:TEX.POOL}\)\.{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ "}{}$;\C{string of length \\{file\_name\_size}; tells where the string pool appears}\par
+\U4.\fi
+
+\M{12}Like the preceding parameters, the following quantities can be changed
+at compile time to extend or reduce \TeX's capacity. But if they are changed,
+it is necessary to rerun the initialization program \.{INITEX}
+to generate new tables for the production \TeX\ program.
+One can't simply make helter-skelter changes to the following constants,
+since certain rather complex initialization
+numbers are computed from them. They are defined here using
+\.{WEB} macros, instead of being put into \PASCAL's list, in order to
+emphasize this distinction.
+
+\Y\B\4\D$\\{mem\_bot}$ \5
+\T{0}\C{smallest index in the \\{mem} array dumped by \.{INITEX}; must not be less than \\{mem\_min}}\par
+\B\4\D$\\{mem\_top}$ \5
+\T{30000}\C{largest index in the \\{mem} array dumped by \.{INITEX}; must be substantially larger than \\{mem\_bot} and not greater than \\{mem\_max}}\par
+\B\4\D$\\{font\_base}$ \5
+\T{0}\C{smallest internal font number; must not be less than \\{min\_quarterword}}\par
+\B\4\D$\\{hash\_size}$ \5
+\T{2100}\C{maximum number of control sequences; it should be at most about $(\\{mem\_max}-\\{mem\_min})/{}$(\&{double}) \T{10}}\par
+\B\4\D$\\{hash\_prime}$ \5
+\T{1777}\C{a prime number equal to about 85\pct! of \\{hash\_size}}\par
+\B\4\D$\\{hyph\_size}$ \5
+\T{307}\C{another prime; the number of \.{\\hyphenation} exceptions}\par
+\fi
+
+\M{13}In case somebody has inadvertently made bad settings of the ``constants,''
+\TeX\ checks them using a global variable called \\{bad}.
+
+This is the first of many sections of \TeX\ where global variables are
+defined.
+
+\Y\B\4\X13:Global variables\X${}\E{}$\6
+\&{int} \\{bad};\C{is some ``constant'' wrong?}\par
+\As20, 26, 30, 32, 39, 50, 54, 73, 76, 79, 96, 104, 115, 116, 117, 118, 124, 165, 173, 181, 213, 246, 253, 256, 271, 286, 297, 301, 304, 305, 308, 309, 310, 333, 361, 382, 387, 388, 410, 438, 447, 480, 489, 493, 512, 513, 520, 526, 532, 539, 549, 550,
+555, 592, 595, 605, 616, 646, 647, 661, 684, 719, 724, 764, 770, 814, 821, 823, 825, 828, 833, 839, 847, 872, 892, 900, 905, 907, 921, 926, 943, 947, 950, 971, 980, 982, 989, 1032, 1074, 1266, 1281, 1299, 1305, 1331, 1342\ETs1345.
+\U4.\fi
+
+\M{14}Later on we will say `\ignorespaces\&{if} ${}(\\{mem\_max}\G\\{max\_halfword})$ $\\{bad}\K\T{14}$',
+or something similar. (We can't do that until \\{max\_halfword} has been defined.)
+
+\Y\B\4\X14:Check the ``constant'' values for consistency\X${}\E{}$\6
+$\\{bad}\K\T{0};{}$\6
+\&{if} ${}((\\{half\_error\_line}<\T{30})\V(\\{half\_error\_line}>\\{error\_line}-\T{15})){}$\1\5
+${}\\{bad}\K\T{1};{}$\2\6
+\&{if} ${}(\\{max\_print\_line}<\T{60}){}$\1\5
+${}\\{bad}\K\T{2};{}$\2\6
+\&{if} ${}(\\{dvi\_buf\_size}\MOD\T{8}\I\T{0}){}$\1\5
+${}\\{bad}\K\T{3};{}$\2\6
+\&{if} ${}(\\{mem\_bot}+\T{1100}>\\{mem\_top}){}$\1\5
+${}\\{bad}\K\T{4};{}$\2\6
+\&{if} ${}(\\{hash\_prime}>\\{hash\_size}){}$\1\5
+${}\\{bad}\K\T{5};{}$\2\6
+\&{if} ${}(\\{max\_in\_open}\G\T{128}){}$\1\5
+${}\\{bad}\K\T{6};{}$\2\6
+\&{if} ${}(\\{mem\_top}<\T{256}+\T{11}){}$\1\5
+${}\\{bad}\K\T{7}{}$;\C{we will want $\\{null\_list}>\T{255}$}\2\par
+\As111, 290, 521\ETs1249.
+\U1332.\fi
+
+\M{15}Labels are given symbolic names by the following definitions, so that
+occasional \&{goto} statements will be meaningful. We insert the label
+`\\{end}' just before the `\ignorespaces$\}$\unskip' of a procedure in
+which we have used the `\&{goto} \\{end}' statement defined below; the label
+`\\{restart}' is occasionally used at the very beginning of a procedure; and
+the label `\\{reswitch}' is occasionally used just prior to a \&{case}
+statement in which some cases change the conditions and we wish to branch
+to the newly applicable case. Loops that are set up with the \&{loop}
+construction defined below are commonly exited by going to `\\{done}' or to
+`\\{found}' or to `\\{not\_found}', and they are sometimes repeated by going to
+`\\{resume}'. If two or more parts of a subroutine start differently but
+end up the same, the shared code may be gathered together at
+`\\{common\_ending}'.
+
+Incidentally, this program never declares a label that isn't actually used,
+because some fussy \PASCAL\ compilers will complain about redundant labels.
+
+\Y\B\4\D$\\{done6}$ \5
+\T{36}\C{for exiting the sixth loop in a block}\par
+\fi
+
+\M{16}Here are some macros for common programming idioms.
+
+\Y\B\4\D$\\{incr}(\|X)$ \5
+$\|X\K\|X+{}$\T{1}\C{increase a variable by unity}\par
+\B\4\D$\\{decr}(\|X)$ \5
+$\|X\K\|X-{}$\T{1}\C{decrease a variable by unity}\par
+\B\4\D$\\{negate}(\|X)$ \5
+$\|X\K{-}{}$\|X\C{change the sign of a variable}\par
+\B\4\D$\&{loop}$ \5
+\&{while} (\\{true})\5
+\C{repeat over and over until a \&{goto} happens}\par
+\B\F\\{loop} \5
+\\{else}\C{\.{WEB}'s \&{else} acts like `\ignorespaces\&{while} \\{true} \&{do}\unskip'}\par
+\B\4\D$\\{do\_nothing}$ \C{empty statement}\par
+\B\4\D$\\{empty}$ \5
+\T{0}\C{symbolic name for a null constant}\par
+\fi
+
+\N{1}{17}The character set.
+In order to make \TeX\ readily portable to a wide variety of
+computers, all of its input text is converted to an internal eight-bit
+code that includes standard ASCII, the ``American Standard Code for
+Information Interchange.'' This conversion is done immediately when each
+character is read in. Conversely, characters are converted from ASCII to
+the user's external representation just before they are output to a
+text file.
+
+Such an internal code is relevant to users of \TeX\ primarily because it
+governs the positions of characters in the fonts. For example, the
+character `\.A' has ASCII code $65=0101$, and when \TeX\ typesets
+this letter it specifies character number 65 in the current font.
+If that font actually has `\.A' in a different position, \TeX\ doesn't
+know what the real position is; the program that does the actual printing from
+\TeX's device-independent files is responsible for converting from ASCII to
+a particular font encoding.
+
+\TeX's internal code also defines the value of constants
+that begin with a reverse apostrophe; and it provides an index to the
+\.{\\catcode}, \.{\\mathcode}, \.{\\uccode}, \.{\\lccode}, and \.{\\delcode}
+tables.
+
+\fi
+
+\M{18}Characters of text that have been converted to \TeX's internal form
+are said to be of type \\{ASCII\_code}, which is a subrange of the integers.
+
+\Y\B\4\X18:Types in the outer block\X${}\E{}$\6
+\&{typedef} \&{uint8\_t} \&{ASCII\_code};\C{eight-bit numbers}\par
+\As25, 38, 101, 109, 113, 150, 212, 269, 300, 548, 594, 920\ETs925.
+\U4.\fi
+
+\M{19}The original \PASCAL\ compiler was designed in the late 60s, when six-bit
+character sets were common, so it did not make provision for lowercase
+letters. Nowadays, of course, we need to deal with both capital and small
+letters in a convenient way, especially in a program for typesetting;
+so the present specification of \TeX\ has been written under the assumption
+that the \PASCAL\ compiler and run-time system permit the use of text files
+with more than 64 distinguishable characters. More precisely, we assume that
+the character set contains at least the letters and symbols associated
+with ASCII codes 040 through 0176; all of these characters are now
+available on most computer terminals.
+
+Since we are dealing with more characters than were present in the first
+\PASCAL\ compilers, we have to decide what to call the associated data
+type. Some \PASCAL s use the original name \&{unsigned} \&{char} for the
+characters in text files, even though there now are more than 64 such
+characters, while other \PASCAL s consider \&{unsigned} \&{char} to be a 64-element
+subrange of a larger data type that has some other name.
+
+In order to accommodate this difference, we shall use the name \\{text\_char}
+to stand for the data type of the characters that are converted to and
+from \&{ASCII\_code} when they are input and output. We shall also assume
+that \\{text\_char} consists of the elements \\{chr}(\\{first\_text\_char}) through
+\\{chr}(\\{last\_text\_char}), inclusive. The following definitions should be
+adjusted if necessary.
+
+\Y\B\4\D$\\{text\_char}$ \5
+\&{unsigned} \&{char}\C{the data type of characters in text files}\par
+\B\4\D$\\{first\_text\_char}$ \5
+\T{0}\C{ordinal number of the smallest element of \\{text\_char}}\par
+\B\4\D$\\{last\_text\_char}$ \5
+\T{255}\C{ordinal number of the largest element of \\{text\_char}}\par
+\Y\B\4\X19:Local variables for initialization\X${}\E{}$\6
+\&{int} \|i;\par
+\As163\ET927.
+\U4.\fi
+
+\M{20}The \TeX\ processor converts between ASCII code and
+the user's external character set by means of arrays \\{xord} and \\{xchr}
+that are analogous to \PASCAL's \\{ord} and \\{chr} functions.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{ASCII\_code} \\{xord}[\T{256}];\C{specifies conversion of input characters}\6
+\&{uint8\_t} \\{xchr}[\T{256}];\C{specifies conversion of output characters}\par
+\fi
+
+\M{21}Since we are assuming that our \PASCAL\ system is able to read and
+write the visible characters of standard ASCII (although not
+necessarily using the ASCII codes to represent them), the following
+assignment statements initialize the standard part of the \\{xchr} array
+properly, without needing any system-dependent changes. On the other
+hand, it is possible to implement \TeX\ with less complete character
+sets, and in such cases it will be necessary to change something here.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\E{}$\6
+$\\{xchr}[\T{\~40}]\K\.{'\ '};{}$\5
+${}\\{xchr}[\T{\~41}]\K\.{'!'};{}$\5
+${}\\{xchr}[\T{\~42}]\K\.{'"'};{}$\5
+${}\\{xchr}[\T{\~43}]\K\.{'\#'};{}$\5
+${}\\{xchr}[\T{\~44}]\K\.{'\$'};{}$\5
+${}\\{xchr}[\T{\~45}]\K\.{'\%'};{}$\5
+${}\\{xchr}[\T{\~46}]\K\.{'\&'};{}$\5
+${}\\{xchr}[\T{\~47}]\K\.{'\\''}{}$;\6
+${}\\{xchr}[\T{\~50}]\K\.{'('};{}$\5
+${}\\{xchr}[\T{\~51}]\K\.{')'};{}$\5
+${}\\{xchr}[\T{\~52}]\K\.{'*'};{}$\5
+${}\\{xchr}[\T{\~53}]\K\.{'+'};{}$\5
+${}\\{xchr}[\T{\~54}]\K\.{','};{}$\5
+${}\\{xchr}[\T{\~55}]\K\.{'-'};{}$\5
+${}\\{xchr}[\T{\~56}]\K\.{'.'};{}$\5
+${}\\{xchr}[\T{\~57}]\K\.{'/'}{}$;\6
+${}\\{xchr}[\T{\~60}]\K\.{'0'};{}$\5
+${}\\{xchr}[\T{\~61}]\K\.{'1'};{}$\5
+${}\\{xchr}[\T{\~62}]\K\.{'2'};{}$\5
+${}\\{xchr}[\T{\~63}]\K\.{'3'};{}$\5
+${}\\{xchr}[\T{\~64}]\K\.{'4'};{}$\5
+${}\\{xchr}[\T{\~65}]\K\.{'5'};{}$\5
+${}\\{xchr}[\T{\~66}]\K\.{'6'};{}$\5
+${}\\{xchr}[\T{\~67}]\K\.{'7'}{}$;\6
+${}\\{xchr}[\T{\~70}]\K\.{'8'};{}$\5
+${}\\{xchr}[\T{\~71}]\K\.{'9'};{}$\5
+${}\\{xchr}[\T{\~72}]\K\.{':'};{}$\5
+${}\\{xchr}[\T{\~73}]\K\.{';'};{}$\5
+${}\\{xchr}[\T{\~74}]\K\.{'<'};{}$\5
+${}\\{xchr}[\T{\~75}]\K\.{'='};{}$\5
+${}\\{xchr}[\T{\~76}]\K\.{'>'};{}$\5
+${}\\{xchr}[\T{\~77}]\K\.{'?'}{}$;\6
+${}\\{xchr}[\T{\~100}]\K\.{'@'};{}$\5
+${}\\{xchr}[\T{\~101}]\K\.{'A'};{}$\5
+${}\\{xchr}[\T{\~102}]\K\.{'B'};{}$\5
+${}\\{xchr}[\T{\~103}]\K\.{'C'};{}$\5
+${}\\{xchr}[\T{\~104}]\K\.{'D'};{}$\5
+${}\\{xchr}[\T{\~105}]\K\.{'E'};{}$\5
+${}\\{xchr}[\T{\~106}]\K\.{'F'};{}$\5
+${}\\{xchr}[\T{\~107}]\K\.{'G'}{}$;\6
+${}\\{xchr}[\T{\~110}]\K\.{'H'};{}$\5
+${}\\{xchr}[\T{\~111}]\K\.{'I'};{}$\5
+${}\\{xchr}[\T{\~112}]\K\.{'J'};{}$\5
+${}\\{xchr}[\T{\~113}]\K\.{'K'};{}$\5
+${}\\{xchr}[\T{\~114}]\K\.{'L'};{}$\5
+${}\\{xchr}[\T{\~115}]\K\.{'M'};{}$\5
+${}\\{xchr}[\T{\~116}]\K\.{'N'};{}$\5
+${}\\{xchr}[\T{\~117}]\K\.{'O'}{}$;\6
+${}\\{xchr}[\T{\~120}]\K\.{'P'};{}$\5
+${}\\{xchr}[\T{\~121}]\K\.{'Q'};{}$\5
+${}\\{xchr}[\T{\~122}]\K\.{'R'};{}$\5
+${}\\{xchr}[\T{\~123}]\K\.{'S'};{}$\5
+${}\\{xchr}[\T{\~124}]\K\.{'T'};{}$\5
+${}\\{xchr}[\T{\~125}]\K\.{'U'};{}$\5
+${}\\{xchr}[\T{\~126}]\K\.{'V'};{}$\5
+${}\\{xchr}[\T{\~127}]\K\.{'W'}{}$;\6
+${}\\{xchr}[\T{\~130}]\K\.{'X'};{}$\5
+${}\\{xchr}[\T{\~131}]\K\.{'Y'};{}$\5
+${}\\{xchr}[\T{\~132}]\K\.{'Z'};{}$\5
+${}\\{xchr}[\T{\~133}]\K\.{'['};{}$\5
+${}\\{xchr}[\T{\~134}]\K\.{'\\\\'};{}$\5
+${}\\{xchr}[\T{\~135}]\K\.{']'};{}$\5
+${}\\{xchr}[\T{\~136}]\K\.{'\^'};{}$\5
+${}\\{xchr}[\T{\~137}]\K\.{'\_'}{}$;\6
+${}\\{xchr}[\T{\~140}]\K\.{'`'};{}$\5
+${}\\{xchr}[\T{\~141}]\K\.{'a'};{}$\5
+${}\\{xchr}[\T{\~142}]\K\.{'b'};{}$\5
+${}\\{xchr}[\T{\~143}]\K\.{'c'};{}$\5
+${}\\{xchr}[\T{\~144}]\K\.{'d'};{}$\5
+${}\\{xchr}[\T{\~145}]\K\.{'e'};{}$\5
+${}\\{xchr}[\T{\~146}]\K\.{'f'};{}$\5
+${}\\{xchr}[\T{\~147}]\K\.{'g'}{}$;\6
+${}\\{xchr}[\T{\~150}]\K\.{'h'};{}$\5
+${}\\{xchr}[\T{\~151}]\K\.{'i'};{}$\5
+${}\\{xchr}[\T{\~152}]\K\.{'j'};{}$\5
+${}\\{xchr}[\T{\~153}]\K\.{'k'};{}$\5
+${}\\{xchr}[\T{\~154}]\K\.{'l'};{}$\5
+${}\\{xchr}[\T{\~155}]\K\.{'m'};{}$\5
+${}\\{xchr}[\T{\~156}]\K\.{'n'};{}$\5
+${}\\{xchr}[\T{\~157}]\K\.{'o'}{}$;\6
+${}\\{xchr}[\T{\~160}]\K\.{'p'};{}$\5
+${}\\{xchr}[\T{\~161}]\K\.{'q'};{}$\5
+${}\\{xchr}[\T{\~162}]\K\.{'r'};{}$\5
+${}\\{xchr}[\T{\~163}]\K\.{'s'};{}$\5
+${}\\{xchr}[\T{\~164}]\K\.{'t'};{}$\5
+${}\\{xchr}[\T{\~165}]\K\.{'u'};{}$\5
+${}\\{xchr}[\T{\~166}]\K\.{'v'};{}$\5
+${}\\{xchr}[\T{\~167}]\K\.{'w'}{}$;\6
+${}\\{xchr}[\T{\~170}]\K\.{'x'};{}$\5
+${}\\{xchr}[\T{\~171}]\K\.{'y'};{}$\5
+${}\\{xchr}[\T{\~172}]\K\.{'z'};{}$\5
+${}\\{xchr}[\T{\~173}]\K\.{'\{'};{}$\5
+${}\\{xchr}[\T{\~174}]\K\.{'|'};{}$\5
+${}\\{xchr}[\T{\~175}]\K\.{'\}'};{}$\5
+${}\\{xchr}[\T{\~176}]\K\.{'\~'}{}$;\par
+\As23, 24, 74, 77, 80, 97, 166, 215, 254, 257, 272, 287, 383, 439, 481, 490, 551, 556, 593, 596, 606, 648, 662, 685, 771, 928, 990, 1033, 1267, 1282, 1300\ETs1343.
+\U8.\fi
+
+\M{22}Some of the ASCII codes without visible characters have been given symbolic
+names in this program because they are used with a special meaning.
+
+\Y\B\4\D$\\{null\_code}$ \5
+\T{\~0}\C{ASCII code that might disappear}\par
+\B\4\D$\\{carriage\_return}$ \5
+\T{\~15}\C{ASCII code used at end of line}\par
+\B\4\D$\\{invalid\_code}$ \5
+\T{\~177}\C{ASCII code that many systems prohibit in text files}\par
+\fi
+
+\M{23}The ASCII code is ``standard'' only to a certain extent, since many
+computer installations have found it advantageous to have ready access
+to more than 94 printing characters. Appendix~C of {\sl The \TeX book\/}
+gives a complete specification of the intended correspondence between
+characters and \TeX's internal representation.
+
+If \TeX\ is being used
+on a garden-variety \PASCAL\ for which only standard ASCII
+codes will appear in the input and output files, it doesn't really matter
+what codes are specified in $\\{xchr}[\T{0}\dotdot\T{\~37}]$, but the safest policy is to
+blank everything out by using the code shown below.
+
+However, other settings of \\{xchr} will make \TeX\ more friendly on
+computers that have an extended character set, so that users can type things
+like `\.^^Z' instead of `\.{\\ne}'. People with extended character sets can
+assign codes arbitrarily, giving an \\{xchr} equivalent to whatever
+characters the users of \TeX\ are allowed to have in their input files.
+It is best to make the codes correspond to the intended interpretations as
+shown in Appendix~C whenever possible; but this is not necessary. For
+example, in countries with an alphabet of more than 26 letters, it is
+usually best to map the additional letters into codes less than~040.
+To get the most ``permissive'' character set, change \.{'\ '} on the
+right of these assignment statements to \\{chr}(\|i).
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|i\K\T{0};{}$ ${}\|i\Z\T{\~37};{}$ ${}\|i\PP){}$\1\5
+${}\\{xchr}[\|i]\K\.{'\ '};{}$\2\6
+\&{for} ${}(\|i\K\T{\~177};{}$ ${}\|i\Z\T{\~377};{}$ ${}\|i\PP){}$\1\5
+${}\\{xchr}[\|i]\K\.{'\ '}{}$;\2\par
+\fi
+
+\M{24}The following system-independent code makes the \\{xord} array contain a
+suitable inverse to the information in \\{xchr}. Note that if $\\{xchr}[\|i]\E\\{xchr}[\|j]$
+where $\|i<\|j<\T{\~177}$, the value of \\{xord}[\\{xchr}[\|i]] will turn out to be
+\|j or more; hence, standard ASCII code numbers will be used instead of
+codes below 040 in case there is a coincidence.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|i\K\\{first\_text\_char};{}$ ${}\|i\Z\\{last\_text\_char};{}$ ${}\|i\PP){}$\1\5
+${}\\{xord}[\\{chr}(\|i)]\K\\{invalid\_code};{}$\2\6
+\&{for} ${}(\|i\K\T{\~200};{}$ ${}\|i\Z\T{\~377};{}$ ${}\|i\PP){}$\1\5
+${}\\{xord}[\\{xchr}[\|i]]\K\|i;{}$\2\6
+\&{for} ${}(\|i\K\T{0};{}$ ${}\|i\Z\T{\~176};{}$ ${}\|i\PP){}$\1\5
+${}\\{xord}[\\{xchr}[\|i]]\K\|i{}$;\2\par
+\fi
+
+\N{1}{25}Input and output.
+The bane of portability is the fact that different operating systems treat
+input and output quite differently, perhaps because computer scientists
+have not given sufficient attention to this problem. People have felt somehow
+that input and output are not part of ``real'' programming. Well, it is true
+that some kinds of programming are more fun than others. With existing
+input/output conventions being so diverse and so messy, the only sources of
+joy in such parts of the code are the rare occasions when one can find a
+way to make the program a little less bad than it might have been. We have
+two choices, either to attack I/O now and get it over with, or to postpone
+I/O until near the end. Neither prospect is very attractive, so let's
+get it over with.
+
+The basic operations we need to do are (1)~inputting and outputting of
+text, to or from a file or the user's terminal; (2)~inputting and
+outputting of eight-bit bytes, to or from a file; (3)~instructing the
+operating system to initiate (``open'') or to terminate (``close'') input or
+output from a specified file; (4)~testing whether the end of an input
+file has been reached.
+
+\TeX\ needs to deal with two kinds of files.
+We shall use the term \\{alpha\_file} for a file that contains textual data,
+and the term \\{byte\_file} for a file that contains eight-bit binary information.
+These two types turn out to be the same on many computers, but
+sometimes there is a significant distinction, so we shall be careful to
+distinguish between them. Standard protocols for transferring
+such files from computer to computer, via high-speed networks, are
+now becoming available to more and more communities of users.
+
+The program actually makes use also of a third kind of file, called a
+\\{word\_file}, when dumping and reloading base information for its own
+initialization. We shall define a word file later; but it will be possible
+for us to specify simple operations on word files before they are defined.
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint8\_t} \&{eight\_bits};\C{unsigned one-byte quantity}\6
+\&{typedef} \&{struct} ${}\{{}$\5
+\1\&{FILE} ${}{*}\|f{}$;\5
+\\{text\_char}\,\|d;\5
+\2${}\}{}$ \&{alpha\_file};\C{files that contain textual data}\6
+\&{typedef} \&{struct} ${}\{{}$\5
+\1\&{FILE} ${}{*}\|f{}$;\5
+\&{eight\_bits}\, \|d;\5
+\2${}\}{}$ \&{byte\_file};\C{files that contain binary data}\par
+\fi
+
+\M{26}Most of what we need to do with respect to input and output can be handled
+by the I/O facilities that are standard in \PASCAL, i.e., the routines
+called \\{get}, \\{put}, \\{eof}, and so on. But
+standard \PASCAL\ does not allow file variables to be associated with file
+names that are determined at run time, so it cannot be used to implement
+\TeX; some sort of extension to \PASCAL's ordinary \\{reset} and \\{rewrite}
+is crucial for our purposes. We shall assume that \\{name\_of\_file} is a variable
+of an appropriate type such that the \PASCAL\ run-time system being used to
+implement \TeX\ can open a file whose external name is specified by
+\\{name\_of\_file}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} ${}\\{name\_of\_file0}[\\{file\_name\_size}+\T{1}]\K\{\T{0}\},{}$ ${}{*\&{const}\ }\\{name\_of\_file}\K\\{name\_of\_file0}-\T{1};{}$\C{on some systems this may be a \&{record} variable}\7
+\&{uint8\_t} \\{name\_length};\C{this many characters are actually relevant in \\{name\_of\_file} (the rest are blank)}\par
+\fi
+
+\M{27}The \ph\ compiler with which the present version of \TeX\ was prepared has
+extended the rules of \PASCAL\ in a very convenient way. To open file~\|f,
+we can write
+$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
+\\{reset} $(\|f,$ $\hbox{\\{name}},$ \.{"/O"} )&for input;\cr
+\\{rewrite} $(\|f,$ $\hbox{\\{name}},$ \.{"/O"} )&for output.\cr}}$$
+The `\\{name}' parameter, which is of type `{\bf packed array
+$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
+the external file that is being opened for input or output.
+Blank spaces that might appear in \\{name} are ignored.
+
+The `\.{/O}' parameter tells the operating system not to issue its own
+error messages if something goes wrong. If a file of the specified name
+cannot be found, or if such a file cannot be opened for some other reason
+(e.g., someone may already be trying to write the same file), we will have
+$\\{erstat}(\|f)\I\T{0}$ after an unsuccessful \\{reset} or \\{rewrite}. This allows
+\TeX\ to undertake appropriate corrective action.
+
+\TeX's file-opening procedures return \\{false} if no file identified by
+\\{name\_of\_file} could be opened.
+
+\Y\B\4\D$\\{reset\_OK}(\|X)$ \5
+$\\{erstat}(\|X)\E{}$\T{0}\par
+\B\4\D$\\{rewrite\_OK}(\|X)$ \5
+$\\{erstat}(\|X)\E{}$\T{0}\par
+\Y\B\&{bool} \\{a\_open\_in}(\&{alpha\_file} ${}{*}\|f{}$)\C{open a text file for input}\6
+${}\{{}$\5
+\1${}\\{reset}(({*}\|f),\39\\{name\_of\_file},\39\.{"r"});{}$\5
+\&{return} \\{reset\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{bool} \\{a\_open\_out}(\&{alpha\_file} ${}{*}\|f{}$)\C{open a text file for output}\6
+${}\{{}$\5
+\1${}\\{rewrite}(({*}\|f),\39\\{name\_of\_file},\39\.{"w"});{}$\5
+\&{return} \\{rewrite\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{bool} \\{b\_open\_in}(\&{byte\_file} ${}{*}\|f{}$)\C{open a binary file for input}\6
+${}\{{}$\5
+\1${}\\{reset}(({*}\|f),\39\\{name\_of\_file},\39\.{"rb"});{}$\5
+\&{return} \\{reset\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{bool} \\{b\_open\_out}(\&{byte\_file} ${}{*}\|f{}$)\C{open a binary file for output}\6
+${}\{{}$\5
+\1${}\\{rewrite}(({*}\|f),\39\\{name\_of\_file},\39\.{"wb"});{}$\5
+\&{return} \\{rewrite\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{bool} ${}\\{w\_open\_in}(\\{word\_file}*\|f{}$)\C{open a word file for input}\6
+${}\{{}$\5
+\1${}\\{reset}(({*}\|f),\39\\{name\_of\_file},\39\.{"rb"});{}$\5
+\&{return} \\{reset\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{bool} ${}\\{w\_open\_out}(\\{word\_file}*\|f{}$)\C{open a word file for output}\6
+${}\{{}$\5
+\1${}\\{rewrite}(({*}\|f),\39\\{name\_of\_file},\39\.{"wb"});{}$\5
+\&{return} \\{rewrite\_OK}${}(({*}\|f));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{28}Files can be closed with the \ph\ routine `\\{close}(\|f)', which
+should be used when all input or output with respect to \|f has been completed.
+This makes \|f available to be opened again, if desired; and if \|f was used for
+output, the \\{close} operation makes the corresponding external file appear
+on the user's area, ready to be read.
+
+These procedures should not generate error messages if a file is
+being closed before it has been successfully opened.
+
+\Y\B\&{void} \\{a\_close}(\&{alpha\_file} ${}{*}\|f{}$)\C{close a text file}\6
+${}\{{}$\5
+\1${}\\{close}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{void} \\{b\_close}(\&{byte\_file} ${}{*}\|f{}$)\C{close a binary file}\6
+${}\{{}$\5
+\1${}\\{close}(({*}\|f));{}$\6
+\4${}\}{}$\2\7
+\&{void} ${}\\{w\_close}(\\{word\_file}*\|f{}$)\C{close a word file}\6
+${}\{{}$\5
+\1${}\\{close}(({*}\|f));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{29}Binary input and output are done with \PASCAL's ordinary \\{get} and \\{put}
+procedures, so we don't have to make any other special arrangements for
+binary~I/O. Text output is also easy to do with standard \PASCAL\ routines.
+The treatment of text input is more difficult, however, because
+of the necessary translation to \&{ASCII\_code} values.
+\TeX's conventions should be efficient, and they should
+blend nicely with the user's operating environment.
+
+\fi
+
+\M{30}Input from text files is read one line at a time, using a routine called
+\\{input\_ln}. This function is defined in terms of global variables called
+\\{buffer}, \\{first}, and \\{last} that will be described in detail later; for
+now, it suffices for us to know that \\{buffer} is an array of \&{ASCII\_code}
+values, and that \\{first} and \\{last} are indices into this array
+representing the beginning and ending of a line of text.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{ASCII\_code} ${}\\{buffer}[\\{buf\_size}+\T{1}]{}$;\C{lines of characters being read}\6
+\&{uint16\_t} \\{first};\C{the first unused position in \\{buffer}}\6
+\&{uint16\_t} \\{last};\C{end of the line just input to \\{buffer}}\6
+\&{uint16\_t} \\{max\_buf\_stack};\C{largest index used in \\{buffer}}\par
+\fi
+
+\M{31}The \\{input\_ln} function brings the next line of input from the specified
+file into available positions of the buffer array and returns the value
+\\{true}, unless the file has already been entirely read, in which case it
+returns \\{false} and sets $\\{last}\K\\{first}$. In general, the \&{ASCII\_code}
+numbers that represent the next line of the file are input into
+\\{buffer}[\\{first}], $\\{buffer}[\\{first}+\T{1}]$, \dots, $\\{buffer}[\\{last}-\T{1}]$; and the
+global variable \\{last} is set equal to \\{first} plus the length of the
+line. Trailing blanks are removed from the line; thus, either $\\{last}\E\\{first}$
+(in which case the line was entirely blank) or $\\{buffer}[\\{last}-\T{1}]\I\.{'\ '}$.
+
+An overflow error is given, however, if the normal actions of \\{input\_ln}
+would make $\\{last}\G\\{buf\_size}$; this is done so that other parts of \TeX\
+can safely look at the contents of $\\{buffer}[\\{last}+\T{1}]$ without overstepping
+the bounds of the \\{buffer} array. Upon entry to \\{input\_ln}, the condition
+$\\{first}<\\{buf\_size}$ will always hold, so that there is always room for an
+``empty'' line.
+
+The variable \\{max\_buf\_stack}, which is used to keep track of how large
+the \\{buf\_size} parameter must be to accommodate the present job, is
+also kept up to date by \\{input\_ln}.
+
+If the \\{bypass\_eoln} parameter is \\{true}, \\{input\_ln} will do a \\{get}
+before looking at the first character of the line; this skips over
+an \\{eoln} that was in $\|f.\|d$. The procedure does not do a \\{get} when it
+reaches the end of the line; therefore it can be used to acquire input
+from the user's terminal as well as from ordinary text files.
+
+Standard \PASCAL\ says that a file should have \\{eoln} immediately
+before \\{eof}, but \TeX\ needs only a weaker restriction: If \\{eof}
+occurs in the middle of a line, the system function \\{eoln} should return
+a \\{true} result (even though $\|f.\|d$ will be undefined).
+
+Since the inner loop of \\{input\_ln} is part of \TeX's ``inner loop''---each
+character of input comes in at this place---it is wise to reduce system
+overhead by making use of special routines that read in an entire array
+of characters at once, if such routines are available. The following
+code uses standard \PASCAL\ to illustrate what needs to be done, but
+finer tuning is often possible at well-developed \PASCAL\ sites.
+
+\Y\B\&{bool} \\{input\_ln}(\&{alpha\_file} ${}{*}\|f,\39{}$\&{bool} \\{bypass\_eoln})\C{inputs the next line or returns \\{false}}\6
+${}\{{}$\5
+\1\&{uint16\_t} \\{last\_nonblank};\C{\\{last} with trailing blanks removed}\7
+\&{if} (\\{bypass\_eoln})\1\6
+\&{if} ${}(\R\\{eof}(({*}\|f))){}$\1\5
+${}\\{get}(({*}\|f)){}$;\C{input the first character of the line into $\|f.\|d$}\2\2\6
+${}\\{last}\K\\{first}{}$;\C{cf.\ Matthew 19\thinspace:\thinspace30}\6
+\&{if} ${}(\\{eof}(({*}\|f))){}$\1\5
+\&{return} \\{false};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{last\_nonblank}\K\\{first};{}$\6
+\&{while} ${}(\R\\{eoln}(({*}\|f))){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{last}\G\\{max\_buf\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_buf\_stack}\K\\{last}+\T{1};{}$\6
+\&{if} ${}(\\{max\_buf\_stack}\E\\{buf\_size}){}$\1\5
+\X35:Report overflow of the input buffer, and abort\X;\2\6
+\4${}\}{}$\2\6
+${}\\{buffer}[\\{last}]\K\\{xord}[({*}\|f).\|d];{}$\5
+${}\\{get}(({*}\|f));{}$\5
+\\{incr}(\\{last});\6
+\&{if} ${}(\\{buffer}[\\{last}-\T{1}]\I\.{'\ '}){}$\1\5
+${}\\{last\_nonblank}\K\\{last};{}$\2\6
+\4${}\}{}$\2\6
+${}\\{last}\K\\{last\_nonblank};{}$\5
+\&{return} \\{true};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{32}The user's terminal acts essentially like other files of text, except
+that it is used both for input and for output. When the terminal is
+considered an input file, the file variable is called \\{term\_in}, and when it
+is considered an output file the file variable is \\{term\_out}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{alpha\_file} \\{term\_in};\C{the terminal as an input file}\6
+\&{alpha\_file} \\{term\_out};\C{the terminal as an output file}\par
+\fi
+
+\M{33}Here is how to open the terminal files
+in \ph. The `\.{/I}' switch suppresses the first \\{get}.
+
+\Y\B\4\D$\\{t\_open\_in}$ \5
+$\\{term\_in}.\|f\K{}$\\{stdin}\C{open the terminal for text input}\par
+\B\4\D$\\{t\_open\_out}$ \5
+$\\{term\_out}.\|f\K{}$\\{stdout}\C{open the terminal for text output}\par
+\fi
+
+\M{34}Sometimes it is necessary to synchronize the input/output mixture that
+happens on the user's terminal, and three system-dependent
+procedures are used for this
+purpose. The first of these, \\{update\_terminal}, is called when we want
+to make sure that everything we have output to the terminal so far has
+actually left the computer's internal buffers and been sent.
+The second, \\{clear\_terminal}, is called when we wish to cancel any
+input that the user may have typed ahead (since we are about to
+issue an unexpected error message). The third, \\{wake\_up\_terminal},
+is supposed to revive the terminal if the user has disabled it by
+some instruction to the operating system. The following macros show how
+these operations can be specified in \ph:
+
+\Y\B\4\D$\\{update\_terminal}$ \5
+$\\{fflush}(\\{term\_out}.\|f{}$)\C{empty the terminal output buffer}\par
+\B\4\D$\\{clear\_terminal}$ \5
+$\\{fflush}(\\{term\_in}.\|f{}$)\C{clear the terminal input buffer}\par
+\B\4\D$\\{wake\_up\_terminal}$ \5
+\\{do\_nothing}\C{cancel the user's cancellation of output}\par
+\fi
+
+\M{35}We need a special routine to read the first line of \TeX\ input from
+the user's terminal. This line is different because it is read before we
+have opened the transcript file; there is sort of a ``chicken and
+egg'' problem here. If the user types `\.{\\input paper}' on the first
+line, or if some macro invoked by that line does such an \.{\\input},
+the transcript file will be named `\.{paper.log}'; but if no \.{\\input}
+commands are performed during the first line of terminal input, the transcript
+file will acquire its default name `\.{texput.log}'. (The transcript file
+will not contain error messages generated by the first line before the
+first \.{\\input} command.)
+
+The first line is even more special if we are lucky enough to have an operating
+system that treats \TeX\ differently from a run-of-the-mill \PASCAL\ object
+program. It's nice to let the user start running a \TeX\ job by typing
+a command line like `\.{tex paper}'; in such a case, \TeX\ will operate
+as if the first line of input were `\.{paper}', i.e., the first line will
+consist of the remainder of the command line, after the part that invoked
+\TeX.
+
+The first line is special also because it may be read before \TeX\ has
+input a format file. In such cases, normal error messages cannot yet
+be given. The following code uses concepts that will be explained later.
+(If the \PASCAL\ compiler does not support non-local \&{goto}\unskip, the
+statement `\&{goto} \\{exit}(\T{0})' should be replaced by something that
+quietly terminates the program.)
+
+\Y\B\4\X35:Report overflow of the input buffer, and abort\X${}\E{}$\6
+\&{if} ${}(\\{format\_ident}\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{write\_ln}(\\{term\_out},\39\.{"Buffer\ size\ exceede}\)\.{d!"});{}$\5
+\\{exit}(\T{0});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_input}.\\{loc\_field}\K\\{first};{}$\5
+${}\\{cur\_input}.\\{limit\_field}\K\\{last}-\T{1};{}$\5
+${}\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size});{}$\6
+\4${}\}{}$\2\par
+\U31.\fi
+
+\M{36}Different systems have different ways to get started. But regardless of
+what conventions are adopted, the routine that initializes the terminal
+should satisfy the following specifications:
+
+\yskip\textindent{1)}It should open file \\{term\_in} for input from the
+terminal. (The file \\{term\_out} will already be open for output to the
+terminal.)
+
+\textindent{2)}If the user has given a command line, this line should be
+considered the first line of terminal input. Otherwise the
+user should be prompted with `\.{**}', and the first line of input
+should be whatever is typed in response.
+
+\textindent{3)}The first line of input, which might or might not be a
+command line, should appear in locations \\{first} to $\\{last}-\T{1}$ of the
+\\{buffer} array.
+
+\textindent{4)}The global variable \\{loc} should be set so that the
+character to be read next by \TeX\ is in \\{buffer}[\\{loc}]. This
+character should not be blank, and we should have $\\{loc}<\\{last}$.
+
+\yskip\noindent(It may be necessary to prompt the user several times
+before a non-blank line comes in. The prompt is `\.{**}' instead of the
+later `\.*' because the meaning is slightly different: `\.{\\input}' need
+not be typed immediately after~`\.{**}'.)
+
+\Y\B\4\D$\\{loc}$ \5
+$\\{cur\_input}.{}$\\{loc\_field}\C{location of first unread character in \\{buffer}}\par
+\fi
+
+\M{37}The following program does the required initialization
+without retrieving a possible command line.
+It should be clear how to modify this routine to deal with command lines,
+if the system permits them.
+
+\Y\B\&{bool} \\{init\_terminal}(\&{void})\C{gets the terminal input started}\6
+${}\{{}$\5
+\1\\{t\_open\_in};\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+${}\\{write}(\\{term\_out},\39\.{"**"});{}$\5
+\\{update\_terminal};\6
+\&{if} ${}(\R\\{input\_ln}({\AND}\\{term\_in},\39\\{true}){}$)\C{this shouldn't happen}\6
+${}\{{}$\5
+\1\\{write\_ln}(\\{term\_out});\5
+${}\\{write}(\\{term\_out},\39\.{"!\ End\ of\ file\ on\ th}\)\.{e\ terminal...\ why?"});{}$\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\6
+${}\\{loc}\K\\{first};{}$\6
+\&{while} ${}((\\{loc}<\\{last})\W(\\{buffer}[\\{loc}]\E\.{'\ '})){}$\1\5
+\\{incr}(\\{loc});\2\6
+\&{if} ${}(\\{loc}<\\{last}){}$\5
+${}\{{}$\5
+\1\&{return} \\{true};\C{return unless the line was all blank}\6
+\4${}\}{}$\2\6
+${}\\{write\_ln}(\\{term\_out},\39\.{"Please\ type\ the\ nam}\)\.{e\ of\ your\ input\ file}\)\.{."});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{38}String handling.
+Control sequence names and diagnostic messages are variable-length strings
+of eight-bit characters. Since \PASCAL\ does not have a well-developed string
+mechanism, \TeX\ does all of its string processing by homegrown methods.
+
+Elaborate facilities for dynamic strings are not needed, so all of the
+necessary operations can be handled with a simple data structure.
+The array \\{str\_pool} contains all of the (eight-bit) ASCII codes in all
+of the strings, and the array \\{str\_start} contains indices of the starting
+points of each string. Strings are referred to by integer numbers, so that
+string number \|s comprises the characters \\{str\_pool}[\|j] for
+$\\{str\_start}[\|s]\Z\|j<\\{str\_start}[\|s+\T{1}]$. Additional integer variables
+\\{pool\_ptr} and \\{str\_ptr} indicate the number of entries used so far
+in \\{str\_pool} and \\{str\_start}, respectively; locations
+\\{str\_pool}[\\{pool\_ptr}] and \\{str\_start}[\\{str\_ptr}] are
+ready for the next string to be allocated.
+
+String numbers 0 to 255 are reserved for strings that correspond to single
+ASCII characters. This is in accordance with the conventions of \.{WEB},
+which converts single-character strings into the ASCII code number of the
+single character involved, while it converts other strings into integers
+and builds a string pool file. Thus, when the string constant \.{"."} appears
+in the program below, \.{WEB} converts it into the integer 46, which is the
+ASCII code for a period, while \.{WEB} will convert a string like \.{"hello"}
+into some integer greater than~255. String number 46 will presumably be the
+single character `\..'; but some ASCII codes have no standard visible
+representation, and \TeX\ sometimes needs to be able to print an arbitrary
+ASCII character, so the first 256 strings are used to specify exactly what
+should be printed for each of the 256 possibilities.
+
+Elements of the \\{str\_pool} array must be ASCII codes that can actually
+be printed; i.e., they must have an \\{xchr} equivalent in the local
+character set. (This restriction applies only to preloaded strings,
+not to those generated dynamically by the user.)
+
+Some \PASCAL\ compilers won't pack integers into a single byte unless the
+integers lie in the range ${-}\T{128}\dotdot\T{127}$. To accommodate such systems
+we access the string pool only via macros that can easily be redefined.
+
+\Y\B\4\D$\\{si}(\|X)$ \5
+\|X\C{convert from \&{ASCII\_code} to \\{packed\_ASCII\_code}}\par
+\B\4\D$\\{so}(\|X)$ \5
+\|X\C{convert from \\{packed\_ASCII\_code} to \&{ASCII\_code}}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint16\_t} \&{pool\_pointer};\C{for variables that point into \\{str\_pool}}\6
+\&{typedef} \&{uint16\_t} \&{str\_number};\C{for variables that point into \\{str\_start}}\6
+\&{typedef} \&{uint8\_t} \&{packed\_ASCII\_code};\C{elements of \\{str\_pool} array}\par
+\fi
+
+\M{39}\B\X13:Global variables\X${}\mathrel+\E{}$\6
+\X1795:prepare for string pool initialization\X\6
+\&{packed\_ASCII\_code} ${}\\{str\_pool}[\\{pool\_size}+\T{1}]$ $\K$ \X1793:\\{str\_pool} initialization\X;\C{the characters}\7
+\&{pool\_pointer} ${}\\{str\_start}[\\{max\_strings}+\T{1}]\K\{\X1794:\\{str\_start} initialization\X\}{}$;\C{the starting pointers}\6
+\&{pool\_pointer} \\{pool\_ptr} $\K$ \X1796:\\{pool\_ptr} initialization\X;\C{first unused position in \\{str\_pool}}\6
+\&{str\_number} \\{str\_ptr} $\K$ \X1797:\\{str\_ptr} initialization\X;\C{number of the current string being created}\7
+\&{pool\_pointer} \\{init\_pool\_ptr};\C{the starting value of \\{pool\_ptr}}\6
+\&{str\_number} \\{init\_str\_ptr};\C{the starting value of \\{str\_ptr}}\par
+\fi
+
+\M{40}Several of the elementary string operations are performed using \.{WEB}
+macros instead of \PASCAL\ procedures, because many of the
+operations are done quite frequently and we want to avoid the
+overhead of procedure calls. For example, here is
+a simple macro that computes the length of a string.
+
+\Y\B\4\D$\\{length}(\|X)$ \5
+$(\\{str\_start}[\|X+\T{1}]-\\{str\_start}[\|X]{}$)\C{the number of characters in string number \#}\par
+\fi
+
+\M{41}The length of the current string is called \\{cur\_length}:
+
+\Y\B\4\D$\\{cur\_length}$ \5
+$(\\{pool\_ptr}-\\{str\_start}[\\{str\_ptr}]{}$)\par
+\fi
+
+\M{42}Strings are created by appending character codes to \\{str\_pool}.
+The \\{append\_char} macro, defined here, does not check to see if the
+value of \\{pool\_ptr} has gotten too high; this test is supposed to be
+made before \\{append\_char} is used. There is also a \\{flush\_char}
+macro, which erases the last character appended.
+
+To test if there is room to append \|l more characters to \\{str\_pool},
+we shall write \\{str\_room}(\|l), which aborts \TeX\ and gives an
+apologetic error message if there isn't enough room.
+
+\Y\B\4\D$\\{append\_char}(\|X)$ \C{put \&{ASCII\_code} \# at the end of \\{str\_pool}}\6
+${}\{{}$\5
+\1${}\\{str\_pool}[\\{pool\_ptr}]\K\\{si}(\|X);{}$\5
+\\{incr}(\\{pool\_ptr});\6
+\4${}\}{}$\2\par
+\B\4\D$\\{flush\_char}$ \5
+\\{decr}(\\{pool\_ptr})\C{forget the last character in the pool}\par
+\B\4\D$\\{str\_room}(\|X)$ \C{make sure that the pool hasn't overflowed}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{pool\_ptr}+\|X>\\{pool\_size}){}$\1\5
+${}\\{overflow}(\.{"pool\ size"},\39\\{pool\_size}-\\{init\_pool\_ptr});{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{43}Once a sequence of characters has been appended to \\{str\_pool}, it
+officially becomes a string when the function \\{make\_string} is called.
+This function returns the identification number of the new string as its
+value.
+
+\Y\B\&{str\_number} \\{make\_string}(\&{void})\C{current string enters the pool}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{str\_ptr}\E\\{max\_strings}){}$\1\5
+${}\\{overflow}(\.{"number\ of\ strings"},\39\\{max\_strings}-\\{init\_str\_ptr});{}$\2\6
+\\{incr}(\\{str\_ptr});\5
+${}\\{str\_start}[\\{str\_ptr}]\K\\{pool\_ptr};{}$\5
+\&{return} \\{str\_ptr}${}-\T{1};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{44}To destroy the most recently made string, we say \\{flush\_string}.
+
+\Y\B\4\D$\\{flush\_string}$ \6
+${}\{{}$\5
+\1\\{decr}(\\{str\_ptr});\5
+${}\\{pool\_ptr}\K\\{str\_start}[\\{str\_ptr}];{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{45}The following subroutine compares string \|s with another string of the
+same length that appears in \\{buffer} starting at position \|k;
+the result is \\{true} if and only if the strings are equal.
+Empirical tests indicate that \\{str\_eq\_buf} is used in such a way that
+it tends to return \\{true} about 80 percent of the time.
+
+\Y\B\&{bool} \\{str\_eq\_buf}(\&{str\_number} \|s${},\39{}$\&{int} \|k)\C{test equality of strings}\6
+${}\{{}$\5
+\C{loop exit}\1\6
+\&{pool\_pointer} \|j;\C{running index}\6
+\&{bool} \\{result};\C{result of comparison}\7
+${}\|j\K\\{str\_start}[\|s];{}$\6
+\&{while} ${}(\|j<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{so}(\\{str\_pool}[\|j])\I\\{buffer}[\|k]){}$\5
+${}\{{}$\5
+\1${}\\{result}\K\\{false};{}$\5
+\&{goto} \\{not\_found};\6
+\4${}\}{}$\2\6
+\\{incr}(\|j);\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+${}\\{result}\K\\{true};{}$\6
+\4\\{not\_found}:\5
+\&{return} \\{result};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{46}Here is a similar routine, but it compares two strings in the string pool,
+and it does not assume that they have the same length.
+
+\Y\B\&{bool} \\{str\_eq\_str}(\&{str\_number} \|s${},\39{}$\&{str\_number} \|t)\C{test equality of strings}\6
+${}\{{}$\5
+\C{loop exit}\1\6
+\&{pool\_pointer} \|j${},{}$ \|k;\C{running indices}\6
+\&{bool} \\{result};\C{result of comparison}\7
+${}\\{result}\K\\{false};{}$\6
+\&{if} ${}(\\{length}(\|s)\I\\{length}(\|t)){}$\1\5
+\&{goto} \\{not\_found};\2\6
+${}\|j\K\\{str\_start}[\|s];{}$\5
+${}\|k\K\\{str\_start}[\|t];{}$\6
+\&{while} ${}(\|j<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{str\_pool}[\|j]\I\\{str\_pool}[\|k]){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\\{incr}(\|j);\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+${}\\{result}\K\\{true};{}$\6
+\4\\{not\_found}:\5
+\&{return} \\{result};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{47}The initial values of \\{str\_pool}, \\{str\_start}, \\{pool\_ptr},
+and \\{str\_ptr} are computed by the \.{INITEX} program, based in part
+on the information that \.{WEB} has output while processing \TeX.
+
+\Y\B\8\#\&{ifdef} \.{INIT}\6
+\&{bool} \\{get\_strings\_started}(\&{void})\C{initializes the string pool, but returns \\{false} if something goes wrong}\6
+${}\{{}$\5
+\1\&{int} \|k${},{}$ \|l;\C{small indices or counters}\6
+\&{uint8\_t} \|m${},{}$ \|n;\C{characters input from \\{pool\_file}}\6
+\&{str\_number} \|g;\C{garbage}\6
+\&{int} \|a;\C{accumulator for check sum}\6
+\&{bool} \|c;\C{check sum has been checked}\7
+${}\\{pool\_ptr}\K\T{0};{}$\5
+${}\\{str\_ptr}\K\T{0};{}$\5
+${}\\{str\_start}[\T{0}]\K\T{0};{}$\5
+\X48:Make the first 256 strings\X;\6
+\X51:Read the other strings from the \.{TEX.POOL} file and return \\{true}, or give an error message and return \\{false}\X;\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{48}\B\D$\\{app\_lc\_hex}(\|X)$ \5
+$\|l\K\|X;$ \6
+\&{if} ${}(\|l<\T{10}){}$\1\5
+${}\\{append\_char}(\|l+\.{'0'}){}$\5
+\2\&{else} $\\{append\_char}(\|l-\T{10}+\.{'a'}{}$)\par
+\Y\B\4\X48:Make the first 256 strings\X${}\E{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{255};{}$ ${}\|k\PP){}$\5
+${}\{{}$\1\6
+\&{if} (\X49:Character \|k cannot be printed\X)\5
+${}\{{}$\1\6
+\\{append\_char}(\.{'\^'});\5
+\\{append\_char}(\.{'\^'});\6
+\&{if} ${}(\|k<\T{\~100}){}$\1\5
+${}\\{append\_char}(\|k+\T{\~100}){}$\2\6
+\&{else} \&{if} ${}(\|k<\T{\~200}){}$\1\5
+${}\\{append\_char}(\|k-\T{\~100}){}$\2\6
+\&{else}\5
+${}\{{}$\1\6
+${}\\{app\_lc\_hex}(\|k/\T{16});{}$\5
+${}\\{app\_lc\_hex}(\|k\MOD\T{16});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{append\_char}(\|k);\2\6
+${}\|g\K\\{make\_string}(\,);{}$\6
+\4${}\}{}$\2\par
+\U47.\fi
+
+\M{49}The first 128 strings will contain 95 standard ASCII characters, and the
+other 33 characters will be printed in three-symbol form like `\.{\^\^A}'
+unless a system-dependent change is made here. Installations that have
+an extended character set, where for example \\{xchr}[\T{\~32}] $\E\hbox{\.{\'^^Z\'}}$,
+would like string 032 to be the single character 032 instead of the
+three characters 0136, 0136, 0132 (\.{\^\^Z}). On the other hand,
+even people with an extended character set will want to represent string
+015 by \.{\^\^M}, since 015 is \\{carriage\_return}; the idea is to
+produce visible strings instead of tabs or line-feeds or carriage-returns
+or bell-rings or characters that are treated anomalously in text files.
+
+Unprintable characters of codes 128--255 are, similarly, rendered
+\.{\^\^80}--\.{\^\^ff}.
+
+The boolean expression defined here should be \\{true} unless \TeX\
+internal code number~\|k corresponds to a non-troublesome visible
+symbol in the local character set. An appropriate formula for the
+extended character set recommended in {\sl The \TeX book\/} would, for
+example, be `$\|k\in[\T{0},\T{\~10}\dotdot\T{\~12},\T{\~14},\T{\~15},\T{\~33},\T{\~177}\dotdot\T{\~377}]$'.
+If character \|k cannot be printed, and $\|k<\T{\~200}$, then character $\|k+\T{\~100}$ or
+$\|k-\T{\~100}$ must be printable; moreover, ASCII codes $[\T{\~41}\dotdot\T{\~46},\T{\~60}\dotdot\T{\~71},\T{\~136},\T{\~141}\dotdot\T{\~146},\T{\~160}\dotdot\T{\~171}]$ must be printable.
+Thus, at least 81 printable characters are needed.
+
+\Y\B\4\X49:Character \|k cannot be printed\X${}\E{}$\6
+$(\|k<\.{'\ '})\V(\|k>\.{'\~'}{}$)\par
+\U48.\fi
+
+\M{50}When the \.{WEB} system program called \.{TANGLE} processes the \.{TEX.WEB}
+description that you are now reading, it outputs the \PASCAL\ program
+\.{TEX.PAS} and also a string pool file called \.{TEX.POOL}. The \.{INITEX}
+program reads the latter file, where each string appears as a two-digit decimal
+length followed by the string itself, and the information is recorded in
+\TeX's string memory.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{alpha\_file} \\{pool\_file};\C{the string-pool file output by \.{TANGLE}}\6
+\8\#\&{endif}\par
+\fi
+
+\M{51}\B\D$\\{bad\_pool}(\|X)$ \6
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+${}\\{write\_ln}(\\{term\_out},\39\|X);{}$\5
+${}\\{a\_close}({\AND}\\{pool\_file});{}$\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\par
+\Y\B\4\X51:Read the other strings from the \.{TEX.POOL} file and return \\{true}, or give an error message and return \\{false}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{int} \|k;\5
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{file\_name\_size};{}$ ${}\|k\PP){}$\1\5
+${}\\{name\_of\_file}[\|k]\K\\{pool\_name}[\|k-\T{1}]{}$;\5
+\2${}\}{}$\C{we needn't set \\{name\_length}}\2\6
+\&{if} ${}(\\{a\_open\_in}({\AND}\\{pool\_file})){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{false}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\X52:Read one string, but return \\{false} if the string memory space is getting too tight for comfort\X;\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|c));{}$\5
+${}\\{a\_close}({\AND}\\{pool\_file});{}$\5
+\&{return} \\{true};\6
+\4${}\}{}$\2\6
+\&{else} \\{bad\_pool}(\.{"!\ I\ can't\ read\ TEX.}\)\.{POOL."})\par
+\U47.\fi
+
+\M{52}\B\X52:Read one string, but return \\{false} if the string memory space is getting too tight for comfort\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{eof}(\\{pool\_file}))\1\5
+\\{bad\_pool}(\.{"!\ TEX.POOL\ has\ no\ c}\)\.{heck\ sum."});\2\6
+${}\\{read}(\\{pool\_file},\39\|m){}$;\5
+${}\\{read}(\\{pool\_file},\39\|n){}$;\C{read two digits of string length}\6
+\&{if} ${}(\|m\E\.{'*'}){}$\1\5
+\X53:Check the pool check sum\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{xord}[\|m]<\.{'0'})\V(\\{xord}[\|m]>\.{'9'})\V\30(\\{xord}[\|n]<\.{'0'})\V(\\{xord}[\|n]>\.{'9'})){}$\1\5
+\\{bad\_pool}(\.{"!\ TEX.POOL\ line\ doe}\)\.{sn't\ begin\ with\ two\ }\)\.{digits."});\2\6
+${}\|l\K\\{xord}[\|m]*\T{10}+\\{xord}[\|n]-\.{'0'}*\T{11}{}$;\C{compute the length}\6
+\&{if} ${}(\\{pool\_ptr}+\|l+\\{string\_vacancies}>\\{pool\_size}){}$\1\5
+\\{bad\_pool}(\.{"!\ You\ have\ to\ incre}\)\.{ase\ POOLSIZE."});\2\6
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\|l;{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1\&{if} (\\{eoln}(\\{pool\_file}))\1\5
+${}\|m\K\.{'\ '}{}$;\5
+\2\&{else}\1\5
+${}\\{read}(\\{pool\_file},\39\|m);{}$\2\6
+\\{append\_char}(\\{xord}[\|m]);\6
+\4${}\}{}$\2\6
+\\{read\_ln}(\\{pool\_file});\5
+${}\|g\K\\{make\_string}(\,);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U51.\fi
+
+\M{53}The \.{WEB} operation \.{@\$} denotes the value that should be at the
+end of this \.{TEX.POOL} file; any other value means that the wrong pool
+file has been loaded.
+
+\Y\B\4\X53:Check the pool check sum\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|a\K\T{0};{}$\5
+${}\|k\K\T{1};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{xord}[\|n]<\.{'0'})\V(\\{xord}[\|n]>\.{'9'})){}$\1\5
+\\{bad\_pool}(\.{"!\ TEX.POOL\ check\ su}\)\.{m\ doesn't\ have\ nine\ }\)\.{digits."});\2\6
+${}\|a\K\T{10}*\|a+\\{xord}[\|n]-\.{'0'};{}$\6
+\&{if} ${}(\|k\E\T{9}){}$\1\5
+\&{goto} \\{done};\2\6
+\\{incr}(\|k);\5
+${}\\{read}(\\{pool\_file},\39\|n);{}$\6
+\4${}\}{}$\2\6
+\4\\{done}:\6
+\&{if} ${}(\|a\I\T{0}){}$\1\5
+\\{bad\_pool}(\.{"!\ TEX.POOL\ doesn't\ }\)\.{match;\ TANGLE\ me\ aga}\)\.{in."});\2\6
+${}\|c\K\\{true};{}$\6
+\4${}\}{}$\2\par
+\U52.\fi
+
+\N{1}{54}On-line and off-line printing.
+Messages that are sent to a user's terminal and to the transcript-log file
+are produced by several `\\{print}' procedures. These procedures will
+direct their output to a variety of places, based on the setting of
+the global variable \\{selector}, which has the following possible
+values:
+
+\yskip
+\hang \\{term\_and\_log}, the normal setting, prints on the terminal and on the
+transcript file.
+
+\hang \\{log\_only}, prints only on the transcript file.
+
+\hang \\{term\_only}, prints only on the terminal.
+
+\hang \\{no\_print}, doesn't print at all. This is used only in rare cases
+before the transcript file is open.
+
+\hang \\{pseudo}, puts output into a cyclic buffer that is used
+by the \\{show\_context} routine; when we get to that routine we shall discuss
+the reasoning behind this curious mode.
+
+\hang \\{new\_string}, appends the output to the current string in the
+string pool.
+
+\hang 0 to 15, prints on one of the sixteen files for \.{\\write} output.
+
+\yskip
+\noindent The symbolic names `\\{term\_and\_log}', etc., have been assigned
+numeric codes that satisfy the convenient relations $\\{no\_print}+\T{1}\E\\{term\_only}$,
+$\\{no\_print}+\T{2}\E\\{log\_only}$, $\\{term\_only}+\T{2}\E\\{log\_only}+\T{1}\E\\{term\_and\_log}$.
+
+Three additional global variables, \\{tally} and \\{term\_offset} and
+\\{file\_offset}, record the number of characters that have been printed
+since they were most recently cleared to zero. We use \\{tally} to record
+the length of (possibly very long) stretches of printing; \\{term\_offset}
+and \\{file\_offset}, on the other hand, keep track of how many characters
+have appeared so far on the current line that has been output to the
+terminal or to the transcript file, respectively.
+
+\Y\B\4\D$\\{no\_print}$ \5
+\T{16}\C{\\{selector} setting that makes data disappear}\par
+\B\4\D$\\{term\_only}$ \5
+\T{17}\C{printing is destined for the terminal only}\par
+\B\4\D$\\{log\_only}$ \5
+\T{18}\C{printing is destined for the transcript file only}\par
+\B\4\D$\\{term\_and\_log}$ \5
+\T{19}\C{normal \\{selector} setting}\par
+\B\4\D$\\{pseudo}$ \5
+\T{20}\C{special \\{selector} setting for \\{show\_context}}\par
+\B\4\D$\\{new\_string}$ \5
+\T{21}\C{printing is deflected to the string pool}\par
+\B\4\D$\\{max\_selector}$ \5
+\T{21}\C{highest selector setting}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{alpha\_file} \\{log\_file};\C{transcript of \TeX\ session}\6
+\&{uint8\_t} \\{selector};\C{where to print a message}\6
+\&{uint8\_t} \\{dig}[\T{23}];\C{digits in a number being output}\6
+\&{int} \\{tally};\C{the number of characters recently printed}\6
+\&{uint8\_t} \\{term\_offset};\C{the number of characters on the current terminal line}\6
+\&{uint8\_t} \\{file\_offset};\C{the number of characters on the current file line}\6
+\&{ASCII\_code} ${}\\{trick\_buf}[\\{error\_line}+\T{1}]{}$;\C{circular buffer for pseudoprinting}\6
+\&{int} \\{trick\_count};\C{threshold for pseudoprinting, explained later}\6
+\&{int} \\{first\_count};\C{another variable for pseudoprinting}\par
+\fi
+
+\M{55}\B\X55:Initialize the output routines\X${}\E{}$\6
+$\\{selector}\K\\{term\_only};{}$\5
+${}\\{tally}\K\T{0};{}$\5
+${}\\{term\_offset}\K\T{0};{}$\5
+${}\\{file\_offset}\K\T{0}{}$;\par
+\As61, 527\ETs533.
+\U1332.\fi
+
+\M{56}Macro abbreviations for output to the terminal and to the log file are
+defined here for convenience. Some systems need special conventions
+for terminal output, and it is possible to adhere to those conventions
+by changing \\{wterm}, \\{wterm\_ln}, and \\{wterm\_cr} in this section.
+
+\Y\B\4\X9:Compiler directives\X${}\mathrel+\E{}$\6
+\8\#\&{define} \\{put}(\\{file}) \5${}\\{fwrite}({\AND}((\\{file}).\|d),\39{}$\&{sizeof} ${}((\\{file}).\|d),\39\T{1},\39(\\{file}).\|f){}$\6
+\8\#\&{define} \\{get}(\\{file}) \5${}\\{fread}({\AND}((\\{file}).\|d),\39{}$\&{sizeof} ${}((\\{file}).\|d),\39\T{1},\39(\\{file}).\|f){}$\6
+\8\#\&{define} ${}\\{reset}(\\{file},\39\\{name},\39\\{mode}) \5((\\{file}).\|f\K\\{fopen}{}$((\&{char} ${}{*})(\\{name})+\T{1},\39\\{mode}),\39(\\{file}).\|f\I\NULL\?\\{get}(\\{file}):\T{0}){}$\6
+\8\#\&{define} ${}\\{rewrite}(\\{file},\39\\{name},\39\\{mode}) \5((\\{file}).\|f\K\\{fopen}{}$((\&{char} ${}{*})(\\{name})+\T{1},\39\\{mode})){}$\6
+\8\#\&{define} \\{close}(\\{file}) \5${}\\{fclose}((\\{file}).\|f){}$\6
+\8\#\&{define} \\{eof}(\\{file}) \5${}\\{feof}((\\{file}).\|f){}$\6
+\8\#\&{define} \\{eoln}(\\{file}) \5${}((\\{file}).\|d\E\.{'\\n'}\V\\{eof}(\\{file})){}$\6
+\8\#\&{define} \\{erstat}(\\{file}) \5${}((\\{file}).\|f\E\NULL\?{-}\T{1}:\\{ferror}((\\{file}).\|f)){}$\6
+\8\#\&{define} ${}\\{read}(\\{file},\39\|x) \5((\|x)\K(\\{file}).\|d,\39\\{get}(\\{file})){}$\6
+\8\#\&{define} \\{read\_ln}(\\{file}) \5\&{do}\\{get}(\\{file});\&{while} ${}(\R\\{eoln}(\\{file})){}$\6
+\8\#\&{define} ${}\\{write}(\\{file},\39\\{format},\39\,\ldots\,) \5\\{fprintf}(\\{file}.\|f,\39\\{format},\39{\#}{\#}\.{\_\_VA\_ARGS\_\_}){}$\6
+\8\#\&{define} ${}\\{write\_ln}(\\{file},\39\,\ldots\,) \5\\{write}(\\{file},\39\.{\_\_VA\_ARGS\_\_}\.{"\\n"}){}$\6
+\8\#\&{define} ${}\\{wterm}(\\{format},\39\,\ldots\,) \5\\{write}(\\{term\_out},\39\\{format},\39{\#}{\#}\.{\_\_VA\_ARGS\_\_}){}$\6
+\8\#\&{define} ${}\\{wterm\_ln}(\\{format},\39\,\ldots\,) \5\\{wterm}(\\{format}\.{"\\n"},\39{\#}{\#}\.{\_\_VA\_ARGS\_\_}){}$\6
+\8\#\&{define} \\{wterm\_cr} \5${}\\{write}(\\{term\_out},\39\.{"\\n"}){}$\6
+\8\#\&{define} ${}\\{wlog}(\\{format},\39\,\ldots\,) \5\\{write}(\\{log\_file},\39\\{format},\39{\#}{\#}\.{\_\_VA\_ARGS\_\_}){}$\6
+\8\#\&{define} ${}\\{wlog\_ln}(\\{format},\39\,\ldots\,) \5\\{wlog}(\\{format}\.{"\\n"},\39{\#}{\#}\.{\_\_VA\_ARGS\_\_}){}$\6
+\8\#\&{define} \\{wlog\_cr} \5${}\\{write}(\\{log\_file},\39\.{"\\n"}){}$\par
+\fi
+
+\M{57}To end a line of text output, we call \\{print\_ln}.
+
+\Y\B\4\X57:Basic printing procedures\X${}\E{}$\6
+\&{void} \\{print\_ln}(\&{void})\C{prints an end-of-line}\6
+${}\{{}$\5
+\1\&{switch} (\\{selector})\5
+${}\{{}$\1\6
+\4\&{case} \\{term\_and\_log}:\6
+${}\{{}$\5
+\1\\{wterm\_cr};\5
+\\{wlog\_cr};\5
+${}\\{term\_offset}\K\T{0};{}$\5
+${}\\{file\_offset}\K\T{0};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{log\_only}:\6
+${}\{{}$\5
+\1\\{wlog\_cr};\5
+${}\\{file\_offset}\K\T{0};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{term\_only}:\6
+${}\{{}$\5
+\1\\{wterm\_cr};\5
+${}\\{term\_offset}\K\T{0};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{no\_print}:\5
+\&{case} \\{pseudo}:\5
+\&{case} \\{new\_string}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{default}:\5
+\\{write\_ln}(\\{write\_file}[\\{selector}]);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{\\{tally} is not affected}\2\par
+\As58, 59, 60, 62, 63, 64, 65, 262, 263, 518, 699\ETs1355.
+\U4.\fi
+
+\M{58}The \\{print\_char} procedure sends one character to the desired destination,
+using the \\{xchr} array to map it into an external character compatible with
+\\{input\_ln}. All printing comes through \\{print\_ln} or \\{print\_char}.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_char}(\&{ASCII\_code} \|s)\C{prints a single character}\6
+${}\{{}$\5
+\1\&{if} (\X244:Character \|s is the current new-line character\X)\1\6
+\&{if} ${}(\\{selector}<\\{pseudo}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\&{return};\6
+\4${}\}{}$\2\2\6
+\&{switch} (\\{selector})\5
+${}\{{}$\1\6
+\4\&{case} \\{term\_and\_log}:\6
+${}\{{}$\5
+\1${}\\{wterm}(\.{"\%c"},\39\\{xchr}[\|s]);{}$\5
+${}\\{wlog}(\.{"\%c"},\39\\{xchr}[\|s]);{}$\5
+\\{incr}(\\{term\_offset});\5
+\\{incr}(\\{file\_offset});\6
+\&{if} ${}(\\{term\_offset}\E\\{max\_print\_line}){}$\5
+${}\{{}$\5
+\1\\{wterm\_cr};\5
+${}\\{term\_offset}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{file\_offset}\E\\{max\_print\_line}){}$\5
+${}\{{}$\5
+\1\\{wlog\_cr};\5
+${}\\{file\_offset}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{log\_only}:\6
+${}\{{}$\5
+\1${}\\{wlog}(\.{"\%c"},\39\\{xchr}[\|s]);{}$\5
+\\{incr}(\\{file\_offset});\6
+\&{if} ${}(\\{file\_offset}\E\\{max\_print\_line}){}$\1\5
+\\{print\_ln}(\,);\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{term\_only}:\6
+${}\{{}$\5
+\1${}\\{wterm}(\.{"\%c"},\39\\{xchr}[\|s]);{}$\5
+\\{incr}(\\{term\_offset});\6
+\&{if} ${}(\\{term\_offset}\E\\{max\_print\_line}){}$\1\5
+\\{print\_ln}(\,);\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{no\_print}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{pseudo}:\6
+\&{if} ${}(\\{tally}<\\{trick\_count}){}$\1\5
+${}\\{trick\_buf}[\\{tally}\MOD\\{error\_line}]\K\|s{}$;\5
+\2\&{break};\6
+\4\&{case} \\{new\_string}:\6
+${}\{{}$\5
+\1\&{if} ${}(\\{pool\_ptr}<\\{pool\_size}){}$\1\5
+\\{append\_char}(\|s);\2\6
+\4${}\}{}$\5
+\2\&{break};\C{we drop characters if the string space is full}\6
+\4\&{default}:\5
+${}\\{write}(\\{write\_file}[\\{selector}],\39\.{"\%c"},\39\\{xchr}[\|s]);{}$\6
+\4${}\}{}$\2\6
+\\{incr}(\\{tally});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{59}An entire string is output by calling \\{print}. Note that if we are outputting
+the single standard ASCII character \.c, we could call \\{print}(\.{'c'}), since
+$\.{'c'}\E\T{99}$ is the number of a single-character string, as explained above. But
+\\{print\_char}(\.{'c'}) is quicker, so \TeX\ goes directly to the \\{print\_char}
+routine when it knows that this is safe. (The present implementation
+assumes that it is always safe to print a visible ASCII character.)
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print}(\&{int} \|s)\C{prints string \|s}\6
+${}\{{}$\5
+\1\&{pool\_pointer} \|j;\C{current character code position}\6
+\&{int} \\{nl};\C{new-line character to restore}\7
+\&{if} ${}(\|s\G\\{str\_ptr}){}$\1\5
+${}\|s\K\X1381:\.{"???"}\X{}$;\C{this can't happen}\2\6
+\&{else} \&{if} ${}(\|s<\T{256}){}$\1\6
+\&{if} ${}(\|s<\T{0}){}$\1\5
+${}\|s\K\X1381:\.{"???"}\X{}$;\C{can't happen}\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{selector}>\\{pseudo}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\|s);\5
+\&{return};\C{internal strings are not expanded}\6
+\4${}\}{}$\2\6
+\&{if} ((\X244:Character \|s is the current new-line character\X))\1\6
+\&{if} ${}(\\{selector}<\\{pseudo}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\&{return};\6
+\4${}\}{}$\2\2\6
+${}\\{nl}\K\\{new\_line\_char};{}$\5
+${}\\{new\_line\_char}\K{-}\T{1}{}$;\C{temporarily disable new-line character}\6
+${}\|j\K\\{str\_start}[\|s];{}$\6
+\&{while} ${}(\|j<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\\{so}(\\{str\_pool}[\|j]));\5
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+${}\\{new\_line\_char}\K\\{nl};{}$\5
+\&{return};\6
+\4${}\}{}$\2\2\6
+${}\|j\K\\{str\_start}[\|s];{}$\6
+\&{while} ${}(\|j<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\\{so}(\\{str\_pool}[\|j]));\5
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\7
+\&{void} \\{print\_str}(\&{char} ${}{*}\|s{}$)\C{ the simple version }\6
+${}\{{}$\1\6
+\&{while} ${}({*}\|s\I\T{0}){}$\1\5
+${}\\{print\_char}({*}\|s\PP){}$;\5
+\2${}\}{}$\2\par
+\fi
+
+\M{60}Control sequence names, file names, and strings constructed with
+\.{\\string} might contain \&{ASCII\_code} values that can't
+be printed using \\{print\_char}. Therefore we use \\{slow\_print} for them:
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{slow\_print}(\&{int} \|s)\C{prints string \|s}\6
+${}\{{}$\5
+\1\&{pool\_pointer} \|j;\C{current character code position}\7
+\&{if} ${}((\|s\G\\{str\_ptr})\V(\|s<\T{256})){}$\1\5
+\\{print}(\|s);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|j\K\\{str\_start}[\|s];{}$\6
+\&{while} ${}(\|j<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\\{print}(\\{so}(\\{str\_pool}[\|j]));\5
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{61}Here is the very first thing that \TeX\ prints: a headline that identifies
+the version number and format package. The \\{term\_offset} variable is temporarily
+incorrect, but the discrepancy is not serious since we assume that the banner
+and format identifier together will occupy at most \\{max\_print\_line}
+character positions.
+
+\Y\B\4\X55:Initialize the output routines\X${}\mathrel+\E{}$\6
+$\\{wterm}(\.{"\%s"},\39\\{banner});{}$\6
+\&{if} ${}(\\{format\_ident}\E\T{0}){}$\1\5
+\\{wterm\_ln}(\.{"\ (no\ format\ preload}\)\.{ed)"});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{slow\_print}(\\{format\_ident});\5
+\\{print\_ln}(\,);\6
+\4${}\}{}$\2\6
+\\{update\_terminal};\par
+\fi
+
+\M{62}The procedure \\{print\_nl} is like \\{print}, but it makes sure that the
+string appears at the beginning of a new line.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_nl}(\&{char} ${}{*}\|s{}$)\C{prints string \|s at beginning of line}\6
+${}\{{}$\5
+\1\&{if} ${}(((\\{term\_offset}>\T{0})\W(\\{odd}(\\{selector})))\V\30((\\{file\_offset}>\T{0})\W(\\{selector}\G\\{log\_only}))){}$\1\5
+\\{print\_ln}(\,);\2\6
+\\{print\_str}(\|s);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{63}The procedure \\{print\_esc} prints a string that is preceded by
+the user's escape character (which is usually a backslash).
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_esc}(\&{str\_number} \|s)\C{prints escape character, then \|s}\6
+${}\{{}$\5
+\1\&{int} \|c;\C{the escape character code}\7
+\X243:Set variable \|c to the current escape character\X;\6
+\&{if} ${}(\|c\G\T{0}){}$\1\6
+\&{if} ${}(\|c<\T{256}){}$\1\5
+\\{print}(\|c);\2\2\6
+\\{slow\_print}(\|s);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{64}An array of digits in the range $\T{0}\dotdot\T{15}$ is printed by \\{print\_the\_digs}.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_the\_digs}(\&{eight\_bits} \|k)\C{prints $\\{dig}[\|k-\T{1}]$$\,\ldots\,$\\{dig}[\T{0}]}\6
+${}\{{}$\5
+\1\&{while} ${}(\|k>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|k);\6
+\&{if} ${}(\\{dig}[\|k]<\T{10}){}$\1\5
+${}\\{print\_char}(\.{'0'}+\\{dig}[\|k]);{}$\2\6
+\&{else}\1\5
+${}\\{print\_char}(\.{'A'}-\T{10}+\\{dig}[\|k]);{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{65}The following procedure, which prints out the decimal representation of a
+given integer \|n, has been written carefully so that it works properly
+if $\|n\E\T{0}$ or if $({-}\|n)$ would cause overflow. It does not apply $\MOD$ or $/$
+to negative arguments, since such operations are not implemented consistently
+by all \PASCAL\ compilers.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_int}(\&{int} \|n)\C{prints an integer in decimal form}\6
+${}\{{}$\5
+\1\&{uint8\_t} \|k;\C{index to current digit; we assume that $\|n<10^{23}$}\6
+\&{int} \|m;\C{used to negate \|n in possibly dangerous cases}\7
+${}\|k\K\T{0};{}$\6
+\&{if} ${}(\|n<\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'-'});\6
+\&{if} ${}(\|n>{-}\T{100000000}){}$\1\5
+\\{negate}(\|n);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|m\K{-}\T{1}-\|n;{}$\5
+${}\|n\K\|m/\T{10};{}$\5
+${}\|m\K(\|m\MOD\T{10})+\T{1};{}$\5
+${}\|k\K\T{1};{}$\6
+\&{if} ${}(\|m<\T{10}){}$\1\5
+${}\\{dig}[\T{0}]\K\|m;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{dig}[\T{0}]\K\T{0};{}$\5
+\\{incr}(\|n);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{dig}[\|k]\K\|n\MOD\T{10};{}$\5
+${}\|n\K\|n/\T{10};{}$\5
+\\{incr}(\|k);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|n\E\T{0}));{}$\5
+\\{print\_the\_digs}(\|k);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{66}Here is a trivial procedure to print two digits; it is usually called with
+a parameter in the range $\T{0}\Z\|n\Z\T{99}$.
+
+\Y\B\&{void} \\{print\_two}(\&{int} \|n)\C{prints two least significant digits}\6
+${}\{{}$\5
+\1${}\|n\K\\{abs}(\|n)\MOD\T{100};{}$\5
+${}\\{print\_char}(\.{'0'}+(\|n/\T{10}));{}$\5
+${}\\{print\_char}(\.{'0'}+(\|n\MOD\T{10}));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{67}Hexadecimal printing of nonnegative integers is accomplished by \\{print\_hex}.
+
+\Y\B\&{void} \\{print\_hex}(\&{int} \|n)\C{prints a positive integer in hexadecimal form}\6
+${}\{{}$\5
+\1\&{uint8\_t} \|k;\C{index to current digit; we assume that $0\L n<16^{22}$}\7
+${}\|k\K\T{0};{}$\5
+\\{print\_char}(\.{'"'});\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{dig}[\|k]\K\|n\MOD\T{16};{}$\5
+${}\|n\K\|n/\T{16};{}$\5
+\\{incr}(\|k);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|n\E\T{0}));{}$\5
+\\{print\_the\_digs}(\|k);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{68}Old versions of \TeX\ needed a procedure called \\{print\_ASCII} whose function
+is now subsumed by \\{print}. We retain the old name here as a possible aid to
+future software arch\ae ologists.
+
+\Y\B\4\D$\\{print\_ASCII}$ \5
+\\{print}\par
+\fi
+
+\M{69}Roman numerals are produced by the \\{print\_roman\_int} routine. Readers
+who like puzzles might enjoy trying to figure out how this tricky code
+works; therefore no explanation will be given. Notice that 1990 yields
+\.{mcmxc}, not \.{mxm}.
+
+\Y\B\&{void} \\{print\_roman\_int}(\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pool\_pointer} \|j${},{}$ \|k;\C{mysterious indices into \\{str\_pool}}\7
+${}\\{nonnegative\_integer}\|u,\39\|v{}$;\C{mysterious numbers}\6
+${}\|j\K\\{str\_start}[\X1382:\.{"m2d5c2l5x2v5i"}\X];{}$\5
+${}\|v\K\T{1000};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{while} ${}(\|n\G\|v){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\\{so}(\\{str\_pool}[\|j]));\5
+${}\|n\K\|n-\|v;{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|n\Z\T{0}){}$\1\5
+\&{return};\C{nonpositive input produces no output}\2\6
+${}\|k\K\|j+\T{2};{}$\5
+${}\|u\K\|v/(\\{so}(\\{str\_pool}[\|k-\T{1}])-\.{'0'});{}$\6
+\&{if} ${}(\\{str\_pool}[\|k-\T{1}]\E\\{si}(\.{'2'})){}$\5
+${}\{{}$\5
+\1${}\|k\K\|k+\T{2};{}$\5
+${}\|u\K\|u/(\\{so}(\\{str\_pool}[\|k-\T{1}])-\.{'0'});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|n+\|u\G\|v){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\\{so}(\\{str\_pool}[\|k]));\5
+${}\|n\K\|n+\|u;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|j\K\|j+\T{2};{}$\5
+${}\|v\K\|v/(\\{so}(\\{str\_pool}[\|j-\T{1}])-\.{'0'});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{70}The \\{print} subroutine will not print a string that is still being
+created. The following procedure will.
+
+\Y\B\&{void} \\{print\_current\_string}(\&{void})\C{prints a yet-unmade string}\6
+${}\{{}$\5
+\1\&{pool\_pointer} \|j;\C{points to current character code}\7
+${}\|j\K\\{str\_start}[\\{str\_ptr}];{}$\6
+\&{while} ${}(\|j<\\{pool\_ptr}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\\{so}(\\{str\_pool}[\|j]));\5
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{71}Here is a procedure that asks the user to type a line of input,
+assuming that the \\{selector} setting is either \\{term\_only} or \\{term\_and\_log}.
+The input is placed into locations \\{first} through $\\{last}-\T{1}$ of the
+\\{buffer} array, and echoed on the transcript file if appropriate.
+
+This procedure is never called when $\\{interaction}<\\{scroll\_mode}$.
+
+\Y\B\4\D$\\{prompt\_input}(\|X)$ \6
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+\\{print\_str}(\|X);\5
+\\{term\_input}(\,);\6
+\4${}\}{}$\C{prints a string and gets a line of input}\2\par
+\Y\B\&{void} \\{term\_input}(\&{void})\C{gets a line from the terminal}\6
+${}\{{}$\5
+\1\&{int} \|k;\C{index into \\{buffer}}\7
+\\{update\_terminal};\C{now the user sees the prompt for sure}\6
+\&{if} ${}(\R\\{input\_ln}({\AND}\\{term\_in},\39\\{true})){}$\1\5
+\\{fatal\_error}(\.{"End\ of\ file\ on\ the\ }\)\.{terminal!"});\2\6
+${}\\{term\_offset}\K\T{0}{}$;\C{the user's line ended with \<\rm return>}\6
+\\{decr}(\\{selector});\C{prepare to echo the input}\6
+\&{if} ${}(\\{last}\I\\{first}){}$\1\6
+\&{for} ${}(\|k\K\\{first};{}$ ${}\|k\Z\\{last}-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{print}(\\{buffer}[\|k]);\2\2\6
+\\{print\_ln}(\,);\5
+\\{incr}(\\{selector});\C{restore previous status}\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{72}Reporting errors.
+When something anomalous is detected, \TeX\ typically does something like this:
+$$\vbox{\halign{#\hfil\cr
+\\{print\_err}(\.{"Something\ anomalous}\)\.{\ has\ been\ detected"});\cr
+\\{help3}(\.{"This\ is\ the\ first\ l}\)\.{ine\ of\ my\ offer\ to\ h}\)\.{elp."})\cr
+(\.{"This\ is\ the\ second\ }\)\.{line.\ I'm\ trying\ to"})\cr
+(\.{"explain\ the\ best\ wa}\)\.{y\ for\ you\ to\ proceed}\)\.{."});\cr
+\&{error} ;\cr}}$$
+A two-line help message would be given using \\{help2}, etc.; these informal
+helps should use simple vocabulary that complements the words used in the
+official error message that was printed. (Outside the U.S.A., the help
+messages should preferably be translated into the local vernacular. Each
+line of help is at most 60 characters long, in the present implementation,
+so that \\{max\_print\_line} will not be exceeded.)
+
+The \\{print\_err} procedure supplies a `\.!' before the official message,
+and makes sure that the terminal is awake if a stop is going to occur.
+The \&{error} procedure supplies a `\..' after the official message, then it
+shows the location of the error; and if $\\{interaction}\E\\{error\_stop\_mode}$,
+it also enters into a dialog with the user, during which time the help
+message may be printed.
+
+\fi
+
+\M{73}The global variable \\{interaction} has four settings, representing increasing
+amounts of user interaction:
+
+\Y\B\4\D$\\{batch\_mode}$ \5
+\T{0}\C{omits all stops and omits terminal output}\par
+\B\4\D$\\{nonstop\_mode}$ \5
+\T{1}\C{omits all stops}\par
+\B\4\D$\\{scroll\_mode}$ \5
+\T{2}\C{omits error stops}\par
+\B\4\D$\\{error\_stop\_mode}$ \5
+\T{3}\C{stops at every opportunity to interact}\par
+\B\4\D$\\{print\_err}(\|X)$ \6
+${}\{{}$\5
+\1\&{if} ${}(\\{interaction}\E\\{error\_stop\_mode}){}$\1\5
+\\{wake\_up\_terminal};\2\6
+\\{print\_nl}(\.{"!\ "});\5
+\\{print\_str}(\|X);\6
+\4${}\}{}$\2\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{interaction};\C{current level of interaction}\par
+\fi
+
+\M{74}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{interaction}\K\\{error\_stop\_mode}{}$;\par
+\fi
+
+\M{75}\TeX\ is careful not to call \&{error} when the print \\{selector} setting
+might be unusual. The only possible values of \\{selector} at the time of
+error messages are
+
+\yskip\hang\\{no\_print} (when $\\{interaction}\E\\{batch\_mode}$
+and \\{log\_file} not yet open);
+
+\hang\\{term\_only} (when $\\{interaction}>\\{batch\_mode}$ and \\{log\_file} not yet open);
+
+\hang\\{log\_only} (when $\\{interaction}\E\\{batch\_mode}$ and \\{log\_file} is open);
+
+\hang\\{term\_and\_log} (when $\\{interaction}>\\{batch\_mode}$ and \\{log\_file} is open).
+
+\Y\B\4\X75:Initialize the print \\{selector} based on \\{interaction}\X${}\E{}$\6
+\&{if} ${}(\\{interaction}\E\\{batch\_mode}){}$\1\5
+${}\\{selector}\K\\{no\_print}{}$;\5
+\2\&{else} $\\{selector}\K{}$\\{term\_only}\par
+\Us1265\ET1337.\fi
+
+\M{76}A global variable \\{deletions\_allowed} is set \\{false} if the \\{get\_next}
+routine is active when \&{error} is called; this ensures that \\{get\_next}
+and related routines like \\{get\_token} will never be called recursively.
+A similar interlock is provided by \\{set\_box\_allowed}.
+
+The global variable \\{history} records the worst level of error that
+has been detected. It has four possible values: \\{spotless}, \\{warning\_issued},
+\\{error\_message\_issued}, and \\{fatal\_error\_stop}.
+
+Another global variable, \\{error\_count}, is increased by one when an
+\&{error} occurs without an interactive dialog, and it is reset to zero at
+the end of every paragraph. If \\{error\_count} reaches 100, \TeX\ decides
+that there is no point in continuing further.
+
+\Y\B\4\D$\\{spotless}$ \5
+\T{0}\C{\\{history} value when nothing has been amiss yet}\par
+\B\4\D$\\{warning\_issued}$ \5
+\T{1}\C{\\{history} value when \\{begin\_diagnostic} has been called}\par
+\B\4\D$\\{error\_message\_issued}$ \5
+\T{2}\C{\\{history} value when \&{error} has been called}\par
+\B\4\D$\\{fatal\_error\_stop}$ \5
+\T{3}\C{\\{history} value when termination was premature}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{deletions\_allowed};\C{is it safe for \&{error} to call \\{get\_token}?}\6
+\&{bool} \\{set\_box\_allowed};\C{is it safe to do a \.{\\setbox} assignment?}\6
+\&{uint8\_t} \\{history};\C{has the source input been clean so far?}\6
+\&{int8\_t} \\{error\_count};\C{the number of scrolled errors since the last paragraph ended}\par
+\fi
+
+\M{77}The value of \\{history} is initially \\{fatal\_error\_stop}, but it will
+be changed to \\{spotless} if \TeX\ survives the initialization process.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{deletions\_allowed}\K\\{true};{}$\5
+${}\\{set\_box\_allowed}\K\\{true};{}$\5
+${}\\{error\_count}\K\T{0}{}$;\C{\\{history} is initialized elsewhere}\par
+\fi
+
+\M{78}Since errors can be detected almost anywhere in \TeX, we want to declare the
+error procedures near the beginning of the program. But the error procedures
+in turn use some other procedures, which need to be declared \\{forward}
+before we get to \&{error} itself.
+
+It is possible for \&{error} to be called recursively if some error arises
+when \\{get\_token} is being used to delete a token, and/or if some fatal error
+occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\Y\B\4\X78:Error handling procedures\X${}\E{}$\6
+\&{void} \\{normalize\_selector}(\&{void});\6
+\&{void} \\{get\_token}(\&{void});\6
+\&{void} \\{term\_input}(\&{void});\6
+\&{void} \\{show\_context}(\&{void});\6
+\&{void} \\{begin\_file\_reading}(\&{void});\6
+\&{void} \\{open\_log\_file}(\&{void});\6
+\&{void} \\{close\_files\_and\_terminate}(\&{void});\6
+\&{void} \\{clear\_for\_error\_prompt}(\&{void});\6
+\&{void} \\{give\_err\_help}(\&{void});\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\&{void} \\{debug\_help}(\&{void});\6
+\8\#\&{else}\6
+\8\#\&{define} \\{debug\_help}(\,) \5\\{do\_nothing}\6
+\8\#\&{endif}\par
+\As81, 82, 93, 94\ETs95.
+\U4.\fi
+
+\M{79}Individual lines of help are recorded in the array \\{help\_line}, which
+contains entries in positions $\T{0}\dotdot(\\{help\_ptr}-\T{1})$. They should be printed
+in reverse order, i.e., with \\{help\_line}[\T{0}] appearing last.
+
+\Y\B\4\D$\\{hlp1}(\|X)$ \5
+$\\{help\_line}[\T{0}]\K\|X{}$;\5
+$\}{}$\par
+\B\4\D$\\{hlp2}(\|X)$ \5
+$\\{help\_line}[\T{1}]\K\|X;$ \\{hlp1}\par
+\B\4\D$\\{hlp3}(\|X)$ \5
+$\\{help\_line}[\T{2}]\K\|X;$ \\{hlp2}\par
+\B\4\D$\\{hlp4}(\|X)$ \5
+$\\{help\_line}[\T{3}]\K\|X;$ \\{hlp3}\par
+\B\4\D$\\{hlp5}(\|X)$ \5
+$\\{help\_line}[\T{4}]\K\|X;$ \\{hlp4}\par
+\B\4\D$\\{hlp6}(\|X)$ \5
+$\\{help\_line}[\T{5}]\K\|X;$ \\{hlp5}\par
+\B\4\D$\\{help0}$ \5
+$\\{help\_ptr}\K{}$\T{0}\C{sometimes there might be no help}\par
+\B\4\D$\\{help1}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{1};$ \\{hlp1}\C{use this with one help line}\par
+\B\4\D$\\{help2}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{2};$ \\{hlp2}\C{use this with two help lines}\par
+\B\4\D$\\{help3}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{3};$ \\{hlp3}\C{use this with three help lines}\par
+\B\4\D$\\{help4}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{4};$ \\{hlp4}\C{use this with four help lines}\par
+\B\4\D$\\{help5}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{5};$ \\{hlp5}\C{use this with five help lines}\par
+\B\4\D$\\{help6}$ \5
+$\{{}$\5
+$\\{help\_ptr}\K\T{6};$ \\{hlp6}\C{use this with six help lines}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{char} ${}{*}\\{help\_line}[\T{6}]{}$;\C{helps for the next \&{error}}\6
+\&{uint8\_t} \\{help\_ptr};\C{the number of help lines present}\6
+\&{bool} \\{use\_err\_help};\C{should the \\{err\_help} list be shown?}\par
+\fi
+
+\M{80}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{help\_ptr}\K\T{0};{}$\5
+${}\\{use\_err\_help}\K\\{false}{}$;\par
+\fi
+
+\M{81}The \\{jump\_out} procedure just cuts across all active procedure levels and
+goes to \\{end\_of\_TEX}. This is the only nontrivial \&{goto} statement in the
+whole program. It is used when there is no recovery from a particular error.
+
+Some \PASCAL\ compilers do not implement non-local \&{goto} statements.
+In such cases the body of \\{jump\_out} should simply be
+`\\{close\_files\_and\_terminate};\thinspace' followed by a call on some system
+procedure that quietly terminates the program.
+
+\Y\B\4\X78:Error handling procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{jump\_out}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{close\_files\_and\_terminate}(\,);\5
+\\{exit}(\T{0});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{82}Here now is the general \&{error} routine.
+
+\Y\B\4\X78:Error handling procedures\X${}\mathrel+\E{}$\6
+\&{void} \&{error} (\&{void})\C{completes the job of error reporting}\6
+${}\{{}$\5
+\1\&{ASCII\_code} \|c;\C{what the user types}\6
+\&{int} \\{s1}${},{}$ \\{s2}${},{}$ \\{s3}${},{}$ \\{s4};\C{used to save global variables when deleting tokens}\7
+\&{if} ${}(\\{history}<\\{error\_message\_issued}){}$\1\5
+${}\\{history}\K\\{error\_message\_issued};{}$\2\6
+\\{print\_char}(\.{'.'});\5
+\\{show\_context}(\,);\6
+\&{if} ${}(\\{interaction}\E\\{error\_stop\_mode}){}$\1\5
+\X83:Get user's advice and \&{return}\X;\2\6
+\\{incr}(\\{error\_count});\6
+\&{if} ${}(\\{error\_count}\E\T{100}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"(That\ makes\ 100\ err}\)\.{ors;\ please\ try\ agai}\)\.{n.)"});\5
+${}\\{history}\K\\{fatal\_error\_stop};{}$\5
+\\{jump\_out}(\,);\6
+\4${}\}{}$\2\6
+\X90:Put help message on the transcript file\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{83}\B\X83:Get user's advice and \&{return}\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{resume}:\5
+\\{clear\_for\_error\_prompt}(\,);\5
+\\{prompt\_input}(\.{"?\ "});\6
+\&{if} ${}(\\{last}\E\\{first}){}$\1\5
+\&{return};\2\6
+${}\|c\K\\{buffer}[\\{first}];{}$\6
+\&{if} ${}(\|c\G\.{'a'}){}$\1\5
+${}\|c\K\|c+\.{'A'}-\.{'a'}{}$;\C{convert to uppercase}\2\6
+\X84:Interpret code \|c and \&{return} if done\X;\6
+\4${}\}{}$\2\par
+\U82.\fi
+
+\M{84}It is desirable to provide an `\.E' option here that gives the user
+an easy way to return from \TeX\ to the system editor, with the offending
+line ready to be edited. But such an extension requires some system
+wizardry, so the present implementation simply types out the name of the
+file that should be
+edited and the relevant line number.
+
+There is a secret `\.D' option available when the debugging routines haven't
+been commented~out.
+
+\Y\B\4\X84:Interpret code \|c and \&{return} if done\X${}\E{}$\6
+\&{switch} (\|c)\5
+${}\{{}$\1\6
+\4\&{case} \.{'0'}:\5
+\&{case} \.{'1'}:\5
+\&{case} \.{'2'}:\5
+\&{case} \.{'3'}:\5
+\&{case} \.{'4'}:\5
+\&{case} \.{'5'}:\5
+\&{case} \.{'6'}:\5
+\&{case} \.{'7'}:\5
+\&{case} \.{'8'}:\5
+\&{case} \.{'9'}:\6
+\&{if} (\\{deletions\_allowed})\1\5
+\X88:Delete \(c)$\|c-\.{"0"}$ tokens and \&{goto} \&{continue}\X\5
+\2\&{break};\5
+\hbox{\4\4}\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\4\&{case} \.{'D'}:\6
+${}\{{}$\5
+\1\\{debug\_help}(\,);\5
+\&{goto} \\{resume};\5
+${}\}{}$\2\6
+\8\#\&{endif}\6
+\4\&{case} \.{'E'}:\6
+\&{if} ${}(\\{base\_ptr}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"You\ want\ to\ edit\ fi}\)\.{le\ "});\5
+${}\\{slow\_print}(\\{input\_stack}[\\{base\_ptr}].\\{name\_field});{}$\5
+\\{print\_str}(\.{"\ at\ line\ "});\5
+\\{print\_int}(\\{line});\5
+${}\\{interaction}\K\\{scroll\_mode};{}$\5
+\\{jump\_out}(\,);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \.{'H'}:\5
+\X89:Print the help information and \&{goto} \&{continue}\X\6
+\4\&{case} \.{'I'}:\5
+\X87:Introduce new material from the terminal and \&{return}\X\6
+\4\&{case} \.{'Q'}:\5
+\&{case} \.{'R'}:\5
+\&{case} \.{'S'}:\5
+\X86:Change the interaction level and \&{return}\X\6
+\4\&{case} \.{'X'}:\6
+${}\{{}$\5
+\1${}\\{interaction}\K\\{scroll\_mode};{}$\5
+\\{jump\_out}(\,);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\X85:Print the menu of available options\X\par
+\U83.\fi
+
+\M{85}\B\X85:Print the menu of available options\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"Type\ <return>\ to\ pr}\)\.{oceed,\ S\ to\ scroll\ f}\)\.{uture\ error\ messages}\)\.{,"});\6
+\\{print\_nl}(\.{"R\ to\ run\ without\ st}\)\.{opping,\ Q\ to\ run\ qui}\)\.{etly,"});\6
+\\{print\_nl}(\.{"I\ to\ insert\ somethi}\)\.{ng,\ "});\6
+\&{if} ${}(\\{base\_ptr}>\T{0}){}$\1\5
+\\{print\_str}(\.{"E\ to\ edit\ your\ file}\)\.{,"});\2\6
+\&{if} (\\{deletions\_allowed})\1\5
+\\{print\_nl}(\.{"1\ or\ ...\ or\ 9\ to\ ig}\)\.{nore\ the\ next\ 1\ to\ 9}\)\.{\ tokens\ of\ input,"});\2\6
+\\{print\_nl}(\.{"H\ for\ help,\ X\ to\ qu}\)\.{it."});\6
+\4${}\}{}$\2\par
+\U84.\fi
+
+\M{86}Here the author of \TeX\ apologizes for making use of the numerical
+relation between \.{'Q'}, \.{'R'}, \.{'S'}, and the desired interaction settings
+\\{batch\_mode}, \\{nonstop\_mode}, \\{scroll\_mode}.
+
+\Y\B\4\X86:Change the interaction level and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{error\_count}\K\T{0};{}$\5
+${}\\{interaction}\K\\{batch\_mode}+\|c-\.{'Q'};{}$\5
+\\{print\_str}(\.{"OK,\ entering\ "});\6
+\&{switch} (\|c)\5
+${}\{{}$\1\6
+\4\&{case} \.{'Q'}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1383:\.{"batchmode"}\X);\5
+\\{decr}(\\{selector});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \.{'R'}:\5
+\\{print\_esc}(\X1384:\.{"nonstopmode"}\X);\5
+\&{break};\6
+\4\&{case} \.{'S'}:\5
+\\{print\_esc}(\X1385:\.{"scrollmode"}\X);\6
+\4${}\}{}$\C{there are no other cases}\2\6
+\\{print\_str}(\.{"..."});\5
+\\{print\_ln}(\,);\5
+\\{update\_terminal};\5
+\&{return};\6
+\4${}\}{}$\2\par
+\U84.\fi
+
+\M{87}When the following code is executed, $\\{buffer}[(\\{first}+\T{1})\dotdot(\\{last}-\T{1})]$ may
+contain the material inserted by the user; otherwise another prompt will
+be given. In order to understand this part of the program fully, you need
+to be familiar with \TeX's input stacks.
+
+\Y\B\4\X87:Introduce new material from the terminal and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_file\_reading}(\,);\C{enter a new syntactic level for terminal input}\C{now $\\{state}\E\\{mid\_line}$, so an initial blank space will count as a blank}\6
+\&{if} ${}(\\{last}>\\{first}+\T{1}){}$\5
+${}\{{}$\5
+\1${}\\{loc}\K\\{first}+\T{1};{}$\5
+${}\\{buffer}[\\{first}]\K\.{'\ '};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{prompt\_input}(\.{"insert>"});\5
+${}\\{loc}\K\\{first};{}$\6
+\4${}\}{}$\2\6
+${}\\{first}\K\\{last};{}$\5
+${}\\{cur\_input}.\\{limit\_field}\K\\{last}-\T{1}{}$;\C{no \\{end\_line\_char} ends this line}\6
+\&{return};\6
+\4${}\}{}$\2\par
+\U84.\fi
+
+\M{88}We allow deletion of up to 99 tokens at a time.
+
+\Y\B\4\X88:Delete \(c)$\|c-\.{"0"}$ tokens and \&{goto} \&{continue}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{s1}\K\\{cur\_tok};{}$\5
+${}\\{s2}\K\\{cur\_cmd};{}$\5
+${}\\{s3}\K\\{cur\_chr};{}$\5
+${}\\{s4}\K\\{align\_state};{}$\5
+${}\\{align\_state}\K\T{1000000};{}$\5
+${}\\{OK\_to\_interrupt}\K\\{false};{}$\6
+\&{if} ${}((\\{last}>\\{first}+\T{1})\W(\\{buffer}[\\{first}+\T{1}]\G\.{'0'})\W(\\{buffer}[\\{first}+\T{1}]\Z\.{'9'})){}$\1\5
+${}\|c\K\|c*\T{10}+\\{buffer}[\\{first}+\T{1}]-\.{'0'}*\T{11};{}$\2\6
+\&{else}\1\5
+${}\|c\K\|c-\.{'0'};{}$\2\6
+\&{while} ${}(\|c>\T{0}){}$\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\C{one-level recursive call of \&{error} is possible}\6
+\\{decr}(\|c);\6
+\4${}\}{}$\2\6
+${}\\{cur\_tok}\K\\{s1};{}$\5
+${}\\{cur\_cmd}\K\\{s2};{}$\5
+${}\\{cur\_chr}\K\\{s3};{}$\5
+${}\\{align\_state}\K\\{s4};{}$\5
+${}\\{OK\_to\_interrupt}\K\\{true};{}$\5
+\\{help2}(\.{"I\ have\ just\ deleted}\)\.{\ some\ text,\ as\ you\ a}\)\.{sked."})\6
+(\.{"You\ can\ now\ delete\ }\)\.{more,\ or\ insert,\ or\ }\)\.{whatever."});\5
+\\{show\_context}(\,);\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U84.\fi
+
+\M{89}\B\X89:Print the help information and \&{goto} \&{continue}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{use\_err\_help})\5
+${}\{{}$\5
+\1\\{give\_err\_help}(\,);\5
+${}\\{use\_err\_help}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{help\_ptr}\E\T{0}){}$\1\5
+\\{help2}(\.{"Sorry,\ I\ don't\ know}\)\.{\ how\ to\ help\ in\ this}\)\.{\ situation."})\6
+\hbox{\kern1em}(\.{"Maybe\ you\ should\ tr}\)\.{y\ asking\ a\ human?"});\2\6
+\&{do}\5
+${}\{{}$\1\6
+\\{decr}(\\{help\_ptr});\5
+\\{print\_str}(\\{help\_line}[\\{help\_ptr}]);\5
+\\{print\_ln}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{help\_ptr}\E\T{0}));{}$\6
+\4${}\}{}$\2\6
+\\{help4}(\.{"Sorry,\ I\ already\ ga}\)\.{ve\ what\ help\ I\ could}\)\.{..."})\6
+(\.{"Maybe\ you\ should\ tr}\)\.{y\ asking\ a\ human?"})\6
+(\.{"An\ error\ might\ have}\)\.{\ occurred\ before\ I\ n}\)\.{oticed\ any\ problems.}\)\.{"})\6
+(\.{"``If\ all\ else\ fails}\)\.{,\ read\ the\ instructi}\)\.{ons.'"});\6
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U84.\fi
+
+\M{90}\B\X90:Put help message on the transcript file\X${}\E{}$\6
+\&{if} ${}(\\{interaction}>\\{batch\_mode}){}$\1\5
+\\{decr}(\\{selector});\C{avoid terminal output}\2\6
+\&{if} (\\{use\_err\_help})\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{give\_err\_help}(\,);\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{while} ${}(\\{help\_ptr}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{help\_ptr});\5
+\\{print\_nl}(\\{help\_line}[\\{help\_ptr}]);\6
+\4${}\}{}$\2\2\6
+\\{print\_ln}(\,);\6
+\&{if} ${}(\\{interaction}>\\{batch\_mode}){}$\1\5
+\\{incr}(\\{selector});\C{re-enable terminal output}\2\6
+\\{print\_ln}(\,)\par
+\U82.\fi
+
+\M{91}A dozen or so error messages end with a parenthesized integer, so we
+save a teeny bit of program space by declaring the following procedure:
+
+\Y\B\&{void} \\{int\_error}(\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ ("});\5
+\\{print\_int}(\|n);\5
+\\{print\_char}(\.{')'});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{92}In anomalous cases, the print selector might be in an unknown state;
+the following subroutine is called to fix things just enough to keep
+running a bit longer.
+
+\Y\B\&{void} \\{normalize\_selector}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} (\\{log\_opened})\1\5
+${}\\{selector}\K\\{term\_and\_log};{}$\2\6
+\&{else}\1\5
+${}\\{selector}\K\\{term\_only};{}$\2\6
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+\\{open\_log\_file}(\,);\2\6
+\&{if} ${}(\\{interaction}\E\\{batch\_mode}){}$\1\5
+\\{decr}(\\{selector});\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{93}The following procedure prints \TeX's last words before dying.
+
+\Y\B\4\D$\\{succumb}$ \6
+${}\{{}$\5
+\1\&{if} ${}(\\{interaction}\E\\{error\_stop\_mode}){}$\1\5
+${}\\{interaction}\K\\{scroll\_mode}{}$;\C{no more interaction}\2\6
+\&{if} (\\{log\_opened})\1\6
+\&{error} (\,)\1\5
+;\2\2\6
+\&{if} ${}(\\{interaction}>\\{batch\_mode}){}$\1\5
+\\{debug\_help}(\,);\2\6
+${}\\{history}\K\\{fatal\_error\_stop};{}$\5
+\\{jump\_out}(\,);\C{irrecoverable error}\6
+\4${}\}{}$\2\par
+\Y\B\4\X78:Error handling procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{fatal\_error}(\&{char} ${}{*}\|s{}$)\C{prints \|s, and that's it}\6
+${}\{{}$\5
+\1\\{normalize\_selector}(\,);\6
+\\{print\_err}(\.{"Emergency\ stop"});\5
+\\{help1}(\|s);\5
+\\{succumb};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{94}Here is the most dreaded error message.
+
+\Y\B\4\X78:Error handling procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{overflow}(\&{char} ${}{*}\|s,\39{}$\&{int} \|n)\C{stop due to finiteness}\6
+${}\{{}$\5
+\1\\{normalize\_selector}(\,);\5
+\\{print\_err}(\.{"TeX\ capacity\ exceed}\)\.{ed,\ sorry\ ["});\5
+\\{print\_str}(\|s);\5
+\\{print\_char}(\.{'='});\5
+\\{print\_int}(\|n);\5
+\\{print\_char}(\.{']'});\5
+\\{help2}(\.{"If\ you\ really\ absol}\)\.{utely\ need\ more\ capa}\)\.{city,"})\6
+(\.{"you\ can\ ask\ a\ wizar}\)\.{d\ to\ enlarge\ me."});\5
+\\{succumb};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{95}The program might sometime run completely amok, at which point there is
+no choice but to stop. If no previous error has been detected, that's bad
+news; a message is printed that is really intended for the \TeX\
+maintenance person instead of the user (unless the user has been
+particularly diabolical). The index entries for `this can't happen' may
+help to pinpoint the problem.
+
+\Y\B\4\X78:Error handling procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{confusion}(\&{str\_number} \|s)\C{consistency check violated; \|s tells where}\6
+${}\{{}$\5
+\1\\{normalize\_selector}(\,);\6
+\&{if} ${}(\\{history}<\\{error\_message\_issued}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"This\ can't\ happen\ (}\)\.{"});\5
+\\{print}(\|s);\5
+\\{print\_char}(\.{')'});\5
+\\{help1}(\.{"I'm\ broken.\ Please\ }\)\.{show\ this\ to\ someone}\)\.{\ who\ can\ fix\ can\ fix}\)\.{"});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"I\ can't\ go\ on\ meeti}\)\.{ng\ you\ like\ this"});\5
+\\{help2}(\.{"One\ of\ your\ faux\ pa}\)\.{s\ seems\ to\ have\ woun}\)\.{ded\ me\ deeply..."})\6
+(\.{"in\ fact,\ I'm\ barely}\)\.{\ conscious.\ Please\ f}\)\.{ix\ it\ and\ try\ again.}\)\.{"});\6
+\4${}\}{}$\2\6
+\\{succumb};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{96}Users occasionally want to interrupt \TeX\ while it's running.
+If the \PASCAL\ runtime system allows this, one can implement
+a routine that sets the global variable \\{interrupt} to some nonzero value
+when such an interrupt is signalled. Otherwise there is probably at least
+a way to make \\{interrupt} nonzero using the \PASCAL\ debugger.
+
+\Y\B\4\D$\\{check\_interrupt}$ \6
+${}\{{}$\5
+\1\&{if} ${}(\\{interrupt}\I\T{0}){}$\1\5
+\\{pause\_for\_instructions}(\,);\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{interrupt};\C{should \TeX\ pause for instructions?}\6
+\&{bool} \\{OK\_to\_interrupt};\C{should interrupts be observed?}\par
+\fi
+
+\M{97}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{interrupt}\K\T{0};{}$\5
+${}\\{OK\_to\_interrupt}\K\\{true}{}$;\par
+\fi
+
+\M{98}When an interrupt has been detected, the program goes into its
+highest interaction level and lets the user have nearly the full flexibility of
+the \&{error} routine. \TeX\ checks for interrupts only at times when it is
+safe to do this.
+
+\Y\B\&{void} \\{pause\_for\_instructions}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} (\\{OK\_to\_interrupt})\5
+${}\{{}$\5
+\1${}\\{interaction}\K\\{error\_stop\_mode};{}$\6
+\&{if} ${}((\\{selector}\E\\{log\_only})\V(\\{selector}\E\\{no\_print})){}$\1\5
+\\{incr}(\\{selector});\2\6
+\\{print\_err}(\.{"Interruption"});\5
+\\{help3}(\.{"You\ rang?"})\6
+(\.{"Try\ to\ insert\ some\ }\)\.{instructions\ for\ me\ }\)\.{(e.g.,`I\\\\showlists'}\)\.{),"})\6
+(\.{"unless\ you\ just\ wan}\)\.{t\ to\ quit\ by\ typing\ }\)\.{`X'."});\5
+${}\\{deletions\_allowed}\K\\{false};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{deletions\_allowed}\K\\{true};{}$\5
+${}\\{interrupt}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{99}Arithmetic with scaled dimensions.
+The principal computations performed by \TeX\ are done entirely in terms of
+integers less than $2^{31}$ in magnitude; and divisions are done only when both
+dividend and divisor are nonnegative. Thus, the arithmetic specified in this
+program can be carried out in exactly the same way on a wide variety of
+computers, including some small ones. Why? Because the arithmetic
+calculations need to be spelled out precisely in order to guarantee that
+\TeX\ will produce identical output on different machines. If some
+quantities were rounded differently in different implementations, we would
+find that line breaks and even page breaks might occur in different places.
+Hence the arithmetic of \TeX\ has been designed with care, and systems that
+claim to be implementations of \TeX82 should follow precisely the
+calculations as they appear in the present program.
+
+(Actually there are three places where \TeX\ uses $/$ with a possibly negative
+numerator. These are harmless; see $/$ in the index. Also if the user
+sets the \.{\\time} or the \.{\\year} to a negative value, some diagnostic
+information will involve negative-numerator division. The same remarks
+apply for $\MOD$ as well as for $/$.)
+
+\fi
+
+\M{100}Here is a routine that calculates half of an integer, using an
+unambiguous convention with respect to signed odd numbers.
+
+\Y\B\&{int} \\{half}(\&{int} \|x)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} (\\{odd}(\|x))\1\5
+\&{return} ${}(\|x+\T{1})/\T{2};{}$\2\6
+\&{else}\1\5
+\&{return} \|x${}/\T{2};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{101}Fixed-point arithmetic is done on {\sl scaled integers\/} that are multiples
+of $2^{-16}$. In other words, a binary point is assumed to be sixteen bit
+positions from the right end of a binary computer word.
+
+\Y\B\4\D$\\{unity}$ \5
+\T{\~200000}\C{$2^{16}$, represents 1.00000}\par
+\B\4\D$\\{two}$ \5
+\T{\~400000}\C{$2^{17}$, represents 2.00000}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{int} \&{scaled};\C{this type is used for scaled integers}\6
+\&{typedef} \&{uint32\_t}\\{nonnegative\_integer};\C{$0\L x<2^{31}$}\6
+\&{typedef} \&{uint8\_t} \&{small\_number};\C{this type is self-explanatory}\par
+\fi
+
+\M{102}The following function is used to create a scaled integer from a given decimal
+fraction $(.d_0d_1\ldots d_{k-1})$, where $\T{0}\Z\|k\Z\T{17}$. The digit $d_i$ is
+given in \\{dig}[\|i], and the calculation produces a correctly rounded result.
+
+\Y\B\&{scaled} \\{round\_decimals}(\&{small\_number} \|k)\C{converts a decimal fraction}\6
+${}\{{}$\5
+\1\&{int} \|a;\C{the accumulator}\7
+${}\|a\K\T{0};{}$\6
+\&{while} ${}(\|k>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|k);\5
+${}\|a\K(\|a+\\{dig}[\|k]*\\{two})/\T{10};{}$\6
+\4${}\}{}$\2\6
+\&{return} ${}(\|a+\T{1})/\T{2};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{103}Conversely, here is a procedure analogous to \\{print\_int}. If the output
+of this procedure is subsequently read by \TeX\ and converted by the
+\\{round\_decimals} routine above, it turns out that the original value will
+be reproduced exactly; the ``simplest'' such decimal number is output,
+but there is always at least one digit following the decimal point.
+
+The invariant relation in the \&{repeat} loop is that a sequence of
+decimal digits yet to be printed will yield the original number if and only if
+they form a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$.
+We can stop if and only if $f=0$ satisfies this condition; the loop will
+terminate before $s$ can possibly become zero.
+
+\Y\B\&{void} \\{print\_scaled}(\&{scaled} \|s)\C{prints scaled real, rounded to five digits}\6
+${}\{{}$\5
+\1\&{scaled} \\{delta};\C{amount of allowable inaccuracy}\7
+\&{if} ${}(\|s<\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'-'});\5
+\\{negate}(\|s);\C{print the sign, if negative}\6
+\4${}\}{}$\2\6
+${}\\{print\_int}(\|s/\\{unity}){}$;\C{print the integer part}\6
+\\{print\_char}(\.{'.'});\5
+${}\|s\K\T{10}*(\|s\MOD\\{unity})+\T{5};{}$\5
+${}\\{delta}\K\T{10}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{delta}>\\{unity}){}$\1\5
+${}\|s\K\|s+\T{\~100000}-\T{50000}{}$;\C{round the last digit}\2\6
+${}\\{print\_char}(\.{'0'}+(\|s/\\{unity}));{}$\5
+${}\|s\K\T{10}*(\|s\MOD\\{unity});{}$\5
+${}\\{delta}\K\\{delta}*\T{10};{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|s\Z\\{delta}));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{104}Physical sizes that a \TeX\ user specifies for portions of documents are
+represented internally as scaled points. Thus, if we define an `sp' (scaled
+point) as a unit equal to $2^{-16}$ printer's points, every dimension
+inside of \TeX\ is an integer number of sp. There are exactly
+4,736,286.72 sp per inch. Users are not allowed to specify dimensions
+larger than $2^{30}-1$ sp, which is a distance of about 18.892 feet (5.7583
+meters); two such quantities can be added without overflow on a 32-bit
+computer.
+
+The present implementation of \TeX\ does not check for overflow when
+dimensions are added or subtracted. This could be done by inserting a
+few dozen tests of the form `\ignorespaces\&{if} ${}(\|x\G\T{\~10000000000}{}$) \hbox{\\{report\_overflow}}', but the chance of overflow is so remote that
+such tests do not seem worthwhile.
+
+\TeX\ needs to do only a few arithmetic operations on scaled quantities,
+other than addition and subtraction, and the following subroutines do most of
+the work. A single computation might use several subroutine calls, and it is
+desirable to avoid producing multiple error messages in case of arithmetic
+overflow; so the routines set the global variable \\{arith\_error} to \\{true}
+instead of reporting errors directly to the user. Another global variable,
+\\{rem}, holds the remainder after a division.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{arith\_error};\C{has arithmetic overflow occurred recently?}\6
+\&{scaled} \\{rem};\C{amount subtracted to get an exact division}\par
+\fi
+
+\M{105}The first arithmetical subroutine we need computes $nx+y$, where \|x
+and~\|y are \&{scaled} and \|n is an integer. We will also use it to
+multiply integers.
+
+\Y\B\4\D$\\{nx\_plus\_y}(\|X,\|Y,\|Z)$ \5
+$\\{mult\_and\_add}(\|X,\39\|Y,\39\|Z,\39\T{\~7777777777}{}$)\par
+\B\4\D$\\{mult\_integers}(\|X,\|Y)$ \5
+$\\{mult\_and\_add}(\|X,\39\|Y,\39\T{0},\39\T{\~17777777777}{}$)\par
+\Y\B\&{scaled} \\{mult\_and\_add}(\&{int} \|n${},\39{}$\&{scaled} \|x${},\39{}$\&{scaled} \|y${},\39{}$\&{scaled} \\{max\_answer})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|n<\T{0}){}$\5
+${}\{{}$\5
+\1\\{negate}(\|x);\5
+\\{negate}(\|n);\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|n\E\T{0}){}$\1\5
+\&{return} \|y;\2\6
+\&{else} \&{if} ${}(((\|x\Z(\\{max\_answer}-\|y)/\|n)\W({-}\|x\Z(\\{max\_answer}+\|y)/\|n))){}$\1\5
+\&{return} \|n${}*\|x+\|y;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{arith\_error}\K\\{true};{}$\5
+\&{return} \T{0};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{106}We also need to divide scaled dimensions by integers.
+
+\Y\B\&{scaled} \\{x\_over\_n}(\&{scaled} \|x${},\39{}$\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{bool} \\{negative};\C{should \\{rem} be negated?}\6
+\&{scaled} \\{x\_over\_n};\7
+${}\\{negative}\K\\{false};{}$\6
+\&{if} ${}(\|n\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{arith\_error}\K\\{true};{}$\5
+${}\\{x\_over\_n}\K\T{0};{}$\5
+${}\\{rem}\K\|x;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\|n<\T{0}){}$\5
+${}\{{}$\5
+\1\\{negate}(\|x);\5
+\\{negate}(\|n);\5
+${}\\{negative}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|x\G\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{x\_over\_n}\K\|x/\|n;{}$\5
+${}\\{rem}\K\|x\MOD\|n;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{x\_over\_n}\K{-}(({-}\|x)/\|n);{}$\5
+${}\\{rem}\K{-}(({-}\|x)\MOD\|n);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} (\\{negative})\1\5
+\\{negate}(\\{rem});\2\6
+\&{return} \\{x\_over\_n};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{107}Then comes the multiplication of a scaled number by a fraction $\|n/{}$(\&{double}) \|d,
+where \|n and \|d are nonnegative integers $\Z\hbox{$2^{16}$}$ and \|d is
+positive. It would be too dangerous to multiply by~\|n and then divide
+by~\|d, in separate operations, since overflow might well occur; and it
+would be too inaccurate to divide by \|d and then multiply by \|n. Hence
+this subroutine simulates 1.5-precision arithmetic.
+
+\Y\B\&{scaled} \\{xn\_over\_d}(\&{scaled} \|x${},\39{}$\&{int} \|n${},\39{}$\&{int} \|d)\1\1\2\2\6
+${}\{{}$\5
+\1\&{bool} \\{positive};\C{was $\|x\G\T{0}$?}\7
+${}\\{nonnegative\_integer}\|t,\39\|u,\39\|v{}$;\C{intermediate quantities}\7
+\&{scaled} \\{xn\_over\_d};\7
+\&{if} ${}(\|x\G\T{0}){}$\1\5
+${}\\{positive}\K\\{true};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{negate}(\|x);\5
+${}\\{positive}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+${}\|t\K(\|x\MOD\T{\~100000})*\|n;{}$\5
+${}\|u\K(\|x/\T{\~100000})*\|n+(\|t/\T{\~100000});{}$\5
+${}\|v\K(\|u\MOD\|d)*\T{\~100000}+(\|t\MOD\T{\~100000});{}$\6
+\&{if} ${}(\|u/\|d\G\T{\~100000}){}$\1\5
+${}\\{arith\_error}\K\\{true};{}$\2\6
+\&{else}\1\5
+${}\|u\K\T{\~100000}*(\|u/\|d)+(\|v/\|d);{}$\2\6
+\&{if} (\\{positive})\5
+${}\{{}$\5
+\1${}\\{xn\_over\_d}\K\|u;{}$\5
+${}\\{rem}\K\|v\MOD\|d;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{xn\_over\_d}\K{-}\|u;{}$\5
+${}\\{rem}\K{-}(\|v\MOD\|d);{}$\6
+\4${}\}{}$\2\6
+\&{return} \\{xn\_over\_d};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{108}The next subroutine is used to compute the ``badness'' of glue, when a
+total~\|t is supposed to be made from amounts that sum to~\|s. According
+to {\sl The \TeX book}, the badness of this situation is $100(t/s)^3$;
+however, badness is simply a heuristic, so we need not squeeze out the
+last drop of accuracy when computing it. All we really want is an
+approximation that has similar properties.
+
+The actual method used to compute the badness is easier to read from the
+program than to describe in words. It produces an integer value that is a
+reasonably close approximation to $100(t/s)^3$, and all implementations
+of \TeX\ should use precisely this method. Any badness of $2^{13}$ or more is
+treated as infinitely bad, and represented by 10000.
+
+It is not difficult to prove that $$\hbox{$\\{badness}(\|t+\T{1},\|s)\G\\{badness}(\|t,\|s)\G\\{badness}(\|t,\|s+\T{1})$}.$$ The badness function defined here is capable of
+computing at most 1095 distinct values, but that is plenty.
+
+\Y\B\4\D$\\{inf\_bad}$ \5
+\T{10000}\C{infinitely bad value}\par
+\Y\B\&{halfword} \\{badness}(\&{scaled} \|t${},\39{}$\&{scaled} \|s)\C{compute badness, given $\|t\G\T{0}$}\6
+${}\{{}$\5
+\1\&{int} \|r;\C{approximation to $\alpha t/s$, where $\alpha^3\approx 100\cdot2^{18}$}\7
+\&{if} ${}(\|t\E\T{0}){}$\1\5
+\&{return} \T{0};\2\6
+\&{else} \&{if} ${}(\|s\Z\T{0}){}$\1\5
+\&{return} \\{inf\_bad};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\|t\Z\T{7230584}){}$\1\5
+${}\|r\K(\|t*\T{297})/\|s{}$;\C{$297^3=99.94\times2^{18}$}\2\6
+\&{else} \&{if} ${}(\|s\G\T{1663497}){}$\1\5
+${}\|r\K\|t/(\|s/\T{297});{}$\2\6
+\&{else}\1\5
+${}\|r\K\|t;{}$\2\6
+\&{if} ${}(\|r>\T{1290}){}$\1\5
+\&{return} \\{inf\_bad};\C{$1290^3<2^{31}<1291^3$}\2\6
+\&{else}\1\5
+\&{return} ${}(\|r*\|r*\|r+\T{\~400000})/\T{\~1000000};{}$\2\6
+\4${}\}{}$\C{that was $r^3/2^{18}$, rounded to the nearest integer}\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{109}When \TeX\ ``packages'' a list into a box, it needs to calculate the
+proportionality ratio by which the glue inside the box should stretch
+or shrink. This calculation does not affect \TeX's decision making,
+so the precise details of rounding, etc., in the glue calculation are not
+of critical importance for the consistency of results on different computers.
+
+We shall use the type \\{glue\_ratio} for such proportionality ratios.
+A glue ratio should take the same amount of memory as an
+\&{int} (usually 32 bits) if it is to blend smoothly with \TeX's
+other data structures. Thus \\{glue\_ratio} should be equivalent to
+\\{short\_real} in some implementations of \PASCAL. Alternatively,
+it is possible to deal with glue ratios using nothing but fixed-point
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+
+\Y\B\4\D$\\{set\_glue\_ratio\_zero}(\|X)$ \5
+$\|X\K{}$\T{0.0}\C{store the representation of zero ratio}\par
+\B\4\D$\\{set\_glue\_ratio\_one}(\|X)$ \5
+$\|X\K{}$\T{1.0}\C{store the representation of unit ratio}\par
+\B\4\D$\&{float}(\|X)$ \5
+((\&{double})(\|X))\C{convert from \\{glue\_ratio} to type \&{double}}\par
+\B\4\D$\\{unfloat}(\|X)$ \5
+((\\{glue\_ratio})(\|X))\C{convert from \&{double} to type \\{glue\_ratio}}\par
+\B\4\D$\\{float\_constant}(\|X)$ \5
+((\&{double})(\|X))\C{convert \&{int} constant to \&{double}}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{float32\_t} \&{glue\_ratio};\C{one-word representation of a glue expansion factor}\par
+\fi
+
+\N{1}{110}Packed data.
+In order to make efficient use of storage space, \TeX\ bases its major data
+structures on a \\{memory\_word}, which contains either a (signed) integer,
+possibly scaled, or a (signed) \&{glue\_ratio}, or a small number of
+fields that are one half or one quarter of the size used for storing
+integers.
+
+If \|x is a variable of type \\{memory\_word}, it contains up to four
+fields that can be referred to as follows:
+$$\vbox{\halign{\hfil#&#\hfil&#\hfil\cr
+\|x&.\|i&(an \&{int})\cr
+\|x&.\\{sc}\qquad&(a \&{scaled} integer)\cr
+\|x&.\\{gr}&(a \&{glue\_ratio})\cr
+$\|x.\\{hh}.\\{lh}$, $\|x.\\{hh}$&.\\{rh}&(two halfword fields)\cr
+$\|x.\\{hh}.\\{b0}$, $\|x.\\{hh}.\\{b1}$, $\|x.\\{hh}$&.\\{rh}&(two quarterword fields, one halfword
+field)\cr
+$\|x.\\{qqqq}.\\{b0}$, $\|x.\\{qqqq}.\\{b1}$, $\|x.\\{qqqq}$&.\\{b2}, $\|x.\\{qqqq}.\\{b3}$\hskip-100pt
+&\qquad\qquad\qquad(four quarterword fields)\cr}}$$
+This is somewhat cumbersome to write, and not very readable either, but
+macros will be used to make the notation shorter and more transparent.
+The \PASCAL\ code below gives a formal definition of \\{memory\_word} and
+its subsidiary types, using packed variant records. \TeX\ makes no
+assumptions about the relative positions of the fields within a word.
+
+Since we are assuming 32-bit integers, a halfword must contain at least
+16 bits, and a quarterword must contain at least 8 bits.
+But it doesn't hurt to have more bits; for example, with enough 36-bit
+words you might be able to have \\{mem\_max} as large as 262142, which is
+eight times as much memory as anybody had during the first four years of
+\TeX's existence.
+
+N.B.: Valuable memory space will be dreadfully wasted unless \TeX\ is compiled
+by a \PASCAL\ that packs all of the \\{memory\_word} variants into
+the space of a single integer. This means, for example, that \&{glue\_ratio}
+words should be \\{short\_real} instead of \&{double} on some computers. Some
+\PASCAL\ compilers will pack an integer whose subrange is `$\T{0}\dotdot\T{255}$' into
+an eight-bit field, but others insist on allocating space for an additional
+sign bit; on such systems you can get 256 values into a quarterword only
+if the subrange is `${-}\T{128}\dotdot\T{127}$'.
+
+The present implementation tries to accommodate as many variations as possible,
+so it makes few assumptions. If integers having the subrange
+`$\\{min\_quarterword}\dotdot\\{max\_quarterword}$' can be packed into a quarterword,
+and if integers having the subrange `$\\{min\_halfword}\dotdot\\{max\_halfword}$'
+can be packed into a halfword, everything should work satisfactorily.
+
+It is usually most efficient to have $\\{min\_quarterword}\E\\{min\_halfword}\E\T{0}$,
+so one should try to achieve this unless it causes a severe problem.
+The values defined here are recommended for most 32-bit computers.
+
+\Y\B\4\D$\\{min\_quarterword}$ \5
+\T{0}\C{smallest allowable value in a \\{quarterword}}\par
+\B\4\D$\\{max\_quarterword}$ \5
+\T{255}\C{largest allowable value in a \\{quarterword}}\par
+\B\4\D$\\{min\_halfword}$ \5
+\T{0}\C{smallest allowable value in a \&{halfword}}\par
+\B\4\D$\\{max\_halfword}$ \5
+\T{65535}\C{largest allowable value in a \&{halfword}}\par
+\fi
+
+\M{111}Here are the inequalities that the quarterword and halfword values
+must satisfy (or rather, the inequalities that they mustn't satisfy):
+
+\Y\B\4\X14:Check the ``constant'' values for consistency\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{if} ${}((\\{mem\_min}\I\\{mem\_bot})\V(\\{mem\_max}\I\\{mem\_top})){}$\1\5
+${}\\{bad}\K\T{10};{}$\2\6
+\8\#\&{endif}\6
+\&{if} ${}((\\{mem\_min}>\\{mem\_bot})\V(\\{mem\_max}<\\{mem\_top})){}$\1\5
+${}\\{bad}\K\T{10};{}$\2\6
+\&{if} ${}((\\{min\_quarterword}>\T{0})\V(\\{max\_quarterword}<\T{127})){}$\1\5
+${}\\{bad}\K\T{11};{}$\2\6
+\&{if} ${}((\\{min\_halfword}>\T{0})\V(\\{max\_halfword}<\T{32767})){}$\1\5
+${}\\{bad}\K\T{12};{}$\2\6
+\&{if} ${}((\\{min\_quarterword}<\\{min\_halfword})\V\30(\\{max\_quarterword}>\\{max\_halfword})){}$\1\5
+${}\\{bad}\K\T{13};{}$\2\6
+\&{if} ${}((\\{mem\_min}<\\{min\_halfword})\V(\\{mem\_max}\G\\{max\_halfword})\V\30(\\{mem\_bot}-\\{mem\_min}>\\{max\_halfword}+\T{1})){}$\1\5
+${}\\{bad}\K\T{14};{}$\2\6
+\&{if} ${}((\\{font\_base}<\\{min\_quarterword})\V(\\{font\_max}>\\{max\_quarterword})){}$\1\5
+${}\\{bad}\K\T{15};{}$\2\6
+\&{if} ${}(\\{font\_max}>\\{font\_base}+\T{256}){}$\1\5
+${}\\{bad}\K\T{16};{}$\2\6
+\&{if} ${}((\\{save\_size}>\\{max\_halfword})\V(\\{max\_strings}>\\{max\_halfword})){}$\1\5
+${}\\{bad}\K\T{17};{}$\2\6
+\&{if} ${}(\\{buf\_size}>\\{max\_halfword}){}$\1\5
+${}\\{bad}\K\T{18};{}$\2\6
+\&{if} ${}(\\{max\_quarterword}-\\{min\_quarterword}<\T{255}){}$\1\5
+${}\\{bad}\K\T{19}{}$;\2\par
+\fi
+
+\M{112}The operation of adding or subtracting \\{min\_quarterword} occurs quite
+frequently in \TeX, so it is convenient to abbreviate this operation
+by using the macros \\{qi} and \\{qo} for input and output to and from
+quarterword format.
+
+The inner loop of \TeX\ will run faster with respect to compilers
+that don't optimize expressions like `$\|x+\T{0}$' and `$\|x-\T{0}$', if these
+macros are simplified in the obvious way when $\\{min\_quarterword}\E\T{0}$.
+
+\Y\B\4\D$\\{qi}(\|X)$ \5
+$\|X+{}$\\{min\_quarterword}\C{to put an \&{eight\_bits} item into a quarterword}\par
+\B\4\D$\\{qo}(\|X)$ \5
+$\|X-{}$\\{min\_quarterword}\C{to take an \&{eight\_bits} item out of a quarterword}\par
+\B\4\D$\\{hi}(\|X)$ \5
+$\|X+{}$\\{min\_halfword}\C{to put a sixteen-bit item into a halfword}\par
+\B\4\D$\\{ho}(\|X)$ \5
+$\|X-{}$\\{min\_halfword}\C{to take a sixteen-bit item from a halfword}\par
+\fi
+
+\M{113}The reader should study the following definitions closely:
+
+\Y\B\4\D$\\{sc}$ \5
+\|i\C{\&{scaled} data is equivalent to \&{int}}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint8\_t} \&{quarterword};\C{1/4 of a word}\6
+\&{typedef} \&{uint16\_t} \&{halfword};\C{1/2 of a word}\6
+\&{typedef} \&{uint8\_t} \&{two\_choices};\C{used when there are two variants in a record}\6
+\&{typedef} \&{uint8\_t} \&{four\_choices};\C{used when there are four variants in a record}\6
+\&{typedef} \&{struct} ${}\{{}$\1\7
+\&{halfword} \\{rh};\6
+\&{union} ${}\{{}$\1\6
+\&{halfword} \\{lh};\6
+\&{struct} ${}\{{}$\1\6
+\&{quarterword} \\{b0};\6
+\&{quarterword} \\{b1};\2\6
+${}\};{}$\2\6
+${}\};{}$\2\6
+${}\}{}$ \&{two\_halves};\6
+\&{typedef} \&{struct} ${}\{{}$\1\7
+\&{quarterword} \\{b0};\6
+\&{quarterword} \\{b1};\6
+\&{quarterword} \\{b2};\6
+\&{quarterword} \\{b3};\2\6
+${}\}{}$ \&{four\_quarters};\6
+\&{typedef} \&{struct} ${}\{{}$\1\7
+\&{union} ${}\{{}$\1\6
+\&{int} \|i;\6
+\&{glue\_ratio} \\{gr};\6
+\&{two\_halves} \\{hh};\6
+\&{four\_quarters} \\{qqqq};\2\6
+${}\};{}$\2\6
+${}\}{}$ \&{memory\_word};\6
+\&{typedef} \&{struct} ${}\{{}$\5
+\1\&{FILE} ${}{*}\|f{}$;\5
+\&{memory\_word}\, \|d;\5
+\2${}\}{}$ \&{word\_file};\par
+\fi
+
+\M{114}When debugging, we may want to print a \&{memory\_word} without knowing
+what type it is; so we print it in all modes.
+
+\Y\B\8\#\&{ifdef} \.{DEBUG}\6
+\&{void} \\{print\_word}(\&{memory\_word} \|w)\C{prints \|w in all ways}\6
+${}\{{}$\5
+\1${}\\{print\_int}(\|w.\|i);{}$\5
+\\{print\_char}(\.{'\ '});\6
+${}\\{print\_scaled}(\|w.\\{sc});{}$\5
+\\{print\_char}(\.{'\ '});\6
+${}\\{print\_scaled}(\\{round}(\\{unity}*\&{float}(\|w.\\{gr})));{}$\5
+\\{print\_ln}(\,);\6
+${}\\{print\_int}(\|w.\\{hh}.\\{lh});{}$\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_int}(\|w.\\{hh}.\\{b0});{}$\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_int}(\|w.\\{hh}.\\{b1});{}$\5
+\\{print\_char}(\.{';'});\5
+${}\\{print\_int}(\|w.\\{hh}.\\{rh});{}$\5
+\\{print\_char}(\.{'\ '});\6
+${}\\{print\_int}(\|w.\\{qqqq}.\\{b0});{}$\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_int}(\|w.\\{qqqq}.\\{b1});{}$\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_int}(\|w.\\{qqqq}.\\{b2});{}$\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_int}(\|w.\\{qqqq}.\\{b3});{}$\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\N{1}{115}Dynamic memory allocation.
+The \TeX\ system does nearly all of its own memory allocation, so that it
+can readily be transported into environments that do not have automatic
+facilities for strings, garbage collection, etc., and so that it can be in
+control of what error messages the user receives. The dynamic storage
+requirements of \TeX\ are handled by providing a large array \\{mem} in
+which consecutive blocks of words are used as nodes by the \TeX\ routines.
+
+Pointer variables are indices into this array, or into another array
+called \\{eqtb} that will be explained later. A pointer variable might
+also be a special flag that lies outside the bounds of \\{mem}, so we
+allow pointers to assume any \&{halfword} value. The minimum halfword
+value represents a null pointer. \TeX\ does not assume that \\{mem}[\\{null}] exists.
+
+\Y\B\4\D$\&{pointer}$ \5
+\&{halfword}\C{a flag or a location in \\{mem} or \\{eqtb}}\par
+\B\4\D$\\{null}$ \5
+\\{min\_halfword}\C{the null pointer}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{temp\_ptr};\C{a pointer variable for occasional emergency use}\par
+\fi
+
+\M{116}The \\{mem} array is divided into two regions that are allocated separately,
+but the dividing line between these two regions is not fixed; they grow
+together until finding their ``natural'' size in a particular job.
+Locations less than or equal to \\{lo\_mem\_max} are used for storing
+variable-length records consisting of two or more words each. This region
+is maintained using an algorithm similar to the one described in exercise
+2.5--19 of {\sl The Art of Computer Programming}. However, no size field
+appears in the allocated nodes; the program is responsible for knowing the
+relevant size when a node is freed. Locations greater than or equal to
+\\{hi\_mem\_min} are used for storing one-word records; a conventional
+\.{AVAIL} stack is used for allocation in this region.
+
+Locations of \\{mem} between \\{mem\_bot} and \\{mem\_top} may be dumped as part
+of preloaded format files, by the \.{INITEX} preprocessor.
+Production versions of \TeX\ may extend the memory at both ends in order to
+provide more space; locations between \\{mem\_min} and \\{mem\_bot} are always
+used for variable-size nodes, and locations between \\{mem\_top} and \\{mem\_max}
+are always used for single-word nodes.
+
+The key pointers that govern \\{mem} allocation have a prescribed order:
+$$\advance\thickmuskip-2mu
+\hbox{$\\{null}\Z\\{mem\_min}\Z\\{mem\_bot}<\\{lo\_mem\_max}<\\{hi\_mem\_min}<\\{mem\_top}\Z\\{mem\_end}\Z\\{mem\_max}$.}$$
+
+Empirical tests show that the present implementation of \TeX\ tends to
+spend about 9\pct! of its running time allocating nodes, and about 6\pct!
+deallocating them after their use.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{memory\_word} ${}\\{mem0}[\\{mem\_max}-\\{mem\_min}+\T{1}],{}$ ${}{*\&{const}\ }\\{mem}\K\\{mem0}-\\{mem\_min}{}$;\C{the big dynamic storage area}\6
+\&{pointer} \\{lo\_mem\_max};\C{the largest location of variable-size memory in use}\6
+\&{pointer} \\{hi\_mem\_min};\C{the smallest location of one-word memory in use}\par
+\fi
+
+\M{117}In order to study the memory requirements of particular applications, it
+is possible to prepare a version of \TeX\ that keeps track of current and
+maximum memory usage. When code between the delimiters \#\&{ifdef} \.{STAT} $\ldots$
+\\{tats} is not ``commented out,'' \TeX\ will run a bit slower but it will
+report these statistics when \\{tracing\_stats} is sufficiently large.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{var\_used}${},{}$ \\{dyn\_used};\C{how much memory is in use}\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\8\#\&{define} \\{incr\_dyn\_used} \5\\{incr}(\\{dyn\_used})\6
+\8\#\&{define} \\{decr\_dyn\_used} \5\\{decr}(\\{dyn\_used})\6
+\8\#\&{else}\6
+\8\#\&{define} \\{incr\_dyn\_used}\6
+\8\#\&{define} \\{decr\_dyn\_used}\6
+\8\#\&{endif}\par
+\fi
+
+\M{118}Let's consider the one-word memory region first, since it's the
+simplest. The pointer variable \\{mem\_end} holds the highest-numbered location
+of \\{mem} that has ever been used. The free locations of \\{mem} that
+occur between \\{hi\_mem\_min} and \\{mem\_end}, inclusive, are of type
+\&{two\_halves}, and we write \\{info}(\|p) and \\{link}(\|p) for the \\{lh}
+and \\{rh} fields of \\{mem}[\|p] when it is of this type. The single-word
+free locations form a linked list
+$$\\{avail},\;\hbox{\\{link}(\\{avail})},\;\hbox{\\{link}(\\{link}(\\{avail}))},\;\ldots$$
+terminated by \\{null}.
+
+\Y\B\4\D$\\{link}(\|X)$ \5
+$\\{mem}[\|X].\\{hh}.{}$\\{rh}\C{the \\{link} field of a memory word}\par
+\B\4\D$\\{info}(\|X)$ \5
+$\\{mem}[\|X].\\{hh}.{}$\\{lh}\C{the \\{info} field of a memory word}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{avail};\C{head of the list of available one-word nodes}\6
+\&{pointer} \\{mem\_end};\C{the last one-word node used in \\{mem}}\par
+\fi
+
+\M{119}If memory is exhausted, it might mean that the user has forgotten
+a right brace. We will define some procedures later that try to help
+pinpoint the trouble.
+
+\Y\B\X292:Declare the procedure called \\{show\_token\_list}\X\6
+\X306:Declare the procedure called \\{runaway}\X\par
+\fi
+
+\M{120}The function \\{get\_avail} returns a pointer to a new one-word node whose
+\\{link} field is null. However, \TeX\ will halt if there is no more room left.
+
+If the available-space list is empty, i.e., if $\\{avail}\E\\{null}$,
+we try first to increase \\{mem\_end}. If that cannot be done, i.e., if
+$\\{mem\_end}\E\\{mem\_max}$, we try to decrease \\{hi\_mem\_min}. If that cannot be
+done, i.e., if $\\{hi\_mem\_min}\E\\{lo\_mem\_max}+\T{1}$, we have to quit.
+
+\Y\B\&{pointer} \\{get\_avail}(\&{void})\C{single-word node allocation}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node being got}\7
+${}\|p\K\\{avail}{}$;\C{get top location in the \\{avail} stack}\6
+\&{if} ${}(\|p\I\\{null}){}$\1\5
+${}\\{avail}\K\\{link}(\\{avail}){}$;\C{and pop it off}\2\6
+\&{else} \&{if} ${}(\\{mem\_end}<\\{mem\_max}{}$)\C{or go into virgin territory}\6
+${}\{{}$\5
+\1\\{incr}(\\{mem\_end});\5
+${}\|p\K\\{mem\_end};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{decr}(\\{hi\_mem\_min});\5
+${}\|p\K\\{hi\_mem\_min};{}$\6
+\&{if} ${}(\\{hi\_mem\_min}\Z\\{lo\_mem\_max}){}$\5
+${}\{{}$\5
+\1\\{runaway}(\,);\C{if memory is exhausted, display possible runaway text}\6
+${}\\{overflow}(\.{"main\ memory\ size"},\39\\{mem\_max}+\T{1}-\\{mem\_min}){}$;\C{quit; all one-word nodes are busy}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{link}(\|p)\K\\{null}{}$;\C{provide an oft-desired initialization of the new node}\6
+\\{incr\_dyn\_used};\C{maintain statistics}\6
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{121}Conversely, a one-word node is recycled by calling \\{free\_avail}.
+This routine is part of \TeX's ``inner loop,'' so we want it to be fast.
+
+\Y\B\4\D$\\{free\_avail}(\|X)$ \C{single-word node liberation}\6
+${}\{{}$\5
+\1${}\\{link}(\|X)\K\\{avail};{}$\5
+${}\\{avail}\K\|X;{}$\5
+\\{decr\_dyn\_used};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{122}There's also a \\{fast\_get\_avail} routine, which saves the procedure-call
+overhead at the expense of extra programming. This routine is used in
+the places that would otherwise account for the most calls of \\{get\_avail}.
+
+\Y\B\4\D$\\{fast\_get\_avail}(\|X)$ \5
+\hbox{}\6
+${}\{{}$\5
+\1${}\|X\K\\{avail}{}$;\C{avoid \\{get\_avail} if possible, to save time}\6
+\&{if} ${}(\|X\E\\{null}){}$\1\5
+${}\|X\K\\{get\_avail}(\,);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{avail}\K\\{link}(\|X);{}$\5
+${}\\{link}(\|X)\K\\{null};{}$\5
+\\{incr\_dyn\_used};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{123}The procedure \\{flush\_list}(\|p) frees an entire linked list of
+one-word nodes that starts at position \|p.
+
+\Y\B\&{void} \\{flush\_list}(\&{pointer} \|p)\C{makes list of single-word nodes available}\6
+${}\{{}$\5
+\1\&{pointer} \|q${},{}$ \|r;\C{list traversers}\7
+\&{if} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|r\K\|p{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|q\K\|r;{}$\5
+${}\|r\K\\{link}(\|r);{}$\5
+\\{decr\_dyn\_used};\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r\E\\{null})){}$;\C{now \|q is the last node on the list}\6
+${}\\{link}(\|q)\K\\{avail};{}$\5
+${}\\{avail}\K\|p;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{124}The available-space list that keeps track of the variable-size portion
+of \\{mem} is a nonempty, doubly-linked circular list of empty nodes,
+pointed to by the roving pointer \\{rover}.
+
+Each empty node has size 2 or more; the first word contains the special
+value \\{max\_halfword} in its \\{link} field and the size in its \\{info} field;
+the second word contains the two pointers for double linking.
+
+Each nonempty node also has size 2 or more. Its first word is of type
+\&{two\_halves}\kern-1pt, and its \\{link} field is never equal to \\{max\_halfword}.
+Otherwise there is complete flexibility with respect to the contents
+of its other fields and its other words.
+
+(We require $\\{mem\_max}<\\{max\_halfword}$ because terrible things can happen
+when \\{max\_halfword} appears in the \\{link} field of a nonempty node.)
+
+\Y\B\4\D$\\{empty\_flag}$ \5
+\\{max\_halfword}\C{the \\{link} of an empty variable-size node}\par
+\B\4\D$\\{is\_empty}(\|X)$ \5
+$(\\{link}(\|X)\E\\{empty\_flag}{}$)\C{tests for empty node}\par
+\B\4\D$\\{node\_size}$ \5
+\\{info}\C{the size field in empty variable-size nodes}\par
+\B\4\D$\\{llink}(\|X)$ \5
+$\\{info}(\|X+\T{1}{}$)\C{left link in doubly-linked list of empty nodes}\par
+\B\4\D$\\{rlink}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{right link in doubly-linked list of empty nodes}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{rover};\C{points to some node in the list of empties}\par
+\fi
+
+\M{125}A call to \\{get\_node} with argument \|s returns a pointer to a new node
+of size~\|s, which must be 2~or more. The \\{link} field of the first word
+of this new node is set to null. An overflow stop occurs if no suitable
+space exists.
+
+If \\{get\_node} is called with $s=2^{30}$, it simply merges adjacent free
+areas and returns the value \\{max\_halfword}.
+
+\Y\B\&{pointer} \\{get\_node}(\&{int} \|s)\C{variable-size node allocation}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the node currently under inspection}\6
+\&{pointer} \|q;\C{the node physically after node \|p}\6
+\&{int} \|r;\C{the newly allocated node, or a candidate for this honor}\6
+\&{int} \|t;\C{temporary register}\7
+\4\\{restart}:\5
+${}\|p\K\\{rover}{}$;\C{start at some free node in the ring}\6
+\&{do}\5
+${}\{{}$\1\6
+\X127:Try to allocate within node \|p and its physical successors, and \&{goto} \\{found} if allocation was possible\X;\6
+${}\|p\K\\{rlink}(\|p){}$;\C{move to the next node in the ring}\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|p\E\\{rover})){}$;\C{repeat until the whole list has been traversed}\6
+\&{if} ${}(\|s\E\T{\~10000000000}){}$\5
+${}\{{}$\5
+\1\&{return} \\{max\_halfword};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{lo\_mem\_max}+\T{2}<\\{hi\_mem\_min}){}$\1\6
+\&{if} ${}(\\{lo\_mem\_max}+\T{2}\Z\\{mem\_bot}+\\{max\_halfword}){}$\1\5
+\X126:Grow more variable-size memory and \&{goto} \\{restart}\X;\2\2\6
+${}\\{overflow}(\.{"main\ memory\ size"},\39\\{mem\_max}+\T{1}-\\{mem\_min}){}$;\C{sorry, nothing satisfactory is left}\6
+\4\\{found}:\5
+${}\\{link}(\|r)\K\\{null}{}$;\C{this node is now nonempty}\6
+\8\#\&{ifdef} \.{STAT}\6
+${}\\{var\_used}\K\\{var\_used}+\|s{}$;\C{maintain usage statistics}\6
+\8\#\&{endif}\6
+\&{return} \|r;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{126}The lower part of \\{mem} grows by 1000 words at a time, unless
+we are very close to going under. When it grows, we simply link
+a new node into the available-space list. This method of controlled
+growth helps to keep the \\{mem} usage consecutive when \TeX\ is
+implemented on ``virtual memory'' systems.
+
+\Y\B\4\X126:Grow more variable-size memory and \&{goto} \\{restart}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{hi\_mem\_min}-\\{lo\_mem\_max}\G\T{1998}){}$\1\5
+${}\|t\K\\{lo\_mem\_max}+\T{1000};{}$\2\6
+\&{else}\1\5
+${}\|t\K\\{lo\_mem\_max}+\T{1}+(\\{hi\_mem\_min}-\\{lo\_mem\_max})/\T{2}{}$;\C{$\\{lo\_mem\_max}+\T{2}\Z\|t<\\{hi\_mem\_min}$}\2\6
+${}\|p\K\\{llink}(\\{rover});{}$\5
+${}\|q\K\\{lo\_mem\_max};{}$\5
+${}\\{rlink}(\|p)\K\|q;{}$\5
+${}\\{llink}(\\{rover})\K\|q{}$;\6
+\&{if} ${}(\|t>\\{mem\_bot}+\\{max\_halfword}){}$\1\5
+${}\|t\K\\{mem\_bot}+\\{max\_halfword};{}$\2\6
+${}\\{rlink}(\|q)\K\\{rover};{}$\5
+${}\\{llink}(\|q)\K\|p;{}$\5
+${}\\{link}(\|q)\K\\{empty\_flag};{}$\5
+${}\\{node\_size}(\|q)\K\|t-\\{lo\_mem\_max}{}$;\6
+${}\\{lo\_mem\_max}\K\|t;{}$\5
+${}\\{link}(\\{lo\_mem\_max})\K\\{null};{}$\5
+${}\\{info}(\\{lo\_mem\_max})\K\\{null};{}$\5
+${}\\{rover}\K\|q;{}$\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\par
+\U125.\fi
+
+\M{127}Empirical tests show that the routine in this section performs a
+node-merging operation about 0.75 times per allocation, on the average,
+after which it finds that $\|r>\|p+\T{1}$ about 95\pct! of the time.
+
+\Y\B\4\X127:Try to allocate within node \|p and its physical successors, and \&{goto} \\{found} if allocation was possible\X${}\E{}$\6
+$\|q\K\|p+\\{node\_size}(\|p){}$;\C{find the physical successor}\6
+\&{while} (\\{is\_empty}(\|q))\C{merge node \|p with node \|q}\6
+${}\{{}$\5
+\1${}\|t\K\\{rlink}(\|q);{}$\6
+\&{if} ${}(\|q\E\\{rover}){}$\1\5
+${}\\{rover}\K\|t;{}$\2\6
+${}\\{llink}(\|t)\K\\{llink}(\|q);{}$\5
+${}\\{rlink}(\\{llink}(\|q))\K\|t{}$;\6
+${}\|q\K\|q+\\{node\_size}(\|q);{}$\6
+\4${}\}{}$\2\6
+${}\|r\K\|q-\|s;{}$\6
+\&{if} ${}(\|r>\|p+\T{1}){}$\1\5
+\X128:Allocate from the top of node \|p and \&{goto} \\{found}\X;\2\6
+\&{if} ${}(\|r\E\|p){}$\1\6
+\&{if} ${}(\\{rlink}(\|p)\I\|p){}$\1\5
+\X129:Allocate entire node \|p and \&{goto} \\{found}\X;\2\2\6
+$\\{node\_size}(\|p)\K\|q-{}$\|p\C{reset the size in case it grew}\par
+\U125.\fi
+
+\M{128}\B\X128:Allocate from the top of node \|p and \&{goto} \\{found}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{node\_size}(\|p)\K\|r-\|p{}$;\C{store the remaining size}\6
+${}\\{rover}\K\|p{}$;\C{start searching here next time}\6
+\&{goto} \\{found};\6
+\4${}\}{}$\2\par
+\U127.\fi
+
+\M{129}Here we delete node \|p from the ring, and let \\{rover} rove around.
+
+\Y\B\4\X129:Allocate entire node \|p and \&{goto} \\{found}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{rover}\K\\{rlink}(\|p);{}$\5
+${}\|t\K\\{llink}(\|p);{}$\5
+${}\\{llink}(\\{rover})\K\|t;{}$\5
+${}\\{rlink}(\|t)\K\\{rover};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\par
+\U127.\fi
+
+\M{130}Conversely, when some variable-size node \|p of size \|s is no longer needed,
+the operation $\\{free\_node}(\|p,\|s)$ will make its words available, by inserting
+\|p as a new empty node just before where \\{rover} now points.
+
+\Y\B\&{void} \\{free\_node}(\&{pointer} \|p${},\39{}$\&{halfword} \|s)\C{variable-size node liberation}\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{\\{llink}(\\{rover})}\7
+${}\\{node\_size}(\|p)\K\|s;{}$\5
+${}\\{link}(\|p)\K\\{empty\_flag};{}$\5
+${}\|q\K\\{llink}(\\{rover});{}$\5
+${}\\{llink}(\|p)\K\|q;{}$\5
+${}\\{rlink}(\|p)\K\\{rover}{}$;\C{set both links}\6
+${}\\{llink}(\\{rover})\K\|p;{}$\5
+${}\\{rlink}(\|q)\K\|p{}$;\C{insert \|p into the ring}\6
+\8\#\&{ifdef} \.{STAT}\6
+${}\\{var\_used}\K\\{var\_used}-\|s;{}$\6
+\8\#\&{endif}\C{maintain statistics}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{131}Just before \.{INITEX} writes out the memory, it sorts the doubly linked
+available space list. The list is probably very short at such times, so a
+simple insertion sort is used. The smallest available location will be
+pointed to by \\{rover}, the next-smallest by \\{rlink}(\\{rover}), etc.
+
+\Y\B\8\#\&{ifdef} \.{INIT}\6
+\&{void} \\{sort\_avail}(\&{void})\C{sorts the available variable-size nodes by location}\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q${},{}$ \|r;\C{indices into \\{mem}}\6
+\&{pointer} \\{old\_rover};\C{initial \\{rover} setting}\7
+${}\|p\K\\{get\_node}(\T{\~10000000000}){}$;\C{merge adjacent free areas}\6
+${}\|p\K\\{rlink}(\\{rover});{}$\5
+${}\\{rlink}(\\{rover})\K\\{max\_halfword};{}$\5
+${}\\{old\_rover}\K\\{rover};{}$\6
+\&{while} ${}(\|p\I\\{old\_rover}){}$\1\5
+\X132:Sort \(p)\|p into the list starting at \\{rover} and advance \|p to \\{rlink}(\|p)\X;\2\6
+${}\|p\K\\{rover};{}$\6
+\&{while} ${}(\\{rlink}(\|p)\I\\{max\_halfword}){}$\5
+${}\{{}$\5
+\1${}\\{llink}(\\{rlink}(\|p))\K\|p;{}$\5
+${}\|p\K\\{rlink}(\|p);{}$\6
+\4${}\}{}$\2\6
+${}\\{rlink}(\|p)\K\\{rover};{}$\5
+${}\\{llink}(\\{rover})\K\|p;{}$\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{132}The following \&{while} loop is guaranteed to
+terminate, since the list that starts at
+\\{rover} ends with \\{max\_halfword} during the sorting procedure.
+
+\Y\B\4\X132:Sort \(p)\|p into the list starting at \\{rover} and advance \|p to \\{rlink}(\|p)\X${}\E{}$\6
+\&{if} ${}(\|p<\\{rover}){}$\5
+${}\{{}$\5
+\1${}\|q\K\|p;{}$\5
+${}\|p\K\\{rlink}(\|q);{}$\5
+${}\\{rlink}(\|q)\K\\{rover};{}$\5
+${}\\{rover}\K\|q;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{rover};{}$\6
+\&{while} ${}(\\{rlink}(\|q)<\|p){}$\1\5
+${}\|q\K\\{rlink}(\|q);{}$\2\6
+${}\|r\K\\{rlink}(\|p);{}$\5
+${}\\{rlink}(\|p)\K\\{rlink}(\|q);{}$\5
+${}\\{rlink}(\|q)\K\|p;{}$\5
+${}\|p\K\|r;{}$\6
+\4${}\}{}$\2\par
+\U131.\fi
+
+\N{1}{133}Data structures for boxes and their friends.
+From the computer's standpoint, \TeX's chief mission is to create
+horizontal and vertical lists. We shall now investigate how the elements
+of these lists are represented internally as nodes in the dynamic memory.
+
+A horizontal or vertical list is linked together by \\{link} fields in
+the first word of each node. Individual nodes represent boxes, glue,
+penalties, or special things like discretionary hyphens; because of this
+variety, some nodes are longer than others, and we must distinguish different
+kinds of nodes. We do this by putting a `\\{type}' field in the first word,
+together with the link and an optional `\\{subtype}'.
+
+\Y\B\4\D$\\{type}(\|X)$ \5
+$\\{mem}[\|X].\\{hh}.{}$\\{b0}\C{identifies what kind of node this is}\par
+\B\4\D$\\{subtype}(\|X)$ \5
+$\\{mem}[\|X].\\{hh}.{}$\\{b1}\C{secondary identification in some cases}\par
+\fi
+
+\M{134}A \\{char\_node}, which represents a single character, is the most important
+kind of node because it accounts for the vast majority of all boxes.
+Special precautions are therefore taken to ensure that a \\{char\_node} does
+not take up much memory space. Every such node is one word long, and in fact
+it is identifiable by this property, since other kinds of nodes have at least
+two words, and they appear in \\{mem} locations less than \\{hi\_mem\_min}.
+This makes it possible to omit the \\{type} field in a \\{char\_node}, leaving
+us room for two bytes that identify a \\{font} and a \\{character} within
+that font.
+
+Note that the format of a \\{char\_node} allows for up to 256 different
+fonts and up to 256 characters per font; but most implementations will
+probably limit the total number of fonts to fewer than 75 per job,
+and most fonts will stick to characters whose codes are
+less than 128 (since higher codes
+are more difficult to access on most keyboards).
+
+Extensions of \TeX\ intended for oriental languages will need even more
+than $256\times256$ possible characters, when we consider different sizes
+and styles of type. It is suggested that Chinese and Japanese fonts be
+handled by representing such characters in two consecutive \\{char\_node}
+entries: The first of these has $\\{font}\E\\{font\_base}$, and its \\{link} points
+to the second;
+the second identifies the font and the character dimensions.
+The saving feature about oriental characters is that most of them have
+the same box dimensions. The \\{character} field of the first \\{char\_node}
+is a ``\\{charext}'' that distinguishes between graphic symbols whose
+dimensions are identical for typesetting purposes. (See the \MF\ manual.)
+Such an extension of \TeX\ would not be difficult; further details are
+left to the reader.
+
+In order to make sure that the \\{character} code fits in a quarterword,
+\TeX\ adds the quantity \\{min\_quarterword} to the actual code.
+
+Character nodes appear only in horizontal lists, never in vertical lists.
+
+\Y\B\4\D$\\{is\_char\_node}(\|X)$ \5
+$(\|X\G\\{hi\_mem\_min}{}$)\C{does the argument point to a \\{char\_node}?}\par
+\B\4\D$\\{font}$ \5
+\\{type}\C{the font code in a \\{char\_node}}\par
+\B\4\D$\\{character}$ \5
+\\{subtype}\C{the character code in a \\{char\_node}}\par
+\fi
+
+\M{135}An \\{hlist\_node} stands for a box that was made from a horizontal list.
+Each \\{hlist\_node} is seven words long, and contains the following fields
+(in addition to the mandatory \\{type} and \\{link}, which we shall not
+mention explicitly when discussing the other node types): The \\{height} and
+\\{width} and \\{depth} are scaled integers denoting the dimensions of the
+box. There is also a \\{shift\_amount} field, a scaled integer indicating
+how much this box should be lowered (if it appears in a horizontal list),
+or how much it should be moved to the right (if it appears in a vertical
+list). There is a \\{list\_ptr} field, which points to the beginning of the
+list from which this box was fabricated; if \\{list\_ptr} is \\{null}, the box
+is empty. Finally, there are three fields that represent the setting of
+the glue: \\{glue\_set}(\|p) is a word of type \&{glue\_ratio} that represents
+the proportionality constant for glue setting; \\{glue\_sign}(\|p) is
+\\{stretching} or \\{shrinking} or \\{normal} depending on whether or not the
+glue should stretch or shrink or remain rigid; and \\{glue\_order}(\|p)
+specifies the order of infinity to which glue setting applies (\\{normal},
+\\{fil}, \\{fill}, or \\{filll}). The \\{subtype} field is not used.
+
+\Y\B\4\D$\\{hlist\_node}$ \5
+\T{0}\C{\\{type} of hlist nodes}\par
+\B\4\D$\\{box\_node\_size}$ \5
+\T{7}\C{number of words to allocate for a box node}\par
+\B\4\D$\\{width\_offset}$ \5
+\T{1}\C{position of \\{width} field in a box node}\par
+\B\4\D$\\{depth\_offset}$ \5
+\T{2}\C{position of \\{depth} field in a box node}\par
+\B\4\D$\\{height\_offset}$ \5
+\T{3}\C{position of \\{height} field in a box node}\par
+\B\4\D$\\{width}(\|X)$ \5
+$\\{mem}[\|X+\\{width\_offset}].{}$\\{sc}\C{width of the box, in sp}\par
+\B\4\D$\\{depth}(\|X)$ \5
+$\\{mem}[\|X+\\{depth\_offset}].{}$\\{sc}\C{depth of the box, in sp}\par
+\B\4\D$\\{height}(\|X)$ \5
+$\\{mem}[\|X+\\{height\_offset}].{}$\\{sc}\C{height of the box, in sp}\par
+\B\4\D$\\{shift\_amount}(\|X)$ \5
+$\\{mem}[\|X+\T{4}].{}$\\{sc}\C{repositioning distance, in sp}\par
+\B\4\D$\\{list\_offset}$ \5
+\T{5}\C{position of \\{list\_ptr} field in a box node}\par
+\B\4\D$\\{list\_ptr}(\|X)$ \5
+$\\{link}(\|X+\\{list\_offset}{}$)\C{beginning of the list inside the box}\par
+\B\4\D$\\{glue\_order}(\|X)$ \5
+$\\{subtype}(\|X+\\{list\_offset}{}$)\C{applicable order of infinity}\par
+\B\4\D$\\{glue\_sign}(\|X)$ \5
+$\\{type}(\|X+\\{list\_offset}{}$)\C{stretching or shrinking}\par
+\B\4\D$\\{normal}$ \5
+\T{0}\C{the most common case when several cases are named}\par
+\B\4\D$\\{stretching}$ \5
+\T{1}\C{glue setting applies to the stretch components}\par
+\B\4\D$\\{shrinking}$ \5
+\T{2}\C{glue setting applies to the shrink components}\par
+\B\4\D$\\{glue\_offset}$ \5
+\T{6}\C{position of \\{glue\_set} in a box node}\par
+\B\4\D$\\{glue\_set}(\|X)$ \5
+$\\{mem}[\|X+\\{glue\_offset}].{}$\\{gr}\C{a word of type \&{glue\_ratio} for glue setting}\par
+\fi
+
+\M{136}The \\{new\_null\_box} function returns a pointer to an \\{hlist\_node} in
+which all subfields have the values corresponding to `\.{\\hbox\{\}}'.
+The \\{subtype} field is set to \\{min\_quarterword}, since that's the desired
+\\{span\_count} value if this \\{hlist\_node} is changed to an \\{unset\_node}.
+
+\Y\B\&{pointer} \\{new\_null\_box}(\&{void})\C{creates a new box node}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{box\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{hlist\_node};{}$\5
+${}\\{subtype}(\|p)\K\\{min\_quarterword};{}$\5
+${}\\{width}(\|p)\K\T{0};{}$\5
+${}\\{depth}(\|p)\K\T{0};{}$\5
+${}\\{height}(\|p)\K\T{0};{}$\5
+${}\\{shift\_amount}(\|p)\K\T{0};{}$\5
+${}\\{list\_ptr}(\|p)\K\\{null};{}$\5
+${}\\{glue\_sign}(\|p)\K\\{normal};{}$\5
+${}\\{glue\_order}(\|p)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|p));\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{137}A \\{vlist\_node} is like an \\{hlist\_node} in all respects except that it
+contains a vertical list.
+
+\Y\B\4\D$\\{vlist\_node}$ \5
+\T{1}\C{\\{type} of vlist nodes}\par
+\fi
+
+\M{138}A \\{rule\_node} stands for a solid black rectangle; it has \\{width},
+\\{depth}, and \\{height} fields just as in an \\{hlist\_node}. However, if
+any of these dimensions is $-2^{30}$, the actual value will be determined
+by running the rule up to the boundary of the innermost enclosing box.
+This is called a ``running dimension.'' The \\{width} is never running in
+an hlist; the \\{height} and \\{depth} are never running in a~vlist.
+
+\Y\B\4\D$\\{rule\_node}$ \5
+\T{2}\C{\\{type} of rule nodes}\par
+\B\4\D$\\{rule\_node\_size}$ \5
+\T{4}\C{number of words to allocate for a rule node}\par
+\B\4\D$\\{null\_flag}$ \5
+${-}{}$\T{\~10000000000}\C{$-2^{30}$, signifies a missing item}\par
+\B\4\D$\\{is\_running}(\|X)$ \5
+$(\|X\E\\{null\_flag}{}$)\C{tests for a running dimension}\par
+\fi
+
+\M{139}A new rule node is delivered by the \\{new\_rule} function. It
+makes all the dimensions ``running,'' so you have to change the
+ones that are not allowed to run.
+
+\Y\B\&{pointer} \\{new\_rule}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{rule\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{rule\_node};{}$\5
+${}\\{subtype}(\|p)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+${}\\{width}(\|p)\K\\{null\_flag};{}$\5
+${}\\{depth}(\|p)\K\\{null\_flag};{}$\5
+${}\\{height}(\|p)\K\\{null\_flag};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{140}Insertions are represented by \\{ins\_node} records, where the \\{subtype}
+indicates the corresponding box number. For example, `\.{\\insert 250}'
+leads to an \\{ins\_node} whose \\{subtype} is $\T{250}+\\{min\_quarterword}$.
+The \\{height} field of an \\{ins\_node} is slightly misnamed; it actually holds
+the natural height plus depth of the vertical list being inserted.
+The \\{depth} field holds the \\{split\_max\_depth} to be used in case this
+insertion is split, and the \\{split\_top\_ptr} points to the corresponding
+\\{split\_top\_skip}. The \\{float\_cost} field holds the \\{floating\_penalty} that
+will be used if this insertion floats to a subsequent page after a
+split insertion of the same class. There is one more field, the
+\\{ins\_ptr}, which points to the beginning of the vlist for the insertion.
+
+\Y\B\4\D$\\{ins\_node}$ \5
+\T{3}\C{\\{type} of insertion nodes}\par
+\B\4\D$\\{ins\_node\_size}$ \5
+\T{5}\C{number of words to allocate for an insertion}\par
+\B\4\D$\\{float\_cost}(\|X)$ \5
+$\\{mem}[\|X+\T{1}].{}$\|i\C{the \\{floating\_penalty} to be used}\par
+\B\4\D$\\{ins\_ptr}(\|X)$ \5
+$\\{info}(\|X+\T{4}{}$)\C{the vertical list to be inserted}\par
+\B\4\D$\\{split\_top\_ptr}(\|X)$ \5
+$\\{link}(\|X+\T{4}{}$)\C{the \\{split\_top\_skip} to be used}\par
+\fi
+
+\M{141}A \\{mark\_node} has a \\{mark\_ptr} field that points to the reference count
+of a token list that contains the user's \.{\\mark} text.
+This field occupies a full word instead of a halfword, because
+there's nothing to put in the other halfword; it is easier in \PASCAL\ to
+use the full word than to risk leaving garbage in the unused half.
+
+\Y\B\4\D$\\{mark\_node}$ \5
+\T{4}\C{\\{type} of a mark node}\par
+\B\4\D$\\{small\_node\_size}$ \5
+\T{2}\C{number of words to allocate for most node types}\par
+\B\4\D$\\{mark\_ptr}(\|X)$ \5
+$\\{mem}[\|X+\T{1}].{}$\|i\C{head of the token list for a mark}\par
+\fi
+
+\M{142}An \\{adjust\_node}, which occurs only in horizontal lists,
+specifies material that will be moved out into the surrounding
+vertical list; i.e., it is used to implement \TeX's `\.{\\vadjust}'
+operation. The \\{adjust\_ptr} field points to the vlist containing this
+material.
+
+\Y\B\4\D$\\{adjust\_node}$ \5
+\T{5}\C{\\{type} of an adjust node}\par
+\B\4\D$\\{adjust\_ptr}$ \5
+\\{mark\_ptr}\C{vertical list to be moved out of horizontal list}\par
+\fi
+
+\M{143}A \\{ligature\_node}, which occurs only in horizontal lists, specifies
+a character that was fabricated from the interaction of two or more
+actual characters. The second word of the node, which is called the
+\\{lig\_char} word, contains \\{font} and \\{character} fields just as in a
+\\{char\_node}. The characters that generated the ligature have not been
+forgotten, since they are needed for diagnostic messages and for
+hyphenation; the \\{lig\_ptr} field points to a linked list of character
+nodes for all original characters that have been deleted. (This list
+might be empty if the characters that generated the ligature were
+retained in other nodes.)
+
+The \\{subtype} field is 0, plus 2 and/or 1 if the original source of the
+ligature included implicit left and/or right boundaries.
+
+\Y\B\4\D$\\{ligature\_node}$ \5
+\T{6}\C{\\{type} of a ligature node}\par
+\B\4\D$\\{lig\_char}(\|X)$ \5
+$\|X+{}$\T{1}\C{the word where the ligature is to be found}\par
+\B\4\D$\\{lig\_ptr}(\|X)$ \5
+\\{link}(\\{lig\_char}(\|X))\C{the list of characters}\par
+\fi
+
+\M{144}The \\{new\_ligature} function creates a ligature node having given
+contents of the \\{font}, \\{character}, and \\{lig\_ptr} fields. We also have
+a \\{new\_lig\_item} function, which returns a two-word node having a given
+\\{character} field. Such nodes are used for temporary processing as ligatures
+are being created.
+
+\Y\B\&{pointer} \\{new\_ligature}(\&{quarterword} \|f${},\39{}$\&{quarterword} \|c${},\39{}$\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{ligature\_node};{}$\5
+${}\\{font}(\\{lig\_char}(\|p))\K\|f;{}$\5
+${}\\{character}(\\{lig\_char}(\|p))\K\|c;{}$\5
+${}\\{lig\_ptr}(\|p)\K\|q;{}$\5
+${}\\{subtype}(\|p)\K\T{0};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\7
+\&{pointer} \\{new\_lig\_item}(\&{quarterword} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{character}(\|p)\K\|c;{}$\5
+${}\\{lig\_ptr}(\|p)\K\\{null};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{145}A \\{disc\_node}, which occurs only in horizontal lists, specifies a
+``dis\-cretion\-ary'' line break. If such a break occurs at node \|p, the text
+that starts at \\{pre\_break}(\|p) will precede the break, the text that starts at
+\\{post\_break}(\|p) will follow the break, and text that appears in the next
+\\{replace\_count}(\|p) nodes will be ignored. For example, an ordinary
+discretionary hyphen, indicated by `\.{\\-}', yields a \\{disc\_node} with
+\\{pre\_break} pointing to a \\{char\_node} containing a hyphen, $\\{post\_break}\E\\{null}$,
+and $\\{replace\_count}\E\T{0}$. All three of the discretionary texts must be
+lists that consist entirely of character, kern, box, rule, and ligature nodes.
+
+If $\\{pre\_break}(\|p)\E\\{null}$, the \\{ex\_hyphen\_penalty} will be charged for this
+break. Otherwise the \\{hyphen\_penalty} will be charged. The texts will
+actually be substituted into the list by the line-breaking algorithm if it
+decides to make the break, and the discretionary node will disappear at
+that time; thus, the output routine sees only discretionaries that were
+not chosen.
+
+\Y\B\4\D$\\{disc\_node}$ \5
+\T{7}\C{\\{type} of a discretionary node}\par
+\B\4\D$\\{replace\_count}$ \5
+\\{subtype}\C{how many subsequent nodes to replace}\par
+\B\4\D$\\{pre\_break}$ \5
+\\{llink}\C{text that precedes a discretionary break}\par
+\B\4\D$\\{post\_break}$ \5
+\\{rlink}\C{text that follows a discretionary break}\par
+\Y\B\&{pointer} \\{new\_disc}(\&{void})\C{creates an empty \\{disc\_node}}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{disc\_node};{}$\5
+${}\\{replace\_count}(\|p)\K\T{0};{}$\5
+${}\\{pre\_break}(\|p)\K\\{null};{}$\5
+${}\\{post\_break}(\|p)\K\\{null};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{146}A \\{whatsit\_node} is a wild card reserved for extensions to \TeX. The
+\\{subtype} field in its first word says what `\\{whatsit}' it is, and
+implicitly determines the node size (which must be 2 or more) and the
+format of the remaining words. When a \\{whatsit\_node} is encountered
+in a list, special actions are invoked; knowledgeable people who are
+careful not to mess up the rest of \TeX\ are able to make \TeX\ do new
+things by adding code at the end of the program. For example, there
+might be a `\TeX nicolor' extension to specify different colors of ink,
+and the whatsit node might contain the desired parameters.
+
+The present implementation of \TeX\ treats the features associated with
+`\.{\\write}' and `\.{\\special}' as if they were extensions, in order to
+illustrate how such routines might be coded. We shall defer further
+discussion of extensions until the end of this program.
+
+\Y\B\4\D$\\{whatsit\_node}$ \5
+\T{8}\C{\\{type} of special extension nodes}\par
+\fi
+
+\M{147}A \\{math\_node}, which occurs only in horizontal lists, appears before and
+after mathematical formulas. The \\{subtype} field is \\{before} before the
+formula and \\{after} after it. There is a \\{width} field, which represents
+the amount of surrounding space inserted by \.{\\mathsurround}.
+
+\Y\B\4\D$\\{math\_node}$ \5
+\T{9}\C{\\{type} of a math node}\par
+\B\4\D$\\{before}$ \5
+\T{0}\C{\\{subtype} for math node that introduces a formula}\par
+\B\4\D$\\{after}$ \5
+\T{1}\C{\\{subtype} for math node that winds up a formula}\par
+\Y\B\&{pointer} \\{new\_math}(\&{scaled} \|w${},\39{}$\&{small\_number} \|s)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{math\_node};{}$\5
+${}\\{subtype}(\|p)\K\|s;{}$\5
+${}\\{width}(\|p)\K\|w;{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{148}\TeX\ makes use of the fact that \\{hlist\_node}, \\{vlist\_node},
+\\{rule\_node}, \\{ins\_node}, \\{mark\_node}, \\{adjust\_node}, \\{ligature\_node},
+\\{disc\_node}, \\{whatsit\_node}, and \\{math\_node} are at the low end of the
+type codes, by permitting a break at glue in a list if and only if the
+\\{type} of the previous node is less than \\{math\_node}. Furthermore, a
+node is discarded after a break if its type is \\{math\_node} or~more.
+
+\Y\B\4\D$\\{precedes\_break}(\|X)$ \5
+$(\\{type}(\|X)<\\{math\_node}{}$)\par
+\B\4\D$\\{non\_discardable}(\|X)$ \5
+$(\\{type}(\|X)<\\{math\_node}{}$)\par
+\fi
+
+\M{149}A \\{glue\_node} represents glue in a list. However, it is really only
+a pointer to a separate glue specification, since \TeX\ makes use of the
+fact that many essentially identical nodes of glue are usually present.
+If \|p points to a \\{glue\_node}, \\{glue\_ptr}(\|p) points to
+another packet of words that specify the stretch and shrink components, etc.
+
+Glue nodes also serve to represent leaders; the \\{subtype} is used to
+distinguish between ordinary glue (which is called \\{normal}) and the three
+kinds of leaders (which are called \\{a\_leaders}, \\{c\_leaders}, and \\{x\_leaders}).
+The \\{leader\_ptr} field points to a rule node or to a box node containing the
+leaders; it is set to \\{null} in ordinary glue nodes.
+
+Many kinds of glue are computed from \TeX's ``skip'' parameters, and
+it is helpful to know which parameter has led to a particular glue node.
+Therefore the \\{subtype} is set to indicate the source of glue, whenever
+it originated as a parameter. We will be defining symbolic names for the
+parameter numbers later (e.g., $\\{line\_skip\_code}\E\T{0}$, $\\{baseline\_skip\_code}\E\T{1}$,
+etc.); it suffices for now to say that the \\{subtype} of parametric glue
+will be the same as the parameter number, plus~one.
+
+In math formulas there are two more possibilities for the \\{subtype} in a
+glue node: \\{mu\_glue} denotes an \.{\\mskip} (where the units are scaled \.{mu}
+instead of scaled \.{pt}); and \\{cond\_math\_glue} denotes the `\.{\\nonscript}'
+feature that cancels the glue node immediately following if it appears
+in a subscript.
+
+\Y\B\4\D$\\{glue\_node}$ \5
+\T{10}\C{\\{type} of node that points to a glue specification}\par
+\B\4\D$\\{cond\_math\_glue}$ \5
+\T{98}\C{special \\{subtype} to suppress glue in the next node}\par
+\B\4\D$\\{mu\_glue}$ \5
+\T{99}\C{\\{subtype} for math glue}\par
+\B\4\D$\\{a\_leaders}$ \5
+\T{100}\C{\\{subtype} for aligned leaders}\par
+\B\4\D$\\{c\_leaders}$ \5
+\T{101}\C{\\{subtype} for centered leaders}\par
+\B\4\D$\\{x\_leaders}$ \5
+\T{102}\C{\\{subtype} for expanded leaders}\par
+\B\4\D$\\{glue\_ptr}$ \5
+\\{llink}\C{pointer to a glue specification}\par
+\B\4\D$\\{leader\_ptr}$ \5
+\\{rlink}\C{pointer to box or rule node for leaders}\par
+\fi
+
+\M{150}A glue specification has a halfword reference count in its first word,
+representing \\{null} plus the number of glue nodes that point to it (less one).
+Note that the reference count appears in the same position as
+the \\{link} field in list nodes; this is the field that is initialized
+to \\{null} when a node is allocated, and it is also the field that is flagged
+by \\{empty\_flag} in empty nodes.
+
+Glue specifications also contain three \&{scaled} fields, for the \\{width},
+\\{stretch}, and \\{shrink} dimensions. Finally, there are two one-byte
+fields called \\{stretch\_order} and \\{shrink\_order}; these contain the
+orders of infinity (\\{normal}, \\{fil}, \\{fill}, or \\{filll})
+corresponding to the stretch and shrink values.
+
+\Y\B\4\D$\\{glue\_spec\_size}$ \5
+\T{4}\C{number of words to allocate for a glue specification}\par
+\B\4\D$\\{glue\_ref\_count}(\|X)$ \5
+\\{link}(\|X)\C{reference count of a glue specification}\par
+\B\4\D$\\{stretch}(\|X)$ \5
+$\\{mem}[\|X+\T{2}].{}$\\{sc}\C{the stretchability of this glob of glue}\par
+\B\4\D$\\{shrink}(\|X)$ \5
+$\\{mem}[\|X+\T{3}].{}$\\{sc}\C{the shrinkability of this glob of glue}\par
+\B\4\D$\\{stretch\_order}$ \5
+\\{type}\C{order of infinity for stretching}\par
+\B\4\D$\\{shrink\_order}$ \5
+\\{subtype}\C{order of infinity for shrinking}\par
+\B\4\D$\\{fil}$ \5
+\T{1}\C{first-order infinity}\par
+\B\4\D$\\{fill}$ \5
+\T{2}\C{second-order infinity}\par
+\B\4\D$\\{filll}$ \5
+\T{3}\C{third-order infinity}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint8\_t} \&{glue\_ord};\C{infinity to the 0, 1, 2, or 3 power}\par
+\fi
+
+\M{151}Here is a function that returns a pointer to a copy of a glue spec.
+The reference count in the copy is \\{null}, because there is assumed
+to be exactly one reference to the new specification.
+
+\Y\B\&{pointer} \\{new\_spec}(\&{pointer} \|p)\C{duplicates a glue specification}\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{the new spec}\7
+${}\|q\K\\{get\_node}(\\{glue\_spec\_size}){}$;\6
+${}\\{mem}[\|q]\K\\{mem}[\|p];{}$\5
+${}\\{glue\_ref\_count}(\|q)\K\\{null}{}$;\6
+${}\\{width}(\|q)\K\\{width}(\|p);{}$\5
+${}\\{stretch}(\|q)\K\\{stretch}(\|p);{}$\5
+${}\\{shrink}(\|q)\K\\{shrink}(\|p);{}$\5
+\&{return} \|q;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{152}And here's a function that creates a glue node for a given parameter
+identified by its code number; for example,
+\\{new\_param\_glue}(\\{line\_skip\_code}) returns a pointer to a glue node for the
+current \.{\\lineskip}.
+
+\Y\B\&{pointer} \\{new\_param\_glue}(\&{small\_number} \|n)\1\1 $\{{}$\5
+\&{pointer} \|p;\C{the new node}\6
+\&{pointer} \|q;\C{the glue specification}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{glue\_node};{}$\5
+${}\\{subtype}(\|p)\K\|n+\T{1};{}$\5
+${}\\{leader\_ptr}(\|p)\K\\{null}{}$;\6
+\|q $\K$ \X224:Current \\{mem} equivalent of glue parameter number \|n\X\hbox{};\6
+${}\\{glue\_ptr}(\|p)\K\|q;{}$\5
+\\{incr}(\\{glue\_ref\_count}(\|q));\5
+\&{return} \|p; $\}{}$\par
+\fi
+
+\M{153}Glue nodes that are more or less anonymous are created by \\{new\_glue},
+whose argument points to a glue specification.
+
+\Y\B\&{pointer} \\{new\_glue}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{glue\_node};{}$\5
+${}\\{subtype}(\|p)\K\\{normal};{}$\5
+${}\\{leader\_ptr}(\|p)\K\\{null};{}$\5
+${}\\{glue\_ptr}(\|p)\K\|q;{}$\5
+\\{incr}(\\{glue\_ref\_count}(\|q));\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{154}Still another subroutine is needed: This one is sort of a combination
+of \\{new\_param\_glue} and \\{new\_glue}. It creates a glue node for one of
+the current glue parameters, but it makes a fresh copy of the glue
+specification, since that specification will probably be subject to change,
+while the parameter will stay put. The global variable \\{temp\_ptr} is
+set to the address of the new spec.
+
+\Y\B\&{pointer} \\{new\_skip\_param}(\&{small\_number} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\\{temp\_ptr}\K\\{new\_spec}(\X224:Current \\{mem} equivalent of glue parameter number \|n\X);{}$\5
+${}\|p\K\\{new\_glue}(\\{temp\_ptr});{}$\5
+${}\\{glue\_ref\_count}(\\{temp\_ptr})\K\\{null};{}$\5
+${}\\{subtype}(\|p)\K\|n+\T{1};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{155}A \\{kern\_node} has a \\{width} field to specify a (normally negative)
+amount of spacing. This spacing correction appears in horizontal lists
+between letters like A and V when the font designer said that it looks
+better to move them closer together or further apart. A kern node can
+also appear in a vertical list, when its `\\{width}' denotes additional
+spacing in the vertical direction. The \\{subtype} is either \\{normal} (for
+kerns inserted from font information or math mode calculations) or \&{explicit}
+(for kerns inserted from \.{\\kern} and \.{\\/} commands) or \\{acc\_kern}
+(for kerns inserted from non-math accents) or \\{mu\_glue} (for kerns
+inserted from \.{\\mkern} specifications in math formulas).
+
+\Y\B\4\D$\\{kern\_node}$ \5
+\T{11}\C{\\{type} of a kern node}\par
+\B\4\D$\&{explicit}$ \5
+\T{1}\C{\\{subtype} of kern nodes from \.{\\kern} and \.{\\/}}\par
+\B\4\D$\\{acc\_kern}$ \5
+\T{2}\C{\\{subtype} of kern nodes from accents}\par
+\fi
+
+\M{156}The \\{new\_kern} function creates a kern node having a given width.
+
+\Y\B\&{pointer} \\{new\_kern}(\&{scaled} \|w)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{kern\_node};{}$\5
+${}\\{subtype}(\|p)\K\\{normal};{}$\5
+${}\\{width}(\|p)\K\|w;{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{157}A \\{penalty\_node} specifies the penalty associated with line or page
+breaking, in its \\{penalty} field. This field is a fullword integer, but
+the full range of integer values is not used: Any penalty $\G$ \T{10000} is
+treated as infinity, and no break will be allowed for such high values.
+Similarly, any penalty $\Z$ ${-}\T{10000}$ is treated as negative infinity, and a
+break will be forced.
+
+\Y\B\4\D$\\{penalty\_node}$ \5
+\T{12}\C{\\{type} of a penalty node}\par
+\B\4\D$\\{inf\_penalty}$ \5
+\\{inf\_bad}\C{``infinite'' penalty value}\par
+\B\4\D$\\{eject\_penalty}$ \5
+$({-}\\{inf\_penalty}{}$)\C{``negatively infinite'' penalty value}\par
+\B\4\D$\\{penalty}(\|X)$ \5
+$\\{mem}[\|X+\T{1}].{}$\|i\C{the added cost of breaking a list here}\par
+\fi
+
+\M{158}Anyone who has been reading the last few sections of the program will
+be able to guess what comes next.
+
+\Y\B\&{pointer} \\{new\_penalty}(\&{int} \|m)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{penalty\_node};{}$\5
+${}\\{subtype}(\|p)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+${}\\{penalty}(\|p)\K\|m;{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{159}You might think that we have introduced enough node types by now. Well,
+almost, but there is one more: An \\{unset\_node} has nearly the same format
+as an \\{hlist\_node} or \\{vlist\_node}; it is used for entries in \.{\\halign}
+or \.{\\valign} that are not yet in their final form, since the box
+dimensions are their ``natural'' sizes before any glue adjustment has been
+made. The \\{glue\_set} word is not present; instead, we have a \\{glue\_stretch}
+field, which contains the total stretch of order \\{glue\_order} that is
+present in the hlist or vlist being boxed.
+Similarly, the \\{shift\_amount} field is replaced by a \\{glue\_shrink} field,
+containing the total shrink of order \\{glue\_sign} that is present.
+The \\{subtype} field is called \\{span\_count}; an unset box typically
+contains the data for $\\{qo}(\\{span\_count})+\T{1}$ columns.
+Unset nodes will be changed to box nodes when alignment is completed.
+
+\Y\B\4\D$\\{unset\_node}$ \5
+\T{13}\C{\\{type} for an unset node}\par
+\B\4\D$\\{glue\_stretch}(\|X)$ \5
+$\\{mem}[\|X+\\{glue\_offset}].{}$\\{sc}\C{total stretch in an unset node}\par
+\B\4\D$\\{glue\_shrink}$ \5
+\\{shift\_amount}\C{total shrink in an unset node}\par
+\B\4\D$\\{span\_count}$ \5
+\\{subtype}\C{indicates the number of spanned columns}\par
+\fi
+
+\M{160}In fact, there are still more types coming. When we get to math formula
+processing we will see that a \\{style\_node} has $\\{type}\E\T{14}$; and a number
+of larger type codes will also be defined, for use in math mode only.
+
+\fi
+
+\M{161}Warning: If any changes are made to these data structure layouts, such as
+changing any of the node sizes or even reordering the words of nodes,
+the \\{copy\_node\_list} procedure and the memory initialization code
+below may have to be changed. Such potentially dangerous parts of the
+program are listed in the index under `data structure assumptions'.
+However, other references to the nodes are made symbolically in terms of
+the \.{WEB} macro definitions above, so that format changes will leave
+\TeX's other algorithms intact.
+
+\fi
+
+\N{1}{162}Memory layout.
+Some areas of \\{mem} are dedicated to fixed usage, since static allocation is
+more efficient than dynamic allocation when we can get away with it. For
+example, locations \\{mem\_bot} to $\\{mem\_bot}+\T{3}$ are always used to store the
+specification for glue that is `\.{0pt plus 0pt minus 0pt}'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Static variable-size nodes appear
+in locations \\{mem\_bot} through \\{lo\_mem\_stat\_max}, and static single-word nodes
+appear in locations \\{hi\_mem\_stat\_min} through \\{mem\_top}, inclusive. It is
+harmless to let \\{lig\_trick} and \\{garbage} share the same location of \\{mem}.
+
+\Y\B\4\D$\\{zero\_glue}$ \5
+\\{mem\_bot}\C{specification for \.{0pt plus 0pt minus 0pt}}\par
+\B\4\D$\\{fil\_glue}$ \5
+$\\{zero\_glue}+{}$\\{glue\_spec\_size}\C{\.{0pt plus 1fil minus 0pt}}\par
+\B\4\D$\\{fill\_glue}$ \5
+$\\{fil\_glue}+{}$\\{glue\_spec\_size}\C{\.{0pt plus 1fill minus 0pt}}\par
+\B\4\D$\\{ss\_glue}$ \5
+$\\{fill\_glue}+{}$\\{glue\_spec\_size}\C{\.{0pt plus 1fil minus 1fil}}\par
+\B\4\D$\\{fil\_neg\_glue}$ \5
+$\\{ss\_glue}+{}$\\{glue\_spec\_size}\C{\.{0pt plus -1fil minus 0pt}}\par
+\B\4\D$\\{lo\_mem\_stat\_max}$ \5
+$\\{fil\_neg\_glue}+\\{glue\_spec\_size}-{}$\T{1}\C{largest statically allocated word in the variable-size \\{mem}}\Y\par
+\B\4\D$\\{page\_ins\_head}$ \5
+\\{mem\_top}\C{list of insertion data for current page}\par
+\B\4\D$\\{contrib\_head}$ \5
+$\\{mem\_top}-{}$\T{1}\C{vlist of items not yet on current page}\par
+\B\4\D$\\{page\_head}$ \5
+$\\{mem\_top}-{}$\T{2}\C{vlist for current page}\par
+\B\4\D$\\{temp\_head}$ \5
+$\\{mem\_top}-{}$\T{3}\C{head of a temporary list of some kind}\par
+\B\4\D$\\{hold\_head}$ \5
+$\\{mem\_top}-{}$\T{4}\C{head of a temporary list of another kind}\par
+\B\4\D$\\{adjust\_head}$ \5
+$\\{mem\_top}-{}$\T{5}\C{head of adjustment list returned by \\{hpack}}\par
+\B\4\D$\\{active}$ \5
+$\\{mem\_top}-{}$\T{7}\C{head of active list in \\{line\_break}, needs two words}\par
+\B\4\D$\\{align\_head}$ \5
+$\\{mem\_top}-{}$\T{8}\C{head of preamble list for alignments}\par
+\B\4\D$\\{end\_span}$ \5
+$\\{mem\_top}-{}$\T{9}\C{tail of spanned-width lists}\par
+\B\4\D$\\{omit\_template}$ \5
+$\\{mem\_top}-{}$\T{10}\C{a constant token list}\par
+\B\4\D$\\{null\_list}$ \5
+$\\{mem\_top}-{}$\T{11}\C{permanently empty list}\par
+\B\4\D$\\{lig\_trick}$ \5
+$\\{mem\_top}-{}$\T{12}\C{a ligature masquerading as a \\{char\_node}}\par
+\B\4\D$\\{garbage}$ \5
+$\\{mem\_top}-{}$\T{12}\C{used for scrap information}\par
+\B\4\D$\\{backup\_head}$ \5
+$\\{mem\_top}-{}$\T{13}\C{head of token list built by \\{scan\_keyword}}\par
+\B\4\D$\\{hi\_mem\_stat\_min}$ \5
+$\\{mem\_top}-{}$\T{13}\C{smallest statically allocated word in the one-word \\{mem}}\par
+\B\4\D$\\{hi\_mem\_stat\_usage}$ \5
+\T{14}\C{the number of one-word nodes always present}\par
+\fi
+
+\M{163}The following code gets \\{mem} off to a good start, when \TeX\ is
+initializing itself the slow~way.
+
+\Y\B\4\X19:Local variables for initialization\X${}\mathrel+\E{}$\6
+\&{int} \|k;\C{index into \\{mem}, \\{eqtb}, etc.}\par
+\fi
+
+\M{164}\B\X164:Initialize table entries (done by \.{INITEX} only)\X${}\E{}$\6
+\&{for} ${}(\|k\K\\{mem\_bot}+\T{1};{}$ ${}\|k\Z\\{lo\_mem\_stat\_max};{}$ ${}\|k\PP){}$\1\5
+${}\\{mem}[\|k].\\{sc}\K\T{0}{}$;\C{all glue dimensions are zeroed}\2\6
+${}\|k\K\\{mem\_bot}{}$;\5
+\&{while} ${}(\|k\Z\\{lo\_mem\_stat\_max}{}$)\C{set first words of glue specifications}\6
+${}\{{}$\5
+\1${}\\{glue\_ref\_count}(\|k)\K\\{null}+\T{1};{}$\5
+${}\\{stretch\_order}(\|k)\K\\{normal};{}$\5
+${}\\{shrink\_order}(\|k)\K\\{normal};{}$\5
+${}\|k\K\|k+\\{glue\_spec\_size};{}$\6
+\4${}\}{}$\2\6
+${}\\{stretch}(\\{fil\_glue})\K\\{unity};{}$\5
+${}\\{stretch\_order}(\\{fil\_glue})\K\\{fil}{}$;\6
+${}\\{stretch}(\\{fill\_glue})\K\\{unity};{}$\5
+${}\\{stretch\_order}(\\{fill\_glue})\K\\{fill}{}$;\6
+${}\\{stretch}(\\{ss\_glue})\K\\{unity};{}$\5
+${}\\{stretch\_order}(\\{ss\_glue})\K\\{fil}{}$;\6
+${}\\{shrink}(\\{ss\_glue})\K\\{unity};{}$\5
+${}\\{shrink\_order}(\\{ss\_glue})\K\\{fil}{}$;\6
+${}\\{stretch}(\\{fil\_neg\_glue})\K{-}\\{unity};{}$\5
+${}\\{stretch\_order}(\\{fil\_neg\_glue})\K\\{fil}{}$;\6
+${}\\{rover}\K\\{lo\_mem\_stat\_max}+\T{1};{}$\5
+${}\\{link}(\\{rover})\K\\{empty\_flag}{}$;\C{now initialize the dynamic memory}\6
+${}\\{node\_size}(\\{rover})\K\T{1000}{}$;\C{which is a 1000-word available node}\6
+${}\\{llink}(\\{rover})\K\\{rover};{}$\5
+${}\\{rlink}(\\{rover})\K\\{rover}{}$;\6
+${}\\{lo\_mem\_max}\K\\{rover}+\T{1000};{}$\5
+${}\\{link}(\\{lo\_mem\_max})\K\\{null};{}$\5
+${}\\{info}(\\{lo\_mem\_max})\K\\{null}{}$;\6
+\&{for} ${}(\|k\K\\{hi\_mem\_stat\_min};{}$ ${}\|k\Z\\{mem\_top};{}$ ${}\|k\PP){}$\1\5
+${}\\{mem}[\|k]\K\\{mem}[\\{lo\_mem\_max}]{}$;\C{clear list heads}\2\6
+\X790:Initialize the special list heads and constant nodes\X;\6
+${}\\{avail}\K\\{null};{}$\5
+${}\\{mem\_end}\K\\{mem\_top};{}$\5
+${}\\{hi\_mem\_min}\K\\{hi\_mem\_stat\_min}{}$;\C{initialize the one-word memory}\6
+${}\\{var\_used}\K\\{lo\_mem\_stat\_max}+\T{1}-\\{mem\_bot};{}$\5
+${}\\{dyn\_used}\K\\{hi\_mem\_stat\_usage}{}$;\C{initialize statistics}\par
+\As222, 228, 232, 240, 250, 258, 552, 946, 951, 1216, 1301\ETs1369.
+\U8.\fi
+
+\M{165}If \TeX\ is extended improperly, the \\{mem} array might get screwed up.
+For example, some pointers might be wrong, or some ``dead'' nodes might not
+have been freed when the last reference to them disappeared. Procedures
+\\{check\_mem} and \\{search\_mem} are available to help diagnose such
+problems. These procedures make use of two arrays called \\{is\_free} and
+\\{was\_free} that are present only if \TeX's debugging routines have
+been included. (You may want to decrease the size of \\{mem} while you
+are debugging.)
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\&{bool} ${}\\{is\_free0}[\\{mem\_max}-\\{mem\_min}+\T{1}],{}$ ${}{*\&{const}\ }\\{is\_free}\K\\{is\_free0}-\\{mem\_min}{}$;\C{free cells}\6
+\hbox{\hskip10pt}\&{bool} ${}\\{was\_free0}[\\{mem\_max}-\\{mem\_min}+\T{1}],{}$ ${}{*\&{const}\ }\\{was\_free}\K\\{was\_free0}-\\{mem\_min}{}$;\C{previously free cells}\6
+\hbox{\hskip10pt}\&{pointer} \\{was\_mem\_end}${},{}$ \\{was\_lo\_max}${},{}$ \\{was\_hi\_min};\C{previous \\{mem\_end}, \\{lo\_mem\_max}, and \\{hi\_mem\_min}}\6
+\hbox{\hskip10pt}\&{bool} \\{panicking};\C{do we want to check memory constantly?}\6
+\8\#\&{endif}\par
+\fi
+
+\M{166}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{DEBUG}\6
+$\\{was\_mem\_end}\K\\{mem\_min}{}$;\C{indicate that everything was previously free}\6
+${}\\{was\_lo\_max}\K\\{mem\_min};{}$\5
+${}\\{was\_hi\_min}\K\\{mem\_max};{}$\5
+${}\\{panicking}\K\\{false};{}$\6
+\8\#\&{endif}\par
+\fi
+
+\M{167}Procedure \\{check\_mem} makes sure that the available space lists of
+\\{mem} are well formed, and it optionally prints out all locations
+that are reserved now but were free the last time this procedure was called.
+
+\Y\B\8\#\&{ifdef} \.{DEBUG}\6
+\&{void} \\{check\_mem}(\&{bool} \\{print\_locs})\1\1\2\2\6
+${}\{{}$\5
+\C{loop exits}\1\6
+\&{pointer} \|p${},{}$ \|q;\C{current locations of interest in \\{mem}}\6
+\&{bool} \\{clobbered};\C{is something amiss?}\7
+\&{for} ${}(\|p\K\\{mem\_min};{}$ ${}\|p\Z\\{lo\_mem\_max};{}$ ${}\|p\PP){}$\1\5
+${}\\{is\_free}[\|p]\K\\{false}{}$;\C{you can probably do this faster}\2\6
+\&{for} ${}(\|p\K\\{hi\_mem\_min};{}$ ${}\|p\Z\\{mem\_end};{}$ ${}\|p\PP){}$\1\5
+${}\\{is\_free}[\|p]\K\\{false}{}$;\C{ditto}\2\6
+\X168:Check single-word \\{avail} list\X;\6
+\X169:Check variable-size \\{avail} list\X;\6
+\X170:Check flags of unavailable nodes\X;\6
+\&{if} (\\{print\_locs})\1\5
+\X171:Print newly busy locations\X;\2\6
+\&{for} ${}(\|p\K\\{mem\_min};{}$ ${}\|p\Z\\{lo\_mem\_max};{}$ ${}\|p\PP){}$\1\5
+${}\\{was\_free}[\|p]\K\\{is\_free}[\|p];{}$\2\6
+\&{for} ${}(\|p\K\\{hi\_mem\_min};{}$ ${}\|p\Z\\{mem\_end};{}$ ${}\|p\PP){}$\1\5
+${}\\{was\_free}[\|p]\K\\{is\_free}[\|p]{}$;\C{$\\{was\_free}\K\\{is\_free}$ might be faster}\2\6
+${}\\{was\_mem\_end}\K\\{mem\_end};{}$\5
+${}\\{was\_lo\_max}\K\\{lo\_mem\_max};{}$\5
+${}\\{was\_hi\_min}\K\\{hi\_mem\_min};{}$\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{168}\B\X168:Check single-word \\{avail} list\X${}\E{}$\6
+$\|p\K\\{avail};{}$\5
+${}\|q\K\\{null};{}$\5
+${}\\{clobbered}\K\\{false};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\|p>\\{mem\_end})\V(\|p<\\{hi\_mem\_min})){}$\1\5
+${}\\{clobbered}\K\\{true};{}$\2\6
+\&{else} \&{if} (\\{is\_free}[\|p])\1\5
+${}\\{clobbered}\K\\{true};{}$\2\6
+\&{if} (\\{clobbered})\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"AVAIL\ list\ clobbere}\)\.{d\ at\ "});\5
+\\{print\_int}(\|q);\5
+\&{goto} \\{done1};\6
+\4${}\}{}$\2\6
+${}\\{is\_free}[\|p]\K\\{true};{}$\5
+${}\|q\K\|p;{}$\5
+${}\|p\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\6
+\\{done1}:\par
+\U167.\fi
+
+\M{169}\B\X169:Check variable-size \\{avail} list\X${}\E{}$\6
+$\|p\K\\{rover};{}$\5
+${}\|q\K\\{null};{}$\5
+${}\\{clobbered}\K\\{false}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}((\|p\G\\{lo\_mem\_max})\V(\|p<\\{mem\_min})){}$\1\5
+${}\\{clobbered}\K\\{true};{}$\2\6
+\&{else} \&{if} ${}((\\{rlink}(\|p)\G\\{lo\_mem\_max})\V(\\{rlink}(\|p)<\\{mem\_min})){}$\1\5
+${}\\{clobbered}\K\\{true};{}$\2\6
+\&{else} \&{if} ${}(\R(\\{is\_empty}(\|p))\V(\\{node\_size}(\|p)<\T{2})\V\30(\|p+\\{node\_size}(\|p)>\\{lo\_mem\_max})\V\30(\\{llink}(\\{rlink}(\|p))\I\|p)){}$\1\5
+${}\\{clobbered}\K\\{true};{}$\2\6
+\&{if} (\\{clobbered})\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Double-AVAIL\ list\ c}\)\.{lobbered\ at\ "});\5
+\\{print\_int}(\|q);\5
+\&{goto} \\{done2};\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|q\K\|p;{}$ ${}\|q\Z\|p+\\{node\_size}(\|p)-\T{1};{}$ ${}\|q\PP{}$)\C{mark all locations free}\6
+${}\{{}$\5
+\1\&{if} (\\{is\_free}[\|q])\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Doubly\ free\ locatio}\)\.{n\ at\ "});\5
+\\{print\_int}(\|q);\5
+\&{goto} \\{done2};\6
+\4${}\}{}$\2\6
+${}\\{is\_free}[\|q]\K\\{true};{}$\6
+\4${}\}{}$\2\6
+${}\|q\K\|p;{}$\5
+${}\|p\K\\{rlink}(\|p);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|p\E\\{rover}));$ \\{done2}:\par
+\U167.\fi
+
+\M{170}\B\X170:Check flags of unavailable nodes\X${}\E{}$\6
+$\|p\K\\{mem\_min};{}$\6
+\&{while} ${}(\|p\Z\\{lo\_mem\_max}{}$)\C{node \|p should not be empty}\6
+${}\{{}$\5
+\1\&{if} (\\{is\_empty}(\|p))\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Bad\ flag\ at\ "});\5
+\\{print\_int}(\|p);\6
+\4${}\}{}$\2\6
+\&{while} ${}((\|p\Z\\{lo\_mem\_max})\W\R\\{is\_free}[\|p]){}$\1\5
+\\{incr}(\|p);\2\6
+\&{while} ${}((\|p\Z\\{lo\_mem\_max})\W\\{is\_free}[\|p]){}$\1\5
+\\{incr}(\|p);\2\6
+\4${}\}{}$\2\par
+\U167.\fi
+
+\M{171}\B\X171:Print newly busy locations\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{"New\ busy\ locs:"});\6
+\&{for} ${}(\|p\K\\{mem\_min};{}$ ${}\|p\Z\\{lo\_mem\_max};{}$ ${}\|p\PP){}$\1\6
+\&{if} ${}(\R\\{is\_free}[\|p]\W((\|p>\\{was\_lo\_max})\V\\{was\_free}[\|p])){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'\ '});\5
+\\{print\_int}(\|p);\6
+\4${}\}{}$\2\2\6
+\&{for} ${}(\|p\K\\{hi\_mem\_min};{}$ ${}\|p\Z\\{mem\_end};{}$ ${}\|p\PP){}$\1\6
+\&{if} ${}(\R\\{is\_free}[\|p]\W((\|p<\\{was\_hi\_min})\V(\|p>\\{was\_mem\_end})\V\\{was\_free}[\|p])){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'\ '});\5
+\\{print\_int}(\|p);\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\par
+\U167.\fi
+
+\M{172}The \\{search\_mem} procedure attempts to answer the question ``Who points
+to node~\|p?'' In doing so, it fetches \\{link} and \\{info} fields of \\{mem}
+that might not be of type \&{two\_halves}. Strictly speaking, this is
+undefined in \PASCAL, and it can lead to ``false drops'' (words that seem to
+point to \|p purely by coincidence). But for debugging purposes, we want
+to rule out the places that do {\sl not\/} point to \|p, so a few false
+drops are tolerable.
+
+\Y\B\8\#\&{ifdef} \.{DEBUG}\6
+\&{void} \\{search\_mem}(\&{pointer} \|p)\C{look for pointers to \|p}\6
+${}\{{}$\5
+\1\&{int} \|q;\C{current position being searched}\7
+\&{for} ${}(\|q\K\\{mem\_min};{}$ ${}\|q\Z\\{lo\_mem\_max};{}$ ${}\|q\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"LINK("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{info}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"INFO("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|q\K\\{hi\_mem\_min};{}$ ${}\|q\Z\\{mem\_end};{}$ ${}\|q\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"LINK("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{info}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"INFO("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\X255:Search \\{eqtb} for equivalents equal to \|p\X;\6
+\X285:Search \\{save\_stack} for equivalents that point to \|p\X;\6
+\X933:Search \\{hyph\_list} for pointers to \|p\X;\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\N{1}{173}Displaying boxes.
+We can reinforce our knowledge of the data structures just introduced
+by considering two procedures that display a list in symbolic form.
+The first of these, called \\{short\_display}, is used in ``overfull box''
+messages to give the top-level description of a list. The other one,
+called \\{show\_node\_list}, prints a detailed description of exactly what
+is in the data structure.
+
+The philosophy of \\{short\_display} is to ignore the fine points about exactly
+what is inside boxes, except that ligatures and discretionary breaks are
+expanded. As a result, \\{short\_display} is a recursive procedure, but the
+recursion is never more than one level deep.
+
+A global variable \\{font\_in\_short\_display} keeps track of the font code that
+is assumed to be present when \\{short\_display} begins; deviations from this
+font will be printed.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{font\_in\_short\_display};\C{an internal font number}\par
+\fi
+
+\M{174}Boxes, rules, inserts, whatsits, marks, and things in general that are
+sort of ``complicated'' are indicated only by printing `\.{[]}'.
+
+\Y\B\&{void} \\{short\_display}(\&{int} \|p)\C{prints highlights of list \|p}\6
+${}\{{}$\5
+\1\&{int} \|n;\C{for replacement counts}\7
+\&{while} ${}(\|p>\\{mem\_min}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{is\_char\_node}(\|p))\5
+${}\{{}$\5
+\1\&{if} ${}(\|p\Z\\{mem\_end}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{font}(\|p)\I\\{font\_in\_short\_display}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{font}(\|p)<\\{font\_base})\V(\\{font}(\|p)>\\{font\_max})){}$\1\5
+\\{print\_char}(\.{'*'});\2\6
+\&{else}\1\5
+\X267:Print the font identifier for \\{font}(\|p)\X;\2\6
+\\{print\_char}(\.{'\ '});\5
+${}\\{font\_in\_short\_display}\K\\{font}(\|p);{}$\6
+\4${}\}{}$\2\6
+\\{print\_ASCII}(\\{qo}(\\{character}(\|p)));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\X175:Print a short indication of the contents of node \|p\X;\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{175}\B\X175:Print a short indication of the contents of node \|p\X${}\E{}$\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{ins\_node}:\5
+\&{case} \\{whatsit\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{case} \\{adjust\_node}:\5
+\&{case} \\{unset\_node}:\5
+\\{print\_str}(\.{"[]"});\5
+\&{break};\6
+\4\&{case} \\{rule\_node}:\5
+\\{print\_char}(\.{'|'});\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\6
+\&{if} ${}(\\{glue\_ptr}(\|p)\I\\{zero\_glue}){}$\1\5
+\\{print\_char}(\.{'\ '});\5
+\2\&{break};\6
+\4\&{case} \\{math\_node}:\5
+\\{print\_char}(\.{'\$'});\5
+\&{break};\6
+\4\&{case} \\{ligature\_node}:\5
+\\{short\_display}(\\{lig\_ptr}(\|p));\5
+\&{break};\6
+\4\&{case} \\{disc\_node}:\6
+${}\{{}$\5
+\1\\{short\_display}(\\{pre\_break}(\|p));\5
+\\{short\_display}(\\{post\_break}(\|p));\6
+${}\|n\K\\{replace\_count}(\|p);{}$\6
+\&{while} ${}(\|n>\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\|p)\I\\{null}){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+\\{decr}(\|n);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\par
+\U174.\fi
+
+\M{176}The \\{show\_node\_list} routine requires some auxiliary subroutines: one to
+print a font-and-character combination, one to print a token list without
+its reference count, and one to print a rule dimension.
+
+\Y\B\&{void} \\{print\_font\_and\_char}(\&{int} \|p)\C{prints \\{char\_node} data}\6
+${}\{{}$\5
+\1\&{if} ${}(\|p>\\{mem\_end}){}$\1\5
+\\{print\_esc}(\X1386:\.{"CLOBBERED."}\X);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{font}(\|p)<\\{font\_base})\V(\\{font}(\|p)>\\{font\_max})){}$\1\5
+\\{print\_char}(\.{'*'});\2\6
+\&{else}\1\5
+\X267:Print the font identifier for \\{font}(\|p)\X;\2\6
+\\{print\_char}(\.{'\ '});\5
+\\{print\_ASCII}(\\{qo}(\\{character}(\|p)));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\7
+\&{void} \\{print\_mark}(\&{int} \|p)\C{prints token list data in braces}\6
+${}\{{}$\5
+\1\\{print\_char}(\.{'\{'});\6
+\&{if} ${}((\|p<\\{hi\_mem\_min})\V(\|p>\\{mem\_end})){}$\1\5
+\\{print\_esc}(\X1386:\.{"CLOBBERED."}\X);\2\6
+\&{else}\1\5
+${}\\{show\_token\_list}(\\{link}(\|p),\39\\{null},\39\\{max\_print\_line}-\T{10});{}$\2\6
+\\{print\_char}(\.{'\}'});\6
+\4${}\}{}$\2\7
+\&{void} \\{print\_rule\_dimen}(\&{scaled} \|d)\C{prints dimension in rule node}\6
+${}\{{}$\5
+\1\&{if} (\\{is\_running}(\|d))\1\5
+\\{print\_char}(\.{'*'});\2\6
+\&{else}\1\5
+\\{print\_scaled}(\|d);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{177}Then there is a subroutine that prints glue stretch and shrink, possibly
+followed by the name of finite units:
+
+\Y\B\&{void} \\{print\_glue}(\&{scaled} \|d${},\39{}$\&{int} \\{order}${},\39{}$\&{str\_number} \|s)\C{prints a glue component}\6
+${}\{{}$\5
+\1\\{print\_scaled}(\|d);\6
+\&{if} ${}((\\{order}<\\{normal})\V(\\{order}>\\{filll})){}$\1\5
+\\{print\_str}(\.{"foul"});\2\6
+\&{else} \&{if} ${}(\\{order}>\\{normal}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"fil"});\6
+\&{while} ${}(\\{order}>\\{fil}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'l'});\5
+\\{decr}(\\{order});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|s\I\T{0}){}$\1\5
+\\{print}(\|s);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{178}The next subroutine prints a whole glue specification.
+
+\Y\B\&{void} \\{print\_spec}(\&{int} \|p${},\39{}$\&{str\_number} \|s)\C{prints a glue specification}\6
+${}\{{}$\5
+\1\&{if} ${}((\|p<\\{mem\_min})\V(\|p\G\\{lo\_mem\_max})){}$\1\5
+\\{print\_char}(\.{'*'});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_scaled}(\\{width}(\|p));\6
+\&{if} ${}(\|s\I\T{0}){}$\1\5
+\\{print}(\|s);\2\6
+\&{if} ${}(\\{stretch}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ plus\ "});\5
+${}\\{print\_glue}(\\{stretch}(\|p),\39\\{stretch\_order}(\|p),\39\|s);{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{shrink}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ minus\ "});\5
+${}\\{print\_glue}(\\{shrink}(\|p),\39\\{shrink\_order}(\|p),\39\|s);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{179}We also need to declare some procedures that appear later in this
+documentation.
+
+\Y\B\X691:Declare procedures needed for displaying the elements of mlists\X\6
+\X225:Declare the procedure called \\{print\_skip\_param}\X\par
+\fi
+
+\M{180}Since boxes can be inside of boxes, \\{show\_node\_list} is inherently recursive,
+up to a given maximum number of levels. The history of nesting is indicated
+by the current string, which will be printed at the beginning of each line;
+the length of this string, namely \\{cur\_length}, is the depth of nesting.
+
+Recursive calls on \\{show\_node\_list} therefore use the following pattern:
+
+\Y\B\4\D$\\{node\_list\_display}(\|X)$ \6
+${}\{{}$\5
+\1\\{append\_char}(\.{'.'});\5
+\\{show\_node\_list}(\|X);\5
+\\{flush\_char};\6
+\4${}\}{}$\C{\\{str\_room} need not be checked; see \\{show\_box} below}\2\par
+\fi
+
+\M{181}A global variable called \\{depth\_threshold} is used to record the maximum
+depth of nesting for which \\{show\_node\_list} will show information. If we
+have $\\{depth\_threshold}\E\T{0}$, for example, only the top level information will
+be given and no sublists will be traversed. Another global variable, called
+\\{breadth\_max}, tells the maximum number of items to show at each level;
+\\{breadth\_max} had better be positive, or you won't see anything.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{depth\_threshold};\C{maximum nesting depth in box displays}\6
+\&{int} \\{breadth\_max};\C{maximum number of items shown at the same list level}\par
+\fi
+
+\M{182}Now we are ready for \\{show\_node\_list} itself. This procedure has been
+written to be ``extra robust'' in the sense that it should not crash or get
+into a loop even if the data structures have been messed up by bugs in
+the rest of the program. You can safely call its parent routine
+\\{show\_box}(\|p) for arbitrary values of \|p when you are debugging \TeX.
+However, in the presence of bad data, the procedure may
+fetch a \&{memory\_word} whose variant is different from the way it was stored;
+for example, it might try to read $\\{mem}[\|p].\\{hh}$ when \\{mem}[\|p]
+contains a scaled integer, if \|p is a pointer that has been
+clobbered or chosen at random.
+
+\Y\B\&{void} \\{show\_node\_list}(\&{int} \|p)\C{prints a node list symbolically}\6
+${}\{{}$\5
+\1\&{int} \|n;\C{the number of items already printed at this level}\6
+\&{double} \|g;\C{a glue ratio, as a floating point number}\7
+\&{if} ${}(\\{cur\_length}>\\{depth\_threshold}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|p>\\{null}){}$\1\5
+\\{print\_str}(\.{"\ []"});\C{indicate that there's been some truncation}\2\6
+\&{return};\6
+\4${}\}{}$\2\6
+${}\|n\K\T{0};{}$\6
+\&{while} ${}(\|p>\\{mem\_min}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_current\_string}(\,);\C{display the nesting history}\6
+\&{if} ${}(\|p>\\{mem\_end}{}$)\C{pointer out of range}\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"Bad\ link,\ display\ a}\)\.{borted."});\5
+\&{return};\6
+\4${}\}{}$\2\6
+\\{incr}(\|n);\6
+\&{if} ${}(\|n>\\{breadth\_max}{}$)\C{time to stop}\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"etc."});\5
+\&{return};\6
+\4${}\}{}$\2\6
+\X183:Display node \|p\X;\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{183}\B\X183:Display node \|p\X${}\E{}$\6
+\&{if} (\\{is\_char\_node}(\|p))\1\5
+\\{print\_font\_and\_char}(\|p);\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{unset\_node}:\5
+\X184:Display box \|p\X\5
+\&{break};\6
+\4\&{case} \\{rule\_node}:\5
+\X187:Display rule \|p\X\5
+\&{break};\6
+\4\&{case} \\{ins\_node}:\5
+\X188:Display insertion \|p\X\5
+\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1356:Display the whatsit node \|p\X\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X189:Display glue \|p\X\5
+\&{break};\6
+\4\&{case} \\{kern\_node}:\5
+\X191:Display kern \|p\X\5
+\&{break};\6
+\4\&{case} \\{math\_node}:\5
+\X192:Display math node \|p\X\5
+\&{break};\6
+\4\&{case} \\{ligature\_node}:\5
+\X193:Display ligature \|p\X\5
+\&{break};\6
+\4\&{case} \\{penalty\_node}:\5
+\X194:Display penalty \|p\X\5
+\&{break};\6
+\4\&{case} \\{disc\_node}:\5
+\X195:Display discretionary \|p\X\5
+\&{break};\6
+\4\&{case} \\{mark\_node}:\5
+\X196:Display mark \|p\X\5
+\&{break};\6
+\4\&{case} \\{adjust\_node}:\5
+\X197:Display adjustment \|p\X\5
+\&{break};\5
+\hbox{\4}\X690:Cases of \\{show\_node\_list} that arise in mlists only\X\6
+\4\&{default}:\5
+\\{print\_str}(\.{"Unknown\ node\ type!"});\6
+\4${}\}{}$\2\2\par
+\U182.\fi
+
+\M{184}\B\X184:Display box \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|p)\E\\{hlist\_node}){}$\1\5
+\\{print\_esc}(\.{'h'});\2\6
+\&{else} \&{if} ${}(\\{type}(\|p)\E\\{vlist\_node}){}$\1\5
+\\{print\_esc}(\.{'v'});\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1388:\.{"unset"}\X);\2\6
+\\{print\_str}(\.{"box("});\5
+\\{print\_scaled}(\\{height}(\|p));\5
+\\{print\_char}(\.{'+'});\5
+\\{print\_scaled}(\\{depth}(\|p));\5
+\\{print\_str}(\.{")x"});\5
+\\{print\_scaled}(\\{width}(\|p));\6
+\&{if} ${}(\\{type}(\|p)\E\\{unset\_node}){}$\1\5
+\X185:Display special fields of the unset node \|p\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\X186:Display the value of \\{glue\_set}(\|p)\X;\6
+\&{if} ${}(\\{shift\_amount}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ shifted\ "});\5
+\\{print\_scaled}(\\{shift\_amount}(\|p));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\\{node\_list\_display}(\\{list\_ptr}(\|p));\C{recursive call}\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{185}\B\X185:Display special fields of the unset node \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{span\_count}(\|p)\I\\{min\_quarterword}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ ("});\5
+${}\\{print\_int}(\\{qo}(\\{span\_count}(\|p))+\T{1});{}$\5
+\\{print\_str}(\.{"\ columns)"});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{glue\_stretch}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ stretch\ "});\5
+${}\\{print\_glue}(\\{glue\_stretch}(\|p),\39\\{glue\_order}(\|p),\39\T{0});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{glue\_shrink}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ shrink\ "});\5
+${}\\{print\_glue}(\\{glue\_shrink}(\|p),\39\\{glue\_sign}(\|p),\39\T{0});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U184.\fi
+
+\M{186}The code will have to change in this place if \&{glue\_ratio} is
+a structured type instead of an ordinary \&{double}. Note that this routine
+should avoid arithmetic errors even if the \\{glue\_set} field holds an
+arbitrary random value. The following code assumes that a properly
+formed nonzero \&{double} number has absolute value $2^{20}$ or more when
+it is regarded as an integer; this precaution was adequate to prevent
+floating point underflow on the author's computer.
+
+\Y\B\4\X186:Display the value of \\{glue\_set}(\|p)\X${}\E{}$\6
+$\|g\K\&{float}(\\{glue\_set}(\|p));{}$\6
+\&{if} ${}((\|g\I\\{float\_constant}(\T{0}))\W(\\{glue\_sign}(\|p)\I\\{normal})){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ glue\ set\ "});\6
+\&{if} ${}(\\{glue\_sign}(\|p)\E\\{shrinking}){}$\1\5
+\\{print\_str}(\.{"-\ "});\2\6
+\&{if} ${}(\\{abs}(\\{mem}[\|p+\\{glue\_offset}].\|i)<\T{\~4000000}){}$\1\5
+\\{print\_str}(\.{"?.?"});\2\6
+\&{else} \&{if} ${}(\\{abs}(\|g)>\\{float\_constant}(\T{20000})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|g>\\{float\_constant}(\T{0})){}$\1\5
+\\{print\_char}(\.{'>'});\2\6
+\&{else}\1\5
+\\{print\_str}(\.{"<\ -"});\2\6
+${}\\{print\_glue}(\T{20000}*\\{unity},\39\\{glue\_order}(\|p),\39\T{0});{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{print\_glue}(\\{round}(\\{unity}*\|g),\39\\{glue\_order}(\|p),\39\T{0});{}$\2\6
+\4${}\}{}$\2\par
+\U184.\fi
+
+\M{187}\B\X187:Display rule \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1389:\.{"rule("}\X);\5
+\\{print\_rule\_dimen}(\\{height}(\|p));\5
+\\{print\_char}(\.{'+'});\5
+\\{print\_rule\_dimen}(\\{depth}(\|p));\5
+\\{print\_str}(\.{")x"});\5
+\\{print\_rule\_dimen}(\\{width}(\|p));\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{188}\B\X188:Display insertion \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1390:\.{"insert"}\X);\5
+\\{print\_int}(\\{qo}(\\{subtype}(\|p)));\5
+\\{print\_str}(\.{",\ natural\ size\ "});\5
+\\{print\_scaled}(\\{height}(\|p));\5
+\\{print\_str}(\.{";\ split("});\5
+${}\\{print\_spec}(\\{split\_top\_ptr}(\|p),\39\T{0});{}$\5
+\\{print\_char}(\.{','});\5
+\\{print\_scaled}(\\{depth}(\|p));\5
+\\{print\_str}(\.{");\ float\ cost\ "});\5
+\\{print\_int}(\\{float\_cost}(\|p));\5
+\\{node\_list\_display}(\\{ins\_ptr}(\|p));\C{recursive call}\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{189}\B\X189:Display glue \|p\X${}\E{}$\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\1\5
+\X190:Display leaders \|p\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1391:\.{"glue"}\X);\6
+\&{if} ${}(\\{subtype}(\|p)\I\\{normal}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'('});\6
+\&{if} ${}(\\{subtype}(\|p)<\\{cond\_math\_glue}){}$\1\5
+${}\\{print\_skip\_param}(\\{subtype}(\|p)-\T{1});{}$\2\6
+\&{else} \&{if} ${}(\\{subtype}(\|p)\E\\{cond\_math\_glue}){}$\1\5
+\\{print\_esc}(\X1392:\.{"nonscript"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1393:\.{"mskip"}\X);\2\6
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{subtype}(\|p)\I\\{cond\_math\_glue}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'\ '});\6
+\&{if} ${}(\\{subtype}(\|p)<\\{cond\_math\_glue}){}$\1\5
+${}\\{print\_spec}(\\{glue\_ptr}(\|p),\39\T{0});{}$\2\6
+\&{else}\1\5
+${}\\{print\_spec}(\\{glue\_ptr}(\|p),\39\X1394:\.{"mu"}\X);{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{190}\B\X190:Display leaders \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\\{empty\_string});\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{c\_leaders}){}$\1\5
+\\{print\_char}(\.{'c'});\2\6
+\&{else} \&{if} ${}(\\{subtype}(\|p)\E\\{x\_leaders}){}$\1\5
+\\{print\_char}(\.{'x'});\2\6
+\\{print\_str}(\.{"leaders\ "});\5
+${}\\{print\_spec}(\\{glue\_ptr}(\|p),\39\T{0});{}$\5
+\\{node\_list\_display}(\\{leader\_ptr}(\|p));\C{recursive call}\6
+\4${}\}{}$\2\par
+\U189.\fi
+
+\M{191}An ``explicit'' kern value is indicated implicitly by an explicit space.
+
+\Y\B\4\X191:Display kern \|p\X${}\E{}$\6
+\&{if} ${}(\\{subtype}(\|p)\I\\{mu\_glue}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1396:\.{"kern"}\X);\6
+\&{if} ${}(\\{subtype}(\|p)\I\\{normal}){}$\1\5
+\\{print\_char}(\.{'\ '});\2\6
+\\{print\_scaled}(\\{width}(\|p));\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{acc\_kern}){}$\1\5
+\\{print\_str}(\.{"\ (for\ accent)"});\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1397:\.{"mkern"}\X);\5
+\\{print\_scaled}(\\{width}(\|p));\5
+\\{print\_str}(\.{"mu"});\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{192}\B\X192:Display math node \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1398:\.{"math"}\X);\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{before}){}$\1\5
+\\{print\_str}(\.{"on"});\2\6
+\&{else}\1\5
+\\{print\_str}(\.{"off"});\2\6
+\&{if} ${}(\\{width}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ surrounded\ "});\5
+\\{print\_scaled}(\\{width}(\|p));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{193}\B\X193:Display ligature \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_font\_and\_char}(\\{lig\_char}(\|p));\5
+\\{print\_str}(\.{"\ (ligature\ "});\6
+\&{if} ${}(\\{subtype}(\|p)>\T{1}){}$\1\5
+\\{print\_char}(\.{'|'});\2\6
+${}\\{font\_in\_short\_display}\K\\{font}(\\{lig\_char}(\|p));{}$\5
+\\{short\_display}(\\{lig\_ptr}(\|p));\6
+\&{if} (\\{odd}(\\{subtype}(\|p)))\1\5
+\\{print\_char}(\.{'|'});\2\6
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{194}\B\X194:Display penalty \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1399:\.{"penalty\ "}\X);\5
+\\{print\_int}(\\{penalty}(\|p));\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{195}The \\{post\_break} list of a discretionary node is indicated by a prefixed
+`\.{\char'174}' instead of the `\..' before the \\{pre\_break} list.
+
+\Y\B\4\X195:Display discretionary \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1400:\.{"discretionary"}\X);\6
+\&{if} ${}(\\{replace\_count}(\|p)>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ replacing\ "});\5
+\\{print\_int}(\\{replace\_count}(\|p));\6
+\4${}\}{}$\2\6
+\\{node\_list\_display}(\\{pre\_break}(\|p));\C{recursive call}\6
+\\{append\_char}(\.{'|'});\5
+\\{show\_node\_list}(\\{post\_break}(\|p));\5
+\\{flush\_char};\C{recursive call}\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{196}\B\X196:Display mark \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1401:\.{"mark"}\X);\5
+\\{print\_mark}(\\{mark\_ptr}(\|p));\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{197}\B\X197:Display adjustment \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1402:\.{"vadjust"}\X);\5
+\\{node\_list\_display}(\\{adjust\_ptr}(\|p));\C{recursive call}\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{198}The recursive machinery is started by calling \\{show\_box}.
+
+\Y\B\&{void} \\{show\_box}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\X236:Assign the values \\{depth\_threshold}: $\K$ \\{show\_box\_depth} and \\{breadth\_max}: $\K$ \\{show\_box\_breadth}\X;\6
+\&{if} ${}(\\{breadth\_max}\Z\T{0}){}$\1\5
+${}\\{breadth\_max}\K\T{5};{}$\2\6
+\&{if} ${}(\\{pool\_ptr}+\\{depth\_threshold}\G\\{pool\_size}){}$\1\5
+${}\\{depth\_threshold}\K\\{pool\_size}-\\{pool\_ptr}-\T{1}{}$;\C{now there's enough room for prefix string}\2\6
+\\{show\_node\_list}(\|p);\C{the show starts at \|p}\6
+\\{print\_ln}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{199}Destroying boxes.
+When we are done with a node list, we are obliged to return it to free
+storage, including all of its sublists. The recursive procedure
+\\{flush\_node\_list} does this for us.
+
+\fi
+
+\M{200}First, however, we shall consider two non-recursive procedures that do
+simpler tasks. The first of these, \\{delete\_token\_ref}, is called when
+a pointer to a token list's reference count is being removed. This means
+that the token list should disappear if the reference count was \\{null},
+otherwise the count should be decreased by one.
+
+\Y\B\4\D$\\{token\_ref\_count}(\|X)$ \5
+\\{info}(\|X)\C{reference count preceding a token list}\par
+\Y\B\&{void} \\{delete\_token\_ref}(\&{pointer} \|p)\C{\|p points to the reference count of a token list that is losing one reference}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{token\_ref\_count}(\|p)\E\\{null}){}$\1\5
+\\{flush\_list}(\|p);\2\6
+\&{else}\1\5
+\\{decr}(\\{token\_ref\_count}(\|p));\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{201}Similarly, \\{delete\_glue\_ref} is called when a pointer to a glue
+specification is being withdrawn.
+\Y\B\4\D$\\{fast\_delete\_glue\_ref}(\|X)$ \5
+\hbox{}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{glue\_ref\_count}(\|X)\E\\{null}){}$\1\5
+${}\\{free\_node}(\|X,\39\\{glue\_spec\_size});{}$\2\6
+\&{else}\1\5
+\\{decr}(\\{glue\_ref\_count}(\|X));\2\6
+\4${}\}{}$\2\par
+\Y\B\&{void} \\{delete\_glue\_ref}(\&{pointer} \|p)\C{\|p points to a glue specification}\6
+\\{fast\_delete\_glue\_ref}(\|p)\par
+\fi
+
+\M{202}Now we are ready to delete any node list, recursively.
+In practice, the nodes deleted are usually charnodes (about 2/3 of the time),
+and they are glue nodes in about half of the remaining cases.
+
+\Y\B\&{void} \\{flush\_node\_list}(\&{pointer} \|p)\C{erase list of nodes starting at \|p}\6
+${}\{{}$\5
+\C{go here when node \|p has been freed}\1\6
+\&{pointer} \|q;\C{successor to node \|p}\7
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{link}(\|p);{}$\6
+\&{if} (\\{is\_char\_node}(\|p))\1\5
+\\{free\_avail}(\|p)\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{unset\_node}:\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{list\_ptr}(\|p));\5
+${}\\{free\_node}(\|p,\39\\{box\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1${}\\{free\_node}(\|p,\39\\{rule\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{ins\_node}:\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{ins\_ptr}(\|p));\5
+\\{delete\_glue\_ref}(\\{split\_top\_ptr}(\|p));\5
+${}\\{free\_node}(\|p,\39\\{ins\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1358:Wipe out the whatsit node \|p and \&{goto} \\{done}\X\6
+\4\&{case} \\{glue\_node}:\6
+${}\{{}$\5
+\1\\{fast\_delete\_glue\_ref}(\\{glue\_ptr}(\|p));\6
+\&{if} ${}(\\{leader\_ptr}(\|p)\I\\{null}){}$\1\5
+\\{flush\_node\_list}(\\{leader\_ptr}(\|p));\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{kern\_node}:\5
+\&{case} \\{math\_node}:\5
+\&{case} \\{penalty\_node}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{ligature\_node}:\5
+\\{flush\_node\_list}(\\{lig\_ptr}(\|p));\5
+\&{break};\6
+\4\&{case} \\{mark\_node}:\5
+\\{delete\_token\_ref}(\\{mark\_ptr}(\|p));\5
+\&{break};\6
+\4\&{case} \\{disc\_node}:\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{pre\_break}(\|p));\5
+\\{flush\_node\_list}(\\{post\_break}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{adjust\_node}:\5
+\\{flush\_node\_list}(\\{adjust\_ptr}(\|p));\5
+\&{break};\5
+\hbox{\4}\X698:Cases of \\{flush\_node\_list} that arise in mlists only\X\6
+\4\&{default}:\5
+\\{confusion}(\X1403:\.{"flushing"}\X);\6
+\4${}\}{}$\2\6
+${}\\{free\_node}(\|p,\39\\{small\_node\_size});{}$\6
+\4\\{done}:\5
+;\6
+\4${}\}{}$\2\6
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{203}Copying boxes.
+Another recursive operation that acts on boxes is sometimes needed: The
+procedure \\{copy\_node\_list} returns a pointer to another node list that has
+the same structure and meaning as the original. Note that since glue
+specifications and token lists have reference counts, we need not make
+copies of them. Reference counts can never get too large to fit in a
+halfword, since each pointer to a node is in a different memory address,
+and the total number of memory addresses fits in a halfword.
+
+(Well, there actually are also references from outside \\{mem}; if the
+\\{save\_stack} is made arbitrarily large, it would theoretically be possible
+to break \TeX\ by overflowing a reference count. But who would want to do that?)
+
+\Y\B\4\D$\\{add\_token\_ref}(\|X)$ \5
+\\{incr}(\\{token\_ref\_count}(\|X))\C{new reference to a token list}\par
+\B\4\D$\\{add\_glue\_ref}(\|X)$ \5
+\\{incr}(\\{glue\_ref\_count}(\|X))\C{new reference to a glue spec}\par
+\fi
+
+\M{204}The copying procedure copies words en masse without bothering
+to look at their individual fields. If the node format changes---for
+example, if the size is altered, or if some link field is moved to another
+relative position---then this code may need to be changed too.
+
+\Y\B\&{pointer} \\{copy\_node\_list}(\&{pointer} \|p)\C{makes a duplicate of the node list that starts at \|p and returns a pointer to the new list}\6
+${}\{{}$\5
+\1\&{pointer} \|h;\C{temporary head of copied list}\6
+\&{pointer} \|q;\C{previous position in new list}\6
+\&{pointer} \|r;\C{current node being fabricated for new list}\6
+\&{uint8\_t} \\{words};\C{number of words remaining to be copied}\7
+${}\|h\K\\{get\_avail}(\,);{}$\5
+${}\|q\K\|h;{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\X205:Make a copy of node \|p in node \|r\X;\6
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\|q\K\|r;{}$\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\|q\K\\{link}(\|h);{}$\5
+\\{free\_avail}(\|h);\5
+\&{return} \|q;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{205}\B\X205:Make a copy of node \|p in node \|r\X${}\E{}$\6
+$\\{words}\K\T{1}{}$;\C{this setting occurs in more branches than any other}\6
+\&{if} (\\{is\_char\_node}(\|p))\1\5
+${}\|r\K\\{get\_avail}(\,);{}$\2\6
+\&{else}\1\5
+\X206:Case statement to copy different types and set \\{words} to the number of initial words not yet copied\X;\2\6
+\&{while} ${}(\\{words}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{words});\5
+${}\\{mem}[\|r+\\{words}]\K\\{mem}[\|p+\\{words}];{}$\6
+\4${}\}{}$\2\par
+\U204.\fi
+
+\M{206}\B\X206:Case statement to copy different types and set \\{words} to the number of initial words not yet copied\X${}\E{}$\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{unset\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{box\_node\_size});{}$\5
+${}\\{mem}[\|r+\T{6}]\K\\{mem}[\|p+\T{6}];{}$\5
+${}\\{mem}[\|r+\T{5}]\K\\{mem}[\|p+\T{5}]{}$;\C{copy the last two words}\6
+${}\\{list\_ptr}(\|r)\K\\{copy\_node\_list}(\\{list\_ptr}(\|p)){}$;\C{this affects $\\{mem}[\|r+\T{5}]$}\6
+${}\\{words}\K\T{5};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{rule\_node\_size});{}$\5
+${}\\{words}\K\\{rule\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{ins\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{ins\_node\_size});{}$\5
+${}\\{mem}[\|r+\T{4}]\K\\{mem}[\|p+\T{4}];{}$\5
+\\{add\_glue\_ref}(\\{split\_top\_ptr}(\|p));\5
+${}\\{ins\_ptr}(\|r)\K\\{copy\_node\_list}(\\{ins\_ptr}(\|p)){}$;\C{this affects $\\{mem}[\|r+\T{4}]$}\6
+${}\\{words}\K\\{ins\_node\_size}-\T{1};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1357:Make a partial copy of the whatsit node \|p and make \|r point to it; set \\{words} to the number of initial words not yet copied\X\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+\\{add\_glue\_ref}(\\{glue\_ptr}(\|p));\5
+${}\\{glue\_ptr}(\|r)\K\\{glue\_ptr}(\|p);{}$\5
+${}\\{leader\_ptr}(\|r)\K\\{copy\_node\_list}(\\{leader\_ptr}(\|p));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{kern\_node}:\5
+\&{case} \\{math\_node}:\5
+\&{case} \\{penalty\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{words}\K\\{small\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{mem}[\\{lig\_char}(\|r)]\K\\{mem}[\\{lig\_char}(\|p)]{}$;\C{copy \\{font} and \\{character}}\6
+${}\\{lig\_ptr}(\|r)\K\\{copy\_node\_list}(\\{lig\_ptr}(\|p));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{disc\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{pre\_break}(\|r)\K\\{copy\_node\_list}(\\{pre\_break}(\|p));{}$\5
+${}\\{post\_break}(\|r)\K\\{copy\_node\_list}(\\{post\_break}(\|p));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mark\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+\\{add\_token\_ref}(\\{mark\_ptr}(\|p));\5
+${}\\{words}\K\\{small\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{adjust\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{adjust\_ptr}(\|r)\K\\{copy\_node\_list}(\\{adjust\_ptr}(\|p));{}$\6
+\4${}\}{}$\5
+\2\&{break};\C{$\\{words}\E\T{1}\E\\{small\_node\_size}-\T{1}$}\6
+\4\&{default}:\5
+\\{confusion}(\X1404:\.{"copying"}\X);\6
+\4${}\}{}$\2\par
+\U205.\fi
+
+\N{1}{207}The command codes.
+Before we can go any further, we need to define symbolic names for the internal
+code numbers that represent the various commands obeyed by \TeX. These codes
+are somewhat arbitrary, but not completely so. For example, the command
+codes for character types are fixed by the language, since a user says,
+e.g., `\.{\\catcode \`\\\${} = 3}' to make \.{\char'44} a math delimiter,
+and the command code \\{math\_shift} is equal to~3. Some other codes have
+been made adjacent so that \&{case} statements in the program need not consider
+cases that are widely spaced, or so that \&{case} statements can be replaced
+by \&{if} ( statements.
+
+At any rate, here is the list, for future reference. First come the
+``catcode'' commands, several of which share their numeric codes with
+ordinary commands when the catcode cannot emerge from \TeX's scanning routine.
+
+\Y\B\4\D$\\{escape}$ \5
+\T{0}\C{escape delimiter (called \.\\ in {\sl The \TeX book\/})}\par
+\B\4\D$\\{relax}$ \5
+\T{0}\C{do nothing ( \.{\\relax} )}\par
+\B\4\D$\\{left\_brace}$ \5
+\T{1}\C{beginning of a group ( \.\{ )}\par
+\B\4\D$\\{right\_brace}$ \5
+\T{2}\C{ending of a group ( \.\} )}\par
+\B\4\D$\\{math\_shift}$ \5
+\T{3}\C{mathematics shift character ( \.\$ )}\par
+\B\4\D$\\{tab\_mark}$ \5
+\T{4}\C{alignment delimiter ( \.\&, \.{\\span} )}\par
+\B\4\D$\\{car\_ret}$ \5
+\T{5}\C{end of line ( \\{carriage\_return}, \.{\\cr}, \.{\\crcr} )}\par
+\B\4\D$\\{out\_param}$ \5
+\T{5}\C{output a macro parameter}\par
+\B\4\D$\\{mac\_param}$ \5
+\T{6}\C{macro parameter symbol ( \.\# )}\par
+\B\4\D$\\{sup\_mark}$ \5
+\T{7}\C{superscript ( \.{\char'136} )}\par
+\B\4\D$\\{sub\_mark}$ \5
+\T{8}\C{subscript ( \.{\char'137} )}\par
+\B\4\D$\\{ignore}$ \5
+\T{9}\C{characters to ignore ( \.{\^\^@} )}\par
+\B\4\D$\\{endv}$ \5
+\T{9}\C{end of \<v_j> list in alignment template}\par
+\B\4\D$\\{spacer}$ \5
+\T{10}\C{characters equivalent to blank space ( \.{\ } )}\par
+\B\4\D$\\{letter}$ \5
+\T{11}\C{characters regarded as letters ( \.{A..Z}, \.{a..z} )}\par
+\B\4\D$\\{other\_char}$ \5
+\T{12}\C{none of the special character types}\par
+\B\4\D$\\{active\_char}$ \5
+\T{13}\C{characters that invoke macros ( \.{\char`\~} )}\par
+\B\4\D$\\{par\_end}$ \5
+\T{13}\C{end of paragraph ( \.{\\par} )}\par
+\B\4\D$\\{match}$ \5
+\T{13}\C{match a macro parameter}\par
+\B\4\D$\\{comment}$ \5
+\T{14}\C{characters that introduce comments ( \.\% )}\par
+\B\4\D$\\{end\_match}$ \5
+\T{14}\C{end of parameters to macro}\par
+\B\4\D$\\{stop}$ \5
+\T{14}\C{end of job ( \.{\\end}, \.{\\dump} )}\par
+\B\4\D$\\{invalid\_char}$ \5
+\T{15}\C{characters that shouldn't appear ( \.{\^\^?} )}\par
+\B\4\D$\\{delim\_num}$ \5
+\T{15}\C{specify delimiter numerically ( \.{\\delimiter} )}\par
+\B\4\D$\\{max\_char\_code}$ \5
+\T{15}\C{largest catcode for individual characters}\par
+\fi
+
+\M{208}Next are the ordinary run-of-the-mill command codes. Codes that are
+\\{min\_internal} or more represent internal quantities that might be
+expanded by `\.{\\the}'.
+
+\Y\B\4\D$\\{char\_num}$ \5
+\T{16}\C{character specified numerically ( \.{\\char} )}\par
+\B\4\D$\\{math\_char\_num}$ \5
+\T{17}\C{explicit math code ( \.{\\mathchar} )}\par
+\B\4\D$\\{mark}$ \5
+\T{18}\C{mark definition ( \.{\\mark} )}\par
+\B\4\D$\\{xray}$ \5
+\T{19}\C{peek inside of \TeX\ ( \.{\\show}, \.{\\showbox}, etc.~)}\par
+\B\4\D$\\{make\_box}$ \5
+\T{20}\C{make a box ( \.{\\box}, \.{\\copy}, \.{\\hbox}, etc.~)}\par
+\B\4\D$\\{hmove}$ \5
+\T{21}\C{horizontal motion ( \.{\\moveleft}, \.{\\moveright} )}\par
+\B\4\D$\\{vmove}$ \5
+\T{22}\C{vertical motion ( \.{\\raise}, \.{\\lower} )}\par
+\B\4\D$\\{un\_hbox}$ \5
+\T{23}\C{unglue a box ( \.{\\unhbox}, \.{\\unhcopy} )}\par
+\B\4\D$\\{un\_vbox}$ \5
+\T{24}\C{unglue a box ( \.{\\unvbox}, \.{\\unvcopy} )}\par
+\B\4\D$\\{remove\_item}$ \5
+\T{25}\C{nullify last item ( \.{\\unpenalty}, \.{\\unkern}, \.{\\unskip} )}\par
+\B\4\D$\\{hskip}$ \5
+\T{26}\C{horizontal glue ( \.{\\hskip}, \.{\\hfil}, etc.~)}\par
+\B\4\D$\\{vskip}$ \5
+\T{27}\C{vertical glue ( \.{\\vskip}, \.{\\vfil}, etc.~)}\par
+\B\4\D$\\{mskip}$ \5
+\T{28}\C{math glue ( \.{\\mskip} )}\par
+\B\4\D$\\{kern}$ \5
+\T{29}\C{fixed space ( \.{\\kern})}\par
+\B\4\D$\\{mkern}$ \5
+\T{30}\C{math kern ( \.{\\mkern} )}\par
+\B\4\D$\\{leader\_ship}$ \5
+\T{31}\C{use a box ( \.{\\shipout}, \.{\\leaders}, etc.~)}\par
+\B\4\D$\\{halign}$ \5
+\T{32}\C{horizontal table alignment ( \.{\\halign} )}\par
+\B\4\D$\\{valign}$ \5
+\T{33}\C{vertical table alignment ( \.{\\valign} )}\par
+\B\4\D$\\{no\_align}$ \5
+\T{34}\C{temporary escape from alignment ( \.{\\noalign} )}\par
+\B\4\D$\\{vrule}$ \5
+\T{35}\C{vertical rule ( \.{\\vrule} )}\par
+\B\4\D$\\{hrule}$ \5
+\T{36}\C{horizontal rule ( \.{\\hrule} )}\par
+\B\4\D$\\{insert}$ \5
+\T{37}\C{vlist inserted in box ( \.{\\insert} )}\par
+\B\4\D$\\{vadjust}$ \5
+\T{38}\C{vlist inserted in enclosing paragraph ( \.{\\vadjust} )}\par
+\B\4\D$\\{ignore\_spaces}$ \5
+\T{39}\C{gobble \\{spacer} tokens ( \.{\\ignorespaces} )}\par
+\B\4\D$\\{after\_assignment}$ \5
+\T{40}\C{save till assignment is done ( \.{\\afterassignment} )}\par
+\B\4\D$\\{after\_group}$ \5
+\T{41}\C{save till group is done ( \.{\\aftergroup} )}\par
+\B\4\D$\\{break\_penalty}$ \5
+\T{42}\C{additional badness ( \.{\\penalty} )}\par
+\B\4\D$\\{start\_par}$ \5
+\T{43}\C{begin paragraph ( \.{\\indent}, \.{\\noindent} )}\par
+\B\4\D$\\{ital\_corr}$ \5
+\T{44}\C{italic correction ( \.{\\/} )}\par
+\B\4\D$\\{accent}$ \5
+\T{45}\C{attach accent in text ( \.{\\accent} )}\par
+\B\4\D$\\{math\_accent}$ \5
+\T{46}\C{attach accent in math ( \.{\\mathaccent} )}\par
+\B\4\D$\\{discretionary}$ \5
+\T{47}\C{discretionary texts ( \.{\\-}, \.{\\discretionary} )}\par
+\B\4\D$\\{eq\_no}$ \5
+\T{48}\C{equation number ( \.{\\eqno}, \.{\\leqno} )}\par
+\B\4\D$\\{left\_right}$ \5
+\T{49}\C{variable delimiter ( \.{\\left}, \.{\\right} )}\par
+\B\4\D$\\{math\_comp}$ \5
+\T{50}\C{component of formula ( \.{\\mathbin}, etc.~)}\par
+\B\4\D$\\{limit\_switch}$ \5
+\T{51}\C{diddle limit conventions ( \.{\\displaylimits}, etc.~)}\par
+\B\4\D$\\{above}$ \5
+\T{52}\C{generalized fraction ( \.{\\above}, \.{\\atop}, etc.~)}\par
+\B\4\D$\\{math\_style}$ \5
+\T{53}\C{style specification ( \.{\\displaystyle}, etc.~)}\par
+\B\4\D$\\{math\_choice}$ \5
+\T{54}\C{choice specification ( \.{\\mathchoice} )}\par
+\B\4\D$\\{non\_script}$ \5
+\T{55}\C{conditional math glue ( \.{\\nonscript} )}\par
+\B\4\D$\\{vcenter}$ \5
+\T{56}\C{vertically center a vbox ( \.{\\vcenter} )}\par
+\B\4\D$\\{case\_shift}$ \5
+\T{57}\C{force specific case ( \.{\\lowercase}, \.{\\uppercase}~)}\par
+\B\4\D$\\{message}$ \5
+\T{58}\C{send to user ( \.{\\message}, \.{\\errmessage} )}\par
+\B\4\D$\\{extension}$ \5
+\T{59}\C{extensions to \TeX\ ( \.{\\write}, \.{\\special}, etc.~)}\par
+\B\4\D$\\{in\_stream}$ \5
+\T{60}\C{files for reading ( \.{\\openin}, \.{\\closein} )}\par
+\B\4\D$\\{begin\_group}$ \5
+\T{61}\C{begin local grouping ( \.{\\begingroup} )}\par
+\B\4\D$\\{end\_group}$ \5
+\T{62}\C{end local grouping ( \.{\\endgroup} )}\par
+\B\4\D$\\{omit}$ \5
+\T{63}\C{omit alignment template ( \.{\\omit} )}\par
+\B\4\D$\\{ex\_space}$ \5
+\T{64}\C{explicit space ( \.{\\\ } )}\par
+\B\4\D$\\{no\_boundary}$ \5
+\T{65}\C{suppress boundary ligatures ( \.{\\noboundary} )}\par
+\B\4\D$\\{radical}$ \5
+\T{66}\C{square root and similar signs ( \.{\\radical} )}\par
+\B\4\D$\\{end\_cs\_name}$ \5
+\T{67}\C{end control sequence ( \.{\\endcsname} )}\par
+\B\4\D$\\{min\_internal}$ \5
+\T{68}\C{the smallest code that can follow \.{\\the}}\par
+\B\4\D$\\{char\_given}$ \5
+\T{68}\C{character code defined by \.{\\chardef}}\par
+\B\4\D$\\{math\_given}$ \5
+\T{69}\C{math code defined by \.{\\mathchardef}}\par
+\B\4\D$\\{last\_item}$ \5
+\T{70}\C{most recent item ( \.{\\lastpenalty}, \.{\\lastkern}, \.{\\lastskip} )}\par
+\B\4\D$\\{max\_non\_prefixed\_command}$ \5
+\T{70}\C{largest command code that can't be \.{\\global}}\par
+\fi
+
+\M{209}The next codes are special; they all relate to mode-independent
+assignment of values to \TeX's internal registers or tables.
+Codes that are \\{max\_internal} or less represent internal quantities
+that might be expanded by `\.{\\the}'.
+
+\Y\B\4\D$\\{toks\_register}$ \5
+\T{71}\C{token list register ( \.{\\toks} )}\par
+\B\4\D$\\{assign\_toks}$ \5
+\T{72}\C{special token list ( \.{\\output}, \.{\\everypar}, etc.~)}\par
+\B\4\D$\\{assign\_int}$ \5
+\T{73}\C{user-defined integer ( \.{\\tolerance}, \.{\\day}, etc.~)}\par
+\B\4\D$\\{assign\_dimen}$ \5
+\T{74}\C{user-defined length ( \.{\\hsize}, etc.~)}\par
+\B\4\D$\\{assign\_glue}$ \5
+\T{75}\C{user-defined glue ( \.{\\baselineskip}, etc.~)}\par
+\B\4\D$\\{assign\_mu\_glue}$ \5
+\T{76}\C{user-defined muglue ( \.{\\thinmuskip}, etc.~)}\par
+\B\4\D$\\{assign\_font\_dimen}$ \5
+\T{77}\C{user-defined font dimension ( \.{\\fontdimen} )}\par
+\B\4\D$\\{assign\_font\_int}$ \5
+\T{78}\C{user-defined font integer ( \.{\\hyphenchar}, \.{\\skewchar} )}\par
+\B\4\D$\\{set\_aux}$ \5
+\T{79}\C{specify state info ( \.{\\spacefactor}, \.{\\prevdepth} )}\par
+\B\4\D$\\{set\_prev\_graf}$ \5
+\T{80}\C{specify state info ( \.{\\prevgraf} )}\par
+\B\4\D$\\{set\_page\_dimen}$ \5
+\T{81}\C{specify state info ( \.{\\pagegoal}, etc.~)}\par
+\B\4\D$\\{set\_page\_int}$ \5
+\T{82}\C{specify state info ( \.{\\deadcycles}, \.{\\insertpenalties} )}\par
+\B\4\D$\\{set\_box\_dimen}$ \5
+\T{83}\C{change dimension of box ( \.{\\wd}, \.{\\ht}, \.{\\dp} )}\par
+\B\4\D$\\{set\_shape}$ \5
+\T{84}\C{specify fancy paragraph shape ( \.{\\parshape} )}\par
+\B\4\D$\\{def\_code}$ \5
+\T{85}\C{define a character code ( \.{\\catcode}, etc.~)}\par
+\B\4\D$\\{def\_family}$ \5
+\T{86}\C{declare math fonts ( \.{\\textfont}, etc.~)}\par
+\B\4\D$\\{set\_font}$ \5
+\T{87}\C{set current font ( font identifiers )}\par
+\B\4\D$\\{def\_font}$ \5
+\T{88}\C{define a font file ( \.{\\font} )}\par
+\B\4\D$\&{register}$ \5
+\T{89}\C{internal register ( \.{\\count}, \.{\\dimen}, etc.~)}\par
+\B\4\D$\\{max\_internal}$ \5
+\T{89}\C{the largest code that can follow \.{\\the}}\par
+\B\4\D$\\{advance}$ \5
+\T{90}\C{advance a register or parameter ( \.{\\advance} )}\par
+\B\4\D$\\{multiply}$ \5
+\T{91}\C{multiply a register or parameter ( \.{\\multiply} )}\par
+\B\4\D$\\{divide}$ \5
+\T{92}\C{divide a register or parameter ( \.{\\divide} )}\par
+\B\4\D$\\{prefix}$ \5
+\T{93}\C{qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )}\par
+\B\4\D$\\{let}$ \5
+\T{94}\C{assign a command code ( \.{\\let}, \.{\\futurelet} )}\par
+\B\4\D$\\{shorthand\_def}$ \5
+\T{95}\C{code definition ( \.{\\chardef}, \.{\\countdef}, etc.~)}\par
+\B\4\D$\\{read\_to\_cs}$ \5
+\T{96}\C{read into a control sequence ( \.{\\read} )}\par
+\B\4\D$\\{def}$ \5
+\T{97}\C{macro definition ( \.{\\def}, \.{\\gdef}, \.{\\xdef}, \.{\\edef} )}\par
+\B\4\D$\\{set\_box}$ \5
+\T{98}\C{set a box ( \.{\\setbox} )}\par
+\B\4\D$\\{hyph\_data}$ \5
+\T{99}\C{hyphenation data ( \.{\\hyphenation}, \.{\\patterns} )}\par
+\B\4\D$\\{set\_interaction}$ \5
+\T{100}\C{define level of interaction ( \.{\\batchmode}, etc.~)}\par
+\B\4\D$\\{max\_command}$ \5
+\T{100}\C{the largest command code seen at \\{big\_switch}}\par
+\fi
+
+\M{210}The remaining command codes are extra special, since they cannot get through
+\TeX's scanner to the main control routine. They have been given values higher
+than \\{max\_command} so that their special nature is easily discernible.
+The ``expandable'' commands come first.
+
+\Y\B\4\D$\\{undefined\_cs}$ \5
+$(\\{max\_command}+\T{1}{}$)\C{initial state of most \\{eq\_type} fields}\par
+\B\4\D$\\{expand\_after}$ \5
+$(\\{max\_command}+\T{2}{}$)\C{special expansion ( \.{\\expandafter} )}\par
+\B\4\D$\\{no\_expand}$ \5
+$(\\{max\_command}+\T{3}{}$)\C{special nonexpansion ( \.{\\noexpand} )}\par
+\B\4\D$\\{input}$ \5
+$(\\{max\_command}+\T{4}{}$)\C{input a source file ( \.{\\input}, \.{\\endinput} )}\par
+\B\4\D$\\{if\_test}$ \5
+$(\\{max\_command}+\T{5}{}$)\C{conditional text ( \.{\\if}, \.{\\ifcase}, etc.~)}\par
+\B\4\D$\\{fi\_or\_else}$ \5
+$(\\{max\_command}+\T{6}{}$)\C{delimiters for conditionals ( \.{\\else}, etc.~)}\par
+\B\4\D$\\{cs\_name}$ \5
+$(\\{max\_command}+\T{7}{}$)\C{make a control sequence from tokens ( \.{\\csname} )}\par
+\B\4\D$\\{convert}$ \5
+$(\\{max\_command}+\T{8}{}$)\C{convert to text ( \.{\\number}, \.{\\string}, etc.~)}\par
+\B\4\D$\\{the}$ \5
+$(\\{max\_command}+\T{9}{}$)\C{expand an internal quantity ( \.{\\the} )}\par
+\B\4\D$\\{top\_bot\_mark}$ \5
+$(\\{max\_command}+\T{10}{}$)\C{inserted mark ( \.{\\topmark}, etc.~)}\par
+\B\4\D$\\{call}$ \5
+$(\\{max\_command}+\T{11}{}$)\C{non-long, non-outer control sequence}\par
+\B\4\D$\\{long\_call}$ \5
+$(\\{max\_command}+\T{12}{}$)\C{long, non-outer control sequence}\par
+\B\4\D$\\{outer\_call}$ \5
+$(\\{max\_command}+\T{13}{}$)\C{non-long, outer control sequence}\par
+\B\4\D$\\{long\_outer\_call}$ \5
+$(\\{max\_command}+\T{14}{}$)\C{long, outer control sequence}\par
+\B\4\D$\\{end\_template}$ \5
+$(\\{max\_command}+\T{15}{}$)\C{end of an alignment template}\par
+\B\4\D$\\{dont\_expand}$ \5
+$(\\{max\_command}+\T{16}{}$)\C{the following token was marked by \.{\\noexpand}}\par
+\B\4\D$\\{glue\_ref}$ \5
+$(\\{max\_command}+\T{17}{}$)\C{the equivalent points to a glue specification}\par
+\B\4\D$\\{shape\_ref}$ \5
+$(\\{max\_command}+\T{18}{}$)\C{the equivalent points to a parshape specification}\par
+\B\4\D$\\{box\_ref}$ \5
+$(\\{max\_command}+\T{19}{}$)\C{the equivalent points to a box node, or is \\{null}}\par
+\B\4\D$\\{data}$ \5
+$(\\{max\_command}+\T{20}{}$)\C{the equivalent is simply a halfword number}\par
+\fi
+
+\N{1}{211}The semantic nest.
+\TeX\ is typically in the midst of building many lists at once. For example,
+when a math formula is being processed, \TeX\ is in math mode and
+working on an mlist; this formula has temporarily interrupted \TeX\ from
+being in horizontal mode and building the hlist of a paragraph; and this
+paragraph has temporarily interrupted \TeX\ from being in vertical mode
+and building the vlist for the next page of a document. Similarly, when a
+\.{\\vbox} occurs inside of an \.{\\hbox}, \TeX\ is temporarily
+interrupted from working in restricted horizontal mode, and it enters
+internal vertical mode. The ``semantic nest'' is a stack that
+keeps track of what lists and modes are currently suspended.
+
+At each level of processing we are in one of six modes:
+
+\yskip\hang\\{vmode} stands for vertical mode (the page builder);
+
+\hang\\{hmode} stands for horizontal mode (the paragraph builder);
+
+\hang\\{mmode} stands for displayed formula mode;
+
+\hang${-}\\{vmode}$ stands for internal vertical mode (e.g., in a \.{\\vbox});
+
+\hang${-}\\{hmode}$ stands for restricted horizontal mode (e.g., in an \.{\\hbox});
+
+\hang${-}\\{mmode}$ stands for math formula mode (not displayed).
+
+\yskip\noindent The mode is temporarily set to zero while processing \.{\\write}
+texts in the \\{ship\_out} routine.
+
+Numeric values are assigned to \\{vmode}, \\{hmode}, and \\{mmode} so that
+\TeX's ``big semantic switch'' can select the appropriate thing to
+do by computing the value $\\{abs}(\\{mode})+\\{cur\_cmd}$, where \\{mode} is the current
+mode and \\{cur\_cmd} is the current command code.
+
+\Y\B\4\D$\\{vmode}$ \5
+\T{1}\C{vertical mode}\par
+\B\4\D$\\{hmode}$ \5
+$(\\{vmode}+\\{max\_command}+\T{1}{}$)\C{horizontal mode}\par
+\B\4\D$\\{mmode}$ \5
+$(\\{hmode}+\\{max\_command}+\T{1}{}$)\C{math mode}\par
+\Y\B\&{void} \\{print\_mode}(\&{int} \|m)\C{prints the mode represented by \|m}\6
+${}\{{}$\5
+\1\&{if} ${}(\|m>\T{0}){}$\1\6
+\&{switch} ${}(\|m/(\\{max\_command}+\T{1})){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+\\{print\_str}(\.{"vertical"});\5
+\&{break};\6
+\4\&{case} \T{1}:\5
+\\{print\_str}(\.{"horizontal"});\5
+\&{break};\6
+\4\&{case} \T{2}:\5
+\\{print\_str}(\.{"display\ math"});\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}(\|m\E\T{0}){}$\1\5
+\\{print\_str}(\.{"no"});\2\6
+\&{else}\1\6
+\&{switch} ${}(({-}\|m)/(\\{max\_command}+\T{1})){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+\\{print\_str}(\.{"internal\ vertical"});\5
+\&{break};\6
+\4\&{case} \T{1}:\5
+\\{print\_str}(\.{"restricted\ horizont}\)\.{al"});\5
+\&{break};\6
+\4\&{case} \T{2}:\5
+\\{print\_str}(\.{"math"});\6
+\4${}\}{}$\2\2\6
+\\{print\_str}(\.{"\ mode"});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{212}The state of affairs at any semantic level can be represented by
+five values:
+
+\yskip\hang\\{mode} is the number representing the semantic mode, as
+just explained.
+
+\yskip\hang\\{head} is a \&{pointer} to a list head for the list being built;
+\\{link}(\\{head}) therefore points to the first element of the list, or
+to \\{null} if the list is empty.
+
+\yskip\hang\\{tail} is a \&{pointer} to the final node of the list being
+built; thus, $\\{tail}\E\\{head}$ if and only if the list is empty.
+
+\yskip\hang\\{prev\_graf} is the number of lines of the current paragraph that
+have already been put into the present vertical list.
+
+\yskip\hang\\{aux} is an auxiliary \&{memory\_word} that gives further information
+that is needed to characterize the situation.
+
+\yskip\noindent
+In vertical mode, \\{aux} is also known as \\{prev\_depth}; it is the scaled
+value representing the depth of the previous box, for use in baseline
+calculations, or it is $\Z$ ${-}\T{1000}$pt if the next box on the vertical list is to
+be exempt from baseline calculations. In horizontal mode, \\{aux} is also
+known as \\{space\_factor} and \\{clang}; it holds the current space factor used in
+spacing calculations, and the current language used for hyphenation.
+(The value of \\{clang} is undefined in restricted horizontal mode.)
+In math mode, \\{aux} is also known as \\{incompleat\_noad}; if
+not \\{null}, it points to a record that represents the numerator of a
+generalized fraction for which the denominator is currently being formed
+in the current list.
+
+There is also a sixth quantity, \\{mode\_line}, which correlates
+the semantic nest with the user's input; \\{mode\_line} contains the source
+line number at which the current level of nesting was entered. The negative
+of this line number is the \\{mode\_line} at the level of the
+user's output routine.
+
+In horizontal mode, the \\{prev\_graf} field is used for initial language data.
+
+The semantic nest is an array called \\{nest} that holds the \\{mode}, \\{head},
+\\{tail}, \\{prev\_graf}, \\{aux}, and \\{mode\_line} values for all semantic levels
+below the currently active one. Information about the currently active
+level is kept in the global quantities \\{mode}, \\{head}, \\{tail}, \\{prev\_graf},
+\\{aux}, and \\{mode\_line}, which live in a \PASCAL\ record that is ready to
+be pushed onto \\{nest} if necessary.
+
+\Y\B\4\D$\\{ignore\_depth}$ \5
+${-}{}$\T{65536000}\C{\\{prev\_depth} value that is ignored}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{struct} ${}\{{}$\1\6
+\\{int16\_t}\\{mode\_field};\5
+\&{pointer} \\{head\_field}${},{}$ \\{tail\_field};\6
+\&{int} \\{pg\_field}${},{}$ \\{ml\_field};\5
+\&{memory\_word} \\{aux\_field};\2\6
+${}\}{}$ \&{list\_state\_record};\par
+\fi
+
+\M{213}\B\D$\\{mode}$ \5
+$\\{cur\_list}.{}$\\{mode\_field}\C{current mode}\par
+\B\4\D$\\{head}$ \5
+$\\{cur\_list}.{}$\\{head\_field}\C{header node of current list}\par
+\B\4\D$\\{tail}$ \5
+$\\{cur\_list}.{}$\\{tail\_field}\C{final node on current list}\par
+\B\4\D$\\{prev\_graf}$ \5
+$\\{cur\_list}.{}$\\{pg\_field}\C{number of paragraph lines accumulated}\par
+\B\4\D$\\{aux}$ \5
+$\\{cur\_list}.{}$\\{aux\_field}\C{auxiliary data about the current list}\par
+\B\4\D$\\{prev\_depth}$ \5
+$\\{aux}.{}$\\{sc}\C{the name of \\{aux} in vertical mode}\par
+\B\4\D$\\{space\_factor}$ \5
+$\\{aux}.\\{hh}.{}$\\{lh}\C{part of \\{aux} in horizontal mode}\par
+\B\4\D$\\{clang}$ \5
+$\\{aux}.\\{hh}.{}$\\{rh}\C{the other part of \\{aux} in horizontal mode}\par
+\B\4\D$\\{incompleat\_noad}$ \5
+$\\{aux}.{}$\|i\C{the name of \\{aux} in math mode}\par
+\B\4\D$\\{mode\_line}$ \5
+$\\{cur\_list}.{}$\\{ml\_field}\C{source file line number at beginning of list}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{list\_state\_record} ${}\\{nest}[\\{nest\_size}+\T{1}];{}$\6
+\&{uint8\_t} \\{nest\_ptr};\C{first unused location of \\{nest}}\6
+\&{uint8\_t} \\{max\_nest\_stack};\C{maximum of \\{nest\_ptr} when pushing}\6
+\&{list\_state\_record} \\{cur\_list};\C{the ``top'' semantic state}\7
+\\{int16\_t}\\{shown\_mode};\C{most recent mode shown by \.{\\tracingcommands}}\par
+\fi
+
+\M{214}Here is a common way to make the current list grow:
+
+\Y\B\4\D$\\{tail\_append}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\|X;{}$\5
+${}\\{tail}\K\\{link}(\\{tail});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{215}We will see later that the vertical list at the bottom semantic level is split
+into two parts; the ``current page'' runs from \\{page\_head} to \\{page\_tail},
+and the ``contribution list'' runs from \\{contrib\_head} to \\{tail} of
+semantic level zero. The idea is that contributions are first formed in
+vertical mode, then ``contributed'' to the current page (during which time
+the page-breaking decisions are made). For now, we don't need to know
+any more details about the page-building process.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{nest\_ptr}\K\T{0};{}$\5
+${}\\{max\_nest\_stack}\K\T{0};{}$\5
+${}\\{mode}\K\\{vmode};{}$\5
+${}\\{head}\K\\{contrib\_head};{}$\5
+${}\\{tail}\K\\{contrib\_head};{}$\5
+${}\\{prev\_depth}\K\\{ignore\_depth};{}$\5
+${}\\{mode\_line}\K\T{0};{}$\5
+${}\\{prev\_graf}\K\T{0};{}$\5
+${}\\{shown\_mode}\K\T{0};{}$\5
+\X991:Start a new current page\X;\par
+\fi
+
+\M{216}When \TeX's work on one level is interrupted, the state is saved by
+calling \\{push\_nest}. This routine changes \\{head} and \\{tail} so that
+a new (empty) list is begun; it does not change \\{mode} or \\{aux}.
+
+\Y\B\&{void} \\{push\_nest}(\&{void})\C{enter a new semantic level, save the old}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{nest\_ptr}>\\{max\_nest\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_nest\_stack}\K\\{nest\_ptr};{}$\6
+\&{if} ${}(\\{nest\_ptr}\E\\{nest\_size}){}$\1\5
+${}\\{overflow}(\.{"semantic\ nest\ size"},\39\\{nest\_size});{}$\2\6
+\4${}\}{}$\2\6
+${}\\{nest}[\\{nest\_ptr}]\K\\{cur\_list}{}$;\C{stack the record}\6
+\\{incr}(\\{nest\_ptr});\5
+${}\\{head}\K\\{get\_avail}(\,);{}$\5
+${}\\{tail}\K\\{head};{}$\5
+${}\\{prev\_graf}\K\T{0};{}$\5
+${}\\{mode\_line}\K\\{line};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{217}Conversely, when \TeX\ is finished on the current level, the former
+state is restored by calling \\{pop\_nest}. This routine will never be
+called at the lowest semantic level, nor will it be called unless \\{head}
+is a node that should be returned to free memory.
+
+\Y\B\&{void} \\{pop\_nest}(\&{void})\C{leave a semantic level, re-enter the old}\6
+${}\{{}$\5
+\1\\{free\_avail}(\\{head});\5
+\\{decr}(\\{nest\_ptr});\5
+${}\\{cur\_list}\K\\{nest}[\\{nest\_ptr}];{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{218}Here is a procedure that displays what \TeX\ is working on, at all levels.
+
+\Y\B\&{void} \\{print\_totals}(\&{void});\7
+\&{void} \\{show\_activities}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|p;\C{index into \\{nest}}\7
+\\{int16\_t}\|m;\C{mode}\7
+\&{memory\_word} \|a;\C{auxiliary}\6
+\&{pointer} \|q${},{}$ \|r;\C{for showing the current page}\6
+\&{int} \|t;\C{ditto}\7
+${}\\{nest}[\\{nest\_ptr}]\K\\{cur\_list}{}$;\C{put the top level into the array}\6
+\\{print\_nl}(\.{""});\5
+\\{print\_ln}(\,);\6
+\&{for} ${}(\|p\K\\{nest\_ptr};{}$ ${}\|p\G\T{0};{}$ ${}\|p\MM){}$\5
+${}\{{}$\5
+\1${}\|m\K\\{nest}[\|p].\\{mode\_field};{}$\5
+${}\|a\K\\{nest}[\|p].\\{aux\_field};{}$\5
+\\{print\_nl}(\.{"\#\#\#\ "});\5
+\\{print\_mode}(\|m);\5
+\\{print\_str}(\.{"\ entered\ at\ line\ "});\5
+${}\\{print\_int}(\\{abs}(\\{nest}[\|p].\\{ml\_field}));{}$\6
+\&{if} ${}(\|m\E\\{hmode}){}$\1\6
+\&{if} ${}(\\{nest}[\|p].\\{pg\_field}\I\T{\~40600000}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ (language"});\5
+${}\\{print\_int}(\\{nest}[\|p].\\{pg\_field}\MOD\T{\~200000});{}$\5
+\\{print\_str}(\.{":hyphenmin"});\5
+${}\\{print\_int}(\\{nest}[\|p].\\{pg\_field}/\T{\~20000000});{}$\5
+\\{print\_char}(\.{','});\5
+${}\\{print\_int}((\\{nest}[\|p].\\{pg\_field}/\T{\~200000})\MOD\T{\~100});{}$\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\\{nest}[\|p].\\{ml\_field}<\T{0}){}$\1\5
+\\{print\_str}(\.{"\ (\\\\output\ routine)}\)\.{"});\2\6
+\&{if} ${}(\|p\E\T{0}){}$\5
+${}\{{}$\5
+\1\X986:Show the status of the current page\X;\6
+\&{if} ${}(\\{link}(\\{contrib\_head})\I\\{null}){}$\1\5
+\\{print\_nl}(\.{"\#\#\#\ recent\ contribu}\)\.{tions:"});\2\6
+\4${}\}{}$\2\6
+${}\\{show\_box}(\\{link}(\\{nest}[\|p].\\{head\_field}));{}$\5
+\X219:Show the auxiliary field, \|a\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{219}\B\X219:Show the auxiliary field, \|a\X${}\E{}$\6
+\&{switch} ${}(\\{abs}(\|m)/(\\{max\_command}+\T{1})){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{"prevdepth\ "});\6
+\&{if} ${}(\|a.\\{sc}\Z\\{ignore\_depth}){}$\1\5
+\\{print\_str}(\.{"ignored"});\2\6
+\&{else}\1\5
+${}\\{print\_scaled}(\|a.\\{sc});{}$\2\6
+\&{if} ${}(\\{nest}[\|p].\\{pg\_field}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ prevgraf\ "});\5
+${}\\{print\_int}(\\{nest}[\|p].\\{pg\_field});{}$\5
+\\{print\_str}(\.{"\ line"});\6
+\&{if} ${}(\\{nest}[\|p].\\{pg\_field}\I\T{1}){}$\1\5
+\\{print\_char}(\.{'s'});\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \T{1}:\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{"spacefactor\ "});\5
+${}\\{print\_int}(\|a.\\{hh}.\\{lh});{}$\6
+\&{if} ${}(\|m>\T{0}{}$)\5
+\1\&{if} ${}(\|a.\\{hh}.\\{rh}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ current\ language\ }\)\.{"});\5
+${}\\{print\_int}(\|a.\\{hh}.\\{rh}){}$;\5
+${}\}{}$\2\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \T{2}:\6
+\&{if} ${}(\|a.\|i\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"this\ will\ be\ denomi}\)\.{nator\ of:"});\5
+${}\\{show\_box}(\|a.\|i){}$;\5
+${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\par
+\U218.\fi
+
+\N{1}{220}The table of equivalents.
+Now that we have studied the data structures for \TeX's semantic routines,
+we ought to consider the data structures used by its syntactic routines. In
+other words, our next concern will be
+the tables that \TeX\ looks at when it is scanning
+what the user has written.
+
+The biggest and most important such table is called \\{eqtb}. It holds the
+current ``equivalents'' of things; i.e., it explains what things mean
+or what their current values are, for all quantities that are subject to
+the nesting structure provided by \TeX's grouping mechanism. There are six
+parts to \\{eqtb}:
+
+\yskip\hangg 1) $\\{eqtb}[\\{active\_base}\dotdot(\\{hash\_base}-\T{1})]$ holds the current
+equivalents of single-character control sequences.
+
+\yskip\hangg 2) $\\{eqtb}[\\{hash\_base}\dotdot(\\{glue\_base}-\T{1})]$ holds the current
+equivalents of multiletter control sequences.
+
+\yskip\hangg 3) $\\{eqtb}[\\{glue\_base}\dotdot(\\{local\_base}-\T{1})]$ holds the current
+equivalents of glue parameters like the current baselineskip.
+
+\yskip\hangg 4) $\\{eqtb}[\\{local\_base}\dotdot(\\{int\_base}-\T{1})]$ holds the current
+equivalents of local halfword quantities like the current box registers,
+the current ``catcodes,'' the current font, and a pointer to the current
+paragraph shape.
+
+\yskip\hangg 5) $\\{eqtb}[\\{int\_base}\dotdot(\\{dimen\_base}-\T{1})]$ holds the current
+equivalents of fullword integer parameters like the current hyphenation
+penalty.
+
+\yskip\hangg 6) $\\{eqtb}[\\{dimen\_base}\dotdot\\{eqtb\_size}]$ holds the current equivalents
+of fullword dimension parameters like the current hsize or amount of
+hanging indentation.
+
+\yskip\noindent Note that, for example, the current amount of
+baselineskip glue is determined by the setting of a particular location
+in region~3 of \\{eqtb}, while the current meaning of the control sequence
+`\.{\\baselineskip}' (which might have been changed by \.{\\def} or
+\.{\\let}) appears in region~2.
+
+\fi
+
+\M{221}Each entry in \\{eqtb} is a \&{memory\_word}. Most of these words are of type
+\&{two\_halves}, and subdivided into three fields:
+
+\yskip\hangg 1) The \\{eq\_level} (a quarterword) is the level of grouping at
+which this equivalent was defined. If the level is \\{level\_zero}, the
+equivalent has never been defined; \\{level\_one} refers to the outer level
+(outside of all groups), and this level is also used for global
+definitions that never go away. Higher levels are for equivalents that
+will disappear at the end of their group.
+
+\yskip\hangg 2) The \\{eq\_type} (another quarterword) specifies what kind of
+entry this is. There are many types, since each \TeX\ primitive like
+\.{\\hbox}, \.{\\def}, etc., has its own special code. The list of
+command codes above includes all possible settings of the \\{eq\_type} field.
+
+\yskip\hangg 3) The \\{equiv} (a halfword) is the current equivalent value.
+This may be a font number, a pointer into \\{mem}, or a variety of other
+things.
+
+\Y\B\4\D$\\{eq\_level\_field}(\|X)$ \5
+$\|X.\\{hh}.{}$\\{b1}\par
+\B\4\D$\\{eq\_type\_field}(\|X)$ \5
+$\|X.\\{hh}.{}$\\{b0}\par
+\B\4\D$\\{equiv\_field}(\|X)$ \5
+$\|X.\\{hh}.{}$\\{rh}\par
+\B\4\D$\\{eq\_level}(\|X)$ \5
+\\{eq\_level\_field}(\\{eqtb}[\|X])\C{level of definition}\par
+\B\4\D$\\{eq\_type}(\|X)$ \5
+\\{eq\_type\_field}(\\{eqtb}[\|X])\C{command code for equivalent}\par
+\B\4\D$\\{equiv}(\|X)$ \5
+\\{equiv\_field}(\\{eqtb}[\|X])\C{equivalent value}\par
+\B\4\D$\\{level\_zero}$ \5
+\\{min\_quarterword}\C{level for undefined quantities}\par
+\B\4\D$\\{level\_one}$ \5
+$(\\{level\_zero}+\T{1}{}$)\C{outermost level for defined quantities}\par
+\fi
+
+\M{222}Many locations in \\{eqtb} have symbolic names. The purpose of the next
+paragraphs is to define these names, and to set up the initial values of the
+equivalents.
+
+In the first region we have 256 equivalents for ``active characters'' that
+act as control sequences, followed by 256 equivalents for single-character
+control sequences.
+
+Then comes region~2, which corresponds to the hash table that we will
+define later. The maximum address in this region is used for a dummy
+control sequence that is perpetually undefined. There also are several
+locations for control sequences that are perpetually defined
+(since they are used in error recovery).
+
+\Y\B\4\D$\\{active\_base}$ \5
+\T{1}\C{beginning of region 1, for active character equivalents}\par
+\B\4\D$\\{single\_base}$ \5
+$(\\{active\_base}+\T{256}{}$)\C{equivalents of one-character control sequences}\par
+\B\4\D$\\{null\_cs}$ \5
+$(\\{single\_base}+\T{256}{}$)\C{equivalent of \.{\\csname\\endcsname}}\par
+\B\4\D$\\{hash\_base}$ \5
+$(\\{null\_cs}+\T{1}{}$)\C{beginning of region 2, for the hash table}\par
+\B\4\D$\\{frozen\_control\_sequence}$ \5
+$(\\{hash\_base}+\\{hash\_size}{}$)\C{for error recovery}\par
+\B\4\D$\\{frozen\_protection}$ \5
+\\{frozen\_control\_sequence}\C{inaccessible but definable}\par
+\B\4\D$\\{frozen\_cr}$ \5
+$(\\{frozen\_control\_sequence}+\T{1}{}$)\C{permanent `\.{\\cr}'}\par
+\B\4\D$\\{frozen\_end\_group}$ \5
+$(\\{frozen\_control\_sequence}+\T{2}{}$)\C{permanent `\.{\\endgroup}'}\par
+\B\4\D$\\{frozen\_right}$ \5
+$(\\{frozen\_control\_sequence}+\T{3}{}$)\C{permanent `\.{\\right}'}\par
+\B\4\D$\\{frozen\_fi}$ \5
+$(\\{frozen\_control\_sequence}+\T{4}{}$)\C{permanent `\.{\\fi}'}\par
+\B\4\D$\\{frozen\_end\_template}$ \5
+$(\\{frozen\_control\_sequence}+\T{5}{}$)\C{permanent `\.{\\endtemplate}'}\par
+\B\4\D$\\{frozen\_endv}$ \5
+$(\\{frozen\_control\_sequence}+\T{6}{}$)\C{second permanent `\.{\\endtemplate}'}\par
+\B\4\D$\\{frozen\_relax}$ \5
+$(\\{frozen\_control\_sequence}+\T{7}{}$)\C{permanent `\.{\\relax}'}\par
+\B\4\D$\\{end\_write}$ \5
+$(\\{frozen\_control\_sequence}+\T{8}{}$)\C{permanent `\.{\\endwrite}'}\par
+\B\4\D$\\{frozen\_dont\_expand}$ \5
+$(\\{frozen\_control\_sequence}+\T{9}{}$)\C{permanent `\.{\\notexpanded:}'}\par
+\B\4\D$\\{frozen\_null\_font}$ \5
+$(\\{frozen\_control\_sequence}+\T{10}{}$)\C{permanent `\.{\\nullfont}'}\par
+\B\4\D$\\{font\_id\_base}$ \5
+$(\\{frozen\_null\_font}-\\{font\_base}{}$)\C{begins table of 257 permanent font identifiers}\par
+\B\4\D$\\{undefined\_control\_sequence}$ \5
+$(\\{frozen\_null\_font}+\T{257}{}$)\C{dummy location}\par
+\B\4\D$\\{glue\_base}$ \5
+$(\\{undefined\_control\_sequence}+\T{1}{}$)\C{beginning of region 3}\par
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{eq\_type}(\\{undefined\_control\_sequence})\K\\{undefined\_cs};{}$\5
+${}\\{equiv}(\\{undefined\_control\_sequence})\K\\{null};{}$\5
+${}\\{eq\_level}(\\{undefined\_control\_sequence})\K\\{level\_zero};{}$\6
+\&{for} ${}(\|k\K\\{active\_base};{}$ ${}\|k\Z\\{undefined\_control\_sequence}-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{undefined\_control\_sequence}]{}$;\2\par
+\fi
+
+\M{223}Here is a routine that displays the current meaning of an \\{eqtb} entry
+in region 1 or~2. (Similar routines for the other regions will appear
+below.)
+
+\Y\B\4\X223:Show equivalent \|n, in region 1 or 2\X${}\E{}$\6
+${}\{{}$\5
+\1\\{sprint\_cs}(\|n);\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_cmd\_chr}(\\{eq\_type}(\|n),\39\\{equiv}(\|n));{}$\6
+\&{if} ${}(\\{eq\_type}(\|n)\G\\{call}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{':'});\5
+${}\\{show\_token\_list}(\\{link}(\\{equiv}(\|n)),\39\\{null},\39\T{32});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U252.\fi
+
+\M{224}Region 3 of \\{eqtb} contains the 256 \.{\\skip} registers, as well as the
+glue parameters defined here. It is important that the ``muskip''
+parameters have larger numbers than the others.
+
+\Y\B\4\D$\\{line\_skip\_code}$ \5
+\T{0}\C{interline glue if \\{baseline\_skip} is infeasible}\par
+\B\4\D$\\{baseline\_skip\_code}$ \5
+\T{1}\C{desired glue between baselines}\par
+\B\4\D$\\{par\_skip\_code}$ \5
+\T{2}\C{extra glue just above a paragraph}\par
+\B\4\D$\\{above\_display\_skip\_code}$ \5
+\T{3}\C{extra glue just above displayed math}\par
+\B\4\D$\\{below\_display\_skip\_code}$ \5
+\T{4}\C{extra glue just below displayed math}\par
+\B\4\D$\\{above\_display\_short\_skip\_code}$ \5
+\T{5}\C{glue above displayed math following short lines}\par
+\B\4\D$\\{below\_display\_short\_skip\_code}$ \5
+\T{6}\C{glue below displayed math following short lines}\par
+\B\4\D$\\{left\_skip\_code}$ \5
+\T{7}\C{glue at left of justified lines}\par
+\B\4\D$\\{right\_skip\_code}$ \5
+\T{8}\C{glue at right of justified lines}\par
+\B\4\D$\\{top\_skip\_code}$ \5
+\T{9}\C{glue at top of main pages}\par
+\B\4\D$\\{split\_top\_skip\_code}$ \5
+\T{10}\C{glue at top of split pages}\par
+\B\4\D$\\{tab\_skip\_code}$ \5
+\T{11}\C{glue between aligned entries}\par
+\B\4\D$\\{space\_skip\_code}$ \5
+\T{12}\C{glue between words (if not \\{zero\_glue})}\par
+\B\4\D$\\{xspace\_skip\_code}$ \5
+\T{13}\C{glue after sentences (if not \\{zero\_glue})}\par
+\B\4\D$\\{par\_fill\_skip\_code}$ \5
+\T{14}\C{glue on last line of paragraph}\par
+\B\4\D$\\{thin\_mu\_skip\_code}$ \5
+\T{15}\C{thin space in math formula}\par
+\B\4\D$\\{med\_mu\_skip\_code}$ \5
+\T{16}\C{medium space in math formula}\par
+\B\4\D$\\{thick\_mu\_skip\_code}$ \5
+\T{17}\C{thick space in math formula}\par
+\B\4\D$\\{glue\_pars}$ \5
+\T{18}\C{total number of glue parameters}\par
+\B\4\D$\\{skip\_base}$ \5
+$(\\{glue\_base}+\\{glue\_pars}{}$)\C{table of 256 ``skip'' registers}\par
+\B\4\D$\\{mu\_skip\_base}$ \5
+$(\\{skip\_base}+\T{256}{}$)\C{table of 256 ``muskip'' registers}\par
+\B\4\D$\\{local\_base}$ \5
+$(\\{mu\_skip\_base}+\T{256}{}$)\C{beginning of region 4}\Y\par
+\B\4\D$\\{skip}(\|X)$ \5
+$\\{equiv}(\\{skip\_base}+\|X{}$)\C{\\{mem} location of glue specification}\par
+\B\4\D$\\{mu\_skip}(\|X)$ \5
+$\\{equiv}(\\{mu\_skip\_base}+\|X{}$)\C{\\{mem} location of math glue spec}\par
+\B\4\D$\\{glue\_par}(\|X)$ \5
+$\\{equiv}(\\{glue\_base}+\|X{}$)\C{\\{mem} location of glue specification}\par
+\B\4\D$\\{line\_skip}$ \5
+\\{glue\_par}(\\{line\_skip\_code})\par
+\B\4\D$\\{baseline\_skip}$ \5
+\\{glue\_par}(\\{baseline\_skip\_code})\par
+\B\4\D$\\{par\_skip}$ \5
+\\{glue\_par}(\\{par\_skip\_code})\par
+\B\4\D$\\{above\_display\_skip}$ \5
+\\{glue\_par}(\\{above\_display\_skip\_code})\par
+\B\4\D$\\{below\_display\_skip}$ \5
+\\{glue\_par}(\\{below\_display\_skip\_code})\par
+\B\4\D$\\{above\_display\_short\_skip}$ \5
+\\{glue\_par}(\\{above\_display\_short\_skip\_code})\par
+\B\4\D$\\{below\_display\_short\_skip}$ \5
+\\{glue\_par}(\\{below\_display\_short\_skip\_code})\par
+\B\4\D$\\{left\_skip}$ \5
+\\{glue\_par}(\\{left\_skip\_code})\par
+\B\4\D$\\{right\_skip}$ \5
+\\{glue\_par}(\\{right\_skip\_code})\par
+\B\4\D$\\{top\_skip}$ \5
+\\{glue\_par}(\\{top\_skip\_code})\par
+\B\4\D$\\{split\_top\_skip}$ \5
+\\{glue\_par}(\\{split\_top\_skip\_code})\par
+\B\4\D$\\{tab\_skip}$ \5
+\\{glue\_par}(\\{tab\_skip\_code})\par
+\B\4\D$\\{space\_skip}$ \5
+\\{glue\_par}(\\{space\_skip\_code})\par
+\B\4\D$\\{xspace\_skip}$ \5
+\\{glue\_par}(\\{xspace\_skip\_code})\par
+\B\4\D$\\{par\_fill\_skip}$ \5
+\\{glue\_par}(\\{par\_fill\_skip\_code})\par
+\B\4\D$\\{thin\_mu\_skip}$ \5
+\\{glue\_par}(\\{thin\_mu\_skip\_code})\par
+\B\4\D$\\{med\_mu\_skip}$ \5
+\\{glue\_par}(\\{med\_mu\_skip\_code})\par
+\B\4\D$\\{thick\_mu\_skip}$ \5
+\\{glue\_par}(\\{thick\_mu\_skip\_code})\par
+\Y\B\4\X224:Current \\{mem} equivalent of glue parameter number \|n\X${}\E{}$\6
+\\{glue\_par}(\|n)\par
+\Us152\ET154.\fi
+
+\M{225}Sometimes we need to convert \TeX's internal code numbers into symbolic
+form. The \\{print\_skip\_param} routine gives the symbolic name of a glue
+parameter.
+
+\Y\B\4\X225:Declare the procedure called \\{print\_skip\_param}\X${}\E{}$\6
+\&{void} \\{print\_skip\_param}(\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{switch} (\|n)\5
+${}\{{}$\1\6
+\4\&{case} \\{line\_skip\_code}:\5
+\\{print\_esc}(\X1405:\.{"lineskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{baseline\_skip\_code}:\5
+\\{print\_esc}(\X1406:\.{"baselineskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{par\_skip\_code}:\5
+\\{print\_esc}(\X1407:\.{"parskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{above\_display\_skip\_code}:\5
+\\{print\_esc}(\X1408:\.{"abovedisplayskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{below\_display\_skip\_code}:\5
+\\{print\_esc}(\X1409:\.{"belowdisplayskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{above\_display\_short\_skip\_code}:\5
+\\{print\_esc}(\X1410:\.{"abovedisplayshortsk}\)\.{ip"}\X);\5
+\&{break};\6
+\4\&{case} \\{below\_display\_short\_skip\_code}:\5
+\\{print\_esc}(\X1411:\.{"belowdisplayshortsk}\)\.{ip"}\X);\5
+\&{break};\6
+\4\&{case} \\{left\_skip\_code}:\5
+\\{print\_esc}(\X1412:\.{"leftskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{right\_skip\_code}:\5
+\\{print\_esc}(\X1413:\.{"rightskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{top\_skip\_code}:\5
+\\{print\_esc}(\X1414:\.{"topskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{split\_top\_skip\_code}:\5
+\\{print\_esc}(\X1415:\.{"splittopskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{tab\_skip\_code}:\5
+\\{print\_esc}(\X1416:\.{"tabskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{space\_skip\_code}:\5
+\\{print\_esc}(\X1417:\.{"spaceskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{xspace\_skip\_code}:\5
+\\{print\_esc}(\X1418:\.{"xspaceskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{par\_fill\_skip\_code}:\5
+\\{print\_esc}(\X1419:\.{"parfillskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{thin\_mu\_skip\_code}:\5
+\\{print\_esc}(\X1420:\.{"thinmuskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{med\_mu\_skip\_code}:\5
+\\{print\_esc}(\X1421:\.{"medmuskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{thick\_mu\_skip\_code}:\5
+\\{print\_esc}(\X1422:\.{"thickmuskip"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_str}(\.{"[unknown\ glue\ param}\)\.{eter!]"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U179.\fi
+
+\M{226}The symbolic names for glue parameters are put into \TeX's hash table
+by using the routine called \\{primitive}, defined below. Let us enter them
+now, so that we don't have to list all those parameter names anywhere else.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\E{}$\6
+$\\{primitive}(\X1405:\.{"lineskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{line\_skip\_code}){}$;\6
+${}\\{primitive}(\X1406:\.{"baselineskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{baseline\_skip\_code}){}$;\6
+${}\\{primitive}(\X1407:\.{"parskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{par\_skip\_code}){}$;\6
+${}\\{primitive}(\X1408:\.{"abovedisplayskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{above\_display\_skip\_code}){}$;\6
+${}\\{primitive}(\X1409:\.{"belowdisplayskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{below\_display\_skip\_code}){}$;\6
+${}\\{primitive}(\X1410:\.{"abovedisplayshortsk}\)\.{ip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{above\_display\_short\_skip\_code}){}$;\6
+${}\\{primitive}(\X1411:\.{"belowdisplayshortsk}\)\.{ip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{below\_display\_short\_skip\_code}){}$;\6
+${}\\{primitive}(\X1412:\.{"leftskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{left\_skip\_code}){}$;\6
+${}\\{primitive}(\X1413:\.{"rightskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{right\_skip\_code}){}$;\6
+${}\\{primitive}(\X1414:\.{"topskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{top\_skip\_code}){}$;\6
+${}\\{primitive}(\X1415:\.{"splittopskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{split\_top\_skip\_code}){}$;\6
+${}\\{primitive}(\X1416:\.{"tabskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{tab\_skip\_code}){}$;\6
+${}\\{primitive}(\X1417:\.{"spaceskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{space\_skip\_code}){}$;\6
+${}\\{primitive}(\X1418:\.{"xspaceskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{xspace\_skip\_code}){}$;\6
+${}\\{primitive}(\X1419:\.{"parfillskip"}\X,\39\\{assign\_glue},\39\\{glue\_base}+\\{par\_fill\_skip\_code}){}$;\6
+${}\\{primitive}(\X1420:\.{"thinmuskip"}\X,\39\\{assign\_mu\_glue},\39\\{glue\_base}+\\{thin\_mu\_skip\_code}){}$;\6
+${}\\{primitive}(\X1421:\.{"medmuskip"}\X,\39\\{assign\_mu\_glue},\39\\{glue\_base}+\\{med\_mu\_skip\_code}){}$;\6
+${}\\{primitive}(\X1422:\.{"thickmuskip"}\X,\39\\{assign\_mu\_glue},\39\\{glue\_base}+\\{thick\_mu\_skip\_code}){}$;\par
+\As230, 238, 248, 265, 334, 376, 384, 411, 416, 468, 487, 491, 553, 780, 983, 1052, 1058, 1071, 1088, 1107, 1114, 1141, 1156, 1169, 1178, 1188, 1208, 1219, 1222, 1230, 1250, 1254, 1262, 1272, 1277, 1286, 1291\ETs1344.
+\U1336.\fi
+
+\M{227}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\E{}$\6
+\4\&{case} \\{assign\_glue}:\5
+\&{case} \\{assign\_mu\_glue}:\6
+\&{if} ${}(\\{chr\_code}<\\{skip\_base}){}$\1\5
+${}\\{print\_skip\_param}(\\{chr\_code}-\\{glue\_base});{}$\2\6
+\&{else} \&{if} ${}(\\{chr\_code}<\\{mu\_skip\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1423:\.{"skip"}\X);\5
+${}\\{print\_int}(\\{chr\_code}-\\{skip\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1424:\.{"muskip"}\X);\5
+${}\\{print\_int}(\\{chr\_code}-\\{mu\_skip\_base});{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\As231, 239, 249, 266, 335, 377, 385, 412, 417, 469, 488, 492, 781, 984, 1053, 1059, 1072, 1089, 1108, 1115, 1143, 1157, 1170, 1179, 1189, 1209, 1220, 1223, 1231, 1251, 1255, 1261, 1263, 1273, 1278, 1287, 1292, 1295\ETs1346.
+\U298.\fi
+
+\M{228}All glue parameters and registers are initially `\.{0pt plus0pt minus0pt}'.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{equiv}(\\{glue\_base})\K\\{zero\_glue};{}$\5
+${}\\{eq\_level}(\\{glue\_base})\K\\{level\_one};{}$\5
+${}\\{eq\_type}(\\{glue\_base})\K\\{glue\_ref};{}$\6
+\&{for} ${}(\|k\K\\{glue\_base}+\T{1};{}$ ${}\|k\Z\\{local\_base}-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{glue\_base}];{}$\2\6
+${}\\{glue\_ref\_count}(\\{zero\_glue})\K\\{glue\_ref\_count}(\\{zero\_glue})+\\{local\_base}-\\{glue\_base}{}$;\par
+\fi
+
+\M{229}\B\X229:Show equivalent \|n, in region 3\X${}\E{}$\6
+\&{if} ${}(\|n<\\{skip\_base}){}$\5
+${}\{{}$\5
+\1${}\\{print\_skip\_param}(\|n-\\{glue\_base});{}$\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\|n<\\{glue\_base}+\\{thin\_mu\_skip\_code}){}$\1\5
+${}\\{print\_spec}(\\{equiv}(\|n),\39\X1425:\.{"pt"}\X);{}$\2\6
+\&{else}\1\5
+${}\\{print\_spec}(\\{equiv}(\|n),\39\X1394:\.{"mu"}\X);{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{mu\_skip\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1423:\.{"skip"}\X);\5
+${}\\{print\_int}(\|n-\\{skip\_base});{}$\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_spec}(\\{equiv}(\|n),\39\X1425:\.{"pt"}\X);{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1424:\.{"muskip"}\X);\5
+${}\\{print\_int}(\|n-\\{mu\_skip\_base});{}$\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_spec}(\\{equiv}(\|n),\39\X1394:\.{"mu"}\X);{}$\6
+\4${}\}{}$\2\par
+\U252.\fi
+
+\M{230}Region 4 of \\{eqtb} contains the local quantities defined here. The
+bulk of this region is taken up by five tables that are indexed by eight-bit
+characters; these tables are important to both the syntactic and semantic
+portions of \TeX. There are also a bunch of special things like font and
+token parameters, as well as the tables of \.{\\toks} and \.{\\box}
+registers.
+
+\Y\B\4\D$\\{par\_shape\_loc}$ \5
+\\{local\_base}\C{specifies paragraph shape}\par
+\B\4\D$\\{output\_routine\_loc}$ \5
+$(\\{local\_base}+\T{1}{}$)\C{points to token list for \.{\\output}}\par
+\B\4\D$\\{every\_par\_loc}$ \5
+$(\\{local\_base}+\T{2}{}$)\C{points to token list for \.{\\everypar}}\par
+\B\4\D$\\{every\_math\_loc}$ \5
+$(\\{local\_base}+\T{3}{}$)\C{points to token list for \.{\\everymath}}\par
+\B\4\D$\\{every\_display\_loc}$ \5
+$(\\{local\_base}+\T{4}{}$)\C{points to token list for \.{\\everydisplay}}\par
+\B\4\D$\\{every\_hbox\_loc}$ \5
+$(\\{local\_base}+\T{5}{}$)\C{points to token list for \.{\\everyhbox}}\par
+\B\4\D$\\{every\_vbox\_loc}$ \5
+$(\\{local\_base}+\T{6}{}$)\C{points to token list for \.{\\everyvbox}}\par
+\B\4\D$\\{every\_job\_loc}$ \5
+$(\\{local\_base}+\T{7}{}$)\C{points to token list for \.{\\everyjob}}\par
+\B\4\D$\\{every\_cr\_loc}$ \5
+$(\\{local\_base}+\T{8}{}$)\C{points to token list for \.{\\everycr}}\par
+\B\4\D$\\{err\_help\_loc}$ \5
+$(\\{local\_base}+\T{9}{}$)\C{points to token list for \.{\\errhelp}}\par
+\B\4\D$\\{toks\_base}$ \5
+$(\\{local\_base}+\T{10}{}$)\C{table of 256 token list registers}\par
+\B\4\D$\\{box\_base}$ \5
+$(\\{toks\_base}+\T{256}{}$)\C{table of 256 box registers}\par
+\B\4\D$\\{cur\_font\_loc}$ \5
+$(\\{box\_base}+\T{256}{}$)\C{internal font number outside math mode}\par
+\B\4\D$\\{math\_font\_base}$ \5
+$(\\{cur\_font\_loc}+\T{1}{}$)\C{table of 48 math font numbers}\par
+\B\4\D$\\{cat\_code\_base}$ \5
+$(\\{math\_font\_base}+\T{48}{}$)\C{table of 256 command codes (the ``catcodes'')}\par
+\B\4\D$\\{lc\_code\_base}$ \5
+$(\\{cat\_code\_base}+\T{256}{}$)\C{table of 256 lowercase mappings}\par
+\B\4\D$\\{uc\_code\_base}$ \5
+$(\\{lc\_code\_base}+\T{256}{}$)\C{table of 256 uppercase mappings}\par
+\B\4\D$\\{sf\_code\_base}$ \5
+$(\\{uc\_code\_base}+\T{256}{}$)\C{table of 256 spacefactor mappings}\par
+\B\4\D$\\{math\_code\_base}$ \5
+$(\\{sf\_code\_base}+\T{256}{}$)\C{table of 256 math mode mappings}\par
+\B\4\D$\\{int\_base}$ \5
+$(\\{math\_code\_base}+\T{256}{}$)\C{beginning of region 5}\Y\par
+\B\4\D$\\{par\_shape\_ptr}$ \5
+\\{equiv}(\\{par\_shape\_loc})\par
+\B\4\D$\\{output\_routine}$ \5
+\\{equiv}(\\{output\_routine\_loc})\par
+\B\4\D$\\{every\_par}$ \5
+\\{equiv}(\\{every\_par\_loc})\par
+\B\4\D$\\{every\_math}$ \5
+\\{equiv}(\\{every\_math\_loc})\par
+\B\4\D$\\{every\_display}$ \5
+\\{equiv}(\\{every\_display\_loc})\par
+\B\4\D$\\{every\_hbox}$ \5
+\\{equiv}(\\{every\_hbox\_loc})\par
+\B\4\D$\\{every\_vbox}$ \5
+\\{equiv}(\\{every\_vbox\_loc})\par
+\B\4\D$\\{every\_job}$ \5
+\\{equiv}(\\{every\_job\_loc})\par
+\B\4\D$\\{every\_cr}$ \5
+\\{equiv}(\\{every\_cr\_loc})\par
+\B\4\D$\\{err\_help}$ \5
+\\{equiv}(\\{err\_help\_loc})\par
+\B\4\D$\\{toks}(\|X)$ \5
+$\\{equiv}(\\{toks\_base}+\|X{}$)\par
+\B\4\D$\\{box}(\|X)$ \5
+$\\{equiv}(\\{box\_base}+\|X{}$)\par
+\B\4\D$\\{cur\_font}$ \5
+\\{equiv}(\\{cur\_font\_loc})\par
+\B\4\D$\\{fam\_fnt}(\|X)$ \5
+$\\{equiv}(\\{math\_font\_base}+\|X{}$)\par
+\B\4\D$\\{cat\_code}(\|X)$ \5
+$\\{equiv}(\\{cat\_code\_base}+\|X{}$)\par
+\B\4\D$\\{lc\_code}(\|X)$ \5
+$\\{equiv}(\\{lc\_code\_base}+\|X{}$)\par
+\B\4\D$\\{uc\_code}(\|X)$ \5
+$\\{equiv}(\\{uc\_code\_base}+\|X{}$)\par
+\B\4\D$\\{sf\_code}(\|X)$ \5
+$\\{equiv}(\\{sf\_code\_base}+\|X{}$)\par
+\B\4\D$\\{math\_code}(\|X)$ \5
+$\\{equiv}(\\{math\_code\_base}+\|X{}$)\C{Note: \\{math\_code}(\|c) is the true math code plus \\{min\_halfword}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1426:\.{"output"}\X,\39\\{assign\_toks},\39\\{output\_routine\_loc});{}$\5
+${}\\{primitive}(\X1427:\.{"everypar"}\X,\39\\{assign\_toks},\39\\{every\_par\_loc});{}$\5
+${}\\{primitive}(\X1428:\.{"everymath"}\X,\39\\{assign\_toks},\39\\{every\_math\_loc});{}$\5
+${}\\{primitive}(\X1429:\.{"everydisplay"}\X,\39\\{assign\_toks},\39\\{every\_display\_loc});{}$\5
+${}\\{primitive}(\X1430:\.{"everyhbox"}\X,\39\\{assign\_toks},\39\\{every\_hbox\_loc});{}$\5
+${}\\{primitive}(\X1431:\.{"everyvbox"}\X,\39\\{assign\_toks},\39\\{every\_vbox\_loc});{}$\5
+${}\\{primitive}(\X1432:\.{"everyjob"}\X,\39\\{assign\_toks},\39\\{every\_job\_loc});{}$\5
+${}\\{primitive}(\X1433:\.{"everycr"}\X,\39\\{assign\_toks},\39\\{every\_cr\_loc});{}$\5
+${}\\{primitive}(\X1434:\.{"errhelp"}\X,\39\\{assign\_toks},\39\\{err\_help\_loc}){}$;\par
+\fi
+
+\M{231}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_toks}:\6
+\&{if} ${}(\\{chr\_code}\G\\{toks\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1435:\.{"toks"}\X);\5
+${}\\{print\_int}(\\{chr\_code}-\\{toks\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{output\_routine\_loc}:\5
+\\{print\_esc}(\X1426:\.{"output"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_par\_loc}:\5
+\\{print\_esc}(\X1427:\.{"everypar"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_math\_loc}:\5
+\\{print\_esc}(\X1428:\.{"everymath"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_display\_loc}:\5
+\\{print\_esc}(\X1429:\.{"everydisplay"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_hbox\_loc}:\5
+\\{print\_esc}(\X1430:\.{"everyhbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_vbox\_loc}:\5
+\\{print\_esc}(\X1431:\.{"everyvbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_job\_loc}:\5
+\\{print\_esc}(\X1432:\.{"everyjob"}\X);\5
+\&{break};\6
+\4\&{case} \\{every\_cr\_loc}:\5
+\\{print\_esc}(\X1433:\.{"everycr"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1434:\.{"errhelp"}\X);\6
+\4${}\}{}$\5
+\2\2\&{break};\par
+\fi
+
+\M{232}We initialize most things to null or undefined values. An undefined font
+is represented by the internal code \\{font\_base}.
+
+However, the character code tables are given initial values based on the
+conventional interpretation of ASCII code. These initial values should
+not be changed when \TeX\ is adapted for use with non-English languages;
+all changes to the initialization conventions should be made in format
+packages, not in \TeX\ itself, so that global interchange of formats is
+possible.
+
+\Y\B\4\D$\\{null\_font}$ \5
+\\{font\_base}\par
+\B\4\D$\\{var\_code}$ \5
+\T{\~70000}\C{math code meaning ``use the current family''}\par
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{par\_shape\_ptr}\K\\{null};{}$\5
+${}\\{eq\_type}(\\{par\_shape\_loc})\K\\{shape\_ref};{}$\5
+${}\\{eq\_level}(\\{par\_shape\_loc})\K\\{level\_one}{}$;\6
+\&{for} ${}(\|k\K\\{output\_routine\_loc};{}$ ${}\|k\Z\\{toks\_base}+\T{255};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{undefined\_control\_sequence}];{}$\2\6
+${}\\{box}(\T{0})\K\\{null};{}$\5
+${}\\{eq\_type}(\\{box\_base})\K\\{box\_ref};{}$\5
+${}\\{eq\_level}(\\{box\_base})\K\\{level\_one};{}$\6
+\&{for} ${}(\|k\K\\{box\_base}+\T{1};{}$ ${}\|k\Z\\{box\_base}+\T{255};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{box\_base}];{}$\2\6
+${}\\{cur\_font}\K\\{null\_font};{}$\5
+${}\\{eq\_type}(\\{cur\_font\_loc})\K\\{data};{}$\5
+${}\\{eq\_level}(\\{cur\_font\_loc})\K\\{level\_one}{}$;\6
+\&{for} ${}(\|k\K\\{math\_font\_base};{}$ ${}\|k\Z\\{math\_font\_base}+\T{47};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{cur\_font\_loc}];{}$\2\6
+${}\\{equiv}(\\{cat\_code\_base})\K\T{0};{}$\5
+${}\\{eq\_type}(\\{cat\_code\_base})\K\\{data};{}$\5
+${}\\{eq\_level}(\\{cat\_code\_base})\K\\{level\_one}{}$;\6
+\&{for} ${}(\|k\K\\{cat\_code\_base}+\T{1};{}$ ${}\|k\Z\\{int\_base}-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k]\K\\{eqtb}[\\{cat\_code\_base}];{}$\2\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{255};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\\{cat\_code}(\|k)\K\\{other\_char};{}$\5
+${}\\{math\_code}(\|k)\K\\{hi}(\|k);{}$\5
+${}\\{sf\_code}(\|k)\K\T{1000};{}$\6
+\4${}\}{}$\2\6
+${}\\{cat\_code}(\\{carriage\_return})\K\\{car\_ret};{}$\5
+${}\\{cat\_code}(\.{'\ '})\K\\{spacer};{}$\5
+${}\\{cat\_code}(\.{'\\\\'})\K\\{escape};{}$\5
+${}\\{cat\_code}(\.{'\%'})\K\\{comment};{}$\5
+${}\\{cat\_code}(\\{invalid\_code})\K\\{invalid\_char};{}$\5
+${}\\{cat\_code}(\\{null\_code})\K\\{ignore};{}$\6
+\&{for} ${}(\|k\K\.{'0'};{}$ ${}\|k\Z\.{'9'};{}$ ${}\|k\PP){}$\1\5
+${}\\{math\_code}(\|k)\K\\{hi}(\|k+\\{var\_code});{}$\2\6
+\&{for} ${}(\|k\K\.{'A'};{}$ ${}\|k\Z\.{'Z'};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\\{cat\_code}(\|k)\K\\{letter};{}$\5
+${}\\{cat\_code}(\|k+\.{'a'}-\.{'A'})\K\\{letter}{}$;\6
+${}\\{math\_code}(\|k)\K\\{hi}(\|k+\\{var\_code}+\T{\^100});{}$\5
+${}\\{math\_code}(\|k+\.{'a'}-\.{'A'})\K\\{hi}(\|k+\.{'a'}-\.{'A'}+\\{var\_code}+\T{\^100}){}$;\6
+${}\\{lc\_code}(\|k)\K\|k+\.{'a'}-\.{'A'};{}$\5
+${}\\{lc\_code}(\|k+\.{'a'}-\.{'A'})\K\|k+\.{'a'}-\.{'A'}{}$;\6
+${}\\{uc\_code}(\|k)\K\|k;{}$\5
+${}\\{uc\_code}(\|k+\.{'a'}-\.{'A'})\K\|k{}$;\6
+${}\\{sf\_code}(\|k)\K\T{999};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{233}\B\X233:Show equivalent \|n, in region 4\X${}\E{}$\6
+\&{if} ${}(\|n\E\\{par\_shape\_loc}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1436:\.{"parshape"}\X);\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\1\5
+\\{print\_char}(\.{'0'});\2\6
+\&{else}\1\5
+\\{print\_int}(\\{info}(\\{par\_shape\_ptr}));\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{toks\_base}){}$\5
+${}\{{}$\5
+\1${}\\{print\_cmd\_chr}(\\{assign\_toks},\39\|n);{}$\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\\{equiv}(\|n)\I\\{null}){}$\1\5
+${}\\{show\_token\_list}(\\{link}(\\{equiv}(\|n)),\39\\{null},\39\T{32});{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{box\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1435:\.{"toks"}\X);\5
+${}\\{print\_int}(\|n-\\{toks\_base});{}$\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\\{equiv}(\|n)\I\\{null}){}$\1\5
+${}\\{show\_token\_list}(\\{link}(\\{equiv}(\|n)),\39\\{null},\39\T{32});{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{cur\_font\_loc}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1437:\.{"box"}\X);\5
+${}\\{print\_int}(\|n-\\{box\_base});{}$\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\\{equiv}(\|n)\E\\{null}){}$\1\5
+\\{print\_str}(\.{"void"});\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{depth\_threshold}\K\T{0};{}$\5
+${}\\{breadth\_max}\K\T{1};{}$\5
+\\{show\_node\_list}(\\{equiv}(\|n));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{cat\_code\_base}){}$\1\5
+\X234:Show the font identifier in \\{eqtb}[\|n]\X\2\6
+\&{else}\1\5
+\X235:Show the halfword code in \\{eqtb}[\|n]\X\2\par
+\U252.\fi
+
+\M{234}\B\X234:Show the font identifier in \\{eqtb}[\|n]\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|n\E\\{cur\_font\_loc}){}$\1\5
+\\{print\_str}(\.{"current\ font"});\2\6
+\&{else} \&{if} ${}(\|n<\\{math\_font\_base}+\T{16}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1438:\.{"textfont"}\X);\5
+${}\\{print\_int}(\|n-\\{math\_font\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{math\_font\_base}+\T{32}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1439:\.{"scriptfont"}\X);\5
+${}\\{print\_int}(\|n-\\{math\_font\_base}-\T{16});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1440:\.{"scriptscriptfont"}\X);\5
+${}\\{print\_int}(\|n-\\{math\_font\_base}-\T{32});{}$\6
+\4${}\}{}$\2\6
+\\{print\_char}(\.{'='});\6
+${}\\{print\_esc}(\\{hash}[\\{font\_id\_base}+\\{equiv}(\|n)].\\{rh}){}$;\C{that's \\{font\_id\_text}(\\{equiv}(\|n))}\6
+\4${}\}{}$\2\par
+\U233.\fi
+
+\M{235}\B\X235:Show the halfword code in \\{eqtb}[\|n]\X${}\E{}$\6
+\&{if} ${}(\|n<\\{math\_code\_base}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|n<\\{lc\_code\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1441:\.{"catcode"}\X);\5
+${}\\{print\_int}(\|n-\\{cat\_code\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{uc\_code\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1442:\.{"lccode"}\X);\5
+${}\\{print\_int}(\|n-\\{lc\_code\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{sf\_code\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1443:\.{"uccode"}\X);\5
+${}\\{print\_int}(\|n-\\{uc\_code\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1444:\.{"sfcode"}\X);\5
+${}\\{print\_int}(\|n-\\{sf\_code\_base});{}$\6
+\4${}\}{}$\2\6
+\\{print\_char}(\.{'='});\5
+\\{print\_int}(\\{equiv}(\|n));\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1445:\.{"mathcode"}\X);\5
+${}\\{print\_int}(\|n-\\{math\_code\_base});{}$\5
+\\{print\_char}(\.{'='});\5
+\\{print\_int}(\\{ho}(\\{equiv}(\|n)));\6
+\4${}\}{}$\2\par
+\U233.\fi
+
+\M{236}Region 5 of \\{eqtb} contains the integer parameters and registers defined
+here, as well as the \\{del\_code} table. The latter table differs from the
+$\\{cat\_code}\dotdot\\{math\_code}$ tables that precede it, since delimiter codes are
+fullword integers while the other kinds of codes occupy at most a
+halfword. This is what makes region~5 different from region~4. We will
+store the \\{eq\_level} information in an auxiliary array of quarterwords
+that will be defined later.
+
+\Y\B\4\D$\\{pretolerance\_code}$ \5
+\T{0}\C{badness tolerance before hyphenation}\par
+\B\4\D$\\{tolerance\_code}$ \5
+\T{1}\C{badness tolerance after hyphenation}\par
+\B\4\D$\\{line\_penalty\_code}$ \5
+\T{2}\C{added to the badness of every line}\par
+\B\4\D$\\{hyphen\_penalty\_code}$ \5
+\T{3}\C{penalty for break after discretionary hyphen}\par
+\B\4\D$\\{ex\_hyphen\_penalty\_code}$ \5
+\T{4}\C{penalty for break after explicit hyphen}\par
+\B\4\D$\\{club\_penalty\_code}$ \5
+\T{5}\C{penalty for creating a club line}\par
+\B\4\D$\\{widow\_penalty\_code}$ \5
+\T{6}\C{penalty for creating a widow line}\par
+\B\4\D$\\{display\_widow\_penalty\_code}$ \5
+\T{7}\C{ditto, just before a display}\par
+\B\4\D$\\{broken\_penalty\_code}$ \5
+\T{8}\C{penalty for breaking a page at a broken line}\par
+\B\4\D$\\{bin\_op\_penalty\_code}$ \5
+\T{9}\C{penalty for breaking after a binary operation}\par
+\B\4\D$\\{rel\_penalty\_code}$ \5
+\T{10}\C{penalty for breaking after a relation}\par
+\B\4\D$\\{pre\_display\_penalty\_code}$ \5
+\T{11}\C{penalty for breaking just before a displayed formula}\par
+\B\4\D$\\{post\_display\_penalty\_code}$ \5
+\T{12}\C{penalty for breaking just after a displayed formula}\par
+\B\4\D$\\{inter\_line\_penalty\_code}$ \5
+\T{13}\C{additional penalty between lines}\par
+\B\4\D$\\{double\_hyphen\_demerits\_code}$ \5
+\T{14}\C{demerits for double hyphen break}\par
+\B\4\D$\\{final\_hyphen\_demerits\_code}$ \5
+\T{15}\C{demerits for final hyphen break}\par
+\B\4\D$\\{adj\_demerits\_code}$ \5
+\T{16}\C{demerits for adjacent incompatible lines}\par
+\B\4\D$\\{mag\_code}$ \5
+\T{17}\C{magnification ratio}\par
+\B\4\D$\\{delimiter\_factor\_code}$ \5
+\T{18}\C{ratio for variable-size delimiters}\par
+\B\4\D$\\{looseness\_code}$ \5
+\T{19}\C{change in number of lines for a paragraph}\par
+\B\4\D$\\{time\_code}$ \5
+\T{20}\C{current time of day}\par
+\B\4\D$\\{day\_code}$ \5
+\T{21}\C{current day of the month}\par
+\B\4\D$\\{month\_code}$ \5
+\T{22}\C{current month of the year}\par
+\B\4\D$\\{year\_code}$ \5
+\T{23}\C{current year of our Lord}\par
+\B\4\D$\\{show\_box\_breadth\_code}$ \5
+\T{24}\C{nodes per level in \\{show\_box}}\par
+\B\4\D$\\{show\_box\_depth\_code}$ \5
+\T{25}\C{maximum level in \\{show\_box}}\par
+\B\4\D$\\{hbadness\_code}$ \5
+\T{26}\C{hboxes exceeding this badness will be shown by \\{hpack}}\par
+\B\4\D$\\{vbadness\_code}$ \5
+\T{27}\C{vboxes exceeding this badness will be shown by \\{vpack}}\par
+\B\4\D$\\{pausing\_code}$ \5
+\T{28}\C{pause after each line is read from a file}\par
+\B\4\D$\\{tracing\_online\_code}$ \5
+\T{29}\C{show diagnostic output on terminal}\par
+\B\4\D$\\{tracing\_macros\_code}$ \5
+\T{30}\C{show macros as they are being expanded}\par
+\B\4\D$\\{tracing\_stats\_code}$ \5
+\T{31}\C{show memory usage if \TeX\ knows it}\par
+\B\4\D$\\{tracing\_paragraphs\_code}$ \5
+\T{32}\C{show line-break calculations}\par
+\B\4\D$\\{tracing\_pages\_code}$ \5
+\T{33}\C{show page-break calculations}\par
+\B\4\D$\\{tracing\_output\_code}$ \5
+\T{34}\C{show boxes when they are shipped out}\par
+\B\4\D$\\{tracing\_lost\_chars\_code}$ \5
+\T{35}\C{show characters that aren't in the font}\par
+\B\4\D$\\{tracing\_commands\_code}$ \5
+\T{36}\C{show command codes at \\{big\_switch}}\par
+\B\4\D$\\{tracing\_restores\_code}$ \5
+\T{37}\C{show equivalents when they are restored}\par
+\B\4\D$\\{uc\_hyph\_code}$ \5
+\T{38}\C{hyphenate words beginning with a capital letter}\par
+\B\4\D$\\{output\_penalty\_code}$ \5
+\T{39}\C{penalty found at current page break}\par
+\B\4\D$\\{max\_dead\_cycles\_code}$ \5
+\T{40}\C{bound on consecutive dead cycles of output}\par
+\B\4\D$\\{hang\_after\_code}$ \5
+\T{41}\C{hanging indentation changes after this many lines}\par
+\B\4\D$\\{floating\_penalty\_code}$ \5
+\T{42}\C{penalty for insertions heldover after a split}\par
+\B\4\D$\\{global\_defs\_code}$ \5
+\T{43}\C{override \.{\\global} specifications}\par
+\B\4\D$\\{cur\_fam\_code}$ \5
+\T{44}\C{current family}\par
+\B\4\D$\\{escape\_char\_code}$ \5
+\T{45}\C{escape character for token output}\par
+\B\4\D$\\{default\_hyphen\_char\_code}$ \5
+\T{46}\C{value of \.{\\hyphenchar} when a font is loaded}\par
+\B\4\D$\\{default\_skew\_char\_code}$ \5
+\T{47}\C{value of \.{\\skewchar} when a font is loaded}\par
+\B\4\D$\\{end\_line\_char\_code}$ \5
+\T{48}\C{character placed at the right end of the buffer}\par
+\B\4\D$\\{new\_line\_char\_code}$ \5
+\T{49}\C{character that prints as \\{print\_ln}}\par
+\B\4\D$\\{language\_code}$ \5
+\T{50}\C{current hyphenation table}\par
+\B\4\D$\\{left\_hyphen\_min\_code}$ \5
+\T{51}\C{minimum left hyphenation fragment size}\par
+\B\4\D$\\{right\_hyphen\_min\_code}$ \5
+\T{52}\C{minimum right hyphenation fragment size}\par
+\B\4\D$\\{holding\_inserts\_code}$ \5
+\T{53}\C{do not remove insertion nodes from \.{\\box255}}\par
+\B\4\D$\\{error\_context\_lines\_code}$ \5
+\T{54}\C{maximum intermediate line pairs shown}\par
+\B\4\D$\\{int\_pars}$ \5
+\T{55}\C{total number of integer parameters}\par
+\B\4\D$\\{count\_base}$ \5
+$(\\{int\_base}+\\{int\_pars}{}$)\C{256 user \.{\\count} registers}\par
+\B\4\D$\\{del\_code\_base}$ \5
+$(\\{count\_base}+\T{256}{}$)\C{256 delimiter code mappings}\par
+\B\4\D$\\{dimen\_base}$ \5
+$(\\{del\_code\_base}+\T{256}{}$)\C{beginning of region 6}\Y\par
+\B\4\D$\\{del\_code}(\|X)$ \5
+$\\{eqtb}[\\{del\_code\_base}+\|X].{}$\|i\par
+\B\4\D$\\{count}(\|X)$ \5
+$\\{eqtb}[\\{count\_base}+\|X].{}$\|i\par
+\B\4\D$\\{int\_par}(\|X)$ \5
+$\\{eqtb}[\\{int\_base}+\|X].{}$\|i\C{an integer parameter}\par
+\B\4\D$\\{pretolerance}$ \5
+\\{int\_par}(\\{pretolerance\_code})\par
+\B\4\D$\\{tolerance}$ \5
+\\{int\_par}(\\{tolerance\_code})\par
+\B\4\D$\\{line\_penalty}$ \5
+\\{int\_par}(\\{line\_penalty\_code})\par
+\B\4\D$\\{hyphen\_penalty}$ \5
+\\{int\_par}(\\{hyphen\_penalty\_code})\par
+\B\4\D$\\{ex\_hyphen\_penalty}$ \5
+\\{int\_par}(\\{ex\_hyphen\_penalty\_code})\par
+\B\4\D$\\{club\_penalty}$ \5
+\\{int\_par}(\\{club\_penalty\_code})\par
+\B\4\D$\\{widow\_penalty}$ \5
+\\{int\_par}(\\{widow\_penalty\_code})\par
+\B\4\D$\\{display\_widow\_penalty}$ \5
+\\{int\_par}(\\{display\_widow\_penalty\_code})\par
+\B\4\D$\\{broken\_penalty}$ \5
+\\{int\_par}(\\{broken\_penalty\_code})\par
+\B\4\D$\\{bin\_op\_penalty}$ \5
+\\{int\_par}(\\{bin\_op\_penalty\_code})\par
+\B\4\D$\\{rel\_penalty}$ \5
+\\{int\_par}(\\{rel\_penalty\_code})\par
+\B\4\D$\\{pre\_display\_penalty}$ \5
+\\{int\_par}(\\{pre\_display\_penalty\_code})\par
+\B\4\D$\\{post\_display\_penalty}$ \5
+\\{int\_par}(\\{post\_display\_penalty\_code})\par
+\B\4\D$\\{inter\_line\_penalty}$ \5
+\\{int\_par}(\\{inter\_line\_penalty\_code})\par
+\B\4\D$\\{double\_hyphen\_demerits}$ \5
+\\{int\_par}(\\{double\_hyphen\_demerits\_code})\par
+\B\4\D$\\{final\_hyphen\_demerits}$ \5
+\\{int\_par}(\\{final\_hyphen\_demerits\_code})\par
+\B\4\D$\\{adj\_demerits}$ \5
+\\{int\_par}(\\{adj\_demerits\_code})\par
+\B\4\D$\\{mag}$ \5
+\\{int\_par}(\\{mag\_code})\par
+\B\4\D$\\{delimiter\_factor}$ \5
+\\{int\_par}(\\{delimiter\_factor\_code})\par
+\B\4\D$\\{looseness}$ \5
+\\{int\_par}(\\{looseness\_code})\par
+\B\4\D$\\{time}$ \5
+\\{int\_par}(\\{time\_code})\par
+\B\4\D$\\{day}$ \5
+\\{int\_par}(\\{day\_code})\par
+\B\4\D$\\{month}$ \5
+\\{int\_par}(\\{month\_code})\par
+\B\4\D$\\{year}$ \5
+\\{int\_par}(\\{year\_code})\par
+\B\4\D$\\{show\_box\_breadth}$ \5
+\\{int\_par}(\\{show\_box\_breadth\_code})\par
+\B\4\D$\\{show\_box\_depth}$ \5
+\\{int\_par}(\\{show\_box\_depth\_code})\par
+\B\4\D$\\{hbadness}$ \5
+\\{int\_par}(\\{hbadness\_code})\par
+\B\4\D$\\{vbadness}$ \5
+\\{int\_par}(\\{vbadness\_code})\par
+\B\4\D$\\{pausing}$ \5
+\\{int\_par}(\\{pausing\_code})\par
+\B\4\D$\\{tracing\_online}$ \5
+\\{int\_par}(\\{tracing\_online\_code})\par
+\B\4\D$\\{tracing\_macros}$ \5
+\\{int\_par}(\\{tracing\_macros\_code})\par
+\B\4\D$\\{tracing\_stats}$ \5
+\\{int\_par}(\\{tracing\_stats\_code})\par
+\B\4\D$\\{tracing\_paragraphs}$ \5
+\\{int\_par}(\\{tracing\_paragraphs\_code})\par
+\B\4\D$\\{tracing\_pages}$ \5
+\\{int\_par}(\\{tracing\_pages\_code})\par
+\B\4\D$\\{tracing\_output}$ \5
+\\{int\_par}(\\{tracing\_output\_code})\par
+\B\4\D$\\{tracing\_lost\_chars}$ \5
+\\{int\_par}(\\{tracing\_lost\_chars\_code})\par
+\B\4\D$\\{tracing\_commands}$ \5
+\\{int\_par}(\\{tracing\_commands\_code})\par
+\B\4\D$\\{tracing\_restores}$ \5
+\\{int\_par}(\\{tracing\_restores\_code})\par
+\B\4\D$\\{uc\_hyph}$ \5
+\\{int\_par}(\\{uc\_hyph\_code})\par
+\B\4\D$\\{output\_penalty}$ \5
+\\{int\_par}(\\{output\_penalty\_code})\par
+\B\4\D$\\{max\_dead\_cycles}$ \5
+\\{int\_par}(\\{max\_dead\_cycles\_code})\par
+\B\4\D$\\{hang\_after}$ \5
+\\{int\_par}(\\{hang\_after\_code})\par
+\B\4\D$\\{floating\_penalty}$ \5
+\\{int\_par}(\\{floating\_penalty\_code})\par
+\B\4\D$\\{global\_defs}$ \5
+\\{int\_par}(\\{global\_defs\_code})\par
+\B\4\D$\\{cur\_fam}$ \5
+\\{int\_par}(\\{cur\_fam\_code})\par
+\B\4\D$\\{escape\_char}$ \5
+\\{int\_par}(\\{escape\_char\_code})\par
+\B\4\D$\\{default\_hyphen\_char}$ \5
+\\{int\_par}(\\{default\_hyphen\_char\_code})\par
+\B\4\D$\\{default\_skew\_char}$ \5
+\\{int\_par}(\\{default\_skew\_char\_code})\par
+\B\4\D$\\{end\_line\_char}$ \5
+\\{int\_par}(\\{end\_line\_char\_code})\par
+\B\4\D$\\{new\_line\_char}$ \5
+\\{int\_par}(\\{new\_line\_char\_code})\par
+\B\4\D$\\{language}$ \5
+\\{int\_par}(\\{language\_code})\par
+\B\4\D$\\{left\_hyphen\_min}$ \5
+\\{int\_par}(\\{left\_hyphen\_min\_code})\par
+\B\4\D$\\{right\_hyphen\_min}$ \5
+\\{int\_par}(\\{right\_hyphen\_min\_code})\par
+\B\4\D$\\{holding\_inserts}$ \5
+\\{int\_par}(\\{holding\_inserts\_code})\par
+\B\4\D$\\{error\_context\_lines}$ \5
+\\{int\_par}(\\{error\_context\_lines\_code})\par
+\Y\B\4\X236:Assign the values \\{depth\_threshold}: $\K$ \\{show\_box\_depth} and \\{breadth\_max}: $\K$ \\{show\_box\_breadth}\X${}\E{}$\6
+$\\{depth\_threshold}\K\\{show\_box\_depth};$ $\\{breadth\_max}\K{}$\\{show\_box\_breadth}\par
+\U198.\fi
+
+\M{237}We can print the symbolic name of an integer parameter as follows.
+
+\Y\B\&{void} \\{print\_param}(\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{switch} (\|n)\5
+${}\{{}$\1\6
+\4\&{case} \\{pretolerance\_code}:\5
+\\{print\_esc}(\X1446:\.{"pretolerance"}\X);\5
+\&{break};\6
+\4\&{case} \\{tolerance\_code}:\5
+\\{print\_esc}(\X1447:\.{"tolerance"}\X);\5
+\&{break};\6
+\4\&{case} \\{line\_penalty\_code}:\5
+\\{print\_esc}(\X1448:\.{"linepenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{hyphen\_penalty\_code}:\5
+\\{print\_esc}(\X1449:\.{"hyphenpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{ex\_hyphen\_penalty\_code}:\5
+\\{print\_esc}(\X1450:\.{"exhyphenpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{club\_penalty\_code}:\5
+\\{print\_esc}(\X1451:\.{"clubpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{widow\_penalty\_code}:\5
+\\{print\_esc}(\X1452:\.{"widowpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{display\_widow\_penalty\_code}:\5
+\\{print\_esc}(\X1453:\.{"displaywidowpenalty}\)\.{"}\X);\5
+\&{break};\6
+\4\&{case} \\{broken\_penalty\_code}:\5
+\\{print\_esc}(\X1454:\.{"brokenpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{bin\_op\_penalty\_code}:\5
+\\{print\_esc}(\X1455:\.{"binoppenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{rel\_penalty\_code}:\5
+\\{print\_esc}(\X1456:\.{"relpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{pre\_display\_penalty\_code}:\5
+\\{print\_esc}(\X1457:\.{"predisplaypenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{post\_display\_penalty\_code}:\5
+\\{print\_esc}(\X1458:\.{"postdisplaypenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{inter\_line\_penalty\_code}:\5
+\\{print\_esc}(\X1459:\.{"interlinepenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{double\_hyphen\_demerits\_code}:\5
+\\{print\_esc}(\X1460:\.{"doublehyphendemerit}\)\.{s"}\X);\5
+\&{break};\6
+\4\&{case} \\{final\_hyphen\_demerits\_code}:\5
+\\{print\_esc}(\X1461:\.{"finalhyphendemerits}\)\.{"}\X);\5
+\&{break};\6
+\4\&{case} \\{adj\_demerits\_code}:\5
+\\{print\_esc}(\X1462:\.{"adjdemerits"}\X);\5
+\&{break};\6
+\4\&{case} \\{mag\_code}:\5
+\\{print\_esc}(\X1463:\.{"mag"}\X);\5
+\&{break};\6
+\4\&{case} \\{delimiter\_factor\_code}:\5
+\\{print\_esc}(\X1464:\.{"delimiterfactor"}\X);\5
+\&{break};\6
+\4\&{case} \\{looseness\_code}:\5
+\\{print\_esc}(\X1465:\.{"looseness"}\X);\5
+\&{break};\6
+\4\&{case} \\{time\_code}:\5
+\\{print\_esc}(\X1466:\.{"time"}\X);\5
+\&{break};\6
+\4\&{case} \\{day\_code}:\5
+\\{print\_esc}(\X1467:\.{"day"}\X);\5
+\&{break};\6
+\4\&{case} \\{month\_code}:\5
+\\{print\_esc}(\X1468:\.{"month"}\X);\5
+\&{break};\6
+\4\&{case} \\{year\_code}:\5
+\\{print\_esc}(\X1469:\.{"year"}\X);\5
+\&{break};\6
+\4\&{case} \\{show\_box\_breadth\_code}:\5
+\\{print\_esc}(\X1470:\.{"showboxbreadth"}\X);\5
+\&{break};\6
+\4\&{case} \\{show\_box\_depth\_code}:\5
+\\{print\_esc}(\X1471:\.{"showboxdepth"}\X);\5
+\&{break};\6
+\4\&{case} \\{hbadness\_code}:\5
+\\{print\_esc}(\X1472:\.{"hbadness"}\X);\5
+\&{break};\6
+\4\&{case} \\{vbadness\_code}:\5
+\\{print\_esc}(\X1473:\.{"vbadness"}\X);\5
+\&{break};\6
+\4\&{case} \\{pausing\_code}:\5
+\\{print\_esc}(\X1474:\.{"pausing"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_online\_code}:\5
+\\{print\_esc}(\X1475:\.{"tracingonline"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_macros\_code}:\5
+\\{print\_esc}(\X1476:\.{"tracingmacros"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_stats\_code}:\5
+\\{print\_esc}(\X1477:\.{"tracingstats"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_paragraphs\_code}:\5
+\\{print\_esc}(\X1478:\.{"tracingparagraphs"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_pages\_code}:\5
+\\{print\_esc}(\X1479:\.{"tracingpages"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_output\_code}:\5
+\\{print\_esc}(\X1480:\.{"tracingoutput"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_lost\_chars\_code}:\5
+\\{print\_esc}(\X1481:\.{"tracinglostchars"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_commands\_code}:\5
+\\{print\_esc}(\X1482:\.{"tracingcommands"}\X);\5
+\&{break};\6
+\4\&{case} \\{tracing\_restores\_code}:\5
+\\{print\_esc}(\X1483:\.{"tracingrestores"}\X);\5
+\&{break};\6
+\4\&{case} \\{uc\_hyph\_code}:\5
+\\{print\_esc}(\X1484:\.{"uchyph"}\X);\5
+\&{break};\6
+\4\&{case} \\{output\_penalty\_code}:\5
+\\{print\_esc}(\X1485:\.{"outputpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{max\_dead\_cycles\_code}:\5
+\\{print\_esc}(\X1486:\.{"maxdeadcycles"}\X);\5
+\&{break};\6
+\4\&{case} \\{hang\_after\_code}:\5
+\\{print\_esc}(\X1487:\.{"hangafter"}\X);\5
+\&{break};\6
+\4\&{case} \\{floating\_penalty\_code}:\5
+\\{print\_esc}(\X1488:\.{"floatingpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{global\_defs\_code}:\5
+\\{print\_esc}(\X1489:\.{"globaldefs"}\X);\5
+\&{break};\6
+\4\&{case} \\{cur\_fam\_code}:\5
+\\{print\_esc}(\X1490:\.{"fam"}\X);\5
+\&{break};\6
+\4\&{case} \\{escape\_char\_code}:\5
+\\{print\_esc}(\X1491:\.{"escapechar"}\X);\5
+\&{break};\6
+\4\&{case} \\{default\_hyphen\_char\_code}:\5
+\\{print\_esc}(\X1492:\.{"defaulthyphenchar"}\X);\5
+\&{break};\6
+\4\&{case} \\{default\_skew\_char\_code}:\5
+\\{print\_esc}(\X1493:\.{"defaultskewchar"}\X);\5
+\&{break};\6
+\4\&{case} \\{end\_line\_char\_code}:\5
+\\{print\_esc}(\X1494:\.{"endlinechar"}\X);\5
+\&{break};\6
+\4\&{case} \\{new\_line\_char\_code}:\5
+\\{print\_esc}(\X1495:\.{"newlinechar"}\X);\5
+\&{break};\6
+\4\&{case} \\{language\_code}:\5
+\\{print\_esc}(\X1496:\.{"language"}\X);\5
+\&{break};\6
+\4\&{case} \\{left\_hyphen\_min\_code}:\5
+\\{print\_esc}(\X1497:\.{"lefthyphenmin"}\X);\5
+\&{break};\6
+\4\&{case} \\{right\_hyphen\_min\_code}:\5
+\\{print\_esc}(\X1498:\.{"righthyphenmin"}\X);\5
+\&{break};\6
+\4\&{case} \\{holding\_inserts\_code}:\5
+\\{print\_esc}(\X1499:\.{"holdinginserts"}\X);\5
+\&{break};\6
+\4\&{case} \\{error\_context\_lines\_code}:\5
+\\{print\_esc}(\X1500:\.{"errorcontextlines"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_str}(\.{"[unknown\ integer\ pa}\)\.{rameter!]"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{238}The integer parameter names must be entered into the hash table.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1446:\.{"pretolerance"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{pretolerance\_code}){}$;\6
+${}\\{primitive}(\X1447:\.{"tolerance"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tolerance\_code}){}$;\6
+${}\\{primitive}(\X1448:\.{"linepenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{line\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1449:\.{"hyphenpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{hyphen\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1450:\.{"exhyphenpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{ex\_hyphen\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1451:\.{"clubpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{club\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1452:\.{"widowpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{widow\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1453:\.{"displaywidowpenalty}\)\.{"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{display\_widow\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1454:\.{"brokenpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{broken\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1455:\.{"binoppenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{bin\_op\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1456:\.{"relpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{rel\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1457:\.{"predisplaypenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{pre\_display\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1458:\.{"postdisplaypenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{post\_display\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1459:\.{"interlinepenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{inter\_line\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1460:\.{"doublehyphendemerit}\)\.{s"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{double\_hyphen\_demerits\_code}){}$;\6
+${}\\{primitive}(\X1461:\.{"finalhyphendemerits}\)\.{"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{final\_hyphen\_demerits\_code}){}$;\6
+${}\\{primitive}(\X1462:\.{"adjdemerits"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{adj\_demerits\_code}){}$;\6
+${}\\{primitive}(\X1463:\.{"mag"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{mag\_code}){}$;\6
+${}\\{primitive}(\X1464:\.{"delimiterfactor"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{delimiter\_factor\_code}){}$;\6
+${}\\{primitive}(\X1465:\.{"looseness"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{looseness\_code}){}$;\6
+${}\\{primitive}(\X1466:\.{"time"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{time\_code}){}$;\6
+${}\\{primitive}(\X1467:\.{"day"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{day\_code}){}$;\6
+${}\\{primitive}(\X1468:\.{"month"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{month\_code}){}$;\6
+${}\\{primitive}(\X1469:\.{"year"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{year\_code}){}$;\6
+${}\\{primitive}(\X1470:\.{"showboxbreadth"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{show\_box\_breadth\_code}){}$;\6
+${}\\{primitive}(\X1471:\.{"showboxdepth"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{show\_box\_depth\_code}){}$;\6
+${}\\{primitive}(\X1472:\.{"hbadness"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{hbadness\_code}){}$;\6
+${}\\{primitive}(\X1473:\.{"vbadness"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{vbadness\_code}){}$;\6
+${}\\{primitive}(\X1474:\.{"pausing"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{pausing\_code}){}$;\6
+${}\\{primitive}(\X1475:\.{"tracingonline"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_online\_code}){}$;\6
+${}\\{primitive}(\X1476:\.{"tracingmacros"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_macros\_code}){}$;\6
+${}\\{primitive}(\X1477:\.{"tracingstats"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_stats\_code}){}$;\6
+${}\\{primitive}(\X1478:\.{"tracingparagraphs"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_paragraphs\_code}){}$;\6
+${}\\{primitive}(\X1479:\.{"tracingpages"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_pages\_code}){}$;\6
+${}\\{primitive}(\X1480:\.{"tracingoutput"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_output\_code}){}$;\6
+${}\\{primitive}(\X1481:\.{"tracinglostchars"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_lost\_chars\_code}){}$;\6
+${}\\{primitive}(\X1482:\.{"tracingcommands"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_commands\_code}){}$;\6
+${}\\{primitive}(\X1483:\.{"tracingrestores"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{tracing\_restores\_code}){}$;\6
+${}\\{primitive}(\X1484:\.{"uchyph"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{uc\_hyph\_code}){}$;\6
+${}\\{primitive}(\X1485:\.{"outputpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{output\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1486:\.{"maxdeadcycles"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{max\_dead\_cycles\_code}){}$;\6
+${}\\{primitive}(\X1487:\.{"hangafter"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{hang\_after\_code}){}$;\6
+${}\\{primitive}(\X1488:\.{"floatingpenalty"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{floating\_penalty\_code}){}$;\6
+${}\\{primitive}(\X1489:\.{"globaldefs"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{global\_defs\_code}){}$;\6
+${}\\{primitive}(\X1490:\.{"fam"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{cur\_fam\_code}){}$;\6
+${}\\{primitive}(\X1491:\.{"escapechar"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{escape\_char\_code}){}$;\6
+${}\\{primitive}(\X1492:\.{"defaulthyphenchar"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{default\_hyphen\_char\_code}){}$;\6
+${}\\{primitive}(\X1493:\.{"defaultskewchar"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{default\_skew\_char\_code}){}$;\6
+${}\\{primitive}(\X1494:\.{"endlinechar"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{end\_line\_char\_code}){}$;\6
+${}\\{primitive}(\X1495:\.{"newlinechar"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{new\_line\_char\_code}){}$;\6
+${}\\{primitive}(\X1496:\.{"language"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{language\_code}){}$;\6
+${}\\{primitive}(\X1497:\.{"lefthyphenmin"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{left\_hyphen\_min\_code}){}$;\6
+${}\\{primitive}(\X1498:\.{"righthyphenmin"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{right\_hyphen\_min\_code}){}$;\6
+${}\\{primitive}(\X1499:\.{"holdinginserts"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{holding\_inserts\_code}){}$;\6
+${}\\{primitive}(\X1500:\.{"errorcontextlines"}\X,\39\\{assign\_int},\39\\{int\_base}+\\{error\_context\_lines\_code}){}$;\par
+\fi
+
+\M{239}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_int}:\6
+\&{if} ${}(\\{chr\_code}<\\{count\_base}){}$\1\5
+${}\\{print\_param}(\\{chr\_code}-\\{int\_base});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1501:\.{"count"}\X);\5
+${}\\{print\_int}(\\{chr\_code}-\\{count\_base});{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{240}The integer parameters should really be initialized by a macro package;
+the following initialization does the minimum to keep \TeX\ from
+complete failure.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\\{int\_base};{}$ ${}\|k\Z\\{del\_code\_base}-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k].\|i\K\T{0};{}$\2\6
+${}\\{mag}\K\T{1000};{}$\5
+${}\\{tolerance}\K\T{10000};{}$\5
+${}\\{hang\_after}\K\T{1};{}$\5
+${}\\{max\_dead\_cycles}\K\T{25};{}$\5
+${}\\{escape\_char}\K\.{'\\\\'};{}$\5
+${}\\{end\_line\_char}\K\\{carriage\_return};{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{255};{}$ ${}\|k\PP){}$\1\5
+${}\\{del\_code}(\|k)\K{-}\T{1};{}$\2\6
+${}\\{del\_code}(\.{'.'})\K\T{0}{}$;\C{this null delimiter is used in error recovery}\par
+\fi
+
+\M{241}The following procedure, which is called just before \TeX\ initializes its
+input and output, establishes the initial values of the date and time.
+Since standard \PASCAL\ cannot provide such information, something special
+is needed. The program here simply specifies July 4, 1776, at noon; but
+users probably want a better approximation to the truth.
+
+\Y\B\&{void} \\{fix\_date\_and\_time}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{time}\K\T{12}*\T{60}{}$;\C{minutes since midnight}\6
+${}\\{day}\K\T{4}{}$;\C{fourth day of the month}\6
+${}\\{month}\K\T{7}{}$;\C{seventh month of the year}\6
+${}\\{year}\K\T{1776}{}$;\C{Anno Domini}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{242}\B\X242:Show equivalent \|n, in region 5\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|n<\\{count\_base}){}$\1\5
+${}\\{print\_param}(\|n-\\{int\_base});{}$\2\6
+\&{else} \&{if} ${}(\|n<\\{del\_code\_base}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1501:\.{"count"}\X);\5
+${}\\{print\_int}(\|n-\\{count\_base});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1502:\.{"delcode"}\X);\5
+${}\\{print\_int}(\|n-\\{del\_code\_base});{}$\6
+\4${}\}{}$\2\6
+\\{print\_char}(\.{'='});\5
+${}\\{print\_int}(\\{eqtb}[\|n].\|i);{}$\6
+\4${}\}{}$\2\par
+\U252.\fi
+
+\M{243}\B\X243:Set variable \|c to the current escape character\X${}\E{}$\6
+$\|c\K{}$\\{escape\_char}\par
+\U63.\fi
+
+\M{244}\B\X244:Character \|s is the current new-line character\X${}\E{}$\6
+$\|s\E{}$\\{new\_line\_char}\par
+\Us58\ET59.\fi
+
+\M{245}\TeX\ is occasionally supposed to print diagnostic information that
+goes only into the transcript file, unless \\{tracing\_online} is positive.
+Here are two routines that adjust the destination of print commands:
+
+\Y\B\&{void} \\{begin\_diagnostic}(\&{void})\C{prepare to do some tracing}\6
+${}\{{}$\5
+\1${}\\{old\_setting}\K\\{selector};{}$\6
+\&{if} ${}((\\{tracing\_online}\Z\T{0})\W(\\{selector}\E\\{term\_and\_log})){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{selector});\6
+\&{if} ${}(\\{history}\E\\{spotless}){}$\1\5
+${}\\{history}\K\\{warning\_issued};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\7
+\&{void} \\{end\_diagnostic}(\&{bool} \\{blank\_line})\C{restore proper conditions after tracing}\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{""});\6
+\&{if} (\\{blank\_line})\1\5
+\\{print\_ln}(\,);\2\6
+${}\\{selector}\K\\{old\_setting};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{246}Of course we had better declare another global variable, if the previous
+routines are going to work.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{old\_setting};\par
+\fi
+
+\M{247}The final region of \\{eqtb} contains the dimension parameters defined
+here, and the 256 \.{\\dimen} registers.
+
+\Y\B\4\D$\\{par\_indent\_code}$ \5
+\T{0}\C{indentation of paragraphs}\par
+\B\4\D$\\{math\_surround\_code}$ \5
+\T{1}\C{space around math in text}\par
+\B\4\D$\\{line\_skip\_limit\_code}$ \5
+\T{2}\C{threshold for \\{line\_skip} instead of \\{baseline\_skip}}\par
+\B\4\D$\\{hsize\_code}$ \5
+\T{3}\C{line width in horizontal mode}\par
+\B\4\D$\\{vsize\_code}$ \5
+\T{4}\C{page height in vertical mode}\par
+\B\4\D$\\{max\_depth\_code}$ \5
+\T{5}\C{maximum depth of boxes on main pages}\par
+\B\4\D$\\{split\_max\_depth\_code}$ \5
+\T{6}\C{maximum depth of boxes on split pages}\par
+\B\4\D$\\{box\_max\_depth\_code}$ \5
+\T{7}\C{maximum depth of explicit vboxes}\par
+\B\4\D$\\{hfuzz\_code}$ \5
+\T{8}\C{tolerance for overfull hbox messages}\par
+\B\4\D$\\{vfuzz\_code}$ \5
+\T{9}\C{tolerance for overfull vbox messages}\par
+\B\4\D$\\{delimiter\_shortfall\_code}$ \5
+\T{10}\C{maximum amount uncovered by variable delimiters}\par
+\B\4\D$\\{null\_delimiter\_space\_code}$ \5
+\T{11}\C{blank space in null delimiters}\par
+\B\4\D$\\{script\_space\_code}$ \5
+\T{12}\C{extra space after subscript or superscript}\par
+\B\4\D$\\{pre\_display\_size\_code}$ \5
+\T{13}\C{length of text preceding a display}\par
+\B\4\D$\\{display\_width\_code}$ \5
+\T{14}\C{length of line for displayed equation}\par
+\B\4\D$\\{display\_indent\_code}$ \5
+\T{15}\C{indentation of line for displayed equation}\par
+\B\4\D$\\{overfull\_rule\_code}$ \5
+\T{16}\C{width of rule that identifies overfull hboxes}\par
+\B\4\D$\\{hang\_indent\_code}$ \5
+\T{17}\C{amount of hanging indentation}\par
+\B\4\D$\\{h\_offset\_code}$ \5
+\T{18}\C{amount of horizontal offset when shipping pages out}\par
+\B\4\D$\\{v\_offset\_code}$ \5
+\T{19}\C{amount of vertical offset when shipping pages out}\par
+\B\4\D$\\{emergency\_stretch\_code}$ \5
+\T{20}\C{reduces badnesses on final pass of line-breaking}\par
+\B\4\D$\\{dimen\_pars}$ \5
+\T{21}\C{total number of dimension parameters}\par
+\B\4\D$\\{scaled\_base}$ \5
+$(\\{dimen\_base}+\\{dimen\_pars}{}$)\C{table of 256 user-defined \.{\\dimen} registers}\par
+\B\4\D$\\{eqtb\_size}$ \5
+$(\\{scaled\_base}+\T{255}{}$)\C{largest subscript of \\{eqtb}}\Y\par
+\B\4\D$\\{dimen}(\|X)$ \5
+$\\{eqtb}[\\{scaled\_base}+\|X].{}$\\{sc}\par
+\B\4\D$\\{dimen\_par}(\|X)$ \5
+$\\{eqtb}[\\{dimen\_base}+\|X].{}$\\{sc}\C{a scaled quantity}\par
+\B\4\D$\\{par\_indent}$ \5
+\\{dimen\_par}(\\{par\_indent\_code})\par
+\B\4\D$\\{math\_surround}$ \5
+\\{dimen\_par}(\\{math\_surround\_code})\par
+\B\4\D$\\{line\_skip\_limit}$ \5
+\\{dimen\_par}(\\{line\_skip\_limit\_code})\par
+\B\4\D$\\{hsize}$ \5
+\\{dimen\_par}(\\{hsize\_code})\par
+\B\4\D$\\{vsize}$ \5
+\\{dimen\_par}(\\{vsize\_code})\par
+\B\4\D$\\{max\_depth}$ \5
+\\{dimen\_par}(\\{max\_depth\_code})\par
+\B\4\D$\\{split\_max\_depth}$ \5
+\\{dimen\_par}(\\{split\_max\_depth\_code})\par
+\B\4\D$\\{box\_max\_depth}$ \5
+\\{dimen\_par}(\\{box\_max\_depth\_code})\par
+\B\4\D$\\{hfuzz}$ \5
+\\{dimen\_par}(\\{hfuzz\_code})\par
+\B\4\D$\\{vfuzz}$ \5
+\\{dimen\_par}(\\{vfuzz\_code})\par
+\B\4\D$\\{delimiter\_shortfall}$ \5
+\\{dimen\_par}(\\{delimiter\_shortfall\_code})\par
+\B\4\D$\\{null\_delimiter\_space}$ \5
+\\{dimen\_par}(\\{null\_delimiter\_space\_code})\par
+\B\4\D$\\{script\_space}$ \5
+\\{dimen\_par}(\\{script\_space\_code})\par
+\B\4\D$\\{pre\_display\_size}$ \5
+\\{dimen\_par}(\\{pre\_display\_size\_code})\par
+\B\4\D$\\{display\_width}$ \5
+\\{dimen\_par}(\\{display\_width\_code})\par
+\B\4\D$\\{display\_indent}$ \5
+\\{dimen\_par}(\\{display\_indent\_code})\par
+\B\4\D$\\{overfull\_rule}$ \5
+\\{dimen\_par}(\\{overfull\_rule\_code})\par
+\B\4\D$\\{hang\_indent}$ \5
+\\{dimen\_par}(\\{hang\_indent\_code})\par
+\B\4\D$\\{h\_offset}$ \5
+\\{dimen\_par}(\\{h\_offset\_code})\par
+\B\4\D$\\{v\_offset}$ \5
+\\{dimen\_par}(\\{v\_offset\_code})\par
+\B\4\D$\\{emergency\_stretch}$ \5
+\\{dimen\_par}(\\{emergency\_stretch\_code})\par
+\Y\B\&{void} \\{print\_length\_param}(\&{int} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{switch} (\|n)\5
+${}\{{}$\1\6
+\4\&{case} \\{par\_indent\_code}:\5
+\\{print\_esc}(\X1503:\.{"parindent"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_surround\_code}:\5
+\\{print\_esc}(\X1504:\.{"mathsurround"}\X);\5
+\&{break};\6
+\4\&{case} \\{line\_skip\_limit\_code}:\5
+\\{print\_esc}(\X1505:\.{"lineskiplimit"}\X);\5
+\&{break};\6
+\4\&{case} \\{hsize\_code}:\5
+\\{print\_esc}(\X1506:\.{"hsize"}\X);\5
+\&{break};\6
+\4\&{case} \\{vsize\_code}:\5
+\\{print\_esc}(\X1507:\.{"vsize"}\X);\5
+\&{break};\6
+\4\&{case} \\{max\_depth\_code}:\5
+\\{print\_esc}(\X1508:\.{"maxdepth"}\X);\5
+\&{break};\6
+\4\&{case} \\{split\_max\_depth\_code}:\5
+\\{print\_esc}(\X1509:\.{"splitmaxdepth"}\X);\5
+\&{break};\6
+\4\&{case} \\{box\_max\_depth\_code}:\5
+\\{print\_esc}(\X1510:\.{"boxmaxdepth"}\X);\5
+\&{break};\6
+\4\&{case} \\{hfuzz\_code}:\5
+\\{print\_esc}(\X1511:\.{"hfuzz"}\X);\5
+\&{break};\6
+\4\&{case} \\{vfuzz\_code}:\5
+\\{print\_esc}(\X1512:\.{"vfuzz"}\X);\5
+\&{break};\6
+\4\&{case} \\{delimiter\_shortfall\_code}:\5
+\\{print\_esc}(\X1513:\.{"delimitershortfall"}\X);\5
+\&{break};\6
+\4\&{case} \\{null\_delimiter\_space\_code}:\5
+\\{print\_esc}(\X1514:\.{"nulldelimiterspace"}\X);\5
+\&{break};\6
+\4\&{case} \\{script\_space\_code}:\5
+\\{print\_esc}(\X1515:\.{"scriptspace"}\X);\5
+\&{break};\6
+\4\&{case} \\{pre\_display\_size\_code}:\5
+\\{print\_esc}(\X1516:\.{"predisplaysize"}\X);\5
+\&{break};\6
+\4\&{case} \\{display\_width\_code}:\5
+\\{print\_esc}(\X1517:\.{"displaywidth"}\X);\5
+\&{break};\6
+\4\&{case} \\{display\_indent\_code}:\5
+\\{print\_esc}(\X1518:\.{"displayindent"}\X);\5
+\&{break};\6
+\4\&{case} \\{overfull\_rule\_code}:\5
+\\{print\_esc}(\X1519:\.{"overfullrule"}\X);\5
+\&{break};\6
+\4\&{case} \\{hang\_indent\_code}:\5
+\\{print\_esc}(\X1520:\.{"hangindent"}\X);\5
+\&{break};\6
+\4\&{case} \\{h\_offset\_code}:\5
+\\{print\_esc}(\X1521:\.{"hoffset"}\X);\5
+\&{break};\6
+\4\&{case} \\{v\_offset\_code}:\5
+\\{print\_esc}(\X1522:\.{"voffset"}\X);\5
+\&{break};\6
+\4\&{case} \\{emergency\_stretch\_code}:\5
+\\{print\_esc}(\X1523:\.{"emergencystretch"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_str}(\.{"[unknown\ dimen\ para}\)\.{meter!]"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{248}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1503:\.{"parindent"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{par\_indent\_code}){}$;\6
+${}\\{primitive}(\X1504:\.{"mathsurround"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{math\_surround\_code}){}$;\6
+${}\\{primitive}(\X1505:\.{"lineskiplimit"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{line\_skip\_limit\_code}){}$;\6
+${}\\{primitive}(\X1506:\.{"hsize"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{hsize\_code}){}$;\6
+${}\\{primitive}(\X1507:\.{"vsize"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{vsize\_code}){}$;\6
+${}\\{primitive}(\X1508:\.{"maxdepth"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{max\_depth\_code}){}$;\6
+${}\\{primitive}(\X1509:\.{"splitmaxdepth"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{split\_max\_depth\_code}){}$;\6
+${}\\{primitive}(\X1510:\.{"boxmaxdepth"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{box\_max\_depth\_code}){}$;\6
+${}\\{primitive}(\X1511:\.{"hfuzz"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{hfuzz\_code}){}$;\6
+${}\\{primitive}(\X1512:\.{"vfuzz"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{vfuzz\_code}){}$;\6
+${}\\{primitive}(\X1513:\.{"delimitershortfall"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{delimiter\_shortfall\_code}){}$;\6
+${}\\{primitive}(\X1514:\.{"nulldelimiterspace"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{null\_delimiter\_space\_code}){}$;\6
+${}\\{primitive}(\X1515:\.{"scriptspace"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{script\_space\_code}){}$;\6
+${}\\{primitive}(\X1516:\.{"predisplaysize"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{pre\_display\_size\_code}){}$;\6
+${}\\{primitive}(\X1517:\.{"displaywidth"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{display\_width\_code}){}$;\6
+${}\\{primitive}(\X1518:\.{"displayindent"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{display\_indent\_code}){}$;\6
+${}\\{primitive}(\X1519:\.{"overfullrule"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{overfull\_rule\_code}){}$;\6
+${}\\{primitive}(\X1520:\.{"hangindent"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{hang\_indent\_code}){}$;\6
+${}\\{primitive}(\X1521:\.{"hoffset"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{h\_offset\_code}){}$;\6
+${}\\{primitive}(\X1522:\.{"voffset"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{v\_offset\_code}){}$;\6
+${}\\{primitive}(\X1523:\.{"emergencystretch"}\X,\39\\{assign\_dimen},\39\\{dimen\_base}+\\{emergency\_stretch\_code}){}$;\par
+\fi
+
+\M{249}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_dimen}:\6
+\&{if} ${}(\\{chr\_code}<\\{scaled\_base}){}$\1\5
+${}\\{print\_length\_param}(\\{chr\_code}-\\{dimen\_base});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1524:\.{"dimen"}\X);\5
+${}\\{print\_int}(\\{chr\_code}-\\{scaled\_base});{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{250}\B\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\\{dimen\_base};{}$ ${}\|k\Z\\{eqtb\_size};{}$ ${}\|k\PP){}$\1\5
+${}\\{eqtb}[\|k].\\{sc}\K\T{0}{}$;\2\par
+\fi
+
+\M{251}\B\X251:Show equivalent \|n, in region 6\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|n<\\{scaled\_base}){}$\1\5
+${}\\{print\_length\_param}(\|n-\\{dimen\_base});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1524:\.{"dimen"}\X);\5
+${}\\{print\_int}(\|n-\\{scaled\_base});{}$\6
+\4${}\}{}$\2\6
+\\{print\_char}(\.{'='});\5
+${}\\{print\_scaled}(\\{eqtb}[\|n].\\{sc});{}$\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\2\par
+\U252.\fi
+
+\M{252}Here is a procedure that displays the contents of \\{eqtb}[\|n]
+symbolically.
+
+\Y\B\hbox{\4}\X298:Declare the procedure called \\{print\_cmd\_chr}\X\6
+\8\#\&{ifdef} \.{STAT}\7
+\&{void} \\{show\_eqtb}(\&{pointer} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|n<\\{active\_base}){}$\1\5
+\\{print\_char}(\.{'?'});\C{this can't happen}\2\6
+\&{else} \&{if} ${}(\|n<\\{glue\_base}){}$\1\5
+\X223:Show equivalent \|n, in region 1 or 2\X\2\6
+\&{else} \&{if} ${}(\|n<\\{local\_base}){}$\1\5
+\X229:Show equivalent \|n, in region 3\X\2\6
+\&{else} \&{if} ${}(\|n<\\{int\_base}){}$\1\5
+\X233:Show equivalent \|n, in region 4\X\2\6
+\&{else} \&{if} ${}(\|n<\\{dimen\_base}){}$\1\5
+\X242:Show equivalent \|n, in region 5\X\2\6
+\&{else} \&{if} ${}(\|n\Z\\{eqtb\_size}){}$\1\5
+\X251:Show equivalent \|n, in region 6\X\2\6
+\&{else}\1\5
+\\{print\_char}(\.{'?'});\C{this can't happen either}\2\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{253}The last two regions of \\{eqtb} have fullword values instead of the
+three fields \\{eq\_level}, \\{eq\_type}, and \\{equiv}. An \\{eq\_type} is unnecessary,
+but \TeX\ needs to store the \\{eq\_level} information in another array
+called \\{xeq\_level}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{memory\_word} ${}\\{eqtb0}[\\{eqtb\_size}-\\{active\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{eqtb}\K\\{eqtb0}-\\{active\_base};{}$\6
+\&{quarterword} ${}\\{xeq\_level0}[\\{eqtb\_size}-\\{int\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{xeq\_level}\K\\{xeq\_level0}-\\{int\_base}{}$;\par
+\fi
+
+\M{254}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\\{int\_base};{}$ ${}\|k\Z\\{eqtb\_size};{}$ ${}\|k\PP){}$\1\5
+${}\\{xeq\_level}[\|k]\K\\{level\_one}{}$;\2\par
+\fi
+
+\M{255}When the debugging routine \\{search\_mem} is looking for pointers having a
+given value, it is interested only in regions 1 to~3 of~\\{eqtb}, and in the
+first part of region~4.
+
+\Y\B\4\X255:Search \\{eqtb} for equivalents equal to \|p\X${}\E{}$\6
+\&{for} ${}(\|q\K\\{active\_base};{}$ ${}\|q\Z\\{box\_base}+\T{255};{}$ ${}\|q\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{equiv}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"EQUIV("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U172.\fi
+
+\N{1}{256}The hash table.
+Control sequences are stored and retrieved by means of a fairly standard hash
+table algorithm called the method of ``coalescing lists'' (cf.\ Algorithm 6.4C
+in {\sl The Art of Computer Programming\/}). Once a control sequence enters the
+table, it is never removed, because there are complicated situations
+involving \.{\\gdef} where the removal of a control sequence at the end of
+a group would be a mistake preventable only by the introduction of a
+complicated reference-count mechanism.
+
+The actual sequence of letters forming a control sequence identifier is
+stored in the \\{str\_pool} array together with all the other strings. An
+auxiliary array \\{hash} consists of items with two halfword fields per
+word. The first of these, called \\{next}(\|p), points to the next identifier
+belonging to the same coalesced list as the identifier corresponding to~\|p;
+and the other, called \\{text}(\|p), points to the \\{str\_start} entry for
+\|p's identifier. If position~\|p of the hash table is empty, we have
+$\\{text}(\|p)\E\T{0}$; if position \|p is either empty or the end of a coalesced
+hash list, we have $\\{next}(\|p)\E\T{0}$. An auxiliary pointer variable called
+\\{hash\_used} is maintained in such a way that all locations $\|p\G\\{hash\_used}$
+are nonempty. The global variable \\{cs\_count} tells how many multiletter
+control sequences have been defined, if statistics are being kept.
+
+A global boolean variable called \\{no\_new\_control\_sequence} is set to
+\\{true} during the time that new hash table entries are forbidden.
+
+\Y\B\4\D$\\{next}(\|X)$ \5
+$\\{hash}[\|X].{}$\\{lh}\C{link for coalesced lists}\par
+\B\4\D$\\{text}(\|X)$ \5
+$\\{hash}[\|X].{}$\\{rh}\C{string number for control sequence name}\par
+\B\4\D$\\{hash\_is\_full}$ \5
+$(\\{hash\_used}\E\\{hash\_base}{}$)\C{test if all positions are occupied}\par
+\B\4\D$\\{font\_id\_text}(\|X)$ \5
+$\\{text}(\\{font\_id\_base}+\|X{}$)\C{a frozen font identifier's name}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{two\_halves} ${}\\{hash0}[\\{undefined\_control\_sequence}-\\{hash\_base}],{}$ ${}{*\&{const}\ }\\{hash}\K\\{hash0}-\\{hash\_base}{}$;\C{the hash table}\6
+\&{pointer} \\{hash\_used};\C{allocation pointer for \\{hash}}\6
+\&{bool} \\{no\_new\_control\_sequence};\C{are new identifiers legal?}\6
+\&{int} \\{cs\_count};\C{total number of known identifiers}\par
+\fi
+
+\M{257}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{no\_new\_control\_sequence}\K\\{true}{}$;\C{new identifiers are usually forbidden}\6
+${}\\{next}(\\{hash\_base})\K\T{0};{}$\5
+${}\\{text}(\\{hash\_base})\K\T{0};{}$\6
+\&{for} ${}(\|k\K\\{hash\_base}+\T{1};{}$ ${}\|k\Z\\{undefined\_control\_sequence}-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{hash}[\|k]\K\\{hash}[\\{hash\_base}]{}$;\2\par
+\fi
+
+\M{258}\B\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{hash\_used}\K\\{frozen\_control\_sequence}{}$;\C{nothing is used}\6
+${}\\{cs\_count}\K\T{0};{}$\5
+${}\\{eq\_type}(\\{frozen\_dont\_expand})\K\\{dont\_expand};{}$\5
+${}\\{text}(\\{frozen\_dont\_expand})\K\X1525:\.{"notexpanded:"}\X{}$;\par
+\fi
+
+\M{259}Here is the subroutine that searches the hash table for an identifier
+that matches a given string of length $\|l>\T{1}$ appearing in $\\{buffer}[\|j\dotdot(\|j+\|l-\T{1})]$. If the identifier is found, the corresponding hash table address
+is returned. Otherwise, if the global variable \\{no\_new\_control\_sequence}
+is \\{true}, the dummy address \\{undefined\_control\_sequence} is returned.
+Otherwise the identifier is inserted into the hash table and its location
+is returned.
+
+\Y\B\&{pointer} \\{id\_lookup}(\&{int} \|j${},\39{}$\&{int} \|l)\C{search the hash table}\6
+${}\{{}$\5
+\C{go here if you found it}\1\6
+\&{int} \|h;\C{hash code}\6
+\&{int} \|d;\C{number of characters in incomplete current string}\6
+\&{pointer} \|p;\C{index in \\{hash} array}\6
+\&{pointer} \|k;\C{index in \\{buffer} array}\7
+\X261:Compute the hash code \|h\X;\6
+${}\|p\K\|h+\\{hash\_base}{}$;\C{we start searching here; note that $\T{0}\Z\|h<\\{hash\_prime}$}\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{text}(\|p)>\T{0}){}$\1\6
+\&{if} ${}(\\{length}(\\{text}(\|p))\E\|l){}$\1\6
+\&{if} ${}(\\{str\_eq\_buf}(\\{text}(\|p),\39\|j)){}$\1\5
+\&{goto} \\{found};\2\2\2\6
+\&{if} ${}(\\{next}(\|p)\E\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{no\_new\_control\_sequence})\1\5
+${}\|p\K\\{undefined\_control\_sequence};{}$\2\6
+\&{else}\1\5
+\X260:Insert a new control sequence after \|p, then make \|p point to it\X;\2\6
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+${}\|p\K\\{next}(\|p);{}$\6
+\4${}\}{}$\2\6
+\4\\{found}:\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{260}\B\X260:Insert a new control sequence after \|p, then make \|p point to it\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{text}(\|p)>\T{0}){}$\5
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+\&{if} (\\{hash\_is\_full})\1\5
+${}\\{overflow}(\.{"hash\ size"},\39\\{hash\_size});{}$\2\6
+\\{decr}(\\{hash\_used});\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{text}(\\{hash\_used})\E\T{0})){}$;\C{search for an empty location in \\{hash}}\6
+${}\\{next}(\|p)\K\\{hash\_used};{}$\5
+${}\|p\K\\{hash\_used};{}$\6
+\4${}\}{}$\2\6
+\\{str\_room}(\|l);\5
+${}\|d\K\\{cur\_length};{}$\6
+\&{while} ${}(\\{pool\_ptr}>\\{str\_start}[\\{str\_ptr}]){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{pool\_ptr});\5
+${}\\{str\_pool}[\\{pool\_ptr}+\|l]\K\\{str\_pool}[\\{pool\_ptr}];{}$\6
+\4${}\}{}$\C{move current string up to make room for another}\2\6
+\&{for} ${}(\|k\K\|j;{}$ ${}\|k\Z\|j+\|l-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{append\_char}(\\{buffer}[\|k]);\2\6
+${}\\{text}(\|p)\K\\{make\_string}(\,);{}$\5
+${}\\{pool\_ptr}\K\\{pool\_ptr}+\|d;{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\\{incr}(\\{cs\_count});\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\par
+\U259.\fi
+
+\M{261}The value of \\{hash\_prime} should be roughly 85\pct! of \\{hash\_size}, and it
+should be a prime number. The theory of hashing tells us to expect fewer
+than two table probes, on the average, when the search is successful.
+[See J.~S. Vitter, {\sl Journal of the ACM\/ \bf30} (1983), 231--258.]
+
+\Y\B\4\X261:Compute the hash code \|h\X${}\E{}$\6
+$\|h\K\\{buffer}[\|j];{}$\6
+\&{for} ${}(\|k\K\|j+\T{1};{}$ ${}\|k\Z\|j+\|l-\T{1};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\|h\K\|h+\|h+\\{buffer}[\|k];{}$\6
+\&{while} ${}(\|h\G\\{hash\_prime}){}$\1\5
+${}\|h\K\|h-\\{hash\_prime};{}$\2\6
+\4${}\}{}$\2\par
+\U259.\fi
+
+\M{262}Single-character control sequences do not need to be looked up in a hash
+table, since we can use the character code itself as a direct address.
+The procedure \\{print\_cs} prints the name of a control sequence, given
+a pointer to its address in \\{eqtb}. A space is printed after the name
+unless it is a single nonletter or an active character. This procedure
+might be invoked with invalid data, so it is ``extra robust.'' The
+individual characters must be printed one at a time using \\{print}, since
+they may be unprintable.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_cs}(\&{int} \|p)\C{prints a purported control sequence}\6
+${}\{{}$\5
+\1\&{if} ${}(\|p<\\{hash\_base}{}$)\C{single character}\1\6
+\&{if} ${}(\|p\G\\{single\_base}){}$\1\6
+\&{if} ${}(\|p\E\\{null\_cs}){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1526:\.{"csname"}\X);\5
+\\{print\_esc}(\X1527:\.{"endcsname"}\X);\5
+\\{print\_char}(\.{'\ '});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{print\_esc}(\|p-\\{single\_base});{}$\6
+\&{if} ${}(\\{cat\_code}(\|p-\\{single\_base})\E\\{letter}){}$\1\5
+\\{print\_char}(\.{'\ '});\2\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}(\|p<\\{active\_base}){}$\1\5
+\\{print\_esc}(\X1528:\.{"IMPOSSIBLE."}\X);\2\6
+\&{else}\1\5
+${}\\{print}(\|p-\\{active\_base});{}$\2\2\6
+\&{else} \&{if} ${}(\|p\G\\{undefined\_control\_sequence}){}$\1\5
+\\{print\_esc}(\X1528:\.{"IMPOSSIBLE."}\X);\2\6
+\&{else} \&{if} ${}((\\{text}(\|p)<\T{0})\V(\\{text}(\|p)\G\\{str\_ptr})){}$\1\5
+\\{print\_esc}(\X1529:\.{"NONEXISTENT."}\X);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\\{text}(\|p));\5
+\\{print\_char}(\.{'\ '});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{263}Here is a similar procedure; it avoids the error checks, and it never
+prints a space after the control sequence.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{sprint\_cs}(\&{pointer} \|p)\C{prints a control sequence}\6
+${}\{{}$\5
+\1\&{if} ${}(\|p<\\{hash\_base}){}$\1\6
+\&{if} ${}(\|p<\\{single\_base}){}$\1\5
+${}\\{print}(\|p-\\{active\_base});{}$\2\6
+\&{else} \&{if} ${}(\|p<\\{null\_cs}){}$\1\5
+${}\\{print\_esc}(\|p-\\{single\_base});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1526:\.{"csname"}\X);\5
+\\{print\_esc}(\X1527:\.{"endcsname"}\X);\6
+\4${}\}{}$\2\2\6
+\&{else}\1\5
+\\{print\_esc}(\\{text}(\|p));\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{264}We need to put \TeX's ``primitive'' control sequences into the hash
+table, together with their command code (which will be the \\{eq\_type})
+and an operand (which will be the \\{equiv}). The \\{primitive} procedure
+does this, in a way that no \TeX\ user can. The global value \\{cur\_val}
+contains the new \\{eqtb} pointer after \\{primitive} has acted.
+
+\Y\B\8\#\&{ifdef} \.{INIT}\6
+\&{void} \\{primitive}(\&{str\_number} \|s${},\39{}$\&{quarterword} \|c${},\39{}$\&{halfword} \|o)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pool\_pointer} \|k;\C{index into \\{str\_pool}}\6
+\&{int} \|j;\C{index into \\{buffer}}\6
+\&{small\_number} \|l;\C{length of the string}\7
+\&{if} ${}(\|s<\T{256}){}$\1\5
+${}\\{cur\_val}\K\|s+\\{single\_base};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|k\K\\{str\_start}[\|s];{}$\5
+${}\|l\K\\{str\_start}[\|s+\T{1}]-\|k{}$;\C{we will move \|s into the (empty) \\{buffer}}\6
+\&{for} ${}(\|j\K\T{0};{}$ ${}\|j\Z\|l-\T{1};{}$ ${}\|j\PP){}$\1\5
+${}\\{buffer}[\|j]\K\\{so}(\\{str\_pool}[\|k+\|j]);{}$\2\6
+${}\\{cur\_val}\K\\{id\_lookup}(\T{0},\39\|l){}$;\C{\\{no\_new\_control\_sequence} is \\{false}}\6
+\\{flush\_string};\5
+${}\\{text}(\\{cur\_val})\K\|s{}$;\C{we don't want to have the string twice}\6
+\4${}\}{}$\2\6
+${}\\{eq\_level}(\\{cur\_val})\K\\{level\_one};{}$\5
+${}\\{eq\_type}(\\{cur\_val})\K\|c;{}$\5
+${}\\{equiv}(\\{cur\_val})\K\|o;{}$\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{265}Many of \TeX's primitives need no \\{equiv}, since they are identifiable
+by their \\{eq\_type} alone. These primitives are loaded into the hash table
+as follows:
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\.{'\ '},\39\\{ex\_space},\39\T{0}){}$;\6
+${}\\{primitive}(\.{'/'},\39\\{ital\_corr},\39\T{0}){}$;\6
+${}\\{primitive}(\X1530:\.{"accent"}\X,\39\\{accent},\39\T{0}){}$;\6
+${}\\{primitive}(\X1531:\.{"advance"}\X,\39\\{advance},\39\T{0}){}$;\6
+${}\\{primitive}(\X1532:\.{"afterassignment"}\X,\39\\{after\_assignment},\39\T{0}){}$;\6
+${}\\{primitive}(\X1533:\.{"aftergroup"}\X,\39\\{after\_group},\39\T{0}){}$;\6
+${}\\{primitive}(\X1534:\.{"begingroup"}\X,\39\\{begin\_group},\39\T{0}){}$;\6
+${}\\{primitive}(\X1535:\.{"char"}\X,\39\\{char\_num},\39\T{0}){}$;\6
+${}\\{primitive}(\X1526:\.{"csname"}\X,\39\\{cs\_name},\39\T{0}){}$;\6
+${}\\{primitive}(\X1536:\.{"delimiter"}\X,\39\\{delim\_num},\39\T{0}){}$;\6
+${}\\{primitive}(\X1537:\.{"divide"}\X,\39\\{divide},\39\T{0}){}$;\6
+${}\\{primitive}(\X1527:\.{"endcsname"}\X,\39\\{end\_cs\_name},\39\T{0}){}$;\6
+${}\\{primitive}(\X1538:\.{"endgroup"}\X,\39\\{end\_group},\39\T{0});{}$\5
+${}\\{text}(\\{frozen\_end\_group})\K\X1538:\.{"endgroup"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_end\_group}]\K\\{eqtb}[\\{cur\_val}]{}$;\6
+${}\\{primitive}(\X1539:\.{"expandafter"}\X,\39\\{expand\_after},\39\T{0}){}$;\6
+${}\\{primitive}(\X1540:\.{"font"}\X,\39\\{def\_font},\39\T{0}){}$;\6
+${}\\{primitive}(\X1541:\.{"fontdimen"}\X,\39\\{assign\_font\_dimen},\39\T{0}){}$;\6
+${}\\{primitive}(\X1542:\.{"halign"}\X,\39\\{halign},\39\T{0}){}$;\6
+${}\\{primitive}(\X1543:\.{"hrule"}\X,\39\\{hrule},\39\T{0}){}$;\6
+${}\\{primitive}(\X1544:\.{"ignorespaces"}\X,\39\\{ignore\_spaces},\39\T{0}){}$;\6
+${}\\{primitive}(\X1390:\.{"insert"}\X,\39\\{insert},\39\T{0}){}$;\6
+${}\\{primitive}(\X1401:\.{"mark"}\X,\39\\{mark},\39\T{0}){}$;\6
+${}\\{primitive}(\X1545:\.{"mathaccent"}\X,\39\\{math\_accent},\39\T{0}){}$;\6
+${}\\{primitive}(\X1546:\.{"mathchar"}\X,\39\\{math\_char\_num},\39\T{0}){}$;\6
+${}\\{primitive}(\X1547:\.{"mathchoice"}\X,\39\\{math\_choice},\39\T{0}){}$;\6
+${}\\{primitive}(\X1548:\.{"multiply"}\X,\39\\{multiply},\39\T{0}){}$;\6
+${}\\{primitive}(\X1549:\.{"noalign"}\X,\39\\{no\_align},\39\T{0}){}$;\6
+${}\\{primitive}(\X1550:\.{"noboundary"}\X,\39\\{no\_boundary},\39\T{0}){}$;\6
+${}\\{primitive}(\X1551:\.{"noexpand"}\X,\39\\{no\_expand},\39\T{0}){}$;\6
+${}\\{primitive}(\X1392:\.{"nonscript"}\X,\39\\{non\_script},\39\T{0}){}$;\6
+${}\\{primitive}(\X1552:\.{"omit"}\X,\39\\{omit},\39\T{0}){}$;\6
+${}\\{primitive}(\X1436:\.{"parshape"}\X,\39\\{set\_shape},\39\T{0}){}$;\6
+${}\\{primitive}(\X1553:\.{"penalty"}\X,\39\\{break\_penalty},\39\T{0}){}$;\6
+${}\\{primitive}(\X1554:\.{"prevgraf"}\X,\39\\{set\_prev\_graf},\39\T{0}){}$;\6
+${}\\{primitive}(\X1555:\.{"radical"}\X,\39\\{radical},\39\T{0}){}$;\6
+${}\\{primitive}(\X1556:\.{"read"}\X,\39\\{read\_to\_cs},\39\T{0}){}$;\6
+${}\\{primitive}(\X1557:\.{"relax"}\X,\39\\{relax},\39\T{256}){}$;\C{cf.\ \\{scan\_file\_name}}\6
+${}\\{text}(\\{frozen\_relax})\K\X1557:\.{"relax"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_relax}]\K\\{eqtb}[\\{cur\_val}]{}$;\6
+${}\\{primitive}(\X1558:\.{"setbox"}\X,\39\\{set\_box},\39\T{0}){}$;\6
+${}\\{primitive}(\X1559:\.{"the"}\X,\39\\{the},\39\T{0}){}$;\6
+${}\\{primitive}(\X1435:\.{"toks"}\X,\39\\{toks\_register},\39\T{0}){}$;\6
+${}\\{primitive}(\X1402:\.{"vadjust"}\X,\39\\{vadjust},\39\T{0}){}$;\6
+${}\\{primitive}(\X1560:\.{"valign"}\X,\39\\{valign},\39\T{0}){}$;\6
+${}\\{primitive}(\X1561:\.{"vcenter"}\X,\39\\{vcenter},\39\T{0}){}$;\6
+${}\\{primitive}(\X1562:\.{"vrule"}\X,\39\\{vrule},\39\T{0}){}$;\par
+\fi
+
+\M{266}Each primitive has a corresponding inverse, so that it is possible to
+display the cryptic numeric contents of \\{eqtb} in symbolic form.
+Every call of \\{primitive} in this program is therefore accompanied by some
+straightforward code that forms part of the \\{print\_cmd\_chr} routine
+below.
+
+\Y\B\4\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{accent}:\5
+\\{print\_esc}(\X1530:\.{"accent"}\X);\5
+\&{break};\6
+\4\&{case} \\{advance}:\5
+\\{print\_esc}(\X1531:\.{"advance"}\X);\5
+\&{break};\6
+\4\&{case} \\{after\_assignment}:\5
+\\{print\_esc}(\X1532:\.{"afterassignment"}\X);\5
+\&{break};\6
+\4\&{case} \\{after\_group}:\5
+\\{print\_esc}(\X1533:\.{"aftergroup"}\X);\5
+\&{break};\6
+\4\&{case} \\{assign\_font\_dimen}:\5
+\\{print\_esc}(\X1541:\.{"fontdimen"}\X);\5
+\&{break};\6
+\4\&{case} \\{begin\_group}:\5
+\\{print\_esc}(\X1534:\.{"begingroup"}\X);\5
+\&{break};\6
+\4\&{case} \\{break\_penalty}:\5
+\\{print\_esc}(\X1553:\.{"penalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{char\_num}:\5
+\\{print\_esc}(\X1535:\.{"char"}\X);\5
+\&{break};\6
+\4\&{case} \\{cs\_name}:\5
+\\{print\_esc}(\X1526:\.{"csname"}\X);\5
+\&{break};\6
+\4\&{case} \\{def\_font}:\5
+\\{print\_esc}(\X1540:\.{"font"}\X);\5
+\&{break};\6
+\4\&{case} \\{delim\_num}:\5
+\\{print\_esc}(\X1536:\.{"delimiter"}\X);\5
+\&{break};\6
+\4\&{case} \\{divide}:\5
+\\{print\_esc}(\X1537:\.{"divide"}\X);\5
+\&{break};\6
+\4\&{case} \\{end\_cs\_name}:\5
+\\{print\_esc}(\X1527:\.{"endcsname"}\X);\5
+\&{break};\6
+\4\&{case} \\{end\_group}:\5
+\\{print\_esc}(\X1538:\.{"endgroup"}\X);\5
+\&{break};\6
+\4\&{case} \\{ex\_space}:\5
+\\{print\_esc}(\.{'\ '});\5
+\&{break};\6
+\4\&{case} \\{expand\_after}:\5
+\\{print\_esc}(\X1539:\.{"expandafter"}\X);\5
+\&{break};\6
+\4\&{case} \\{halign}:\5
+\\{print\_esc}(\X1542:\.{"halign"}\X);\5
+\&{break};\6
+\4\&{case} \\{hrule}:\5
+\\{print\_esc}(\X1543:\.{"hrule"}\X);\5
+\&{break};\6
+\4\&{case} \\{ignore\_spaces}:\5
+\\{print\_esc}(\X1544:\.{"ignorespaces"}\X);\5
+\&{break};\6
+\4\&{case} \\{insert}:\5
+\\{print\_esc}(\X1390:\.{"insert"}\X);\5
+\&{break};\6
+\4\&{case} \\{ital\_corr}:\5
+\\{print\_esc}(\.{'/'});\5
+\&{break};\6
+\4\&{case} \\{mark}:\5
+\\{print\_esc}(\X1401:\.{"mark"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_accent}:\5
+\\{print\_esc}(\X1545:\.{"mathaccent"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_char\_num}:\5
+\\{print\_esc}(\X1546:\.{"mathchar"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_choice}:\5
+\\{print\_esc}(\X1547:\.{"mathchoice"}\X);\5
+\&{break};\6
+\4\&{case} \\{multiply}:\5
+\\{print\_esc}(\X1548:\.{"multiply"}\X);\5
+\&{break};\6
+\4\&{case} \\{no\_align}:\5
+\\{print\_esc}(\X1549:\.{"noalign"}\X);\5
+\&{break};\6
+\4\&{case} \\{no\_boundary}:\5
+\\{print\_esc}(\X1550:\.{"noboundary"}\X);\5
+\&{break};\6
+\4\&{case} \\{no\_expand}:\5
+\\{print\_esc}(\X1551:\.{"noexpand"}\X);\5
+\&{break};\6
+\4\&{case} \\{non\_script}:\5
+\\{print\_esc}(\X1392:\.{"nonscript"}\X);\5
+\&{break};\6
+\4\&{case} \\{omit}:\5
+\\{print\_esc}(\X1552:\.{"omit"}\X);\5
+\&{break};\6
+\4\&{case} \\{radical}:\5
+\\{print\_esc}(\X1555:\.{"radical"}\X);\5
+\&{break};\6
+\4\&{case} \\{read\_to\_cs}:\5
+\\{print\_esc}(\X1556:\.{"read"}\X);\5
+\&{break};\6
+\4\&{case} \\{relax}:\5
+\\{print\_esc}(\X1557:\.{"relax"}\X);\5
+\&{break};\6
+\4\&{case} \\{set\_box}:\5
+\\{print\_esc}(\X1558:\.{"setbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{set\_prev\_graf}:\5
+\\{print\_esc}(\X1554:\.{"prevgraf"}\X);\5
+\&{break};\6
+\4\&{case} \\{set\_shape}:\5
+\\{print\_esc}(\X1436:\.{"parshape"}\X);\5
+\&{break};\6
+\4\&{case} \\{the}:\5
+\\{print\_esc}(\X1559:\.{"the"}\X);\5
+\&{break};\6
+\4\&{case} \\{toks\_register}:\5
+\\{print\_esc}(\X1435:\.{"toks"}\X);\5
+\&{break};\6
+\4\&{case} \\{vadjust}:\5
+\\{print\_esc}(\X1402:\.{"vadjust"}\X);\5
+\&{break};\6
+\4\&{case} \\{valign}:\5
+\\{print\_esc}(\X1560:\.{"valign"}\X);\5
+\&{break};\6
+\4\&{case} \\{vcenter}:\5
+\\{print\_esc}(\X1561:\.{"vcenter"}\X);\5
+\&{break};\6
+\4\&{case} \\{vrule}:\5
+\\{print\_esc}(\X1562:\.{"vrule"}\X);\5
+\&{break};\par
+\fi
+
+\M{267}We will deal with the other primitives later, at some point in the program
+where their \\{eq\_type} and \\{equiv} values are more meaningful. For example,
+the primitives for math mode will be loaded when we consider the routines
+that deal with formulas. It is easy to find where each particular
+primitive was treated by looking in the index at the end; for example, the
+section where $\X1555:\.{"radical"}\X$ entered \\{eqtb} is listed under `\.{\\radical}
+primitive'. (Primitives consisting of a single nonalphabetic character,
+like `\.{\\/}', are listed under `Single-character primitives'.)
+
+Meanwhile, this is a convenient place to catch up on something we were unable
+to do before the hash table was defined:
+
+\Y\B\4\X267:Print the font identifier for \\{font}(\|p)\X${}\E{}$\6
+\\{print\_esc}(\\{font\_id\_text}(\\{font}(\|p)))\par
+\Us174\ET176.\fi
+
+\N{1}{268}Saving and restoring equivalents.
+The nested structure provided by `$\.{\char'173}\ldots\.{\char'175}$' groups
+in \TeX\ means that \\{eqtb} entries valid in outer groups should be saved
+and restored later if they are overridden inside the braces. When a new \\{eqtb}
+value is being assigned, the program therefore checks to see if the previous
+entry belongs to an outer level. In such a case, the old value is placed
+on the \\{save\_stack} just before the new value enters \\{eqtb}. At the
+end of a grouping level, i.e., when the right brace is sensed, the
+\\{save\_stack} is used to restore the outer values, and the inner ones are
+destroyed.
+
+Entries on the \\{save\_stack} are of type \&{memory\_word}. The top item on
+this stack is \\{save\_stack}[\|p], where $\|p\E\\{save\_ptr}-\T{1}$; it contains three
+fields called \\{save\_type}, \\{save\_level}, and \\{save\_index}, and it is
+interpreted in one of four ways:
+
+\yskip\hangg 1) If $\\{save\_type}(\|p)\E\\{restore\_old\_value}$, then
+\\{save\_index}(\|p) is a location in \\{eqtb} whose current value should
+be destroyed at the end of the current group and replaced by $\\{save\_stack}[\|p-\T{1}]$.
+Furthermore if $\\{save\_index}(\|p)\G\\{int\_base}$, then \\{save\_level}(\|p)
+should replace the corresponding entry in \\{xeq\_level}.
+
+\yskip\hangg 2) If $\\{save\_type}(\|p)\E\\{restore\_zero}$, then \\{save\_index}(\|p)
+is a location in \\{eqtb} whose current value should be destroyed at the end
+of the current group, when it should be
+replaced by the current value of \\{eqtb}[\\{undefined\_control\_sequence}].
+
+\yskip\hangg 3) If $\\{save\_type}(\|p)\E\\{insert\_token}$, then \\{save\_index}(\|p)
+is a token that should be inserted into \TeX's input when the current
+group ends.
+
+\yskip\hangg 4) If $\\{save\_type}(\|p)\E\\{level\_boundary}$, then \\{save\_level}(\|p)
+is a code explaining what kind of group we were previously in, and
+\\{save\_index}(\|p) points to the level boundary word at the bottom of
+the entries for that group.
+
+\Y\B\4\D$\\{save\_type}(\|X)$ \5
+$\\{save\_stack}[\|X].\\{hh}.{}$\\{b0}\C{classifies a \\{save\_stack} entry}\par
+\B\4\D$\\{save\_level}(\|X)$ \5
+$\\{save\_stack}[\|X].\\{hh}.{}$\\{b1}\C{saved level for regions 5 and 6, or group code}\par
+\B\4\D$\\{save\_index}(\|X)$ \5
+$\\{save\_stack}[\|X].\\{hh}.{}$\\{rh}\C{\\{eqtb} location or token or \\{save\_stack} location}\par
+\B\4\D$\\{restore\_old\_value}$ \5
+\T{0}\C{\\{save\_type} when a value should be restored later}\par
+\B\4\D$\\{restore\_zero}$ \5
+\T{1}\C{\\{save\_type} when an undefined entry should be restored}\par
+\B\4\D$\\{insert\_token}$ \5
+\T{2}\C{\\{save\_type} when a token is being saved for later use}\par
+\B\4\D$\\{level\_boundary}$ \5
+\T{3}\C{\\{save\_type} corresponding to beginning of group}\par
+\fi
+
+\M{269}Here are the group codes that are used to discriminate between different
+kinds of groups. They allow \TeX\ to decide what special actions, if any,
+should be performed when a group ends.
+\def\grp{\.{\char'173...\char'175}}
+
+Some groups are not supposed to be ended by right braces. For example,
+the `\.\$' that begins a math formula causes a \\{math\_shift\_group} to
+be started, and this should be terminated by a matching `\.\$'. Similarly,
+a group that starts with \.{\\left} should end with \.{\\right}, and
+one that starts with \.{\\begingroup} should end with \.{\\endgroup}.
+
+\Y\B\4\D$\\{bottom\_level}$ \5
+\T{0}\C{group code for the outside world}\par
+\B\4\D$\\{simple\_group}$ \5
+\T{1}\C{group code for local structure only}\par
+\B\4\D$\\{hbox\_group}$ \5
+\T{2}\C{code for `\.{\\hbox}\grp'}\par
+\B\4\D$\\{adjusted\_hbox\_group}$ \5
+\T{3}\C{code for `\.{\\hbox}\grp' in vertical mode}\par
+\B\4\D$\\{vbox\_group}$ \5
+\T{4}\C{code for `\.{\\vbox}\grp'}\par
+\B\4\D$\\{vtop\_group}$ \5
+\T{5}\C{code for `\.{\\vtop}\grp'}\par
+\B\4\D$\\{align\_group}$ \5
+\T{6}\C{code for `\.{\\halign}\grp', `\.{\\valign}\grp'}\par
+\B\4\D$\\{no\_align\_group}$ \5
+\T{7}\C{code for `\.{\\noalign}\grp'}\par
+\B\4\D$\\{output\_group}$ \5
+\T{8}\C{code for output routine}\par
+\B\4\D$\\{math\_group}$ \5
+\T{9}\C{code for, e.g., `\.{\char'136}\grp'}\par
+\B\4\D$\\{disc\_group}$ \5
+\T{10}\C{code for `\.{\\discretionary}\grp\grp\grp'}\par
+\B\4\D$\\{insert\_group}$ \5
+\T{11}\C{code for `\.{\\insert}\grp', `\.{\\vadjust}\grp'}\par
+\B\4\D$\\{vcenter\_group}$ \5
+\T{12}\C{code for `\.{\\vcenter}\grp'}\par
+\B\4\D$\\{math\_choice\_group}$ \5
+\T{13}\C{code for `\.{\\mathchoice}\grp\grp\grp\grp'}\par
+\B\4\D$\\{semi\_simple\_group}$ \5
+\T{14}\C{code for `\.{\\begingroup...\\endgroup}'}\par
+\B\4\D$\\{math\_shift\_group}$ \5
+\T{15}\C{code for `\.{\$...\$}'}\par
+\B\4\D$\\{math\_left\_group}$ \5
+\T{16}\C{code for `\.{\\left...\\right}'}\par
+\B\4\D$\\{max\_group\_code}$ \5
+\T{16}\par
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint8\_t} \&{group\_code};\C{\\{save\_level} for a level boundary}\par
+\fi
+
+\M{270}The global variable \\{cur\_group} keeps track of what sort of group we are
+currently in. Another global variable, \\{cur\_boundary}, points to the
+topmost \\{level\_boundary} word. And \\{cur\_level} is the current depth of
+nesting. The routines are designed to preserve the condition that no entry
+in the \\{save\_stack} or in \\{eqtb} ever has a level greater than \\{cur\_level}.
+
+\fi
+
+\M{271}\B\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{memory\_word} ${}\\{save\_stack}[\\{save\_size}+\T{1}];{}$\6
+\&{uint16\_t} \\{save\_ptr};\C{first unused entry on \\{save\_stack}}\6
+\&{uint16\_t} \\{max\_save\_stack};\C{maximum usage of save stack}\6
+\&{quarterword} \\{cur\_level};\C{current nesting level for groups}\6
+\&{group\_code} \\{cur\_group};\C{current group type}\6
+\&{uint16\_t} \\{cur\_boundary};\C{where the current level begins}\par
+\fi
+
+\M{272}At this time it might be a good idea for the reader to review the introduction
+to \\{eqtb} that was given above just before the long lists of parameter names.
+Recall that the ``outer level'' of the program is \\{level\_one}, since
+undefined control sequences are assumed to be ``defined'' at \\{level\_zero}.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{save\_ptr}\K\T{0};{}$\5
+${}\\{cur\_level}\K\\{level\_one};{}$\5
+${}\\{cur\_group}\K\\{bottom\_level};{}$\5
+${}\\{cur\_boundary}\K\T{0};{}$\5
+${}\\{max\_save\_stack}\K\T{0}{}$;\par
+\fi
+
+\M{273}The following macro is used to test if there is room for up to six more
+entries on \\{save\_stack}. By making a conservative test like this, we can
+get by with testing for overflow in only a few places.
+
+\Y\B\4\D$\\{check\_full\_save\_stack}$ \6
+\&{if} ${}(\\{save\_ptr}>\\{max\_save\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_save\_stack}\K\\{save\_ptr};{}$\6
+\&{if} ${}(\\{max\_save\_stack}>\\{save\_size}-\T{6}){}$\1\5
+${}\\{overflow}(\.{"save\ size"},\39\\{save\_size});{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{274}Procedure \\{new\_save\_level} is called when a group begins. The
+argument is a group identification code like `\\{hbox\_group}'. After
+calling this routine, it is safe to put five more entries on \\{save\_stack}.
+
+In some cases integer-valued items are placed onto the
+\\{save\_stack} just below a \\{level\_boundary} word, because this is a
+convenient place to keep information that is supposed to ``pop up'' just
+when the group has finished.
+For example, when `\.{\\hbox to 100pt}\grp' is being treated, the 100pt
+dimension is stored on \\{save\_stack} just before \\{new\_save\_level} is
+called.
+
+We use the notation \\{saved}(\|k) to stand for an integer item that
+appears in location $\\{save\_ptr}+\|k$ of the save stack.
+
+\Y\B\4\D$\\{saved}(\|X)$ \5
+$\\{save\_stack}[\\{save\_ptr}+\|X].{}$\|i\par
+\Y\B\&{void} \\{new\_save\_level}(\&{group\_code} \|c)\C{begin a new level of grouping}\6
+${}\{{}$\5
+\1\\{check\_full\_save\_stack};\5
+${}\\{save\_type}(\\{save\_ptr})\K\\{level\_boundary};{}$\5
+${}\\{save\_level}(\\{save\_ptr})\K\\{cur\_group};{}$\5
+${}\\{save\_index}(\\{save\_ptr})\K\\{cur\_boundary};{}$\6
+\&{if} ${}(\\{cur\_level}\E\\{max\_quarterword}){}$\1\5
+${}\\{overflow}(\.{"grouping\ levels"},\39\\{max\_quarterword}-\\{min\_quarterword}){}$;\C{quit if $(\\{cur\_level}+\T{1})$ is too big to be stored in \\{eqtb}}\2\6
+${}\\{cur\_boundary}\K\\{save\_ptr};{}$\5
+\\{incr}(\\{cur\_level});\5
+\\{incr}(\\{save\_ptr});\5
+${}\\{cur\_group}\K\|c;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{275}Just before an entry of \\{eqtb} is changed, the following procedure should
+be called to update the other data structures properly. It is important
+to keep in mind that reference counts in \\{mem} include references from
+within \\{save\_stack}, so these counts must be handled carefully.
+
+\Y\B\&{void} \\{eq\_destroy}(\&{memory\_word} \|w)\C{gets ready to forget \|w}\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{\\{equiv} field of \|w}\7
+\&{switch} (\\{eq\_type\_field}(\|w))\5
+${}\{{}$\1\6
+\4\&{case} \\{call}:\5
+\&{case} \\{long\_call}:\5
+\&{case} \\{outer\_call}:\5
+\&{case} \\{long\_outer\_call}:\5
+\\{delete\_token\_ref}(\\{equiv\_field}(\|w));\5
+\&{break};\6
+\4\&{case} \\{glue\_ref}:\5
+\\{delete\_glue\_ref}(\\{equiv\_field}(\|w));\5
+\&{break};\6
+\4\&{case} \\{shape\_ref}:\6
+${}\{{}$\5
+\1${}\|q\K\\{equiv\_field}(\|w){}$;\C{we need to free a \.{\\parshape} block}\6
+\&{if} ${}(\|q\I\\{null}){}$\1\5
+${}\\{free\_node}(\|q,\39\\{info}(\|q)+\\{info}(\|q)+\T{1});{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\C{such a block is $\T{2}\|n+\T{1}$ words long, where $\|n\E\\{info}(\|q)$}\6
+\4\&{case} \\{box\_ref}:\5
+\\{flush\_node\_list}(\\{equiv\_field}(\|w));\5
+\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{276}To save a value of \\{eqtb}[\|p] that was established at level \|l, we
+can use the following subroutine.
+
+\Y\B\&{void} \\{eq\_save}(\&{pointer} \|p${},\39{}$\&{quarterword} \|l)\C{saves \\{eqtb}[\|p]}\6
+${}\{{}$\5
+\1\\{check\_full\_save\_stack};\6
+\&{if} ${}(\|l\E\\{level\_zero}){}$\1\5
+${}\\{save\_type}(\\{save\_ptr})\K\\{restore\_zero};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{save\_stack}[\\{save\_ptr}]\K\\{eqtb}[\|p];{}$\5
+\\{incr}(\\{save\_ptr});\5
+${}\\{save\_type}(\\{save\_ptr})\K\\{restore\_old\_value};{}$\6
+\4${}\}{}$\2\6
+${}\\{save\_level}(\\{save\_ptr})\K\|l;{}$\5
+${}\\{save\_index}(\\{save\_ptr})\K\|p;{}$\5
+\\{incr}(\\{save\_ptr});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{277}The procedure \\{eq\_define} defines an \\{eqtb} entry having specified
+\\{eq\_type} and \\{equiv} fields, and saves the former value if appropriate.
+This procedure is used only for entries in the first four regions of \\{eqtb},
+i.e., only for entries that have \\{eq\_type} and \\{equiv} fields.
+After calling this routine, it is safe to put four more entries on
+\\{save\_stack}, provided that there was room for four more entries before
+the call, since \\{eq\_save} makes the necessary test.
+
+\Y\B\&{void} \\{eq\_define}(\&{pointer} \|p${},\39{}$\&{quarterword} \|t${},\39{}$\&{halfword} \|e)\C{new data for \\{eqtb}}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{eq\_level}(\|p)\E\\{cur\_level}){}$\1\5
+\\{eq\_destroy}(\\{eqtb}[\|p]);\2\6
+\&{else} \&{if} ${}(\\{cur\_level}>\\{level\_one}){}$\1\5
+${}\\{eq\_save}(\|p,\39\\{eq\_level}(\|p));{}$\2\6
+${}\\{eq\_level}(\|p)\K\\{cur\_level};{}$\5
+${}\\{eq\_type}(\|p)\K\|t;{}$\5
+${}\\{equiv}(\|p)\K\|e;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{278}The counterpart of \\{eq\_define} for the remaining (fullword) positions in
+\\{eqtb} is called \\{eq\_word\_define}. Since $\\{xeq\_level}[\|p]\G\\{level\_one}$ for all
+\|p, a `\\{restore\_zero}' will never be used in this case.
+
+\Y\B\&{void} \\{eq\_word\_define}(\&{pointer} \|p${},\39{}$\&{int} \|w)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{xeq\_level}[\|p]\I\\{cur\_level}){}$\5
+${}\{{}$\5
+\1${}\\{eq\_save}(\|p,\39\\{xeq\_level}[\|p]);{}$\5
+${}\\{xeq\_level}[\|p]\K\\{cur\_level};{}$\6
+\4${}\}{}$\2\6
+${}\\{eqtb}[\|p].\|i\K\|w;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{279}The \\{eq\_define} and \\{eq\_word\_define} routines take care of local definitions.
+Global definitions are done in almost the same way, but there is no need
+to save old values, and the new value is associated with \\{level\_one}.
+
+\Y\B\&{void} \\{geq\_define}(\&{pointer} \|p${},\39{}$\&{quarterword} \|t${},\39{}$\&{halfword} \|e)\C{global \\{eq\_define}}\6
+${}\{{}$\5
+\1\\{eq\_destroy}(\\{eqtb}[\|p]);\5
+${}\\{eq\_level}(\|p)\K\\{level\_one};{}$\5
+${}\\{eq\_type}(\|p)\K\|t;{}$\5
+${}\\{equiv}(\|p)\K\|e;{}$\6
+\4${}\}{}$\2\7
+\&{void} \\{geq\_word\_define}(\&{pointer} \|p${},\39{}$\&{int} \|w)\C{global \\{eq\_word\_define}}\6
+${}\{{}$\5
+\1${}\\{eqtb}[\|p].\|i\K\|w;{}$\5
+${}\\{xeq\_level}[\|p]\K\\{level\_one};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{280}Subroutine \\{save\_for\_after} puts a token on the stack for save-keeping.
+
+\Y\B\&{void} \\{save\_for\_after}(\&{halfword} \|t)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_level}>\\{level\_one}){}$\5
+${}\{{}$\5
+\1\\{check\_full\_save\_stack};\5
+${}\\{save\_type}(\\{save\_ptr})\K\\{insert\_token};{}$\5
+${}\\{save\_level}(\\{save\_ptr})\K\\{level\_zero};{}$\5
+${}\\{save\_index}(\\{save\_ptr})\K\|t;{}$\5
+\\{incr}(\\{save\_ptr});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{281}The \\{unsave} routine goes the other way, taking items off of \\{save\_stack}.
+This routine takes care of restoration when a level ends; everything
+belonging to the topmost group is cleared off of the save stack.
+
+\Y\B\hbox{\4}\X284:Declare the procedure called \\{restore\_trace}\X\7
+\&{void} \\{back\_input}(\&{void});\7
+\&{void} \\{unsave}(\&{void})\C{pops the top level off the save stack}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{position to be restored}\6
+\&{quarterword} \|l;\C{saved level, if in fullword regions of \\{eqtb}}\6
+\&{halfword} \|t;\C{saved value of \\{cur\_tok}}\7
+\&{if} ${}(\\{cur\_level}>\\{level\_one}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{cur\_level});\5
+\X282:Clear off top level from \\{save\_stack}\X;\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{confusion}(\X1563:\.{"curlevel"}\X);\C{\\{unsave} is not used when $\\{cur\_group}\E\\{bottom\_level}$}\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{282}\B\X282:Clear off top level from \\{save\_stack}\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{decr}(\\{save\_ptr});\6
+\&{if} ${}(\\{save\_type}(\\{save\_ptr})\E\\{level\_boundary}){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|p\K\\{save\_index}(\\{save\_ptr});{}$\6
+\&{if} ${}(\\{save\_type}(\\{save\_ptr})\E\\{insert\_token}){}$\1\5
+\X326:Insert token \|p into \TeX's input\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{save\_type}(\\{save\_ptr})\E\\{restore\_old\_value}){}$\5
+${}\{{}$\5
+\1${}\|l\K\\{save\_level}(\\{save\_ptr});{}$\5
+\\{decr}(\\{save\_ptr});\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{save\_stack}[\\{save\_ptr}]\K\\{eqtb}[\\{undefined\_control\_sequence}];{}$\2\6
+\X283:Store \(s)\\{save\_stack}[\\{save\_ptr}] in \\{eqtb}[\|p], unless \\{eqtb}[\|p] holds a global value\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+${}\\{cur\_group}\K\\{save\_level}(\\{save\_ptr});$ $\\{cur\_boundary}\K\\{save\_index}{}$(\\{save\_ptr})\par
+\U281.\fi
+
+\M{283}A global definition, which sets the level to \\{level\_one},
+will not be undone by \\{unsave}. If at least one global definition of
+\\{eqtb}[\|p] has been carried out within the group that just ended, the
+last such definition will therefore survive.
+
+\Y\B\4\X283:Store \(s)\\{save\_stack}[\\{save\_ptr}] in \\{eqtb}[\|p], unless \\{eqtb}[\|p] holds a global value\X${}\E{}$\6
+\&{if} ${}(\|p<\\{int\_base}){}$\1\6
+\&{if} ${}(\\{eq\_level}(\|p)\E\\{level\_one}){}$\5
+${}\{{}$\5
+\1\\{eq\_destroy}(\\{save\_stack}[\\{save\_ptr}]);\C{destroy the saved value}\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_restores}>\T{0}){}$\1\5
+${}\\{restore\_trace}(\|p,\39\X1564:\.{"retaining"}\X);{}$\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{eq\_destroy}(\\{eqtb}[\|p]);\C{destroy the current value}\6
+${}\\{eqtb}[\|p]\K\\{save\_stack}[\\{save\_ptr}]{}$;\C{restore the saved value}\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_restores}>\T{0}){}$\1\5
+${}\\{restore\_trace}(\|p,\39\X1565:\.{"restoring"}\X);{}$\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}(\\{xeq\_level}[\|p]\I\\{level\_one}){}$\5
+${}\{{}$\5
+\1${}\\{eqtb}[\|p]\K\\{save\_stack}[\\{save\_ptr}];{}$\5
+${}\\{xeq\_level}[\|p]\K\|l;{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_restores}>\T{0}){}$\1\5
+${}\\{restore\_trace}(\|p,\39\X1565:\.{"restoring"}\X);{}$\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{STAT}\1\6
+\&{if} ${}(\\{tracing\_restores}>\T{0}){}$\1\5
+${}\\{restore\_trace}(\|p,\39\X1564:\.{"retaining"}\X);{}$\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\par
+\U282.\fi
+
+\M{284}\B\X284:Declare the procedure called \\{restore\_trace}\X${}\E{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{void} \\{restore\_trace}(\&{pointer} \|p${},\39{}$\&{str\_number} \|s)\C{\\{eqtb}[\|p] has just been restored or retained}\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_char}(\.{'\{'});\5
+\\{print}(\|s);\5
+\\{print\_char}(\.{'\ '});\5
+\\{show\_eqtb}(\|p);\5
+\\{print\_char}(\.{'\}'});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\U281.\fi
+
+\M{285}When looking for possible pointers to a memory location, it is helpful
+to look for references from \\{eqtb} that might be waiting on the
+save stack. Of course, we might find spurious pointers too; but this
+routine is merely an aid when debugging, and at such times we are
+grateful for any scraps of information, even if they prove to be irrelevant.
+
+\Y\B\4\X285:Search \\{save\_stack} for equivalents that point to \|p\X${}\E{}$\6
+\&{if} ${}(\\{save\_ptr}>\T{0}){}$\1\6
+\&{for} ${}(\|q\K\T{0};{}$ ${}\|q\Z\\{save\_ptr}-\T{1};{}$ ${}\|q\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{equiv\_field}(\\{save\_stack}[\|q])\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"SAVE("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\par
+\U172.\fi
+
+\M{286}Most of the parameters kept in \\{eqtb} can be changed freely, but there's
+an exception: The magnification should not be used with two different
+values during any \TeX\ job, since a single magnification is applied to an
+entire run. The global variable \\{mag\_set} is set to the current magnification
+whenever it becomes necessary to ``freeze'' it at a particular value.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{mag\_set};\C{if nonzero, this magnification should be used henceforth}\par
+\fi
+
+\M{287}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{mag\_set}\K\T{0}{}$;\par
+\fi
+
+\M{288}The \\{prepare\_mag} subroutine is called whenever \TeX\ wants to use \\{mag}
+for magnification.
+
+\Y\B\&{void} \\{prepare\_mag}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}((\\{mag\_set}>\T{0})\W(\\{mag}\I\\{mag\_set})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Incompatible\ magnif}\)\.{ication\ ("});\5
+\\{print\_int}(\\{mag});\5
+\\{print\_str}(\.{");"});\5
+\\{print\_nl}(\.{"\ the\ previous\ value}\)\.{\ will\ be\ retained"});\5
+\\{help2}(\.{"I\ can\ handle\ only\ o}\)\.{ne\ magnification\ rat}\)\.{io\ per\ job.\ So\ I've"})\6
+(\.{"reverted\ to\ the\ mag}\)\.{nification\ you\ used\ }\)\.{earlier\ on\ this\ run.}\)\.{"});\6
+\\{int\_error}(\\{mag\_set});\5
+${}\\{geq\_word\_define}(\\{int\_base}+\\{mag\_code},\39\\{mag\_set}){}$;\C{$\\{mag}\K\\{mag\_set}$}\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{mag}\Z\T{0})\V(\\{mag}>\T{32768})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ magnificati}\)\.{on\ has\ been\ changed\ }\)\.{to\ 1000"});\6
+\\{help1}(\.{"The\ magnification\ r}\)\.{atio\ must\ be\ between}\)\.{\ 1\ and\ 32768."});\5
+\\{int\_error}(\\{mag});\5
+${}\\{geq\_word\_define}(\\{int\_base}+\\{mag\_code},\39\T{1000});{}$\6
+\4${}\}{}$\2\6
+${}\\{mag\_set}\K\\{mag};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{289}Token lists.
+A \TeX\ token is either a character or a control sequence, and it is
+represented internally in one of two ways: (1)~A character whose ASCII
+code number is \|c and whose command code is \|m is represented as the
+number $2^8m+c$; the command code is in the range $\T{1}\Z\|m\Z\T{14}$. (2)~A control
+sequence whose \\{eqtb} address is \|p is represented as the number
+$\\{cs\_token\_flag}+\|p$. Here \\{cs\_token\_flag} $\E\hbox{$2^{12}-1$}$ is larger than
+$2^8m+c$, yet it is small enough that $\\{cs\_token\_flag}+\|p<\\{max\_halfword}$;
+thus, a token fits comfortably in a halfword.
+
+A token \|t represents a \\{left\_brace} command if and only if
+$\|t<\\{left\_brace\_limit}$; it represents a \\{right\_brace} command if and only if
+we have $\\{left\_brace\_limit}\Z\|t<\\{right\_brace\_limit}$; and it represents a \\{match} or
+\\{end\_match} command if and only if $\\{match\_token}\Z\|t\Z\\{end\_match\_token}$.
+The following definitions take care of these token-oriented constants
+and a few others.
+
+\Y\B\4\D$\\{cs\_token\_flag}$ \5
+\T{\~7777}\C{amount added to the \\{eqtb} location in a token that stands for a control sequence; is a multiple of~256, less~1}\par
+\B\4\D$\\{left\_brace\_token}$ \5
+\T{\~0400}\C{$2^8\cdot\\{left\_brace}$}\par
+\B\4\D$\\{left\_brace\_limit}$ \5
+\T{\~1000}\C{$2^8\cdot(\\{left\_brace}+1)$}\par
+\B\4\D$\\{right\_brace\_token}$ \5
+\T{\~1000}\C{$2^8\cdot\\{right\_brace}$}\par
+\B\4\D$\\{right\_brace\_limit}$ \5
+\T{\~1400}\C{$2^8\cdot(\\{right\_brace}+1)$}\par
+\B\4\D$\\{math\_shift\_token}$ \5
+\T{\~1400}\C{$2^8\cdot\\{math\_shift}$}\par
+\B\4\D$\\{tab\_token}$ \5
+\T{\~2000}\C{$2^8\cdot\\{tab\_mark}$}\par
+\B\4\D$\\{out\_param\_token}$ \5
+\T{\~2400}\C{$2^8\cdot\\{out\_param}$}\par
+\B\4\D$\\{space\_token}$ \5
+\T{\~5040}\C{$2^8\cdot\\{spacer}+\.{'\ '}$}\par
+\B\4\D$\\{letter\_token}$ \5
+\T{\~5400}\C{$2^8\cdot\\{letter}$}\par
+\B\4\D$\\{other\_token}$ \5
+\T{\~6000}\C{$2^8\cdot\\{other\_char}$}\par
+\B\4\D$\\{match\_token}$ \5
+\T{\~6400}\C{$2^8\cdot\\{match}$}\par
+\B\4\D$\\{end\_match\_token}$ \5
+\T{\~7000}\C{$2^8\cdot\\{end\_match}$}\par
+\fi
+
+\M{290}\B\X14:Check the ``constant'' values for consistency\X${}\mathrel+\E{}$\6
+\&{if} ${}(\\{cs\_token\_flag}+\\{undefined\_control\_sequence}>\\{max\_halfword}){}$\1\5
+${}\\{bad}\K\T{21}{}$;\2\par
+\fi
+
+\M{291}A token list is a singly linked list of one-word nodes in \\{mem}, where
+each word contains a token and a link. Macro definitions, output-routine
+definitions, marks, \.{\\write} texts, and a few other things
+are remembered by \TeX\ in the form
+of token lists, usually preceded by a node with a reference count in its
+\\{token\_ref\_count} field. The token stored in location \|p is called
+\\{info}(\|p).
+
+Three special commands appear in the token lists of macro definitions.
+When $\|m\E\\{match}$, it means that \TeX\ should scan a parameter
+for the current macro; when $\|m\E\\{end\_match}$, it means that parameter
+matching should end and \TeX\ should start reading the macro text; and
+when $\|m\E\\{out\_param}$, it means that \TeX\ should insert parameter
+number \|c into the text at this point.
+
+The enclosing \.{\char'173} and \.{\char'175} characters of a macro
+definition are omitted, but the final right brace of an output routine
+is included at the end of its token list.
+
+Here is an example macro definition that illustrates these conventions.
+After \TeX\ processes the text
+$$\.{\\def\\mac a\#1\#2 \\b \{\#1\\-a \#\#1\#2 \#2\}}$$
+the definition of \.{\\mac} is represented as a token list containing
+$$\def\,{\hskip2pt}
+\vbox{\halign{\hfil#\hfil\cr
+(reference count), \\{letter}\,\.a, \\{match}\,\#, \\{match}\,\#, \\{spacer}\,\.\ ,
+\.{\\b}, \\{end\_match},\cr
+\\{out\_param}\,1, \.{\\-}, \\{letter}\,\.a, \\{spacer}\,\.\ , \\{mac\_param}\,\#,
+\\{other\_char}\,\.1,\cr
+\\{out\_param}\,2, \\{spacer}\,\.\ , \\{out\_param}\,2.\cr}}$$
+The procedure \\{scan\_toks} builds such token lists, and \\{macro\_call}
+does the parameter matching.
+
+Examples such as
+$$\.{\\def\\m\{\\def\\m\{a\}\ b\}}$$
+explain why reference counts would be needed even if \TeX\ had no \.{\\let}
+operation: When the token list for \.{\\m} is being read, the redefinition of
+\.{\\m} changes the \\{eqtb} entry before the token list has been fully
+consumed, so we dare not simply destroy a token list when its
+control sequence is being redefined.
+
+If the parameter-matching part of a definition ends with `\.{\#\{}',
+the corresponding token list will have `\.\{' just before the `\\{end\_match}'
+and also at the very end. The first `\.\{' is used to delimit the parameter; the
+second one keeps the first from disappearing.
+
+\fi
+
+\M{292}The procedure \\{show\_token\_list}, which prints a symbolic form of
+the token list that starts at a given node \|p, illustrates these
+conventions. The token list being displayed should not begin with a reference
+count. However, the procedure is intended to be robust, so that if the
+memory links are awry or if \|p is not really a pointer to a token list,
+nothing catastrophic will happen.
+
+An additional parameter \|q is also given; this parameter is either null
+or it points to a node in the token list where a certain magic computation
+takes place that will be explained later. (Basically, \|q is non-null when
+we are printing the two-line context information at the time of an error
+message; \|q marks the place corresponding to where the second line
+should begin.)
+
+For example, if \|p points to the node containing the first \.a in the
+token list above, then \\{show\_token\_list} will print the string
+$$\hbox{`\.{a\#1\#2\ \\b\ ->\#1\\-a\ \#\#1\#2\ \#2}';}$$
+and if \|q points to the node containing the second \.a,
+the magic computation will be performed just before the second \.a is printed.
+
+The generation will stop, and `\.{\\ETC.}' will be printed, if the length
+of printing exceeds a given limit~\|l. Anomalous entries are printed in the
+form of control sequences that are not followed by a blank space, e.g.,
+`\.{\\BAD.}'; this cannot be confused with actual control sequences because
+a real control sequence named \.{BAD} would come out `\.{\\BAD\ }'.
+
+\Y\B\4\X292:Declare the procedure called \\{show\_token\_list}\X${}\E{}$\6
+\&{void} \\{show\_token\_list}(\&{int} \|p${},\39{}$\&{int} \|q${},\39{}$\&{int} \|l)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|m${},{}$ \|c;\C{pieces of a token}\6
+\&{ASCII\_code} \\{match\_chr};\C{character used in a `\\{match}'}\6
+\&{ASCII\_code} \|n;\C{the highest parameter number, as an ASCII digit}\7
+${}\\{match\_chr}\K\.{'\#'};{}$\5
+${}\|n\K\.{'0'};{}$\5
+${}\\{tally}\K\T{0};{}$\6
+\&{while} ${}((\|p\I\\{null})\W(\\{tally}<\|l)){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|p\E\|q){}$\1\5
+\X320:Do magic computation\X;\2\6
+\X293:Display token \|p, and \&{return} if there are problems\X;\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|p\I\\{null}){}$\1\5
+\\{print\_esc}(\X1566:\.{"ETC."}\X);\2\6
+\4${}\}{}$\2\par
+\U119.\fi
+
+\M{293}\B\X293:Display token \|p, and \&{return} if there are problems\X${}\E{}$\6
+\&{if} ${}((\|p<\\{hi\_mem\_min})\V(\|p>\\{mem\_end})){}$\5
+${}\{{}$\5
+\1\\{print\_esc}(\X1386:\.{"CLOBBERED."}\X);\5
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{info}(\|p)\G\\{cs\_token\_flag}){}$\1\5
+${}\\{print\_cs}(\\{info}(\|p)-\\{cs\_token\_flag});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|m\K\\{info}(\|p)/\T{\~400};{}$\5
+${}\|c\K\\{info}(\|p)\MOD\T{\~400};{}$\6
+\&{if} ${}(\\{info}(\|p)<\T{0}){}$\1\5
+\\{print\_esc}(\X1567:\.{"BAD."}\X);\2\6
+\&{else}\1\5
+\X294:Display the token $(\|m,\|c)$\X;\2\6
+\4${}\}{}$\2\par
+\U292.\fi
+
+\M{294}The procedure usually ``learns'' the character code used for macro
+parameters by seeing one in a \\{match} command before it runs into any
+\\{out\_param} commands.
+
+\Y\B\4\X294:Display the token $(\|m,\|c)$\X${}\E{}$\6
+\&{switch} (\|m)\5
+${}\{{}$\1\6
+\4\&{case} \\{left\_brace}:\5
+\&{case} \\{right\_brace}:\5
+\&{case} \\{math\_shift}:\5
+\&{case} \\{tab\_mark}:\5
+\&{case} \\{sup\_mark}:\5
+\&{case} \\{sub\_mark}:\5
+\&{case} \\{spacer}:\5
+\&{case} \\{letter}:\5
+\&{case} \\{other\_char}:\5
+\\{print}(\|c);\5
+\&{break};\6
+\4\&{case} \\{mac\_param}:\6
+${}\{{}$\5
+\1\\{print}(\|c);\5
+\\{print}(\|c);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{out\_param}:\6
+${}\{{}$\5
+\1\\{print}(\\{match\_chr});\6
+\&{if} ${}(\|c\Z\T{9}){}$\1\5
+${}\\{print\_char}(\|c+\.{'0'});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_char}(\.{'!'});\5
+\&{return};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{match}:\6
+${}\{{}$\5
+\1${}\\{match\_chr}\K\|c;{}$\5
+\\{print}(\|c);\5
+\\{incr}(\|n);\5
+\\{print\_char}(\|n);\6
+\&{if} ${}(\|n>\.{'9'}){}$\1\5
+\&{return};\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{end\_match}:\5
+\\{print\_str}(\.{"->"});\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1567:\.{"BAD."}\X);\6
+\4${}\}{}$\2\par
+\U293.\fi
+
+\M{295}Here's the way we sometimes want to display a token list, given a pointer
+to its reference count; the pointer may be null.
+
+\Y\B\&{void} \\{token\_show}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|p\I\\{null}){}$\1\5
+${}\\{show\_token\_list}(\\{link}(\|p),\39\\{null},\39\T{10000000});{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{296}The \\{print\_meaning} subroutine displays \\{cur\_cmd} and \\{cur\_chr} in
+symbolic form, including the expansion of a macro or mark.
+
+\Y\B\&{void} \\{print\_meaning}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\6
+\&{if} ${}(\\{cur\_cmd}\G\\{call}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{':'});\5
+\\{print\_ln}(\,);\5
+\\{token\_show}(\\{cur\_chr});\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{top\_bot\_mark}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{':'});\5
+\\{print\_ln}(\,);\5
+\\{token\_show}(\\{cur\_mark}[\\{cur\_chr}]);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{297}Introduction to the syntactic routines.
+Let's pause a moment now and try to look at the Big Picture.
+The \TeX\ program consists of three main parts: syntactic routines,
+semantic routines, and output routines. The chief purpose of the
+syntactic routines is to deliver the user's input to the semantic routines,
+one token at a time. The semantic routines act as an interpreter
+responding to these tokens, which may be regarded as commands. And the
+output routines are periodically called on to convert box-and-glue
+lists into a compact set of instructions that will be sent
+to a typesetter. We have discussed the basic data structures and utility
+routines of \TeX, so we are good and ready to plunge into the real activity by
+considering the syntactic routines.
+
+Our current goal is to come to grips with the \\{get\_next} procedure,
+which is the keystone of \TeX's input mechanism. Each call of \\{get\_next}
+sets the value of three variables \\{cur\_cmd}, \\{cur\_chr}, and \\{cur\_cs},
+representing the next input token.
+$$\vbox{\halign{#\hfil\cr
+\hbox{\\{cur\_cmd} denotes a command code from the long list of codes
+given above;}\cr
+\hbox{\\{cur\_chr} denotes a character code or other modifier of the command
+code;}\cr
+\hbox{\\{cur\_cs} is the \\{eqtb} location of the current control sequence,}\cr
+\hbox{\qquad if the current token was a control sequence,
+otherwise it's zero.}\cr}}$$
+Underlying this external behavior of \\{get\_next} is all the machinery
+necessary to convert from character files to tokens. At a given time we
+may be only partially finished with the reading of several files (for
+which \.{\\input} was specified), and partially finished with the expansion
+of some user-defined macros and/or some macro parameters, and partially
+finished with the generation of some text in a template for \.{\\halign},
+and so on. When reading a character file, special characters must be
+classified as math delimiters, etc.; comments and extra blank spaces must
+be removed, paragraphs must be recognized, and control sequences must be
+found in the hash table. Furthermore there are occasions in which the
+scanning routines have looked ahead for a word like `\.{plus}' but only
+part of that word was found, hence a few characters must be put back
+into the input and scanned again.
+
+To handle these situations, which might all be present simultaneously,
+\TeX\ uses various stacks that hold information about the incomplete
+activities, and there is a finite state control for each level of the
+input mechanism. These stacks record the current state of an implicitly
+recursive process, but the \\{get\_next} procedure is not recursive.
+Therefore it will not be difficult to translate these algorithms into
+low-level languages that do not support recursion.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{eight\_bits} \\{cur\_cmd};\C{current command set by \\{get\_next}}\6
+\&{halfword} \\{cur\_chr};\C{operand of current command}\6
+\&{pointer} \\{cur\_cs};\C{control sequence found here, zero if none found}\6
+\&{halfword} \\{cur\_tok};\C{packed representative of \\{cur\_cmd} and \\{cur\_chr}}\par
+\fi
+
+\M{298}The \\{print\_cmd\_chr} routine prints a symbolic interpretation of a
+command code and its modifier. This is used in certain `\.{You can\'t}'
+error messages, and in the implementation of diagnostic routines like
+\.{\\show}.
+
+The body of \\{print\_cmd\_chr} is a rather tedious listing of print
+commands, and most of it is essentially an inverse to the \\{primitive}
+routine that enters a \TeX\ primitive into \\{eqtb}. Therefore much of
+this procedure appears elsewhere in the program,
+together with the corresponding \\{primitive} calls.
+
+\Y\B\4\D$\\{chr\_cmd}(\|X)$ \6
+${}\{{}$\5
+\1\\{print\_str}(\|X);\5
+\\{print\_ASCII}(\\{chr\_code});\6
+\4${}\}{}$\2\par
+\Y\B\4\X298:Declare the procedure called \\{print\_cmd\_chr}\X${}\E{}$\6
+\&{void} \\{print\_cmd\_chr}(\&{quarterword} \\{cmd}${},\39{}$\&{halfword} \\{chr\_code})\1\1\2\2\6
+${}\{{}$\5
+\1\&{switch} (\\{cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{left\_brace}:\5
+\\{chr\_cmd}(\.{"begin-group\ charact}\)\.{er\ "})\5
+\&{break};\6
+\4\&{case} \\{right\_brace}:\5
+\\{chr\_cmd}(\.{"end-group\ character}\)\.{\ "})\5
+\&{break};\6
+\4\&{case} \\{math\_shift}:\5
+\\{chr\_cmd}(\.{"math\ shift\ characte}\)\.{r\ "})\5
+\&{break};\6
+\4\&{case} \\{mac\_param}:\5
+\\{chr\_cmd}(\.{"macro\ parameter\ cha}\)\.{racter\ "})\5
+\&{break};\6
+\4\&{case} \\{sup\_mark}:\5
+\\{chr\_cmd}(\.{"superscript\ charact}\)\.{er\ "})\5
+\&{break};\6
+\4\&{case} \\{sub\_mark}:\5
+\\{chr\_cmd}(\.{"subscript\ character}\)\.{\ "})\5
+\&{break};\6
+\4\&{case} \\{endv}:\5
+\\{print\_str}(\.{"end\ of\ alignment\ te}\)\.{mplate"});\5
+\&{break};\6
+\4\&{case} \\{spacer}:\5
+\\{chr\_cmd}(\.{"blank\ space\ "})\5
+\&{break};\6
+\4\&{case} \\{letter}:\5
+\\{chr\_cmd}(\.{"the\ letter\ "})\5
+\&{break};\6
+\4\&{case} \\{other\_char}:\5
+\\{chr\_cmd}(\.{"the\ character\ "})\5
+\&{break};\5
+\hbox{\4}\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X\6
+\4\&{default}:\5
+\\{print\_str}(\.{"[unknown\ command\ co}\)\.{de!]"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U252.\fi
+
+\M{299}Here is a procedure that displays the current command.
+
+\Y\B\&{void} \\{show\_cur\_cmd\_chr}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"\{"});\6
+\&{if} ${}(\\{mode}\I\\{shown\_mode}){}$\5
+${}\{{}$\5
+\1\\{print\_mode}(\\{mode});\5
+\\{print\_str}(\.{":\ "});\5
+${}\\{shown\_mode}\K\\{mode};{}$\6
+\4${}\}{}$\2\6
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_char}(\.{'\}'});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{300}Input stacks and states.
+This implementation of
+\TeX\ uses two different conventions for representing sequential stacks.
+
+\yskip\hangg 1) If there is frequent access to the top entry, and if the
+stack is essentially never empty, then the top entry is kept in a global
+variable (even better would be a machine register), and the other entries
+appear in the array $\\{stack}[0\to(\\{ptr}-1)]$. For example, the
+semantic stack described above is handled this way, and so is the input
+stack that we are about to study.
+
+\yskip\hangg 2) If there is infrequent top access, the entire stack contents
+are in the array $\\{stack}[0\to(\\{ptr}-1)]$. For example, the \\{save\_stack}
+is treated this way, as we have seen.
+
+\yskip\noindent
+The state of \TeX's input mechanism appears in the input stack, whose
+entries are records with six fields, called \\{state}, \\{index}, \\{start}, \\{loc},
+\\{limit}, and \\{name}. This stack is maintained with
+convention~(1), so it is declared in the following way:
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{struct} ${}\{{}$\1\6
+\&{quarterword} \\{state\_field}${},{}$ \\{index\_field};\6
+\&{halfword} \\{start\_field}${},{}$ \\{loc\_field}${},{}$ \\{limit\_field}${},{}$ \\{name\_field};\2\6
+${}\}{}$ \&{in\_state\_record};\par
+\fi
+
+\M{301}\B\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{in\_state\_record} ${}\\{input\_stack}[\\{stack\_size}+\T{1}];{}$\6
+\&{uint8\_t} \\{input\_ptr};\C{first unused location of \\{input\_stack}}\6
+\&{uint8\_t} \\{max\_in\_stack};\C{largest value of \\{input\_ptr} when pushing}\6
+\&{in\_state\_record} \\{cur\_input};\C{the ``top'' input state, according to convention (1)}\par
+\fi
+
+\M{302}We've already defined the special variable $\\{loc}\MRL{{\E}{\E}}\\{cur\_input}.\\{loc\_field}$
+in our discussion of basic input-output routines. The other components of
+\\{cur\_input} are defined in the same way:
+
+\Y\B\4\D$\\{state}$ \5
+$\\{cur\_input}.{}$\\{state\_field}\C{current scanner state}\par
+\B\4\D$\\{index}$ \5
+$\\{cur\_input}.{}$\\{index\_field}\C{reference for buffer information}\par
+\B\4\D$\\{start}$ \5
+$\\{cur\_input}.{}$\\{start\_field}\C{starting position in \\{buffer}}\par
+\B\4\D$\\{limit}$ \5
+$\\{cur\_input}.{}$\\{limit\_field}\C{end of current line in \\{buffer}}\par
+\B\4\D$\\{name}$ \5
+$\\{cur\_input}.{}$\\{name\_field}\C{name of the current file}\par
+\fi
+
+\M{303}Let's look more closely now at the control variables
+(\\{state},~\\{index},~\\{start},~\\{loc},~\\{limit},~\\{name}),
+assuming that \TeX\ is reading a line of characters that have been input
+from some file or from the user's terminal. There is an array called
+\\{buffer} that acts as a stack of all lines of characters that are
+currently being read from files, including all lines on subsidiary
+levels of the input stack that are not yet completed. \TeX\ will return to
+the other lines when it is finished with the present input file.
+
+(Incidentally, on a machine with byte-oriented addressing, it might be
+appropriate to combine \\{buffer} with the \\{str\_pool} array,
+letting the buffer entries grow downward from the top of the string pool
+and checking that these two tables don't bump into each other.)
+
+The line we are currently working on begins in position \\{start} of the
+buffer; the next character we are about to read is \\{buffer}[\\{loc}]; and
+\\{limit} is the location of the last character present. If $\\{loc}>\\{limit}$,
+the line has been completely read. Usually \\{buffer}[\\{limit}] is the
+\\{end\_line\_char}, denoting the end of a line, but this is not
+true if the current line is an insertion that was entered on the user's
+terminal in response to an error message.
+
+The \\{name} variable is a string number that designates the name of
+the current file, if we are reading a text file. It is zero if we
+are reading from the terminal; it is $\|n+\T{1}$ if we are reading from
+input stream \|n, where $\T{0}\Z\|n\Z\T{16}$. (Input stream 16 stands for
+an invalid stream number; in such cases the input is actually from
+the terminal, under control of the procedure \\{read\_toks}.)
+
+The \\{state} variable has one of three values, when we are scanning such
+files:
+$$\baselineskip 15pt\vbox{\halign{#\hfil\cr
+1) $\\{state}\E\\{mid\_line}$ is the normal state.\cr
+2) $\\{state}\E\\{skip\_blanks}$ is like \\{mid\_line}, but blanks are ignored.\cr
+3) $\\{state}\E\\{new\_line}$ is the state at the beginning of a line.\cr}}$$
+These state values are assigned numeric codes so that if we add the state
+code to the next character's command code, we get distinct values. For
+example, `$\\{mid\_line}+\\{spacer}$' stands for the case that a blank
+space character occurs in the middle of a line when it is not being
+ignored; after this case is processed, the next value of \\{state} will
+be \\{skip\_blanks}.
+
+\Y\B\4\D$\\{mid\_line}$ \5
+\T{1}\C{\\{state} code when scanning a line of characters}\par
+\B\4\D$\\{skip\_blanks}$ \5
+$(\T{2}+\\{max\_char\_code}{}$)\C{\\{state} code when ignoring blanks}\par
+\B\4\D$\\{new\_line}$ \5
+$(\T{3}+\\{max\_char\_code}+\\{max\_char\_code}{}$)\C{\\{state} code at start of line}\par
+\fi
+
+\M{304}Additional information about the current line is available via the
+\\{index} variable, which counts how many lines of characters are present
+in the buffer below the current level. We have $\\{index}\E\T{0}$ when reading
+from the terminal and prompting the user for each line; then if the user types,
+e.g., `\.{\\input paper}', we will have $\\{index}\E\T{1}$ while reading
+the file \.{paper.tex}. However, it does not follow that \\{index} is the
+same as the input stack pointer, since many of the levels on the input
+stack may come from token lists. For example, the instruction `\.{\\input
+paper}' might occur in a token list.
+
+The global variable \\{in\_open} is equal to the \\{index}
+value of the highest non-token-list level. Thus, the number of partially read
+lines in the buffer is $\\{in\_open}+\T{1}$, and we have $\\{in\_open}\E\\{index}$
+when we are not reading a token list.
+
+If we are not currently reading from the terminal, or from an input
+stream, we are reading from the file variable \\{input\_file}[\\{index}]. We use
+the notation \\{terminal\_input} as a convenient abbreviation for $\\{name}\E\T{0}$,
+and \\{cur\_file} as an abbreviation for \\{input\_file}[\\{index}].
+
+The global variable \\{line} contains the line number in the topmost
+open file, for use in error messages. If we are not reading from
+the terminal, \\{line\_stack}[\\{index}] holds the line number for the
+enclosing level, so that \\{line} can be restored when the current
+file has been read. Line numbers should never be negative, since the
+negative of the current line number is used to identify the user's output
+routine in the \\{mode\_line} field of the semantic nest entries.
+
+If more information about the input state is needed, it can be
+included in small arrays like those shown here. For example,
+the current page or segment number in the input file might be
+put into a variable \\{page}, maintained for enclosing levels in
+`\ignorespaces\\{page\_stack}: $\\{array}[\T{1}\dotdot\\{max\_in\_open}]{}$ \&{int}\unskip'
+by analogy with \\{line\_stack}.
+
+\Y\B\4\D$\\{terminal\_input}$ \5
+$(\\{name}\E\T{0}{}$)\C{are we reading from the terminal?}\par
+\B\4\D$\\{cur\_file}$ \5
+\\{input\_file}[\\{index}]\C{the current \&{alpha\_file} variable}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{in\_open};\C{the number of lines in the buffer, less one}\6
+\&{uint8\_t} \\{open\_parens};\C{the number of open text files}\6
+\&{alpha\_file} \\{input\_file0}[\\{max\_in\_open}]${},{}$ ${}{*\&{const}\ }\\{input\_file}\K\\{input\_file0}-\T{1};{}$\6
+\&{int} \\{line};\C{current line number in the current source file}\6
+\&{int} \\{line\_stack0}[\\{max\_in\_open}]${},{}$ ${}{*\&{const}\ }\\{line\_stack}\K\\{line\_stack0}-\T{1}{}$;\par
+\fi
+
+\M{305}Users of \TeX\ sometimes forget to balance left and right braces properly,
+and one of the ways \TeX\ tries to spot such errors is by considering an
+input file as broken into subfiles by control sequences that
+are declared to be \.{\\outer}.
+
+A variable called \\{scanner\_status} tells \TeX\ whether or not to complain
+when a subfile ends. This variable has six possible values:
+
+\yskip\hang\\{normal}, means that a subfile can safely end here without incident.
+
+\yskip\hang\\{skipping}, means that a subfile can safely end here, but not a file,
+because we're reading past some conditional text that was not selected.
+
+\yskip\hang\\{defining}, means that a subfile shouldn't end now because a
+macro is being defined.
+
+\yskip\hang\\{matching}, means that a subfile shouldn't end now because a
+macro is being used and we are searching for the end of its arguments.
+
+\yskip\hang\\{aligning}, means that a subfile shouldn't end now because we are
+not finished with the preamble of an \.{\\halign} or \.{\\valign}.
+
+\yskip\hang\\{absorbing}, means that a subfile shouldn't end now because we are
+reading a balanced token list for \.{\\message}, \.{\\write}, etc.
+
+\yskip\noindent
+If the \\{scanner\_status} is not \\{normal}, the variable \\{warning\_index} points
+to the \\{eqtb} location for the relevant control sequence name to print
+in an error message.
+
+\Y\B\4\D$\\{skipping}$ \5
+\T{1}\C{\\{scanner\_status} when passing conditional text}\par
+\B\4\D$\\{defining}$ \5
+\T{2}\C{\\{scanner\_status} when reading a macro definition}\par
+\B\4\D$\\{matching}$ \5
+\T{3}\C{\\{scanner\_status} when reading macro arguments}\par
+\B\4\D$\\{aligning}$ \5
+\T{4}\C{\\{scanner\_status} when reading an alignment preamble}\par
+\B\4\D$\\{absorbing}$ \5
+\T{5}\C{\\{scanner\_status} when reading a balanced text}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{scanner\_status};\C{can a subfile end now?}\6
+\&{pointer} \\{warning\_index};\C{identifier relevant to non-\\{normal} scanner status}\6
+\&{pointer} \\{def\_ref};\C{reference count of token list being defined}\par
+\fi
+
+\M{306}Here is a procedure that uses \\{scanner\_status} to print a warning message
+when a subfile has ended, and at certain other crucial times:
+
+\Y\B\4\X306:Declare the procedure called \\{runaway}\X${}\E{}$\6
+\&{void} \\{runaway}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{head of runaway list}\7
+\&{if} ${}(\\{scanner\_status}>\\{skipping}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Runaway\ "});\6
+\&{switch} (\\{scanner\_status})\5
+${}\{{}$\1\6
+\4\&{case} \\{defining}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"definition"});\5
+${}\|p\K\\{def\_ref};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{matching}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"argument"});\5
+${}\|p\K\\{temp\_head};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{aligning}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"preamble"});\5
+${}\|p\K\\{hold\_head};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{absorbing}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"text"});\5
+${}\|p\K\\{def\_ref};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\6
+\\{print\_char}(\.{'?'});\5
+\\{print\_ln}(\,);\5
+${}\\{show\_token\_list}(\\{link}(\|p),\39\\{null},\39\\{error\_line}-\T{10});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U119.\fi
+
+\M{307}However, all this discussion about input state really applies only to the
+case that we are inputting from a file. There is another important case,
+namely when we are currently getting input from a token list. In this case
+$\\{state}\E\\{token\_list}$, and the conventions about the other state variables
+are different:
+
+\yskip\hang\\{loc} is a pointer to the current node in the token list, i.e.,
+the node that will be read next. If $\\{loc}\E\\{null}$, the token list has been
+fully read.
+
+\yskip\hang\\{start} points to the first node of the token list; this node
+may or may not contain a reference count, depending on the type of token
+list involved.
+
+\yskip\hang\\{token\_type}, which takes the place of \\{index} in the
+discussion above, is a code number that explains what kind of token list
+is being scanned.
+
+\yskip\hang\\{name} points to the \\{eqtb} address of the control sequence
+being expanded, if the current token list is a macro.
+
+\yskip\hang\\{param\_start}, which takes the place of \\{limit}, tells where
+the parameters of the current macro begin in the \\{param\_stack}, if the
+current token list is a macro.
+
+\yskip\noindent The \\{token\_type} can take several values, depending on
+where the current token list came from:
+
+\yskip\hang\\{parameter}, if a parameter is being scanned;
+
+\hang\\{u\_template}, if the \<u_j> part of an alignment
+template is being scanned;
+
+\hang\\{v\_template}, if the \<v_j> part of an alignment
+template is being scanned;
+
+\hang\\{backed\_up}, if the token list being scanned has been inserted as
+`to be read again'.
+
+\hang\\{inserted}, if the token list being scanned has been inserted as
+the text expansion of a \.{\\count} or similar variable;
+
+\hang\\{macro}, if a user-defined control sequence is being scanned;
+
+\hang\\{output\_text}, if an \.{\\output} routine is being scanned;
+
+\hang\\{every\_par\_text}, if the text of \.{\\everypar} is being scanned;
+
+\hang\\{every\_math\_text}, if the text of \.{\\everymath} is being scanned;
+
+\hang\\{every\_display\_text}, if the text of \.{\\everydisplay} is being scanned;
+
+\hang\\{every\_hbox\_text}, if the text of \.{\\everyhbox} is being scanned;
+
+\hang\\{every\_vbox\_text}, if the text of \.{\\everyvbox} is being scanned;
+
+\hang\\{every\_job\_text}, if the text of \.{\\everyjob} is being scanned;
+
+\hang\\{every\_cr\_text}, if the text of \.{\\everycr} is being scanned;
+
+\hang\\{mark\_text}, if the text of a \.{\\mark} is being scanned;
+
+\hang\\{write\_text}, if the text of a \.{\\write} is being scanned.
+
+\yskip\noindent
+The codes for \\{output\_text}, \\{every\_par\_text}, etc., are equal to a constant
+plus the corresponding codes for token list parameters \\{output\_routine\_loc},
+\\{every\_par\_loc}, etc. The token list begins with a reference count if and
+only if $\\{token\_type}\G\\{macro}$.
+
+\Y\B\4\D$\\{token\_list}$ \5
+\T{0}\C{\\{state} code when scanning a token list}\par
+\B\4\D$\\{token\_type}$ \5
+\\{index}\C{type of current token list}\par
+\B\4\D$\\{param\_start}$ \5
+\\{limit}\C{base of macro parameters in \\{param\_stack}}\par
+\B\4\D$\\{parameter}$ \5
+\T{0}\C{\\{token\_type} code for parameter}\par
+\B\4\D$\\{u\_template}$ \5
+\T{1}\C{\\{token\_type} code for \<u_j> template}\par
+\B\4\D$\\{v\_template}$ \5
+\T{2}\C{\\{token\_type} code for \<v_j> template}\par
+\B\4\D$\\{backed\_up}$ \5
+\T{3}\C{\\{token\_type} code for text to be reread}\par
+\B\4\D$\\{inserted}$ \5
+\T{4}\C{\\{token\_type} code for inserted texts}\par
+\B\4\D$\\{macro}$ \5
+\T{5}\C{\\{token\_type} code for defined control sequences}\par
+\B\4\D$\\{output\_text}$ \5
+\T{6}\C{\\{token\_type} code for output routines}\par
+\B\4\D$\\{every\_par\_text}$ \5
+\T{7}\C{\\{token\_type} code for \.{\\everypar}}\par
+\B\4\D$\\{every\_math\_text}$ \5
+\T{8}\C{\\{token\_type} code for \.{\\everymath}}\par
+\B\4\D$\\{every\_display\_text}$ \5
+\T{9}\C{\\{token\_type} code for \.{\\everydisplay}}\par
+\B\4\D$\\{every\_hbox\_text}$ \5
+\T{10}\C{\\{token\_type} code for \.{\\everyhbox}}\par
+\B\4\D$\\{every\_vbox\_text}$ \5
+\T{11}\C{\\{token\_type} code for \.{\\everyvbox}}\par
+\B\4\D$\\{every\_job\_text}$ \5
+\T{12}\C{\\{token\_type} code for \.{\\everyjob}}\par
+\B\4\D$\\{every\_cr\_text}$ \5
+\T{13}\C{\\{token\_type} code for \.{\\everycr}}\par
+\B\4\D$\\{mark\_text}$ \5
+\T{14}\C{\\{token\_type} code for \.{\\topmark}, etc.}\par
+\B\4\D$\\{write\_text}$ \5
+\T{15}\C{\\{token\_type} code for \.{\\write}}\par
+\fi
+
+\M{308}The \\{param\_stack} is an auxiliary array used to hold pointers to the token
+lists for parameters at the current level and subsidiary levels of input.
+This stack is maintained with convention (2), and it grows at a different
+rate from the others.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} ${}\\{param\_stack}[\\{param\_size}+\T{1}]{}$;\C{token list pointers for parameters}\6
+\&{uint8\_t} \\{param\_ptr};\C{first unused entry in \\{param\_stack}}\6
+\&{int} \\{max\_param\_stack};\C{largest value of \\{param\_ptr}, will be $\Z$ $\\{param\_size}+\T{9}$}\par
+\fi
+
+\M{309}The input routines must also interact with the processing of
+\.{\\halign} and \.{\\valign}, since the appearance of tab marks and
+\.{\\cr} in certain places is supposed to trigger the beginning of special
+\<v_j> template text in the scanner. This magic is accomplished by an
+\\{align\_state} variable that is increased by~1 when a `\.{\char'173}' is
+scanned and decreased by~1 when a `\.{\char'175}' is scanned. The \\{align\_state}
+is nonzero during the \<u_j> template, after which it is set to zero; the
+\<v_j> template begins when a tab mark or \.{\\cr} occurs at a time that
+$\\{align\_state}\E\T{0}$.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{align\_state};\C{group level with respect to current alignment}\par
+\fi
+
+\M{310}Thus, the ``current input state'' can be very complicated indeed; there
+can be many levels and each level can arise in a variety of ways. The
+\\{show\_context} procedure, which is used by \TeX's error-reporting routine to
+print out the current input state on all levels down to the most recent
+line of characters from an input file, illustrates most of these conventions.
+The global variable \\{base\_ptr} contains the lowest level that was
+displayed by this procedure.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{base\_ptr};\C{shallowest level shown by \\{show\_context}}\par
+\fi
+
+\M{311}The status at each level is indicated by printing two lines, where the first
+line indicates what was read so far and the second line shows what remains
+to be read. The context is cropped, if necessary, so that the first line
+contains at most \\{half\_error\_line} characters, and the second contains
+at most \\{error\_line}. Non-current input levels whose \\{token\_type} is
+`\\{backed\_up}' are shown only if they have not been fully read.
+
+\Y\B\&{void} \\{show\_context}(\&{void})\C{prints where the scanner is}\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{saved \\{selector} setting}\6
+\&{int} \\{nn};\C{number of contexts shown so far, less one}\6
+\&{bool} \\{bottom\_line};\C{have we reached the final context to be shown?}\7
+\X315:Local variables for formatting calculations\X\6
+${}\\{base\_ptr}\K\\{input\_ptr};{}$\5
+${}\\{input\_stack}[\\{base\_ptr}]\K\\{cur\_input}{}$;\C{store current state}\6
+${}\\{nn}\K{-}\T{1};{}$\5
+${}\\{bottom\_line}\K\\{false};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1${}\\{cur\_input}\K\\{input\_stack}[\\{base\_ptr}]{}$;\C{enter into the context}\6
+\&{if} ${}((\\{state}\I\\{token\_list})){}$\1\6
+\&{if} ${}((\\{name}>\T{17})\V(\\{base\_ptr}\E\T{0})){}$\1\5
+${}\\{bottom\_line}\K\\{true};{}$\2\2\6
+\&{if} ${}((\\{base\_ptr}\E\\{input\_ptr})\V\\{bottom\_line}\V(\\{nn}<\\{error\_context\_lines})){}$\1\5
+\X312:Display the current context\X\2\6
+\&{else} \&{if} ${}(\\{nn}\E\\{error\_context\_lines}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"..."});\5
+\\{incr}(\\{nn});\C{omitted if $\\{error\_context\_lines}<\T{0}$}\6
+\4${}\}{}$\2\6
+\&{if} (\\{bottom\_line})\1\5
+\&{goto} \\{done};\2\6
+\\{decr}(\\{base\_ptr});\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+${}\\{cur\_input}\K\\{input\_stack}[\\{input\_ptr}]{}$;\C{restore original state}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{312}\B\X312:Display the current context\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\\{base\_ptr}\E\\{input\_ptr})\V(\\{state}\I\\{token\_list})\V(\\{token\_type}\I\\{backed\_up})\V(\\{loc}\I\\{null}){}$)\C{we omit backed-up token lists that have already been read}\6
+${}\{{}$\5
+\1${}\\{tally}\K\T{0}{}$;\C{get ready to count characters}\6
+${}\\{old\_setting}\K\\{selector};{}$\6
+\&{if} ${}(\\{state}\I\\{token\_list}){}$\5
+${}\{{}$\5
+\1\X313:Print location of current line\X;\6
+\X318:Pseudoprint the line\X;\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\X314:Print type of token list\X;\6
+\X319:Pseudoprint the token list\X;\6
+\4${}\}{}$\2\6
+${}\\{selector}\K\\{old\_setting}{}$;\C{stop pseudoprinting}\6
+\X317:Print two lines using the tricky pseudoprinted information\X;\6
+\\{incr}(\\{nn});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U311.\fi
+
+\M{313}This routine should be changed, if necessary, to give the best possible
+indication of where the current line resides in the input file.
+For example, on some systems it is best to print both a page and line number.
+
+\Y\B\4\X313:Print location of current line\X${}\E{}$\6
+\&{if} ${}(\\{name}\Z\T{17}){}$\1\6
+\&{if} (\\{terminal\_input})\1\6
+\&{if} ${}(\\{base\_ptr}\E\T{0}){}$\1\5
+\\{print\_nl}(\.{"<*>"});\2\6
+\&{else}\1\5
+\\{print\_nl}(\.{"<insert>\ "});\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"<read\ "});\6
+\&{if} ${}(\\{name}\E\T{17}){}$\1\5
+\\{print\_char}(\.{'*'});\5
+\2\&{else}\1\5
+${}\\{print\_int}(\\{name}-\T{1});{}$\2\6
+\\{print\_char}(\.{'>'});\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"l."});\5
+\\{print\_int}(\\{line});\6
+\4${}\}{}$\2\6
+\\{print\_char}(\.{'\ '})\par
+\U312.\fi
+
+\M{314}\B\X314:Print type of token list\X${}\E{}$\6
+\&{switch} (\\{token\_type})\5
+${}\{{}$\1\6
+\4\&{case} \\{parameter}:\5
+\\{print\_nl}(\.{"<argument>\ "});\5
+\&{break};\6
+\4\&{case} \\{u\_template}:\5
+\&{case} \\{v\_template}:\5
+\\{print\_nl}(\.{"<template>\ "});\5
+\&{break};\6
+\4\&{case} \\{backed\_up}:\6
+\&{if} ${}(\\{loc}\E\\{null}){}$\1\5
+\\{print\_nl}(\.{"<recently\ read>\ "});\2\6
+\&{else}\1\5
+\\{print\_nl}(\.{"<to\ be\ read\ again>\ }\)\.{"});\5
+\2\&{break};\6
+\4\&{case} \\{inserted}:\5
+\\{print\_nl}(\.{"<inserted\ text>\ "});\5
+\&{break};\6
+\4\&{case} \\{macro}:\6
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_cs}(\\{name});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{output\_text}:\5
+\\{print\_nl}(\.{"<output>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_par\_text}:\5
+\\{print\_nl}(\.{"<everypar>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_math\_text}:\5
+\\{print\_nl}(\.{"<everymath>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_display\_text}:\5
+\\{print\_nl}(\.{"<everydisplay>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_hbox\_text}:\5
+\\{print\_nl}(\.{"<everyhbox>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_vbox\_text}:\5
+\\{print\_nl}(\.{"<everyvbox>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_job\_text}:\5
+\\{print\_nl}(\.{"<everyjob>\ "});\5
+\&{break};\6
+\4\&{case} \\{every\_cr\_text}:\5
+\\{print\_nl}(\.{"<everycr>\ "});\5
+\&{break};\6
+\4\&{case} \\{mark\_text}:\5
+\\{print\_nl}(\.{"<mark>\ "});\5
+\&{break};\6
+\4\&{case} \\{write\_text}:\5
+\\{print\_nl}(\.{"<write>\ "});\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_nl}(\.{"?"});\C{this should never happen}\6
+\4${}\}{}$\2\par
+\U312.\fi
+
+\M{315}Here it is necessary to explain a little trick. We don't want to store a long
+string that corresponds to a token list, because that string might take up
+lots of memory; and we are printing during a time when an error message is
+being given, so we dare not do anything that might overflow one of \TeX's
+tables. So `pseudoprinting' is the answer: We enter a mode of printing
+that stores characters into a buffer of length \\{error\_line}, where character
+$k+1$ is placed into \hbox{$\\{trick\_buf}[\|k\MOD\\{error\_line}]$} if
+$\|k<\\{trick\_count}$, otherwise character \|k is dropped. Initially we set
+$\\{tally}\K\T{0}$ and $\\{trick\_count}\K\T{1000000}$; then when we reach the
+point where transition from line 1 to line 2 should occur, we
+set $\\{first\_count}\K\\{tally}$ and $\\{trick\_count}\K\hbox{max}(\\{error\_line},\\{tally}+\T{1}+\\{error\_line}-\\{half\_error\_line})$. At the end of the
+pseudoprinting, the values of \\{first\_count}, \\{tally}, and
+\\{trick\_count} give us all the information we need to print the two lines,
+and all of the necessary text is in \\{trick\_buf}.
+
+Namely, let \|l be the length of the descriptive information that appears
+on the first line. The length of the context information gathered for that
+line is $\|k\E\\{first\_count}$, and the length of the context information
+gathered for line~2 is $m=\min(\\{tally}, \\{trick\_count})-k$. If $\|l+\|k\Z\|h$,
+where $\|h\E\\{half\_error\_line}$, we print $\\{trick\_buf}[\T{0}\dotdot\|k-\T{1}]$ after the
+descriptive information on line~1, and set $\|n\K\|l+\|k$; here \|n is the
+length of line~1. If $l+k>h$, some cropping is necessary, so we set $\|n\K\|h$
+and print `\.{...}' followed by
+$$\hbox{$\\{trick\_buf}[(\|l+\|k-\|h+\T{3})\dotdot\|k-\T{1}]$,}$$
+where subscripts of \\{trick\_buf} are circular modulo \\{error\_line}. The
+second line consists of \|n~spaces followed by $\\{trick\_buf}[\|k\dotdot(\|k+\|m-\T{1})]$,
+unless $\|n+\|m>\\{error\_line}$; in the latter case, further cropping is done.
+This is easier to program than to explain.
+
+\Y\B\4\X315:Local variables for formatting calculations\X${}\E{}$\6
+\&{int} \|i;\C{index into \\{buffer}}\6
+\&{uint16\_t} \|j;\C{end of current line in \\{buffer}}\6
+\&{uint8\_t} \|l;\C{length of descriptive information on line 1}\6
+\&{int} \|m;\C{context information gathered for line 2}\6
+\&{uint8\_t} \|n;\C{length of line 1}\6
+\&{int} \|p;\C{starting or ending place in \\{trick\_buf}}\6
+\&{int} \|q;\C{temporary index}\par
+\U311.\fi
+
+\M{316}The following code sets up the print routines so that they will gather
+the desired information.
+
+\Y\B\4\D$\\{begin\_pseudoprint}$ \6
+${}\{{}$\5
+\1${}\|l\K\\{tally};{}$\5
+${}\\{tally}\K\T{0};{}$\5
+${}\\{selector}\K\\{pseudo};{}$\5
+${}\\{trick\_count}\K\T{1000000};{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{set\_trick\_count}$ \6
+${}\{{}$\5
+\1${}\\{first\_count}\K\\{tally};{}$\5
+${}\\{trick\_count}\K\\{tally}+\T{1}+\\{error\_line}-\\{half\_error\_line};{}$\6
+\&{if} ${}(\\{trick\_count}<\\{error\_line}){}$\1\5
+${}\\{trick\_count}\K\\{error\_line};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{317}And the following code uses the information after it has been gathered.
+
+\Y\B\4\X317:Print two lines using the tricky pseudoprinted information\X${}\E{}$\6
+\&{if} ${}(\\{trick\_count}\E\T{1000000}){}$\1\5
+\\{set\_trick\_count};\C{\\{set\_trick\_count} must be performed}\2\6
+\&{if} ${}(\\{tally}<\\{trick\_count}){}$\1\5
+${}\|m\K\\{tally}-\\{first\_count};{}$\2\6
+\&{else}\1\5
+${}\|m\K\\{trick\_count}-\\{first\_count}{}$;\C{context on line 2}\2\6
+\&{if} ${}(\|l+\\{first\_count}\Z\\{half\_error\_line}){}$\5
+${}\{{}$\5
+\1${}\|p\K\T{0};{}$\5
+${}\|n\K\|l+\\{first\_count};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"..."});\5
+${}\|p\K\|l+\\{first\_count}-\\{half\_error\_line}+\T{3};{}$\5
+${}\|n\K\\{half\_error\_line};{}$\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|q\K\|p;{}$ ${}\|q\Z\\{first\_count}-\T{1};{}$ ${}\|q\PP){}$\1\5
+${}\\{print\_char}(\\{trick\_buf}[\|q\MOD\\{error\_line}]);{}$\2\6
+\\{print\_ln}(\,);\6
+\&{for} ${}(\|q\K\T{1};{}$ ${}\|q\Z\|n;{}$ ${}\|q\PP){}$\1\5
+\\{print\_char}(\.{'\ '});\C{print \|n spaces to begin line~2}\2\6
+\&{if} ${}(\|m+\|n\Z\\{error\_line}){}$\1\5
+${}\|p\K\\{first\_count}+\|m;{}$\2\6
+\&{else}\1\5
+${}\|p\K\\{first\_count}+(\\{error\_line}-\|n-\T{3});{}$\2\6
+\&{for} ${}(\|q\K\\{first\_count};{}$ ${}\|q\Z\|p-\T{1};{}$ ${}\|q\PP){}$\1\5
+${}\\{print\_char}(\\{trick\_buf}[\|q\MOD\\{error\_line}]);{}$\2\6
+\&{if} ${}(\|m+\|n>\\{error\_line})$ \\{print\_str}(\.{"..."})\par
+\U312.\fi
+
+\M{318}But the trick is distracting us from our current goal, which is to
+understand the input state. So let's concentrate on the data structures that
+are being pseudoprinted as we finish up the \\{show\_context} procedure.
+
+\Y\B\4\X318:Pseudoprint the line\X${}\E{}$\6
+\\{begin\_pseudoprint};\6
+\&{if} ${}(\\{buffer}[\\{limit}]\E\\{end\_line\_char}){}$\1\5
+${}\|j\K\\{limit};{}$\2\6
+\&{else}\1\5
+${}\|j\K\\{limit}+\T{1}{}$;\C{determine the effective end of the line}\2\6
+\&{if} ${}(\|j>\T{0}){}$\1\6
+\&{for} ${}(\|i\K\\{start};{}$ ${}\|i\Z\|j-\T{1};{}$ ${}\|i\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|i\E\\{loc}){}$\1\5
+\\{set\_trick\_count};\2\6
+\\{print}(\\{buffer}[\|i]);\6
+\4${}\}{}$\2\2\par
+\U312.\fi
+
+\M{319}\B\X319:Pseudoprint the token list\X${}\E{}$\6
+\\{begin\_pseudoprint}; \6
+\&{if} ${}(\\{token\_type}<\\{macro}){}$\1\5
+${}\\{show\_token\_list}(\\{start},\39\\{loc},\39\T{100000});{}$\2\6
+\&{else} $\\{show\_token\_list}(\\{link}(\\{start}),\39\\{loc},\39\T{100000}{}$)\C{avoid reference count}\par
+\U312.\fi
+
+\M{320}Here is the missing piece of \\{show\_token\_list} that is activated when the
+token beginning line~2 is about to be shown:
+
+\Y\B\4\X320:Do magic computation\X${}\E{}$\6
+\\{set\_trick\_count}\par
+\U292.\fi
+
+\N{1}{321}Maintaining the input stacks.
+The following subroutines change the input status in commonly needed ways.
+
+First comes \\{push\_input}, which stores the current state and creates a
+new level (having, initially, the same properties as the old).
+
+\Y\B\4\D$\\{push\_input}$ \5
+\hbox{}\C{enter a new input level, save the old}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{input\_ptr}>\\{max\_in\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_in\_stack}\K\\{input\_ptr};{}$\6
+\&{if} ${}(\\{input\_ptr}\E\\{stack\_size}){}$\1\5
+${}\\{overflow}(\.{"input\ stack\ size"},\39\\{stack\_size});{}$\2\6
+\4${}\}{}$\2\6
+${}\\{input\_stack}[\\{input\_ptr}]\K\\{cur\_input}{}$;\C{stack the record}\6
+\\{incr}(\\{input\_ptr});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{322}And of course what goes up must come down.
+
+\Y\B\4\D$\\{pop\_input}$ \5
+\hbox{}\C{leave an input level, re-enter the old}\6
+${}\{{}$\5
+\1\\{decr}(\\{input\_ptr});\5
+${}\\{cur\_input}\K\\{input\_stack}[\\{input\_ptr}];{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{323}Here is a procedure that starts a new level of token-list input, given
+a token list \|p and its type \|t. If $\|t\E\\{macro}$, the calling routine should
+set \\{name} and \\{loc}.
+
+\Y\B\4\D$\\{back\_list}(\|X)$ \5
+$\\{begin\_token\_list}(\|X,\39\\{backed\_up}{}$)\C{backs up a simple token list}\par
+\B\4\D$\\{ins\_list}(\|X)$ \5
+$\\{begin\_token\_list}(\|X,\39\\{inserted}{}$)\C{inserts a simple token list}\par
+\Y\B\&{void} \\{begin\_token\_list}(\&{pointer} \|p${},\39{}$\&{quarterword} \|t)\1\1\2\2\6
+${}\{{}$\5
+\1\\{push\_input};\5
+${}\\{state}\K\\{token\_list};{}$\5
+${}\\{start}\K\|p;{}$\5
+${}\\{token\_type}\K\|t;{}$\6
+\&{if} ${}(\|t\G\\{macro}{}$)\C{the token list starts with a reference count}\6
+${}\{{}$\5
+\1\\{add\_token\_ref}(\|p);\6
+\&{if} ${}(\|t\E\\{macro}){}$\1\5
+${}\\{param\_start}\K\\{param\_ptr};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{loc}\K\\{link}(\|p);{}$\6
+\&{if} ${}(\\{tracing\_macros}>\T{1}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{""});\6
+\&{switch} (\|t)\5
+${}\{{}$\1\6
+\4\&{case} \\{mark\_text}:\5
+\\{print\_esc}(\X1401:\.{"mark"}\X);\5
+\&{break};\6
+\4\&{case} \\{write\_text}:\5
+\\{print\_esc}(\X1568:\.{"write"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+${}\\{print\_cmd\_chr}(\\{assign\_toks},\39\|t-\\{output\_text}+\\{output\_routine\_loc});{}$\6
+\4${}\}{}$\2\6
+\\{print\_str}(\.{"->"});\5
+\\{token\_show}(\|p);\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{loc}\K\|p;{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{324}When a token list has been fully scanned, the following computations
+should be done as we leave that level of input. The \\{token\_type} tends
+to be equal to either \\{backed\_up} or \\{inserted} about 2/3 of the time.
+
+\Y\B\&{void} \\{end\_token\_list}(\&{void})\C{leave a token-list input level}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{token\_type}\G\\{backed\_up}{}$)\C{token list to be deleted}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{token\_type}\Z\\{inserted}){}$\1\5
+\\{flush\_list}(\\{start});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{delete\_token\_ref}(\\{start});\C{update reference count}\6
+\&{if} ${}(\\{token\_type}\E\\{macro}{}$)\C{parameters must be flushed}\1\6
+\&{while} ${}(\\{param\_ptr}>\\{param\_start}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{param\_ptr});\5
+\\{flush\_list}(\\{param\_stack}[\\{param\_ptr}]);\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{token\_type}\E\\{u\_template}){}$\1\6
+\&{if} ${}(\\{align\_state}>\T{500000}){}$\1\5
+${}\\{align\_state}\K\T{0};{}$\2\6
+\&{else}\1\5
+\\{fatal\_error}(\.{"(interwoven\ alignme}\)\.{nt\ preambles\ are\ not}\)\.{\ allowed)"});\2\2\6
+\\{pop\_input};\5
+\\{check\_interrupt};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{325}Sometimes \TeX\ has read too far and wants to ``unscan'' what it has
+seen. The \\{back\_input} procedure takes care of this by putting the token
+just scanned back into the input stream, ready to be read again. This
+procedure can be used only if \\{cur\_tok} represents the token to be
+replaced. Some applications of \TeX\ use this procedure a lot,
+so it has been slightly optimized for speed.
+
+\Y\B\&{void} \\{back\_input}(\&{void})\C{undoes one token of input}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{a token list of length one}\7
+\&{while} ${}((\\{state}\E\\{token\_list})\W(\\{loc}\E\\{null})\W(\\{token\_type}\I\\{v\_template})){}$\1\5
+\\{end\_token\_list}(\,);\C{conserve stack space}\2\6
+${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|p)\K\\{cur\_tok};{}$\6
+\&{if} ${}(\\{cur\_tok}<\\{right\_brace\_limit}){}$\1\6
+\&{if} ${}(\\{cur\_tok}<\\{left\_brace\_limit}){}$\1\5
+\\{decr}(\\{align\_state});\2\6
+\&{else}\1\5
+\\{incr}(\\{align\_state});\2\2\6
+\\{push\_input};\5
+${}\\{state}\K\\{token\_list};{}$\5
+${}\\{start}\K\|p;{}$\5
+${}\\{token\_type}\K\\{backed\_up};{}$\5
+${}\\{loc}\K\|p{}$;\C{that was \\{back\_list}(\|p), without procedure overhead}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{326}\B\X326:Insert token \|p into \TeX's input\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|t\K\\{cur\_tok};{}$\5
+${}\\{cur\_tok}\K\|p;{}$\5
+\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\|t;{}$\6
+\4${}\}{}$\2\par
+\U282.\fi
+
+\M{327}The \\{back\_error} routine is used when we want to replace an offending token
+just before issuing an error message. This routine, like \\{back\_input},
+requires that \\{cur\_tok} has been set. We disable interrupts during the
+call of \\{back\_input} so that the help message won't be lost.
+
+\Y\B\&{void} \\{back\_error}(\&{void})\C{back up one token and call \&{error}}\6
+${}\{{}$\5
+\1${}\\{OK\_to\_interrupt}\K\\{false};{}$\5
+\\{back\_input}(\,);\5
+${}\\{OK\_to\_interrupt}\K\\{true};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\7
+\&{void} \\{ins\_error}(\&{void})\C{back up one inserted token and call \&{error}}\6
+${}\{{}$\5
+\1${}\\{OK\_to\_interrupt}\K\\{false};{}$\5
+\\{back\_input}(\,);\5
+${}\\{token\_type}\K\\{inserted};{}$\5
+${}\\{OK\_to\_interrupt}\K\\{true};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{328}The \\{begin\_file\_reading} procedure starts a new level of input for lines
+of characters to be read from a file, or as an insertion from the
+terminal. It does not take care of opening the file, nor does it set \\{loc}
+or \\{limit} or \\{line}.
+
+\Y\B\&{void} \\{begin\_file\_reading}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{in\_open}\E\\{max\_in\_open}){}$\1\5
+${}\\{overflow}(\.{"text\ input\ levels"},\39\\{max\_in\_open});{}$\2\6
+\&{if} ${}(\\{first}\E\\{buf\_size}){}$\1\5
+${}\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size});{}$\2\6
+\\{incr}(\\{in\_open});\5
+\\{push\_input};\5
+${}\\{index}\K\\{in\_open};{}$\5
+${}\\{line\_stack}[\\{index}]\K\\{line};{}$\5
+${}\\{start}\K\\{first};{}$\5
+${}\\{state}\K\\{mid\_line};{}$\5
+${}\\{name}\K\T{0}{}$;\C{\\{terminal\_input} is now \\{true}}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{329}Conversely, the variables must be downdated when such a level of input
+is finished:
+
+\Y\B\&{void} \\{end\_file\_reading}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{first}\K\\{start};{}$\5
+${}\\{line}\K\\{line\_stack}[\\{index}];{}$\6
+\&{if} ${}(\\{name}>\T{17}){}$\1\5
+${}\\{a\_close}({\AND}\\{cur\_file}){}$;\C{forget it}\2\6
+\\{pop\_input};\5
+\\{decr}(\\{in\_open});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{330}In order to keep the stack from overflowing during a long sequence of
+inserted `\.{\\show}' commands, the following routine removes completed
+error-inserted lines from memory.
+
+\Y\B\&{void} \\{clear\_for\_error\_prompt}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{while} ${}((\\{state}\I\\{token\_list})\W\\{terminal\_input}\W\30(\\{input\_ptr}>\T{0})\W(\\{loc}>\\{limit})){}$\1\5
+\\{end\_file\_reading}(\,);\2\6
+\\{print\_ln}(\,);\5
+\\{clear\_terminal};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{331}To get \TeX's whole input mechanism going, we perform the following
+actions.
+
+\Y\B\4\X331:Initialize the input routines\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{input\_ptr}\K\T{0};{}$\5
+${}\\{max\_in\_stack}\K\T{0};{}$\5
+${}\\{in\_open}\K\T{0};{}$\5
+${}\\{open\_parens}\K\T{0};{}$\5
+${}\\{max\_buf\_stack}\K\T{0};{}$\5
+${}\\{param\_ptr}\K\T{0};{}$\5
+${}\\{max\_param\_stack}\K\T{0};{}$\5
+${}\\{first}\K\\{buf\_size}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{buffer}[\\{first}]\K\T{0};{}$\5
+\\{decr}(\\{first});\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{first}\E\T{0}));{}$\5
+${}\\{scanner\_status}\K\\{normal};{}$\5
+${}\\{warning\_index}\K\\{null};{}$\5
+${}\\{first}\K\T{1};{}$\5
+${}\\{state}\K\\{new\_line};{}$\5
+${}\\{start}\K\T{1};{}$\5
+${}\\{index}\K\T{0};{}$\5
+${}\\{line}\K\T{0};{}$\5
+${}\\{name}\K\T{0};{}$\5
+${}\\{force\_eof}\K\\{false};{}$\5
+${}\\{align\_state}\K\T{1000000}{}$;\6
+\&{if} ${}(\R\\{init\_terminal}(\,)){}$\1\5
+\\{exit}(\T{0});\2\6
+${}\\{limit}\K\\{last};{}$\5
+${}\\{first}\K\\{last}+\T{1}{}$;\C{\\{init\_terminal} has set \\{loc} and \\{last}}\6
+\4${}\}{}$\2\par
+\U1337.\fi
+
+\N{1}{332}Getting the next token.
+The heart of \TeX's input mechanism is the \\{get\_next} procedure, which
+we shall develop in the next few sections of the program. Perhaps we
+shouldn't actually call it the ``heart,'' however, because it really acts
+as \TeX's eyes and mouth, reading the source files and gobbling them up.
+And it also helps \TeX\ to regurgitate stored token lists that are to be
+processed again.
+
+The main duty of \\{get\_next} is to input one token and to set \\{cur\_cmd}
+and \\{cur\_chr} to that token's command code and modifier. Furthermore, if
+the input token is a control sequence, the \\{eqtb} location of that control
+sequence is stored in \\{cur\_cs}; otherwise \\{cur\_cs} is set to zero.
+
+Underlying this simple description is a certain amount of complexity
+because of all the cases that need to be handled.
+However, the inner loop of \\{get\_next} is reasonably short and fast.
+
+When \\{get\_next} is asked to get the next token of a \.{\\read} line,
+it sets $\\{cur\_cmd}\E\\{cur\_chr}\E\\{cur\_cs}\E\T{0}$ in the case that no more tokens
+appear on that line. (There might not be any tokens at all, if the
+\\{end\_line\_char} has \\{ignore} as its catcode.)
+
+\fi
+
+\M{333}The value of \\{par\_loc} is the \\{eqtb} address of `\.{\\par}'. This quantity
+is needed because a blank line of input is supposed to be exactly equivalent
+to the appearance of \.{\\par}; we must set $\\{cur\_cs}\K\\{par\_loc}$
+when detecting a blank line.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{par\_loc};\C{location of `\.{\\par}' in \\{eqtb}}\6
+\&{halfword} \\{par\_token};\C{token representing `\.{\\par}'}\par
+\fi
+
+\M{334}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1569:\.{"par"}\X,\39\\{par\_end},\39\T{256}){}$;\C{cf.\ \\{scan\_file\_name}}\6
+${}\\{par\_loc}\K\\{cur\_val};{}$\5
+${}\\{par\_token}\K\\{cs\_token\_flag}+\\{par\_loc}{}$;\par
+\fi
+
+\M{335}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{par\_end}:\5
+\\{print\_esc}(\X1569:\.{"par"}\X);\5
+\&{break};\par
+\fi
+
+\M{336}Before getting into \\{get\_next}, let's consider the subroutine that
+is called when an `\.{\\outer}' control sequence has been scanned or
+when the end of a file has been reached. These two cases are distinguished
+by \\{cur\_cs}, which is zero at the end of a file.
+
+\Y\B\&{void} \\{check\_outer\_validity}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{points to inserted token list}\6
+\&{pointer} \|q;\C{auxiliary pointer}\7
+\&{if} ${}(\\{scanner\_status}\I\\{normal}){}$\5
+${}\{{}$\5
+\1${}\\{deletions\_allowed}\K\\{false};{}$\5
+\X337:Back up an outer control sequence so that it can be reread\X;\6
+\&{if} ${}(\\{scanner\_status}>\\{skipping}){}$\1\5
+\X338:Tell the user what has run away and try to recover\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Incomplete\ "});\5
+${}\\{print\_cmd\_chr}(\\{if\_test},\39\\{cur\_if});{}$\5
+\\{print\_str}(\.{";\ all\ text\ was\ igno}\)\.{red\ after\ line\ "});\5
+\\{print\_int}(\\{skip\_line});\5
+\\{help3}(\.{"A\ forbidden\ control}\)\.{\ sequence\ occurred\ i}\)\.{n\ skipped\ text."})\6
+(\.{"This\ kind\ of\ error\ }\)\.{happens\ when\ you\ say}\)\.{\ `\\\\if...'\ and\ forge}\)\.{t"})\6
+(\.{"the\ matching\ `\\\\fi'}\)\.{.\ I've\ inserted\ a\ `\\}\)\.{\\fi';\ this\ might\ wor}\)\.{k."});\6
+\&{if} ${}(\\{cur\_cs}\I\T{0}){}$\1\5
+${}\\{cur\_cs}\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\\{help\_line}[\T{2}]\K\30\.{"The\ file\ ended\ whil}\)\.{e\ I\ was\ skipping\ con}\)\.{ditional\ text."};{}$\2\6
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{frozen\_fi};{}$\5
+\\{ins\_error}(\,);\6
+\4${}\}{}$\2\6
+${}\\{deletions\_allowed}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{337}An outer control sequence that occurs in a \.{\\read} will not be reread,
+since the error recovery for \.{\\read} is not very powerful.
+
+\Y\B\4\X337:Back up an outer control sequence so that it can be reread\X${}\E{}$\6
+\&{if} ${}(\\{cur\_cs}\I\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{state}\E\\{token\_list})\V(\\{name}<\T{1})\V(\\{name}>\T{17})){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|p)\K\\{cs\_token\_flag}+\\{cur\_cs};{}$\5
+\\{back\_list}(\|p);\C{prepare to read the control sequence again}\6
+\4${}\}{}$\2\6
+${}\\{cur\_cmd}\K\\{spacer};{}$\5
+${}\\{cur\_chr}\K\.{'\ '}{}$;\C{replace it by a space}\6
+\4${}\}{}$\2\par
+\U336.\fi
+
+\M{338}\B\X338:Tell the user what has run away and try to recover\X${}\E{}$\6
+${}\{{}$\5
+\1\\{runaway}(\,);\C{print a definition, argument, or preamble}\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+\\{print\_err}(\.{"File\ ended"})\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\T{0};{}$\5
+\\{print\_err}(\.{"Forbidden\ control\ s}\)\.{equence\ found"});\6
+\4${}\}{}$\2\6
+\\{print\_str}(\.{"\ while\ scanning\ "});\5
+\X339:Print either `\.{definition}' or `\.{use}' or `\.{preamble}' or `\.{text}', and insert tokens that should lead to recovery\X;\6
+\\{print\_str}(\.{"\ of\ "});\5
+\\{sprint\_cs}(\\{warning\_index});\5
+\\{help4}(\.{"I\ suspect\ you\ have\ }\)\.{forgotten\ a\ `\}',\ cau}\)\.{sing\ me"})\6
+(\.{"to\ read\ past\ where\ }\)\.{you\ wanted\ me\ to\ sto}\)\.{p."})\6
+(\.{"I'll\ try\ to\ recover}\)\.{;\ but\ if\ the\ error\ i}\)\.{s\ serious,"})\6
+(\.{"you'd\ better\ type\ `}\)\.{E'\ or\ `X'\ now\ and\ fi}\)\.{x\ your\ file."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U336.\fi
+
+\M{339}The recovery procedure can't be fully understood without knowing more
+about the \TeX\ routines that should be aborted, but we can sketch the
+ideas here: For a runaway definition we will insert a right brace; for a
+runaway preamble, we will insert a special \.{\\cr} token and a right
+brace; and for a runaway argument, we will set \\{long\_state} to
+\\{outer\_call} and insert \.{\\par}.
+
+\Y\B\4\X339:Print either `\.{definition}' or `\.{use}' or `\.{preamble}' or `\.{text}', and insert tokens that should lead to recovery\X${}\E{}$\6
+$\|p\K\\{get\_avail}(\,);{}$\6
+\&{switch} (\\{scanner\_status})\5
+${}\{{}$\1\6
+\4\&{case} \\{defining}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"definition"});\5
+${}\\{info}(\|p)\K\\{right\_brace\_token}+\.{'\}'};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{matching}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"use"});\5
+${}\\{info}(\|p)\K\\{par\_token};{}$\5
+${}\\{long\_state}\K\\{outer\_call};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{aligning}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"preamble"});\5
+${}\\{info}(\|p)\K\\{right\_brace\_token}+\.{'\}'};{}$\5
+${}\|q\K\|p;{}$\5
+${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\|p)\K\|q;{}$\5
+${}\\{info}(\|p)\K\\{cs\_token\_flag}+\\{frozen\_cr};{}$\5
+${}\\{align\_state}\K{-}\T{1000000};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{absorbing}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"text"});\5
+${}\\{info}(\|p)\K\\{right\_brace\_token}+\.{'\}'};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\6
+\\{ins\_list}(\|p)\par
+\U338.\fi
+
+\M{340}We need to mention a procedure here that may be called by \\{get\_next}.
+
+\Y\B\&{void} \\{firm\_up\_the\_line}(\&{void});\par
+\fi
+
+\M{341}Now we're ready to take the plunge into \\{get\_next} itself. Parts of
+this routine are executed more often than any other instructions of \TeX.
+
+\Y\B\&{void} \\{get\_next}(\&{void})\C{sets \\{cur\_cmd}, \\{cur\_chr}, \\{cur\_cs} to next token}\6
+${}\{{}$\5
+\C{go here to get the next input token}\C{go here to eat the next character from a file}\C{go here to digest it again}\C{go here to start looking for a control sequence}\C{go here when a control sequence has been found}\C{go here when the next input
+token has been got}\1\6
+\&{uint16\_t} \|k;\C{an index into \\{buffer}}\6
+\&{halfword} \|t;\C{a token}\6
+\&{uint8\_t} \\{cat};\C{\\{cat\_code}(\\{cur\_chr}), usually}\6
+\&{ASCII\_code} \|c${},{}$ \\{cc};\C{constituents of a possible expanded code}\6
+\&{uint8\_t} \|d;\C{number of excess characters in an expanded code}\7
+\4\\{restart}:\5
+${}\\{cur\_cs}\K\T{0};{}$\6
+\&{if} ${}(\\{state}\I\\{token\_list}){}$\1\5
+\X343:Input from external file, \&{goto} \\{restart} if no input found\X\2\6
+\&{else}\1\5
+\X357:Input from token list, \&{goto} \\{restart} if end of list or if a parameter needs to be expanded\X;\2\6
+\X342:If an alignment entry has just ended, take appropriate action\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{342}An alignment entry ends when a tab or \.{\\cr} occurs, provided that the
+current level of braces is the same as the level that was present at the
+beginning of that alignment entry; i.e., provided that \\{align\_state} has
+returned to the value it had after the \<u_j> template for that entry.
+
+\Y\B\4\X342:If an alignment entry has just ended, take appropriate action\X${}\E{}$\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{car\_ret}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}\G\\{tab\_mark}){}$\1\6
+\&{if} ${}(\\{align\_state}\E\T{0}){}$\1\5
+\X789:Insert the \(v)\<v_j> template and \&{goto} \\{restart}\X\2\2\2\par
+\U341.\fi
+
+\M{343}\B\X343:Input from external file, \&{goto} \\{restart} if no input found\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_cur\_chr}:\6
+\&{if} ${}(\\{loc}\Z\\{limit}{}$)\C{current line not yet finished}\6
+${}\{{}$\5
+\1${}\\{cur\_chr}\K\\{buffer}[\\{loc}];{}$\5
+\\{incr}(\\{loc});\6
+\4\\{reswitch}:\5
+${}\\{cur\_cmd}\K\\{cat\_code}(\\{cur\_chr});{}$\5
+\X344:Change state if necessary, and \&{goto} \&{switch} if the current character should be ignored, or \&{goto} \\{reswitch} if the current character changes to another\X;\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{state}\K\\{new\_line}{}$;\6
+\X360:Move to next line of file, or \&{goto} \\{restart} if there is no next line, or \&{return} if a \.{\\read} line has finished\X;\6
+\\{check\_interrupt};\5
+\&{goto} \\{get\_cur\_chr};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U341.\fi
+
+\M{344}The following 48-way switch accomplishes the scanning quickly, assuming
+that a decent \PASCAL\ compiler has translated the code. Note that the numeric
+values for \\{mid\_line}, \\{skip\_blanks}, and \\{new\_line} are spaced
+apart from each other by $\\{max\_char\_code}+\T{1}$, so we can add a character's
+command code to the state to get a single number that characterizes both.
+
+\Y\B\4\D$\\{any\_state\_plus}(\|X)$ \5
+\&{case} \\{mid\_line}${}+\|X{}$:\5
+\&{case} \\{skip\_blanks}${}+\|X{}$: \&{case} \\{new\_line}${}+{}$\|X\par
+\Y\B\4\X344:Change state if necessary, and \&{goto} \&{switch} if the current character should be ignored, or \&{goto} \\{reswitch} if the current character changes to another\X${}\E{}$\6
+\&{switch} ${}(\\{state}+\\{cur\_cmd}){}$\5
+${}\{{}$\1\6
+\4\X345:Cases where character is ignored\X:\5
+\&{goto} \\{get\_cur\_chr};\6
+\4\\{any\_state\_plus}(\\{escape}):\5
+\X354:Scan a control sequence and set \\{state}: $\K$ \\{skip\_blanks} or \\{mid\_line}\X\5
+\&{break};\6
+\4\\{any\_state\_plus}(\\{active\_char}):\5
+\X353:Process an active-character control sequence and set \\{state}: $\K$ \\{mid\_line}\X\5
+\&{break};\6
+\4\\{any\_state\_plus}(\\{sup\_mark}):\5
+\X352:If this \\{sup\_mark} starts an expanded character like~\.{\^\^A} or~\.{\^\^df}, then \&{goto} \\{reswitch}, otherwise set \\{state}: $\K$ \\{mid\_line}\X\5
+\&{break};\6
+\4\\{any\_state\_plus}(\\{invalid\_char}):\5
+\X346:Decry the invalid character and \&{goto} \\{restart}\X\6
+\hbox{\4}\X347:Handle situations involving spaces, braces, changes of state\X\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\par
+\U343.\fi
+
+\M{345}\B\X345:Cases where character is ignored\X${}\E{}$\6
+\\{any\_state\_plus}(\\{ignore}):\5
+\&{case} \\{skip\_blanks}${}+\\{spacer}{}$: \&{case} \\{new\_line}${}+{}$\\{spacer}\par
+\U344.\fi
+
+\M{346}We go to \\{restart} instead of to \\{get\_cur\_chr}, because \\{state} might equal
+\\{token\_list} after the error has been dealt with
+(cf.\ \\{clear\_for\_error\_prompt}).
+
+\Y\B\4\X346:Decry the invalid character and \&{goto} \\{restart}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Text\ line\ contains\ }\)\.{an\ invalid\ character}\)\.{"});\5
+\\{help2}(\.{"A\ funny\ symbol\ that}\)\.{\ I\ can't\ read\ has\ ju}\)\.{st\ been\ input."})\6
+(\.{"Continue,\ and\ I'll\ }\)\.{forget\ that\ it\ ever\ }\)\.{happened."});\6
+${}\\{deletions\_allowed}\K\\{false};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{deletions\_allowed}\K\\{true};{}$\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\par
+\U344.\fi
+
+\M{347}\B\D$\\{add\_delims\_to}(\|X)$ \5
+$\|X+\\{math\_shift}{}$:\5
+${}\|X+\\{tab\_mark}{}$:\5
+${}\|X+\\{mac\_param}{}$:\5
+${}\|X+\\{sub\_mark}{}$:\5
+${}\|X+\\{letter}{}$: $\|X+{}$\\{other\_char}\par
+\Y\B\4\X347:Handle situations involving spaces, braces, changes of state\X${}\E{}$\6
+\4\&{case} \\{mid\_line}${}+\\{spacer}{}$:\5
+\X349:Enter \\{skip\_blanks} state, emit a space\X\5
+\&{break};\6
+\4\&{case} \\{mid\_line}${}+\\{car\_ret}{}$:\5
+\X348:Finish line, emit a space\X\5
+\&{break};\6
+\4\&{case} \\{skip\_blanks}${}+\\{car\_ret}{}$:\5
+\\{any\_state\_plus}(\\{comment}):\5
+\X350:Finish line, \&{goto} \&{switch}\X\6
+\4\&{case} \\{new\_line}${}+\\{car\_ret}{}$:\5
+\X351:Finish line, emit a \.{\\par}\X\5
+\&{break};\6
+\4\&{case} \\{mid\_line}${}+\\{left\_brace}{}$:\5
+\\{incr}(\\{align\_state});\5
+\&{break};\6
+\4\&{case} \\{skip\_blanks}${}+\\{left\_brace}{}$:\5
+\&{case} \\{new\_line}${}+\\{left\_brace}{}$:\6
+${}\{{}$\5
+\1${}\\{state}\K\\{mid\_line};{}$\5
+\\{incr}(\\{align\_state});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mid\_line}${}+\\{right\_brace}{}$:\5
+\\{decr}(\\{align\_state});\5
+\&{break};\6
+\4\&{case} \\{skip\_blanks}${}+\\{right\_brace}{}$:\5
+\&{case} \\{new\_line}${}+\\{right\_brace}{}$:\6
+${}\{{}$\5
+\1${}\\{state}\K\\{mid\_line};{}$\5
+\\{decr}(\\{align\_state});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{add\_delims\_to}(\&{case} \\{skip\_blanks}):\5
+\\{add\_delims\_to}(\&{case} \\{new\_line}):\5
+${}\\{state}\K\\{mid\_line}{}$;\5
+\&{break};\par
+\U344.\fi
+
+\M{348}When a character of type \\{spacer} gets through, its character code is
+changed to $\.{"\ "}=040$. This means that the ASCII codes for tab and space,
+and for the space inserted at the end of a line, will
+be treated alike when macro parameters are being matched. We do this
+since such characters are indistinguishable on most computer terminal displays.
+
+\Y\B\4\X348:Finish line, emit a space\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{loc}\K\\{limit}+\T{1};{}$\5
+${}\\{cur\_cmd}\K\\{spacer};{}$\5
+${}\\{cur\_chr}\K\.{'\ '};{}$\6
+\4${}\}{}$\2\par
+\U347.\fi
+
+\M{349}The following code is performed only when $\\{cur\_cmd}\E\\{spacer}$.
+
+\Y\B\4\X349:Enter \\{skip\_blanks} state, emit a space\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{state}\K\\{skip\_blanks};{}$\5
+${}\\{cur\_chr}\K\.{'\ '};{}$\6
+\4${}\}{}$\2\par
+\U347.\fi
+
+\M{350}\B\X350:Finish line, \&{goto} \&{switch}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{loc}\K\\{limit}+\T{1};{}$\5
+\&{goto} \\{get\_cur\_chr};\6
+\4${}\}{}$\2\par
+\U347.\fi
+
+\M{351}\B\X351:Finish line, emit a \.{\\par}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{loc}\K\\{limit}+\T{1};{}$\5
+${}\\{cur\_cs}\K\\{par\_loc};{}$\5
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\6
+\&{if} ${}(\\{cur\_cmd}\G\\{outer\_call}){}$\1\5
+\\{check\_outer\_validity}(\,);\2\6
+\4${}\}{}$\2\par
+\U347.\fi
+
+\M{352}Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit.
+
+\Y\B\4\D$\\{is\_hex}(\|X)$ \5
+$(((\|X\G\.{'0'})\W(\|X\Z\.{'9'}))\V((\|X\G\.{'a'})\W(\|X\Z\.{'f'})){}$)\par
+\B\4\D$\\{hex\_to\_cur\_chr}$ \6
+\&{if} ${}(\|c\Z\.{'9'}){}$\1\5
+${}\\{cur\_chr}\K\|c-\.{'0'}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_chr}\K\|c-\.{'a'}+\T{10};{}$\2\6
+\&{if} ${}(\\{cc}\Z\.{'9'}){}$\1\5
+${}\\{cur\_chr}\K\T{16}*\\{cur\_chr}+\\{cc}-\.{'0'};{}$\2\6
+\&{else} $\\{cur\_chr}\K\T{16}*\\{cur\_chr}+\\{cc}-\.{'a'}+{}$\T{10}\par
+\Y\B\4\X352:If this \\{sup\_mark} starts an expanded character like~\.{\^\^A} or~\.{\^\^df}, then \&{goto} \\{reswitch}, otherwise set \\{state}: $\K$ \\{mid\_line}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_chr}\E\\{buffer}[\\{loc}]){}$\1\6
+\&{if} ${}(\\{loc}<\\{limit}){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{buffer}[\\{loc}+\T{1}]{}$;\5
+\&{if} ${}(\|c<\T{\~200}{}$)\C{yes we have an expanded char}\6
+${}\{{}$\5
+\1${}\\{loc}\K\\{loc}+\T{2};{}$\6
+\&{if} (\\{is\_hex}(\|c))\1\6
+\&{if} ${}(\\{loc}\Z\\{limit}){}$\5
+${}\{{}$\5
+\1${}\\{cc}\K\\{buffer}[\\{loc}]{}$;\5
+\&{if} (\\{is\_hex}(\\{cc}))\5
+${}\{{}$\5
+\1\\{incr}(\\{loc});\5
+\\{hex\_to\_cur\_chr};\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\|c<\T{\~100}){}$\1\5
+${}\\{cur\_chr}\K\|c+\T{\~100}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_chr}\K\|c-\T{\~100};{}$\2\6
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\6
+${}\\{state}\K\\{mid\_line};{}$\6
+\4${}\}{}$\2\par
+\U344.\fi
+
+\M{353}\B\X353:Process an active-character control sequence and set \\{state}: $\K$ \\{mid\_line}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\\{cur\_chr}+\\{active\_base};{}$\5
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\5
+${}\\{state}\K\\{mid\_line};{}$\6
+\&{if} ${}(\\{cur\_cmd}\G\\{outer\_call}){}$\1\5
+\\{check\_outer\_validity}(\,);\2\6
+\4${}\}{}$\2\par
+\U344.\fi
+
+\M{354}Control sequence names are scanned only when they appear in some line of
+a file; once they have been scanned the first time, their \\{eqtb} location
+serves as a unique identification, so \TeX\ doesn't need to refer to the
+original name any more except when it prints the equivalent in symbolic form.
+
+The program that scans a control sequence has been written carefully
+in order to avoid the blowups that might otherwise occur if a malicious
+user tried something like `\.{\\catcode\'15=0}'. The algorithm might
+look at $\\{buffer}[\\{limit}+\T{1}]$, but it never looks at $\\{buffer}[\\{limit}+\T{2}]$.
+
+If expanded characters like `\.{\^\^A}' or `\.{\^\^df}'
+appear in or just following
+a control sequence name, they are converted to single characters in the
+buffer and the process is repeated, slowly but surely.
+
+\Y\B\4\X354:Scan a control sequence and set \\{state}: $\K$ \\{skip\_blanks} or \\{mid\_line}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{loc}>\\{limit}){}$\1\5
+${}\\{cur\_cs}\K\\{null\_cs}{}$;\C{\\{state} is irrelevant in this case}\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{start\_cs}:\5
+${}\|k\K\\{loc};{}$\5
+${}\\{cur\_chr}\K\\{buffer}[\|k];{}$\5
+${}\\{cat}\K\\{cat\_code}(\\{cur\_chr});{}$\5
+\\{incr}(\|k);\6
+\&{if} ${}(\\{cat}\E\\{letter}){}$\1\5
+${}\\{state}\K\\{skip\_blanks};{}$\2\6
+\&{else} \&{if} ${}(\\{cat}\E\\{spacer}){}$\1\5
+${}\\{state}\K\\{skip\_blanks};{}$\2\6
+\&{else}\1\5
+${}\\{state}\K\\{mid\_line};{}$\2\6
+\&{if} ${}((\\{cat}\E\\{letter})\W(\|k\Z\\{limit})){}$\1\5
+\X356:Scan ahead in the buffer until finding a nonletter; if an expanded code is encountered, reduce it and \&{goto} \\{start\_cs}; otherwise if a multiletter control sequence is found, adjust \\{cur\_cs} and \\{loc}, and \&{goto} \\{found}\X\2\6
+\&{else}\1\5
+\X355:If an expanded code is present, reduce it and \&{goto} \\{start\_cs}\X;\2\6
+${}\\{cur\_cs}\K\\{single\_base}+\\{buffer}[\\{loc}];{}$\5
+\\{incr}(\\{loc});\6
+\4${}\}{}$\2\6
+\4\\{found}:\5
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\6
+\&{if} ${}(\\{cur\_cmd}\G\\{outer\_call}){}$\1\5
+\\{check\_outer\_validity}(\,);\2\6
+\4${}\}{}$\2\par
+\U344.\fi
+
+\M{355}Whenever we reach the following piece of code, we will have
+$\\{cur\_chr}\E\\{buffer}[\|k-\T{1}]$ and $\|k\Z\\{limit}+\T{1}$ and $\\{cat}\E\\{cat\_code}(\\{cur\_chr})$. If an
+expanded code like \.{\^\^A} or \.{\^\^df} appears in $\\{buffer}[(\|k-\T{1})\dotdot(\|k+\T{1})]$
+or $\\{buffer}[(\|k-\T{1})\dotdot(\|k+\T{2})]$, we
+will store the corresponding code in $\\{buffer}[\|k-\T{1}]$ and shift the rest of
+the buffer left two or three places.
+
+\Y\B\4\X355:If an expanded code is present, reduce it and \&{goto} \\{start\_cs}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{buffer}[\|k]\E\\{cur\_chr}{}$)\5
+\1\&{if} ${}(\\{cat}\E\\{sup\_mark}{}$)\5
+\1\&{if} ${}(\|k<\\{limit}){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{buffer}[\|k+\T{1}]{}$;\5
+\&{if} ${}(\|c<\T{\~200}{}$)\C{yes, one is indeed present}\6
+${}\{{}$\5
+\1${}\|d\K\T{2};{}$\6
+\&{if} (\\{is\_hex}(\|c))\5
+\1\&{if} ${}(\|k+\T{2}\Z\\{limit}){}$\5
+${}\{{}$\5
+\1${}\\{cc}\K\\{buffer}[\|k+\T{2}]{}$;\5
+\&{if} (\\{is\_hex}(\\{cc}))\1\5
+\\{incr}(\|d);\2\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\|d>\T{2}){}$\5
+${}\{{}$\5
+\1\\{hex\_to\_cur\_chr};\5
+${}\\{buffer}[\|k-\T{1}]\K\\{cur\_chr};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|c<\T{\~100}){}$\1\5
+${}\\{buffer}[\|k-\T{1}]\K\|c+\T{\~100};{}$\2\6
+\&{else}\1\5
+${}\\{buffer}[\|k-\T{1}]\K\|c-\T{\~100};{}$\2\6
+${}\\{limit}\K\\{limit}-\|d;{}$\5
+${}\\{first}\K\\{first}-\|d;{}$\6
+\&{while} ${}(\|k\Z\\{limit}){}$\5
+${}\{{}$\5
+\1${}\\{buffer}[\|k]\K\\{buffer}[\|k+\|d];{}$\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+\&{goto} \\{start\_cs};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\2\6
+\4${}\}{}$\2\par
+\Us354\ET356.\fi
+
+\M{356}\B\X356:Scan ahead in the buffer until finding a nonletter; if an expanded code is encountered, reduce it and \&{goto} \\{start\_cs}; otherwise if a multiletter control sequence is found, adjust \\{cur\_cs} and \\{loc}, and \&{goto} \\{found}\X${}%
+\E{}$\6
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+${}\\{cur\_chr}\K\\{buffer}[\|k];{}$\5
+${}\\{cat}\K\\{cat\_code}(\\{cur\_chr});{}$\5
+\\{incr}(\|k);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R((\\{cat}\I\\{letter})\V(\|k>\\{limit})));{}$\5
+\X355:If an expanded code is present, reduce it and \&{goto} \\{start\_cs}\X;\6
+\&{if} ${}(\\{cat}\I\\{letter}){}$\1\5
+\\{decr}(\|k);\C{now \|k points to first nonletter}\2\6
+\&{if} ${}(\|k>\\{loc}+\T{1}{}$)\C{multiletter control sequence has been scanned}\6
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\\{id\_lookup}(\\{loc},\39\|k-\\{loc});{}$\5
+${}\\{loc}\K\|k;{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U354.\fi
+
+\M{357}Let's consider now what happens when \\{get\_next} is looking at a token list.
+
+\Y\B\4\X357:Input from token list, \&{goto} \\{restart} if end of list or if a parameter needs to be expanded\X${}\E{}$\6
+\&{if} ${}(\\{loc}\I\\{null}{}$)\C{list not exhausted}\6
+${}\{{}$\5
+\1${}\|t\K\\{info}(\\{loc});{}$\5
+${}\\{loc}\K\\{link}(\\{loc}){}$;\C{move to next}\6
+\&{if} ${}(\|t\G\\{cs\_token\_flag}{}$)\C{a control sequence token}\6
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\|t-\\{cs\_token\_flag};{}$\5
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\6
+\&{if} ${}(\\{cur\_cmd}\G\\{outer\_call}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}\E\\{dont\_expand}){}$\1\5
+\X358:Get the next token, suppressing expansion\X\2\6
+\&{else}\1\5
+\\{check\_outer\_validity}(\,);\2\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_cmd}\K\|t/\T{\~400};{}$\5
+${}\\{cur\_chr}\K\|t\MOD\T{\~400};{}$\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{left\_brace}:\5
+\\{incr}(\\{align\_state});\5
+\&{break};\6
+\4\&{case} \\{right\_brace}:\5
+\\{decr}(\\{align\_state});\5
+\&{break};\6
+\4\&{case} \\{out\_param}:\5
+\X359:Insert macro parameter and \&{goto} \\{restart}\X\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\C{we are done with this token list}\1\6
+\\{end\_token\_list}(\,);\5
+\&{goto} \\{restart};\C{resume previous level}\6
+\4${}\}{}$\2\par
+\U341.\fi
+
+\M{358}The present point in the program is reached only when the \\{expand}
+routine has inserted a special marker into the input. In this special
+case, \\{info}(\\{loc}) is known to be a control sequence token, and $\\{link}(\\{loc})\E\\{null}$.
+
+\Y\B\4\D$\\{no\_expand\_flag}$ \5
+\T{257}\C{this characterizes a special variant of \\{relax}}\par
+\Y\B\4\X358:Get the next token, suppressing expansion\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\\{info}(\\{loc})-\\{cs\_token\_flag};{}$\5
+${}\\{loc}\K\\{null}{}$;\6
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\6
+\&{if} ${}(\\{cur\_cmd}>\\{max\_command}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_cmd}\K\\{relax};{}$\5
+${}\\{cur\_chr}\K\\{no\_expand\_flag};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U357.\fi
+
+\M{359}\B\X359:Insert macro parameter and \&{goto} \\{restart}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{begin\_token\_list}(\\{param\_stack}[\\{param\_start}+\\{cur\_chr}-\T{1}],\39\\{parameter});{}$\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\par
+\U357.\fi
+
+\M{360}All of the easy branches of \\{get\_next} have now been taken care of.
+There is one more branch.
+
+\Y\B\4\D$\\{end\_line\_char\_inactive}$ \5
+$(\\{end\_line\_char}<\T{0})\V(\\{end\_line\_char}>\T{255}{}$)\par
+\Y\B\4\X360:Move to next line of file, or \&{goto} \\{restart} if there is no next line, or \&{return} if a \.{\\read} line has finished\X${}\E{}$\6
+\&{if} ${}(\\{name}>\T{17}){}$\1\5
+\X362:Read next line of file into \\{buffer}, or \&{goto} \\{restart} if the file has ended\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{terminal\_input}{}$)\C{\.{\\read} line has ended}\6
+${}\{{}$\5
+\1${}\\{cur\_cmd}\K\T{0};{}$\5
+${}\\{cur\_chr}\K\T{0};{}$\5
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{input\_ptr}>\T{0}{}$)\C{text was inserted during error recovery}\6
+${}\{{}$\5
+\1\\{end\_file\_reading}(\,);\5
+\&{goto} \\{restart};\C{resume previous level}\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{selector}<\\{log\_only}){}$\1\5
+\\{open\_log\_file}(\,);\2\6
+\&{if} ${}(\\{interaction}>\\{nonstop\_mode}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{incr}(\\{limit});\2\6
+\&{if} ${}(\\{limit}\E\\{start}{}$)\C{previous line was empty}\1\6
+\\{print\_nl}(\.{"(Please\ type\ a\ comm}\)\.{and\ or\ say\ `\\\\end')"});\2\6
+\\{print\_ln}(\,);\5
+${}\\{first}\K\\{start};{}$\5
+\\{prompt\_input}(\.{"*"});\C{input on-line into \\{buffer}}\6
+${}\\{limit}\K\\{last};{}$\6
+\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{decr}(\\{limit});\2\6
+\&{else}\1\5
+${}\\{buffer}[\\{limit}]\K\\{end\_line\_char};{}$\2\6
+${}\\{first}\K\\{limit}+\T{1};{}$\5
+${}\\{loc}\K\\{start};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{fatal\_error}(\.{"***\ (job\ aborted,\ n}\)\.{o\ legal\ \\\\end\ found)}\)\.{"});\C{nonstop mode, which is intended for overnight batch processing, never waits for on-line input}\2\6
+\4${}\}{}$\2\par
+\U343.\fi
+
+\M{361}The global variable \\{force\_eof} is normally \\{false}; it is set \\{true}
+by an \.{\\endinput} command.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{force\_eof};\C{should the next \.{\\input} be aborted early?}\par
+\fi
+
+\M{362}\B\X362:Read next line of file into \\{buffer}, or \&{goto} \\{restart} if the file has ended\X${}\E{}$\6
+${}\{{}$\5
+\1\\{incr}(\\{line});\5
+${}\\{first}\K\\{start};{}$\6
+\&{if} ${}(\R\\{force\_eof}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{input\_ln}({\AND}\\{cur\_file},\39\\{true}){}$)\C{not end of file}\1\6
+\\{firm\_up\_the\_line}(\,);\C{this sets \\{limit}}\2\6
+\&{else}\1\5
+${}\\{force\_eof}\K\\{true};{}$\2\6
+\4${}\}{}$\2\6
+\&{if} (\\{force\_eof})\5
+${}\{{}$\5
+\1\\{print\_char}(\.{')'});\5
+\\{decr}(\\{open\_parens});\5
+\\{update\_terminal};\C{show user that file has been read}\6
+${}\\{force\_eof}\K\\{false};{}$\5
+\\{end\_file\_reading}(\,);\C{resume previous level}\6
+\\{check\_outer\_validity}(\,);\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\6
+\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{decr}(\\{limit});\2\6
+\&{else}\1\5
+${}\\{buffer}[\\{limit}]\K\\{end\_line\_char};{}$\2\6
+${}\\{first}\K\\{limit}+\T{1};{}$\5
+${}\\{loc}\K\\{start}{}$;\C{ready to read}\6
+\4${}\}{}$\2\par
+\U360.\fi
+
+\M{363}If the user has set the \\{pausing} parameter to some positive value,
+and if nonstop mode has not been selected, each line of input is displayed
+on the terminal and the transcript file, followed by `\.{=>}'.
+\TeX\ waits for a response. If the response is simply \\{carriage\_return}, the
+line is accepted as it stands, otherwise the line typed is
+used instead of the line in the file.
+
+\Y\B\&{void} \\{firm\_up\_the\_line}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{an index into \\{buffer}}\7
+${}\\{limit}\K\\{last};{}$\6
+\&{if} ${}(\\{pausing}>\T{0}){}$\1\6
+\&{if} ${}(\\{interaction}>\\{nonstop\_mode}){}$\5
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+\\{print\_ln}(\,);\6
+\&{if} ${}(\\{start}<\\{limit}){}$\1\6
+\&{for} ${}(\|k\K\\{start};{}$ ${}\|k\Z\\{limit}-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{print}(\\{buffer}[\|k]);\2\2\6
+${}\\{first}\K\\{limit};{}$\5
+\\{prompt\_input}(\.{"=>"});\C{wait for user response}\6
+\&{if} ${}(\\{last}>\\{first}){}$\5
+${}\{{}$\5
+\1\&{for} ${}(\|k\K\\{first};{}$ ${}\|k\Z\\{last}-\T{1};{}$ ${}\|k\PP{}$)\C{move line down in buffer}\1\6
+${}\\{buffer}[\|k+\\{start}-\\{first}]\K\\{buffer}[\|k];{}$\2\6
+${}\\{limit}\K\\{start}+\\{last}-\\{first};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{364}Since \\{get\_next} is used so frequently in \TeX, it is convenient
+to define three related procedures that do a little more:
+
+\yskip\hang\\{get\_token} not only sets \\{cur\_cmd} and \\{cur\_chr}, it
+also sets \\{cur\_tok}, a packed halfword version of the current token.
+
+\yskip\hang\\{get\_x\_token}, meaning ``get an expanded token,'' is like
+\\{get\_token}, but if the current token turns out to be a user-defined
+control sequence (i.e., a macro call), or a conditional,
+or something like \.{\\topmark} or \.{\\expandafter} or \.{\\csname},
+it is eliminated from the input by beginning the expansion of the macro
+or the evaluation of the conditional.
+
+\yskip\hang\\{x\_token} is like \\{get\_x\_token} except that it assumes that
+\\{get\_next} has already been called.
+
+\yskip\noindent
+In fact, these three procedures account for almost every use of \\{get\_next}.
+
+\fi
+
+\M{365}No new control sequences will be defined except during a call of
+\\{get\_token}, or when \.{\\csname} compresses a token list, because
+\\{no\_new\_control\_sequence} is always \\{true} at other times.
+
+\Y\B\&{void} \\{get\_token}(\&{void})\C{sets \\{cur\_cmd}, \\{cur\_chr}, \\{cur\_tok}}\6
+${}\{{}$\5
+\1${}\\{no\_new\_control\_sequence}\K\\{false};{}$\5
+\\{get\_next}(\,);\5
+${}\\{no\_new\_control\_sequence}\K\\{true};{}$\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+${}\\{cur\_tok}\K(\\{cur\_cmd}*\T{\~400})+\\{cur\_chr};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{cur\_cs};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{366}Expanding the next token.
+Only a dozen or so command codes $>$ \\{max\_command} can possibly be returned by
+\\{get\_next}; in increasing order, they are \\{undefined\_cs}, \\{expand\_after},
+\\{no\_expand}, \\{input}, \\{if\_test}, \\{fi\_or\_else}, \\{cs\_name}, \\{convert}, \\{the},
+\\{top\_bot\_mark}, \\{call}, \\{long\_call}, \\{outer\_call}, \\{long\_outer\_call}, and
+\\{end\_template}.{\emergencystretch=40pt\par}
+
+The \\{expand} subroutine is used when $\\{cur\_cmd}>\\{max\_command}$. It removes a
+``call'' or a conditional or one of the other special operations just
+listed. It follows that \\{expand} might invoke itself recursively. In all
+cases, \\{expand} destroys the current token, but it sets things up so that
+the next \\{get\_next} will deliver the appropriate next token. The value of
+\\{cur\_tok} need not be known when \\{expand} is called.
+
+Since several of the basic scanning routines communicate via global variables,
+their values are saved as local variables of \\{expand} so that
+recursive calls don't invalidate them.
+
+\Y\B\hbox{\4}\X389:Declare the procedure called \\{macro\_call}\X\6
+\hbox{\4}\X379:Declare the procedure called \\{insert\_relax}\X\7
+\&{void} \\{pass\_text}(\&{void});\6
+\&{void} \\{start\_input}(\&{void});\6
+\&{void} \\{conditional}(\&{void});\6
+\&{void} \\{get\_x\_token}(\&{void});\6
+\&{void} \\{conv\_toks}(\&{void});\6
+\&{void} \\{ins\_the\_toks}(\&{void});\7
+\&{void} \\{expand}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{halfword} \|t;\C{token that is being ``expanded after''}\6
+\&{pointer} \|p${},{}$ \|q${},{}$ \|r;\C{for list manipulation}\6
+\&{uint16\_t} \|j;\C{index into \\{buffer}}\6
+\&{int} \\{cv\_backup};\C{to save the global quantity \\{cur\_val}}\6
+\&{small\_number} \\{cvl\_backup}${},{}$ \\{radix\_backup}${},{}$ \\{co\_backup};\C{to save \\{cur\_val\_level}, etc.}\6
+\&{pointer} \\{backup\_backup};\C{to save \\{link}(\\{backup\_head})}\6
+\&{small\_number} \\{save\_scanner\_status};\C{temporary storage of \\{scanner\_status}}\7
+${}\\{cv\_backup}\K\\{cur\_val};{}$\5
+${}\\{cvl\_backup}\K\\{cur\_val\_level};{}$\5
+${}\\{radix\_backup}\K\\{radix};{}$\5
+${}\\{co\_backup}\K\\{cur\_order};{}$\5
+${}\\{backup\_backup}\K\\{link}(\\{backup\_head});{}$\6
+\&{if} ${}(\\{cur\_cmd}<\\{call}){}$\1\5
+\X367:Expand a nonmacro\X\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}<\\{end\_template}){}$\1\5
+\\{macro\_call}(\,);\2\6
+\&{else}\1\5
+\X375:Insert a token containing \\{frozen\_endv}\X;\2\6
+${}\\{cur\_val}\K\\{cv\_backup};{}$\5
+${}\\{cur\_val\_level}\K\\{cvl\_backup};{}$\5
+${}\\{radix}\K\\{radix\_backup};{}$\5
+${}\\{cur\_order}\K\\{co\_backup};{}$\5
+${}\\{link}(\\{backup\_head})\K\\{backup\_backup};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{367}\B\X367:Expand a nonmacro\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{tracing\_commands}>\T{1}){}$\1\5
+\\{show\_cur\_cmd\_chr}(\,);\2\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{top\_bot\_mark}:\5
+\X386:Insert the \(a)appropriate mark text into the scanner\X\5
+\&{break};\6
+\4\&{case} \\{expand\_after}:\5
+\X368:Expand the token after the next token\X\5
+\&{break};\6
+\4\&{case} \\{no\_expand}:\5
+\X369:Suppress expansion of the next token\X\5
+\&{break};\6
+\4\&{case} \\{cs\_name}:\5
+\X372:Manufacture a control sequence name\X\5
+\&{break};\6
+\4\&{case} \\{convert}:\5
+\\{conv\_toks}(\,);\5
+\&{break};\C{this procedure is discussed in Part 27 below}\6
+\4\&{case} \\{the}:\5
+\\{ins\_the\_toks}(\,);\5
+\&{break};\C{this procedure is discussed in Part 27 below}\6
+\4\&{case} \\{if\_test}:\5
+\\{conditional}(\,);\5
+\&{break};\C{this procedure is discussed in Part 28 below}\6
+\4\&{case} \\{fi\_or\_else}:\5
+\X510:Terminate the current conditional and skip to \.{\\fi}\X\5
+\&{break};\6
+\4\&{case} \\{input}:\5
+\X378:Initiate or terminate input from a file\X;\5
+\&{break};\6
+\4\&{default}:\5
+\X370:Complain about an undefined macro\X\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U366.\fi
+
+\M{368}It takes only a little shuffling to do what \TeX\ calls \.{\\expandafter}.
+
+\Y\B\4\X368:Expand the token after the next token\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_token}(\,);\5
+${}\|t\K\\{cur\_tok};{}$\5
+\\{get\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}>\\{max\_command}){}$\1\5
+\\{expand}(\,);\5
+\2\&{else}\1\5
+\\{back\_input}(\,);\2\6
+${}\\{cur\_tok}\K\|t;{}$\5
+\\{back\_input}(\,);\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\M{369}The implementation of \.{\\noexpand} is a bit trickier, because it is
+necessary to insert a special `\\{dont\_expand}' marker into \TeX's reading
+mechanism. This special marker is processed by \\{get\_next}, but it does
+not slow down the inner loop.
+
+Since \.{\\outer} macros might arise here, we must also
+clear the \\{scanner\_status} temporarily.
+
+\Y\B\4\X369:Suppress expansion of the next token\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{save\_scanner\_status}\K\\{scanner\_status};{}$\5
+${}\\{scanner\_status}\K\\{normal};{}$\5
+\\{get\_token}(\,);\5
+${}\\{scanner\_status}\K\\{save\_scanner\_status};{}$\5
+${}\|t\K\\{cur\_tok};{}$\5
+\\{back\_input}(\,);\C{now \\{start} and \\{loc} point to the backed-up token \|t}\6
+\&{if} ${}(\|t\G\\{cs\_token\_flag}){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|p)\K\\{cs\_token\_flag}+\\{frozen\_dont\_expand};{}$\5
+${}\\{link}(\|p)\K\\{loc};{}$\5
+${}\\{start}\K\|p;{}$\5
+${}\\{loc}\K\|p;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\M{370}\B\X370:Complain about an undefined macro\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Undefined\ control\ s}\)\.{equence"});\5
+\\{help5}(\.{"The\ control\ sequenc}\)\.{e\ at\ the\ end\ of\ the\ }\)\.{top\ line"})\6
+(\.{"of\ your\ error\ messa}\)\.{ge\ was\ never\ \\\\def'e}\)\.{d.\ If\ you\ have"})\6
+(\.{"misspelled\ it\ (e.g.}\)\.{,\ `\\\\hobx'),\ type\ `I}\)\.{'\ and\ the\ correct"})\6
+(\.{"spelling\ (e.g.,\ `I\\}\)\.{\\hbox').\ Otherwise\ j}\)\.{ust\ continue,"})\6
+(\.{"and\ I'll\ forget\ abo}\)\.{ut\ whatever\ was\ unde}\)\.{fined."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\M{371}The \\{expand} procedure and some other routines that construct token
+lists find it convenient to use the following macros, which are valid only if
+the variables \|p and \|q are reserved for token-list building.
+
+\Y\B\4\D$\\{store\_new\_token}(\|X)$ \6
+${}\{{}$\5
+\1${}\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\|p)\K\|q;{}$\5
+${}\\{info}(\|q)\K\|X;{}$\5
+${}\|p\K\|q{}$;\C{\\{link}(\|p) is \\{null}}\6
+\4${}\}{}$\2\par
+\B\4\D$\\{fast\_store\_new\_token}(\|X)$ \6
+${}\{{}$\5
+\1\\{fast\_get\_avail}(\|q);\5
+${}\\{link}(\|p)\K\|q;{}$\5
+${}\\{info}(\|q)\K\|X;{}$\5
+${}\|p\K\|q{}$;\C{\\{link}(\|p) is \\{null}}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{372}\B\X372:Manufacture a control sequence name\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_avail}(\,);{}$\5
+${}\|p\K\|r{}$;\C{head of the list of characters}\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_x\_token}(\,);\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+\\{store\_new\_token}(\\{cur\_tok});\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_cs}\I\T{0}));{}$\6
+\&{if} ${}(\\{cur\_cmd}\I\\{end\_cs\_name}){}$\1\5
+\X373:Complain about missing \.{\\endcsname}\X;\2\6
+\X374:Look up the characters of list \|r in the hash table, and set \\{cur\_cs}\X;\6
+\\{flush\_list}(\|r);\6
+\&{if} ${}(\\{eq\_type}(\\{cur\_cs})\E\\{undefined\_cs}){}$\5
+${}\{{}$\5
+\1${}\\{eq\_define}(\\{cur\_cs},\39\\{relax},\39\T{256}){}$;\C{N.B.: The \\{save\_stack} might change}\6
+\4${}\}{}$\C{the control sequence will now match `\.{\\relax}'}\2\6
+${}\\{cur\_tok}\K\\{cur\_cs}+\\{cs\_token\_flag};{}$\5
+\\{back\_input}(\,);\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\M{373}\B\X373:Complain about missing \.{\\endcsname}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ "});\5
+\\{print\_esc}(\X1527:\.{"endcsname"}\X);\5
+\\{print\_str}(\.{"\ inserted"});\5
+\\{help2}(\.{"The\ control\ sequenc}\)\.{e\ marked\ <to\ be\ read}\)\.{\ again>\ should"})\6
+(\.{"not\ appear\ between\ }\)\.{\\\\csname\ and\ \\\\endcs}\)\.{name."});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\par
+\U372.\fi
+
+\M{374}\B\X374:Look up the characters of list \|r in the hash table, and set \\{cur\_cs}\X${}\E{}$\6
+$\|j\K\\{first};{}$\5
+${}\|p\K\\{link}(\|r);{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|j\G\\{max\_buf\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_buf\_stack}\K\|j+\T{1};{}$\6
+\&{if} ${}(\\{max\_buf\_stack}\E\\{buf\_size}){}$\1\5
+${}\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size});{}$\2\6
+\4${}\}{}$\2\6
+${}\\{buffer}[\|j]\K\\{info}(\|p)\MOD\T{\~400};{}$\5
+\\{incr}(\|j);\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|j>\\{first}+\T{1}){}$\5
+${}\{{}$\5
+\1${}\\{no\_new\_control\_sequence}\K\\{false};{}$\5
+${}\\{cur\_cs}\K\\{id\_lookup}(\\{first},\39\|j-\\{first});{}$\5
+${}\\{no\_new\_control\_sequence}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|j\E\\{first}){}$\1\5
+${}\\{cur\_cs}\K\\{null\_cs}{}$;\C{the list is empty}\2\6
+\&{else} $\\{cur\_cs}\K\\{single\_base}+\\{buffer}{}$[\\{first}]\C{the list has length one}\par
+\U372.\fi
+
+\M{375}An \\{end\_template} command is effectively changed to an \\{endv} command
+by the following code. (The reason for this is discussed below; the
+\\{frozen\_end\_template} at the end of the template has passed the
+\\{check\_outer\_validity} test, so its mission of error detection has been
+accomplished.)
+
+\Y\B\4\X375:Insert a token containing \\{frozen\_endv}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{frozen\_endv};{}$\5
+\\{back\_input}(\,);\6
+\4${}\}{}$\2\par
+\U366.\fi
+
+\M{376}The processing of \.{\\input} involves the \\{start\_input} subroutine,
+which will be declared later; the processing of \.{\\endinput} is trivial.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1570:\.{"input"}\X,\39\\{input},\39\T{0}){}$;\6
+${}\\{primitive}(\X1571:\.{"endinput"}\X,\39\\{input},\39\T{1}){}$;\par
+\fi
+
+\M{377}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{input}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1570:\.{"input"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1571:\.{"endinput"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{378}\B\X378:Initiate or terminate input from a file\X${}\E{}$\6
+\&{if} ${}(\\{cur\_chr}>\T{0}){}$\1\5
+${}\\{force\_eof}\K\\{true};{}$\2\6
+\&{else} \&{if} (\\{name\_in\_progress})\1\5
+\\{insert\_relax}(\,);\2\6
+\&{else} \\{start\_input}(\,)\par
+\U367.\fi
+
+\M{379}Sometimes the expansion looks too far ahead, so we want to insert
+a harmless \.{\\relax} into the user's input.
+
+\Y\B\4\X379:Declare the procedure called \\{insert\_relax}\X${}\E{}$\6
+\&{void} \\{insert\_relax}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{cur\_cs};{}$\5
+\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{frozen\_relax};{}$\5
+\\{back\_input}(\,);\5
+${}\\{token\_type}\K\\{inserted};{}$\6
+\4${}\}{}$\2\par
+\U366.\fi
+
+\M{380}Here is a recursive procedure that is \TeX's usual way to get the
+next token of input. It has been slightly optimized to take account of
+common cases.
+
+\Y\B\&{void} \\{get\_x\_token}(\&{void})\C{sets \\{cur\_cmd}, \\{cur\_chr}, \\{cur\_tok}, and expands macros}\6
+${}\{{}$\5
+\1\\{restart}:\5
+\\{get\_next}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{max\_command}){}$\1\5
+\&{goto} \\{done};\2\6
+\&{if} ${}(\\{cur\_cmd}\G\\{call}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}<\\{end\_template}){}$\1\5
+\\{macro\_call}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\\{frozen\_endv};{}$\5
+${}\\{cur\_cmd}\K\\{endv};{}$\5
+\&{goto} \\{done};\C{$\\{cur\_chr}\E\\{null\_list}$}\6
+\4${}\}{}$\2\2\6
+\&{else}\1\5
+\\{expand}(\,);\2\6
+\&{goto} \\{restart};\6
+\4\\{done}:\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+${}\\{cur\_tok}\K(\\{cur\_cmd}*\T{\~400})+\\{cur\_chr};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{cur\_cs};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{381}The \\{get\_x\_token} procedure is equivalent to two consecutive
+procedure calls: \\{get\_next}; \\{x\_token}.
+
+\Y\B\&{void} \\{x\_token}(\&{void})\C{\\{get\_x\_token} without the initial \\{get\_next}}\6
+${}\{{}$\5
+\1\&{while} ${}(\\{cur\_cmd}>\\{max\_command}){}$\5
+${}\{{}$\5
+\1\\{expand}(\,);\5
+\\{get\_next}(\,);\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+${}\\{cur\_tok}\K(\\{cur\_cmd}*\T{\~400})+\\{cur\_chr};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{cur\_cs};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{382}A control sequence that has been \.{\\def}'ed by the user is expanded by
+\TeX's \\{macro\_call} procedure.
+
+Before we get into the details of \\{macro\_call}, however, let's consider the
+treatment of primitives like \.{\\topmark}, since they are essentially
+macros without parameters. The token lists for such marks are kept in a
+global array of five pointers; we refer to the individual entries of this
+array by symbolic names \\{top\_mark}, etc. The value of \\{top\_mark} is either
+\\{null} or a pointer to the reference count of a token list.
+
+\Y\B\4\D$\\{top\_mark\_code}$ \5
+\T{0}\C{the mark in effect at the previous page break}\par
+\B\4\D$\\{first\_mark\_code}$ \5
+\T{1}\C{the first mark between \\{top\_mark} and \\{bot\_mark}}\par
+\B\4\D$\\{bot\_mark\_code}$ \5
+\T{2}\C{the mark in effect at the current page break}\par
+\B\4\D$\\{split\_first\_mark\_code}$ \5
+\T{3}\C{the first mark found by \.{\\vsplit}}\par
+\B\4\D$\\{split\_bot\_mark\_code}$ \5
+\T{4}\C{the last mark found by \.{\\vsplit}}\par
+\B\4\D$\\{top\_mark}$ \5
+\\{cur\_mark}[\\{top\_mark\_code}]\par
+\B\4\D$\\{first\_mark}$ \5
+\\{cur\_mark}[\\{first\_mark\_code}]\par
+\B\4\D$\\{bot\_mark}$ \5
+\\{cur\_mark}[\\{bot\_mark\_code}]\par
+\B\4\D$\\{split\_first\_mark}$ \5
+\\{cur\_mark}[\\{split\_first\_mark\_code}]\par
+\B\4\D$\\{split\_bot\_mark}$ \5
+\\{cur\_mark}[\\{split\_bot\_mark\_code}]\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} ${}\\{cur\_mark0}[\\{split\_bot\_mark\_code}-\\{top\_mark\_code}+\T{1}],{}$ ${}{*\&{const}\ }\\{cur\_mark}\K\\{cur\_mark0}-\\{top\_mark\_code}{}$;\C{token lists for marks}\par
+\fi
+
+\M{383}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{top\_mark}\K\\{null};{}$\5
+${}\\{first\_mark}\K\\{null};{}$\5
+${}\\{bot\_mark}\K\\{null};{}$\5
+${}\\{split\_first\_mark}\K\\{null};{}$\5
+${}\\{split\_bot\_mark}\K\\{null}{}$;\par
+\fi
+
+\M{384}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1572:\.{"topmark"}\X,\39\\{top\_bot\_mark},\39\\{top\_mark\_code});{}$\5
+${}\\{primitive}(\X1573:\.{"firstmark"}\X,\39\\{top\_bot\_mark},\39\\{first\_mark\_code});{}$\5
+${}\\{primitive}(\X1574:\.{"botmark"}\X,\39\\{top\_bot\_mark},\39\\{bot\_mark\_code});{}$\5
+${}\\{primitive}(\X1575:\.{"splitfirstmark"}\X,\39\\{top\_bot\_mark},\39\\{split\_first\_mark\_code});{}$\5
+${}\\{primitive}(\X1576:\.{"splitbotmark"}\X,\39\\{top\_bot\_mark},\39\\{split\_bot\_mark\_code}){}$;\par
+\fi
+
+\M{385}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{top\_bot\_mark}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{first\_mark\_code}:\5
+\\{print\_esc}(\X1573:\.{"firstmark"}\X);\5
+\&{break};\6
+\4\&{case} \\{bot\_mark\_code}:\5
+\\{print\_esc}(\X1574:\.{"botmark"}\X);\5
+\&{break};\6
+\4\&{case} \\{split\_first\_mark\_code}:\5
+\\{print\_esc}(\X1575:\.{"splitfirstmark"}\X);\5
+\&{break};\6
+\4\&{case} \\{split\_bot\_mark\_code}:\5
+\\{print\_esc}(\X1576:\.{"splitbotmark"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1572:\.{"topmark"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{386}The following code is activated when $\\{cur\_cmd}\E\\{top\_bot\_mark}$ and
+when \\{cur\_chr} is a code like \\{top\_mark\_code}.
+
+\Y\B\4\X386:Insert the \(a)appropriate mark text into the scanner\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_mark}[\\{cur\_chr}]\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{cur\_mark}[\\{cur\_chr}],\39\\{mark\_text});{}$\2\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\M{387}Now let's consider \\{macro\_call} itself, which is invoked when \TeX\ is
+scanning a control sequence whose \\{cur\_cmd} is either \\{call}, \\{long\_call},
+\\{outer\_call}, or \\{long\_outer\_call}. The control sequence definition
+appears in the token list whose reference count is in location \\{cur\_chr}
+of \\{mem}.
+
+The global variable \\{long\_state} will be set to \\{call} or to \\{long\_call},
+depending on whether or not the control sequence disallows \.{\\par}
+in its parameters. The \\{get\_next} routine will set \\{long\_state} to
+\\{outer\_call} and emit \.{\\par}, if a file ends or if an \.{\\outer}
+control sequence occurs in the midst of an argument.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{long\_state};\C{governs the acceptance of \.{\\par}}\par
+\fi
+
+\M{388}The parameters, if any, must be scanned before the macro is expanded.
+Parameters are token lists without reference counts. They are placed on
+an auxiliary stack called \\{pstack} while they are being scanned, since
+the \\{param\_stack} may be losing entries during the matching process.
+(Note that \\{param\_stack} can't be gaining entries, since \\{macro\_call} is
+the only routine that puts anything onto \\{param\_stack}, and it
+is not recursive.)
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{pstack}[\T{9}];\C{arguments supplied to a macro}\par
+\fi
+
+\M{389}After parameter scanning is complete, the parameters are moved to the
+\\{param\_stack}. Then the macro body is fed to the scanner; in other words,
+\\{macro\_call} places the defined text of the control sequence at the
+top of\/ \TeX's input stack, so that \\{get\_next} will proceed to read it
+next.
+
+The global variable \\{cur\_cs} contains the \\{eqtb} address of the control sequence
+being expanded, when \\{macro\_call} begins. If this control sequence has not been
+declared \.{\\long}, i.e., if its command code in the \\{eq\_type} field is
+not \\{long\_call} or \\{long\_outer\_call}, its parameters are not allowed to contain
+the control sequence \.{\\par}. If an illegal \.{\\par} appears, the macro
+call is aborted, and the \.{\\par} will be rescanned.
+
+\Y\B\4\X389:Declare the procedure called \\{macro\_call}\X${}\E{}$\6
+\&{void} \\{macro\_call}(\&{void})\C{invokes a user-defined control sequence}\6
+${}\{{}$\5
+\1\&{pointer} \|r;\C{current node in the macro's token list}\6
+\&{pointer} \|p;\C{current node in parameter token list being built}\6
+\&{pointer} \|q;\C{new node being put into the token list}\6
+\&{pointer} \|s;\C{backup pointer for parameter matching}\6
+\&{pointer} \|t;\C{cycle pointer for backup recovery}\6
+\&{pointer} \|u${},{}$ \|v;\C{auxiliary pointers for backup recovery}\6
+\&{pointer} \\{rbrace\_ptr};\C{one step before the last \\{right\_brace} token}\6
+\&{small\_number} \|n;\C{the number of parameters scanned}\6
+\&{halfword} \\{unbalance};\C{unmatched left braces in current parameter}\6
+\&{int} \|m;\C{the number of tokens or groups (usually)}\6
+\&{pointer} \\{ref\_count};\C{start of the token list}\6
+\&{small\_number} \\{save\_scanner\_status};\C{\\{scanner\_status} upon entry}\6
+\&{pointer} \\{save\_warning\_index};\C{\\{warning\_index} upon entry}\6
+\&{ASCII\_code} \\{match\_chr};\C{character used in parameter}\7
+${}\\{save\_scanner\_status}\K\\{scanner\_status};{}$\5
+${}\\{save\_warning\_index}\K\\{warning\_index};{}$\5
+${}\\{warning\_index}\K\\{cur\_cs};{}$\5
+${}\\{ref\_count}\K\\{cur\_chr};{}$\5
+${}\|r\K\\{link}(\\{ref\_count});{}$\5
+${}\|n\K\T{0};{}$\6
+\&{if} ${}(\\{tracing\_macros}>\T{0}){}$\1\5
+\X401:Show the text of the macro being expanded\X;\2\6
+\&{if} ${}(\\{info}(\|r)\I\\{end\_match\_token}){}$\1\5
+\X391:Scan the parameters and make \\{link}(\|r) point to the macro body; but \&{return} if an illegal \.{\\par} is detected\X;\2\6
+\X390:Feed the macro body and its parameters to the scanner\X;\6
+\4\\{end}:\5
+${}\\{scanner\_status}\K\\{save\_scanner\_status};{}$\5
+${}\\{warning\_index}\K\\{save\_warning\_index};{}$\6
+\4${}\}{}$\2\par
+\U366.\fi
+
+\M{390}Before we put a new token list on the input stack, it is wise to clean off
+all token lists that have recently been depleted. Then a user macro that ends
+with a call to itself will not require unbounded stack space.
+
+\Y\B\4\X390:Feed the macro body and its parameters to the scanner\X${}\E{}$\6
+\&{while} ${}((\\{state}\E\\{token\_list})\W(\\{loc}\E\\{null})\W(\\{token\_type}\I\\{v\_template})){}$\1\5
+\\{end\_token\_list}(\,);\C{conserve stack space}\2\6
+${}\\{begin\_token\_list}(\\{ref\_count},\39\\{macro});{}$\5
+${}\\{name}\K\\{warning\_index};{}$\5
+${}\\{loc}\K\\{link}(\|r);{}$\6
+\&{if} ${}(\|n>\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{param\_ptr}+\|n>\\{max\_param\_stack}){}$\5
+${}\{{}$\5
+\1${}\\{max\_param\_stack}\K\\{param\_ptr}+\|n;{}$\6
+\&{if} ${}(\\{max\_param\_stack}>\\{param\_size}){}$\1\5
+${}\\{overflow}(\.{"parameter\ stack\ siz}\)\.{e"},\39\\{param\_size});{}$\2\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|m\K\T{0};{}$ ${}\|m\Z\|n-\T{1};{}$ ${}\|m\PP){}$\1\5
+${}\\{param\_stack}[\\{param\_ptr}+\|m]\K\\{pstack}[\|m];{}$\2\6
+${}\\{param\_ptr}\K\\{param\_ptr}+\|n;{}$\6
+\4${}\}{}$\2\par
+\U389.\fi
+
+\M{391}At this point, the reader will find it advisable to review the explanation
+of token list format that was presented earlier, since many aspects of that
+format are of importance chiefly in the \\{macro\_call} routine.
+
+The token list might begin with a string of compulsory tokens before the
+first \\{match} or \\{end\_match}. In that case the macro name is supposed to be
+followed by those tokens; the following program will set $\|s\E\\{null}$ to
+represent this restriction. Otherwise \|s will be set to the first token of
+a string that will delimit the next parameter.
+
+\Y\B\4\X391:Scan the parameters and make \\{link}(\|r) point to the macro body; but \&{return} if an illegal \.{\\par} is detected\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{scanner\_status}\K\\{matching};{}$\5
+${}\\{unbalance}\K\T{0};{}$\5
+${}\\{long\_state}\K\\{eq\_type}(\\{cur\_cs});{}$\6
+\&{if} ${}(\\{long\_state}\G\\{outer\_call}){}$\1\5
+${}\\{long\_state}\K\\{long\_state}-\T{2}{}$;\2\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{link}(\\{temp\_head})\K\\{null};{}$\6
+\&{if} ${}((\\{info}(\|r)>\\{match\_token}+\T{255})\V(\\{info}(\|r)<\\{match\_token})){}$\1\5
+${}\|s\K\\{null};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{match\_chr}\K\\{info}(\|r)-\\{match\_token};{}$\5
+${}\|s\K\\{link}(\|r);{}$\5
+${}\|r\K\|s;{}$\5
+${}\|p\K\\{temp\_head};{}$\5
+${}\|m\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\X392:Scan a parameter until its delimiter string has been found; or, if $\|s\K\\{null}$, simply scan the delimiter string\X;\C{now \\{info}(\|r) is a token whose command code is either \\{match} or \\{end\_match}}\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{info}(\|r)\E\\{end\_match\_token}));{}$\6
+\4${}\}{}$\2\par
+\U389.\fi
+
+\M{392}If \\{info}(\|r) is a \\{match} or \\{end\_match} command, it cannot be equal to
+any token found by \\{get\_token}. Therefore an undelimited parameter---i.e.,
+a \\{match} that is immediately followed by \\{match} or \\{end\_match}---will
+always fail the test `$\\{cur\_tok}\E\\{info}(\|r)$' in the following algorithm.
+
+\Y\B\4\X392:Scan a parameter until its delimiter string has been found; or, if $\|s\K\\{null}$, simply scan the delimiter string\X${}\E{}$\6
+\4\\{resume}:\5
+\\{get\_token}(\,);\C{set \\{cur\_tok} to the next token of input}\6
+\&{if} ${}(\\{cur\_tok}\E\\{info}(\|r)){}$\1\5
+\X394:Advance \(r)\|r; \&{goto} \\{found} if the parameter delimiter has been fully matched, otherwise \&{goto} \&{continue}\X;\2\6
+\X397:Contribute the recently matched tokens to the current parameter, and \&{goto} \&{continue} if a partial match is still in effect; but abort if $\|s\K\\{null}$\X;\6
+\&{if} ${}(\\{cur\_tok}\E\\{par\_token}){}$\1\6
+\&{if} ${}(\\{long\_state}\I\\{long\_call}){}$\1\5
+\X396:Report a runaway argument and abort\X;\2\2\6
+\&{if} ${}(\\{cur\_tok}<\\{right\_brace\_limit}){}$\1\6
+\&{if} ${}(\\{cur\_tok}<\\{left\_brace\_limit}){}$\1\5
+\X399:Contribute an entire group to the current parameter\X\2\6
+\&{else}\1\5
+\X395:Report an extra right brace and \&{goto} \&{continue}\X\2\2\6
+\&{else}\1\5
+\X393:Store the current token, but \&{goto} \&{continue} if it is a blank space that would become an undelimited parameter\X;\2\6
+\\{incr}(\|m);\6
+\&{if} ${}(\\{info}(\|r)>\\{end\_match\_token}){}$\1\5
+\&{goto} \\{resume};\2\6
+\&{if} ${}(\\{info}(\|r)<\\{match\_token}){}$\1\5
+\&{goto} \\{resume};\2\6
+\4\\{found}:\6
+\&{if} ${}(\|s\I\\{null}){}$\1\5
+\X400:Tidy up the parameter just scanned, and tuck it away\X\2\par
+\U391.\fi
+
+\M{393}\B\X393:Store the current token, but \&{goto} \&{continue} if it is a blank space that would become an undelimited parameter\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_tok}\E\\{space\_token}){}$\1\6
+\&{if} ${}(\\{info}(\|r)\Z\\{end\_match\_token}){}$\1\6
+\&{if} ${}(\\{info}(\|r)\G\\{match\_token}){}$\1\5
+\&{goto} \\{resume};\2\2\2\6
+\\{store\_new\_token}(\\{cur\_tok});\6
+\4${}\}{}$\2\par
+\U392.\fi
+
+\M{394}A slightly subtle point arises here: When the parameter delimiter ends
+with `\.{\#\{}', the token list will have a left brace both before and
+after the \\{end\_match}\kern-.4pt. Only one of these should affect the
+\\{align\_state}, but both will be scanned, so we must make a correction.
+
+\Y\B\4\X394:Advance \(r)\|r; \&{goto} \\{found} if the parameter delimiter has been fully matched, otherwise \&{goto} \&{continue}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{link}(\|r);{}$\6
+\&{if} ${}((\\{info}(\|r)\G\\{match\_token})\W(\\{info}(\|r)\Z\\{end\_match\_token})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_tok}<\\{left\_brace\_limit}){}$\1\5
+\\{decr}(\\{align\_state});\2\6
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\&{goto} \\{resume};\2\6
+\4${}\}{}$\2\par
+\U392.\fi
+
+\M{395}\B\X395:Report an extra right brace and \&{goto} \&{continue}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\\{print\_err}(\.{"Argument\ of\ "});\5
+\\{sprint\_cs}(\\{warning\_index});\5
+\\{print\_str}(\.{"\ has\ an\ extra\ \}"});\5
+\\{help6}(\.{"I've\ run\ across\ a\ `}\)\.{\}'\ that\ doesn't\ seem}\)\.{\ to\ match\ anything."})\6
+(\.{"For\ example,\ `\\\\def}\)\.{\\\\a\#1\{...\}'\ and\ `\\\\a}\)\.{\}'\ would\ produce"})\6
+(\.{"this\ error.\ If\ you\ }\)\.{simply\ proceed\ now,\ }\)\.{the\ `\\\\par'\ that"})\6
+(\.{"I've\ just\ inserted\ }\)\.{will\ cause\ me\ to\ rep}\)\.{ort\ a\ runaway"})\6
+(\.{"argument\ that\ might}\)\.{\ be\ the\ root\ of\ the\ }\)\.{problem.\ But\ if"})\6
+(\.{"your\ `\}'\ was\ spurio}\)\.{us,\ just\ type\ `2'\ an}\)\.{d\ it\ will\ go\ away."});\5
+\\{incr}(\\{align\_state});\5
+${}\\{long\_state}\K\\{call};{}$\5
+${}\\{cur\_tok}\K\\{par\_token};{}$\5
+\\{ins\_error}(\,);\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\C{a white lie; the \.{\\par} won't always trigger a runaway}\2\par
+\U392.\fi
+
+\M{396}If $\\{long\_state}\E\\{outer\_call}$, a runaway argument has already been reported.
+
+\Y\B\4\X396:Report a runaway argument and abort\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{long\_state}\E\\{call}){}$\5
+${}\{{}$\5
+\1\\{runaway}(\,);\5
+\\{print\_err}(\.{"Paragraph\ ended\ bef}\)\.{ore\ "});\5
+\\{sprint\_cs}(\\{warning\_index});\5
+\\{print\_str}(\.{"\ was\ complete"});\5
+\\{help3}(\.{"I\ suspect\ you've\ fo}\)\.{rgotten\ a\ `\}',\ causi}\)\.{ng\ me\ to\ apply\ this"})\6
+(\.{"control\ sequence\ to}\)\.{\ too\ much\ text.\ How\ }\)\.{can\ we\ recover?"})\6
+(\.{"My\ plan\ is\ to\ forge}\)\.{t\ the\ whole\ thing\ an}\)\.{d\ hope\ for\ the\ best.}\)\.{"});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\6
+${}\\{pstack}[\|n]\K\\{link}(\\{temp\_head});{}$\5
+${}\\{align\_state}\K\\{align\_state}-\\{unbalance};{}$\6
+\&{for} ${}(\|m\K\T{0};{}$ ${}\|m\Z\|n;{}$ ${}\|m\PP){}$\1\5
+\\{flush\_list}(\\{pstack}[\|m]);\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\Us392\ET399.\fi
+
+\M{397}When the following code becomes active, we have matched tokens from \|s to
+the predecessor of \|r, and we have found that $\\{cur\_tok}\I\\{info}(\|r)$. An
+interesting situation now presents itself: If the parameter is to be
+delimited by a string such as `\.{ab}', and if we have scanned `\.{aa}',
+we want to contribute one `\.a' to the current parameter and resume
+looking for a `\.b'. The program must account for such partial matches and
+for others that can be quite complex. But most of the time we have $\|s\E\|r$
+and nothing needs to be done.
+
+Incidentally, it is possible for \.{\\par} tokens to sneak in to certain
+parameters of non-\.{\\long} macros. For example, consider a case like
+`\.{\\def\\a\#1\\par!\{...\}}' where the first \.{\\par} is not followed
+by an exclamation point. In such situations it does not seem appropriate
+to prohibit the \.{\\par}, so \TeX\ keeps quiet about this bending of
+the rules.
+
+\Y\B\4\X397:Contribute the recently matched tokens to the current parameter, and \&{goto} \&{continue} if a partial match is still in effect; but abort if $\|s\K\\{null}$\X${}\E{}$\6
+\&{if} ${}(\|s\I\|r){}$\1\6
+\&{if} ${}(\|s\E\\{null}){}$\1\5
+\X398:Report an improper use of the macro and abort\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|t\K\|s{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\\{store\_new\_token}(\\{info}(\|t));\5
+\\{incr}(\|m);\5
+${}\|u\K\\{link}(\|t);{}$\5
+${}\|v\K\|s;{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\|u\E\|r){}$\1\6
+\&{if} ${}(\\{cur\_tok}\I\\{info}(\|v)){}$\1\5
+\&{goto} \\{done};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\|v);{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\\{info}(\|u)\I\\{info}(\|v)){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|u\K\\{link}(\|u);{}$\5
+${}\|v\K\\{link}(\|v);{}$\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+${}\|t\K\\{link}(\|t);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|t\E\|r));{}$\5
+${}\|r\K\|s{}$;\C{at this point, no tokens are recently matched}\6
+\4${}\}{}$\2\2\par
+\U392.\fi
+
+\M{398}\B\X398:Report an improper use of the macro and abort\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Use\ of\ "});\5
+\\{sprint\_cs}(\\{warning\_index});\5
+\\{print\_str}(\.{"\ doesn't\ match\ its\ }\)\.{definition"});\5
+\\{help4}(\.{"If\ you\ say,\ e.g.,\ `}\)\.{\\\\def\\\\a1\{...\}',\ the}\)\.{n\ you\ must\ always"})\6
+(\.{"put\ `1'\ after\ `\\\\a'}\)\.{,\ since\ control\ sequ}\)\.{ence\ names\ are"})\6
+(\.{"made\ up\ of\ letters\ }\)\.{only.\ The\ macro\ here}\)\.{\ has\ not\ been"})\6
+(\.{"followed\ by\ the\ req}\)\.{uired\ stuff,\ so\ I'm\ }\)\.{ignoring\ it."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\U397.\fi
+
+\M{399}\B\X399:Contribute an entire group to the current parameter\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{unbalance}\K\T{1};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{fast\_store\_new\_token}(\\{cur\_tok});\5
+\\{get\_token}(\,);\6
+\&{if} ${}(\\{cur\_tok}\E\\{par\_token}){}$\1\6
+\&{if} ${}(\\{long\_state}\I\\{long\_call}){}$\1\5
+\X396:Report a runaway argument and abort\X;\2\2\6
+\&{if} ${}(\\{cur\_tok}<\\{right\_brace\_limit}){}$\1\6
+\&{if} ${}(\\{cur\_tok}<\\{left\_brace\_limit}){}$\1\5
+\\{incr}(\\{unbalance});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{decr}(\\{unbalance});\6
+\&{if} ${}(\\{unbalance}\E\T{0}){}$\1\5
+\&{goto} \\{done1};\2\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\6
+\4\\{done1}:\5
+${}\\{rbrace\_ptr}\K\|p;{}$\5
+\\{store\_new\_token}(\\{cur\_tok});\6
+\4${}\}{}$\2\par
+\U392.\fi
+
+\M{400}If the parameter consists of a single group enclosed in braces, we must
+strip off the enclosing braces. That's why \\{rbrace\_ptr} was introduced.
+
+\Y\B\4\X400:Tidy up the parameter just scanned, and tuck it away\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\|m\E\T{1})\W(\\{info}(\|p)<\\{right\_brace\_limit})\W(\|p\I\\{temp\_head})){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{rbrace\_ptr})\K\\{null};{}$\5
+\\{free\_avail}(\|p);\5
+${}\|p\K\\{link}(\\{temp\_head});{}$\5
+${}\\{pstack}[\|n]\K\\{link}(\|p);{}$\5
+\\{free\_avail}(\|p);\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{pstack}[\|n]\K\\{link}(\\{temp\_head});{}$\2\6
+\\{incr}(\|n);\6
+\&{if} ${}(\\{tracing\_macros}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{""});\5
+\\{print}(\\{match\_chr});\5
+\\{print\_int}(\|n);\5
+\\{print\_str}(\.{"<-"});\5
+${}\\{show\_token\_list}(\\{pstack}[\|n-\T{1}],\39\\{null},\39\T{1000});{}$\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U392.\fi
+
+\M{401}\B\X401:Show the text of the macro being expanded\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_ln}(\,);\5
+\\{print\_cs}(\\{warning\_index});\5
+\\{token\_show}(\\{ref\_count});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\par
+\U389.\fi
+
+\N{1}{402}Basic scanning subroutines.
+Let's turn now to some procedures that \TeX\ calls upon frequently to digest
+certain kinds of patterns in the input. Most of these are quite simple;
+some are quite elaborate. Almost all of the routines call \\{get\_x\_token},
+which can cause them to be invoked recursively.
+
+\fi
+
+\M{403}The \\{scan\_left\_brace} routine is called when a left brace is supposed to be
+the next non-blank token. (The term ``left brace'' means, more precisely,
+a character whose catcode is \\{left\_brace}.) \TeX\ allows \.{\\relax} to
+appear before the \\{left\_brace}.
+
+\Y\B\&{void} \\{scan\_left\_brace}(\&{void})\C{reads a mandatory \\{left\_brace}}\6
+${}\{{}$\5
+\1\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\I\\{left\_brace}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \{\ inserted"});\5
+\\{help4}(\.{"A\ left\ brace\ was\ ma}\)\.{ndatory\ here,\ so\ I'v}\)\.{e\ put\ one\ in."})\6
+(\.{"You\ might\ want\ to\ d}\)\.{elete\ and/or\ insert\ }\)\.{some\ corrections"})\6
+(\.{"so\ that\ I\ will\ find}\)\.{\ a\ matching\ right\ br}\)\.{ace\ soon."})\6
+(\.{"(If\ you're\ confused}\)\.{\ by\ all\ this,\ try\ ty}\)\.{ping\ `I\}'\ now.)"});\5
+\\{back\_error}(\,);\5
+${}\\{cur\_tok}\K\\{left\_brace\_token}+\.{'\{'};{}$\5
+${}\\{cur\_cmd}\K\\{left\_brace};{}$\5
+${}\\{cur\_chr}\K\.{'\{'};{}$\5
+\\{incr}(\\{align\_state});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{404}\B\X404:Get the next non-blank non-relax non-call token\X${}\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R((\\{cur\_cmd}\I\\{spacer})\W(\\{cur\_cmd}\I\\{relax})){}$)\par
+\Us403, 1078, 1084, 1151, 1160, 1211, 1226\ETs1270.\fi
+
+\M{405}The \\{scan\_optional\_equals} routine looks for an optional `\.=' sign preceded
+by optional spaces; `\.{\\relax}' is not ignored here.
+
+\Y\B\&{void} \\{scan\_optional\_equals}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}(\\{cur\_tok}\I\\{other\_token}+\.{'='}){}$\1\5
+\\{back\_input}(\,);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{406}\B\X406:Get the next non-blank non-call token\X${}\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\\{cur\_cmd}\I\\{spacer}){}$)\par
+\Us405, 441, 455, 503, 525, 577, 785, 791\ETs1045.\fi
+
+\M{407}In case you are getting bored, here is a slightly less trivial routine:
+Given a string of lowercase letters, like `\.{pt}' or `\.{plus}' or
+`\.{width}', the \\{scan\_keyword} routine checks to see whether the next
+tokens of input match this string. The match must be exact, except that
+uppercase letters will match their lowercase counterparts; uppercase
+equivalents are determined by subtracting $\.{'a'}-\.{'A'}$, rather than using the
+\\{uc\_code} table, since \TeX\ uses this routine only for its own limited
+set of keywords.
+
+If a match is found, the characters are effectively removed from the input
+and \\{true} is returned. Otherwise \\{false} is returned, and the input
+is left essentially unchanged (except for the fact that some macros
+may have been expanded, etc.).
+
+\Y\B\&{bool} \\{scan\_keyword}(\&{str\_number} \|s)\C{look for a given string}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{tail of the backup list}\6
+\&{pointer} \|q;\C{new node being added to the token list via \\{store\_new\_token}}\6
+\&{pool\_pointer} \|k;\C{index into \\{str\_pool}}\7
+${}\|p\K\\{backup\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+${}\|k\K\\{str\_start}[\|s];{}$\6
+\&{while} ${}(\|k<\\{str\_start}[\|s+\T{1}]){}$\5
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\C{recursion is possible here}\6
+\&{if} ${}((\\{cur\_cs}\E\T{0})\W\30((\\{cur\_chr}\E\\{so}(\\{str\_pool}[\|k]))\V(\\{cur\_chr}\E\\{so}(\\{str\_pool}[\|k])-\.{'a'}+\.{'A'}))){}$\5
+${}\{{}$\5
+\1\\{store\_new\_token}(\\{cur\_tok});\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\\{cur\_cmd}\I\\{spacer})\V(\|p\I\\{backup\_head})){}$\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\6
+\&{if} ${}(\|p\I\\{backup\_head}){}$\1\5
+\\{back\_list}(\\{link}(\\{backup\_head}));\2\6
+\&{return} \\{false};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\\{flush\_list}(\\{link}(\\{backup\_head}));\5
+\&{return} \\{true};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{408}Here is a procedure that sounds an alarm when mu and non-mu units
+are being switched.
+
+\Y\B\&{void} \\{mu\_error}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Incompatible\ glue\ u}\)\.{nits"});\5
+\\{help1}(\.{"I'm\ going\ to\ assume}\)\.{\ that\ 1mu=1pt\ when\ t}\)\.{hey're\ mixed."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{409}The next routine `\\{scan\_something\_internal}' is used to fetch internal
+numeric quantities like `\.{\\hsize}', and also to handle the `\.{\\the}'
+when expanding constructions like `\.{\\the\\toks0}' and
+`\.{\\the\\baselineskip}'. Soon we will be considering the \\{scan\_int}
+procedure, which calls \\{scan\_something\_internal}; on the other hand,
+\\{scan\_something\_internal} also calls \\{scan\_int}, for constructions like
+`\.{\\catcode\`\\\$}' or `\.{\\fontdimen} \.3 \.{\\ff}'. So we
+have to declare \\{scan\_int} as a \\{forward} procedure. A few other
+procedures are also declared at this point.
+
+\Y\B\&{void} \\{scan\_int}(\&{void});\C{scans an integer value}\7
+\hbox{\4\4}\X433:Declare procedures that scan restricted classes of integers\X\6
+\hbox{\4\4}\X577:Declare procedures that scan font-related stuff\X\par
+\fi
+
+\M{410}\TeX\ doesn't know exactly what to expect when \\{scan\_something\_internal}
+begins. For example, an integer or dimension or glue value could occur
+immediately after `\.{\\hskip}'; and one can even say \.{\\the} with
+respect to token lists in constructions like
+`\.{\\xdef\\o\{\\the\\output\}}'. On the other hand, only integers are
+allowed after a construction like `\.{\\count}'. To handle the various
+possibilities, \\{scan\_something\_internal} has a \\{level} parameter, which
+tells the ``highest'' kind of quantity that \\{scan\_something\_internal} is
+allowed to produce. Six levels are distinguished, namely \\{int\_val},
+\\{dimen\_val}, \\{glue\_val}, \\{mu\_val}, \\{ident\_val}, and \\{tok\_val}.
+
+The output of \\{scan\_something\_internal} (and of the other routines
+\\{scan\_int}, \\{scan\_dimen}, and \\{scan\_glue} below) is put into the global
+variable \\{cur\_val}, and its level is put into \\{cur\_val\_level}. The highest
+values of \\{cur\_val\_level} are special: \\{mu\_val} is used only when
+\\{cur\_val} points to something in a ``muskip'' register, or to one of the
+three parameters \.{\\thinmuskip}, \.{\\medmuskip}, \.{\\thickmuskip};
+\\{ident\_val} is used only when \\{cur\_val} points to a font identifier;
+\\{tok\_val} is used only when \\{cur\_val} points to \\{null} or to the reference
+count of a token list. The last two cases are allowed only when
+\\{scan\_something\_internal} is called with $\\{level}\E\\{tok\_val}$.
+
+If the output is glue, \\{cur\_val} will point to a glue specification, and
+the reference count of that glue will have been updated to reflect this
+reference; if the output is a nonempty token list, \\{cur\_val} will point to
+its reference count, but in this case the count will not have been updated.
+Otherwise \\{cur\_val} will contain the integer or scaled value in question.
+
+\Y\B\4\D$\\{int\_val}$ \5
+\T{0}\C{integer values}\par
+\B\4\D$\\{dimen\_val}$ \5
+\T{1}\C{dimension values}\par
+\B\4\D$\\{glue\_val}$ \5
+\T{2}\C{glue specifications}\par
+\B\4\D$\\{mu\_val}$ \5
+\T{3}\C{math glue specifications}\par
+\B\4\D$\\{ident\_val}$ \5
+\T{4}\C{font identifier}\par
+\B\4\D$\\{tok\_val}$ \5
+\T{5}\C{token lists}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{cur\_val};\C{value returned by numeric scanners}\6
+\&{uint8\_t} \\{cur\_val\_level};\C{the ``level'' of this value}\par
+\fi
+
+\M{411}The hash table is initialized with `\.{\\count}', `\.{\\dimen}', `\.{\\skip}',
+and `\.{\\muskip}' all having \&{register} as their command code; they are
+distinguished by the \\{chr\_code}, which is either \\{int\_val}, \\{dimen\_val},
+\\{glue\_val}, or \\{mu\_val}.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1501:\.{"count"}\X,\39\&{register},\39\\{int\_val});{}$\5
+${}\\{primitive}(\X1524:\.{"dimen"}\X,\39\&{register},\39\\{dimen\_val});{}$\5
+${}\\{primitive}(\X1423:\.{"skip"}\X,\39\&{register},\39\\{glue\_val});{}$\5
+${}\\{primitive}(\X1424:\.{"muskip"}\X,\39\&{register},\39\\{mu\_val}){}$;\par
+\fi
+
+\M{412}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\&{case} \&{register} : \6
+\&{if} ${}(\\{chr\_code}\E\\{int\_val}){}$\1\5
+\\{print\_esc}(\X1501:\.{"count"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{dimen\_val}){}$\1\5
+\\{print\_esc}(\X1524:\.{"dimen"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{glue\_val}){}$\1\5
+\\{print\_esc}(\X1423:\.{"skip"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1424:\.{"muskip"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{413}OK, we're ready for \\{scan\_something\_internal} itself. A second parameter,
+\\{negative}, is set \\{true} if the value that is found should be negated.
+It is assumed that \\{cur\_cmd} and \\{cur\_chr} represent the first token of
+the internal quantity to be scanned; an error will be signalled if
+$\\{cur\_cmd}<\\{min\_internal}$ or $\\{cur\_cmd}>\\{max\_internal}$.
+
+\Y\B\4\D$\\{scanned\_result\_end}(\|X)$ \5
+$\\{cur\_val\_level}\K\|X{}$;\5
+$\}{}$\par
+\B\4\D$\\{scanned\_result}(\|X)$ \5
+$\{{}$\5
+$\\{cur\_val}\K\|X;$ \\{scanned\_result\_end}\par
+\Y\B\&{void} \\{scan\_something\_internal}(\&{small\_number} \\{level}${},\39{}$\&{bool} \\{negative})\C{fetch an internal parameter}\1\1\6
+$\{{}$\5
+\&{halfword} \|m;\C{\\{chr\_code} part of the operand token}\6
+\&{uint8\_t} \|p;\C{index into \\{nest}}\7
+${}\|m\K\\{cur\_chr};$ \&{switch} (\\{cur\_cmd}) $\{$ \6
+\4\&{case} \\{def\_code}:\5
+\X414:Fetch a character code from some table\X\5
+\&{break};\6
+\4\&{case} \\{toks\_register}:\5
+\&{case} \\{assign\_toks}:\5
+\&{case} \\{def\_family}:\5
+\&{case} \\{set\_font}:\5
+\&{case} \\{def\_font}:\5
+\X415:Fetch a token list or font identifier, provided that $\\{level}\K\\{tok\_val}$\X\5
+\&{break};\6
+\4\&{case} \\{assign\_int}:\5
+${}\\{scanned\_result}(\\{eqtb}[\|m].\|i)(\\{int\_val}){}$\5
+\&{break};\6
+\4\&{case} \\{assign\_dimen}:\5
+${}\\{scanned\_result}(\\{eqtb}[\|m].\\{sc})(\\{dimen\_val}){}$\5
+\&{break};\6
+\4\&{case} \\{assign\_glue}:\5
+\\{scanned\_result}(\\{equiv}(\|m))(\\{glue\_val})\5
+\&{break};\6
+\4\&{case} \\{assign\_mu\_glue}:\5
+\\{scanned\_result}(\\{equiv}(\|m))(\\{mu\_val})\5
+\&{break};\6
+\4\&{case} \\{set\_aux}:\5
+\X418:Fetch the \\{space\_factor} or the \\{prev\_depth}\X\5
+\&{break};\6
+\4\&{case} \\{set\_prev\_graf}:\5
+\X422:Fetch the \\{prev\_graf}\X\5
+\&{break};\6
+\4\&{case} \\{set\_page\_int}:\5
+\X419:Fetch the \\{dead\_cycles} or the \\{insert\_penalties}\X\5
+\&{break};\6
+\4\&{case} \\{set\_page\_dimen}:\5
+\X421:Fetch something on the \\{page\_so\_far}\X\5
+\&{break};\6
+\4\&{case} \\{set\_shape}:\5
+\X423:Fetch the \\{par\_shape} size\X\5
+\&{break};\6
+\4\&{case} \\{set\_box\_dimen}:\5
+\X420:Fetch a box dimension\X\5
+\&{break};\6
+\4\&{case} \\{char\_given}:\5
+\&{case} \\{math\_given}:\5
+\\{scanned\_result}(\\{cur\_chr})(\\{int\_val})\5
+\&{break};\6
+\4\&{case} \\{assign\_font\_dimen}:\5
+\X425:Fetch a font dimension\X\5
+\&{break};\6
+\4\&{case} \\{assign\_font\_int}:\5
+\X426:Fetch a font integer\X\5
+\&{break}; \&{case} \&{register} : \X427:Fetch a register\X\5
+\&{break};\6
+\4\&{case} \\{last\_item}:\5
+\X424:Fetch an item in the current node, if appropriate\X\5
+\&{break};\6
+\4\&{default}:\5
+\X428:Complain that \.{\\the} can't do this; give zero result\X\6
+$\}{}$\6
+\&{while} ${}(\\{cur\_val\_level}>\\{level}){}$\1\5
+\X429:Convert \(c)\\{cur\_val} to a lower level\X;\2\6
+\X430:Fix the reference count, if any, and negate \\{cur\_val} if \\{negative}\X;\6
+$\}{}$\par
+\fi
+
+\M{414}\B\X414:Fetch a character code from some table\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\6
+\&{if} ${}(\|m\E\\{math\_code\_base}){}$\1\5
+\\{scanned\_result}(\\{ho}(\\{math\_code}(\\{cur\_val})))(\\{int\_val})\2\6
+\&{else} \&{if} ${}(\|m<\\{math\_code\_base}){}$\1\5
+${}\\{scanned\_result}(\\{equiv}(\|m+\\{cur\_val}))(\\{int\_val}){}$\2\6
+\&{else}\1\5
+${}\\{scanned\_result}(\\{eqtb}[\|m+\\{cur\_val}].\|i)(\\{int\_val});{}$\2\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{415}\B\X415:Fetch a token list or font identifier, provided that $\\{level}\K\\{tok\_val}$\X${}\E{}$\6
+\&{if} ${}(\\{level}\I\\{tok\_val}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ number,\ tre}\)\.{ated\ as\ zero"});\5
+\\{help3}(\.{"A\ number\ should\ hav}\)\.{e\ been\ here;\ I\ inser}\)\.{ted\ `0'."})\6
+(\.{"(If\ you\ can't\ figur}\)\.{e\ out\ why\ I\ needed\ t}\)\.{o\ see\ a\ number,"})\6
+(\.{"look\ up\ `weird\ erro}\)\.{r'\ in\ the\ index\ to\ T}\)\.{he\ TeXbook.)"});\5
+\\{back\_error}(\,);\5
+\\{scanned\_result}(\T{0})(\\{dimen\_val});\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\Z\\{assign\_toks}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_cmd}<\\{assign\_toks}{}$)\C{$\\{cur\_cmd}\E\\{toks\_register}$}\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\|m\K\\{toks\_base}+\\{cur\_val};{}$\6
+\4${}\}{}$\2\6
+\\{scanned\_result}(\\{equiv}(\|m))(\\{tok\_val});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\\{scan\_font\_ident}(\,);\5
+${}\\{scanned\_result}(\\{font\_id\_base}+\\{cur\_val})(\\{ident\_val});{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{416}Users refer to `\.{\\the\\spacefactor}' only in horizontal
+mode, and to `\.{\\the\\prevdepth}' only in vertical mode; so we put the
+associated mode in the modifier part of the \\{set\_aux} command.
+The \\{set\_page\_int} command has modifier 0 or 1, for `\.{\\deadcycles}' and
+`\.{\\insertpenalties}', respectively. The \\{set\_box\_dimen} command is
+modified by either \\{width\_offset}, \\{height\_offset}, or \\{depth\_offset}.
+And the \\{last\_item} command is modified by either \\{int\_val}, \\{dimen\_val},
+\\{glue\_val}, \\{input\_line\_no\_code}, or \\{badness\_code}.
+
+\Y\B\4\D$\\{input\_line\_no\_code}$ \5
+$(\\{glue\_val}+\T{1}{}$)\C{code for \.{\\inputlineno}}\par
+\B\4\D$\\{badness\_code}$ \5
+$(\\{glue\_val}+\T{2}{}$)\C{code for \.{\\badness}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1577:\.{"spacefactor"}\X,\39\\{set\_aux},\39\\{hmode});{}$\5
+${}\\{primitive}(\X1578:\.{"prevdepth"}\X,\39\\{set\_aux},\39\\{vmode}){}$;\6
+${}\\{primitive}(\X1579:\.{"deadcycles"}\X,\39\\{set\_page\_int},\39\T{0});{}$\5
+${}\\{primitive}(\X1580:\.{"insertpenalties"}\X,\39\\{set\_page\_int},\39\T{1});{}$\5
+${}\\{primitive}(\X1581:\.{"wd"}\X,\39\\{set\_box\_dimen},\39\\{width\_offset});{}$\5
+${}\\{primitive}(\X1582:\.{"ht"}\X,\39\\{set\_box\_dimen},\39\\{height\_offset});{}$\5
+${}\\{primitive}(\X1583:\.{"dp"}\X,\39\\{set\_box\_dimen},\39\\{depth\_offset});{}$\5
+${}\\{primitive}(\X1584:\.{"lastpenalty"}\X,\39\\{last\_item},\39\\{int\_val});{}$\5
+${}\\{primitive}(\X1585:\.{"lastkern"}\X,\39\\{last\_item},\39\\{dimen\_val});{}$\5
+${}\\{primitive}(\X1586:\.{"lastskip"}\X,\39\\{last\_item},\39\\{glue\_val});{}$\5
+${}\\{primitive}(\X1587:\.{"inputlineno"}\X,\39\\{last\_item},\39\\{input\_line\_no\_code});{}$\5
+${}\\{primitive}(\X1588:\.{"badness"}\X,\39\\{last\_item},\39\\{badness\_code}){}$;\par
+\fi
+
+\M{417}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_aux}:\6
+\&{if} ${}(\\{chr\_code}\E\\{vmode}){}$\1\5
+\\{print\_esc}(\X1578:\.{"prevdepth"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1577:\.{"spacefactor"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{set\_page\_int}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1579:\.{"deadcycles"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1580:\.{"insertpenalties"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{set\_box\_dimen}:\6
+\&{if} ${}(\\{chr\_code}\E\\{width\_offset}){}$\1\5
+\\{print\_esc}(\X1581:\.{"wd"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{height\_offset}){}$\1\5
+\\{print\_esc}(\X1582:\.{"ht"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1583:\.{"dp"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{last\_item}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\5
+\\{print\_esc}(\X1584:\.{"lastpenalty"}\X);\5
+\&{break};\6
+\4\&{case} \\{dimen\_val}:\5
+\\{print\_esc}(\X1585:\.{"lastkern"}\X);\5
+\&{break};\6
+\4\&{case} \\{glue\_val}:\5
+\\{print\_esc}(\X1586:\.{"lastskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{input\_line\_no\_code}:\5
+\\{print\_esc}(\X1587:\.{"inputlineno"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1588:\.{"badness"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{418}\B\X418:Fetch the \\{space\_factor} or the \\{prev\_depth}\X${}\E{}$\6
+\&{if} ${}(\\{abs}(\\{mode})\I\|m){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ "});\5
+${}\\{print\_cmd\_chr}(\\{set\_aux},\39\|m);{}$\5
+\\{help4}(\.{"You\ can\ refer\ to\ \\\\}\)\.{spacefactor\ only\ in\ }\)\.{horizontal\ mode;"})\6
+(\.{"you\ can\ refer\ to\ \\\\}\)\.{prevdepth\ only\ in\ ve}\)\.{rtical\ mode;\ and"})\6
+(\.{"neither\ of\ these\ is}\)\.{\ meaningful\ inside\ \\}\)\.{\\write.\ So"})\6
+(\.{"I'm\ forgetting\ what}\)\.{\ you\ said\ and\ using\ }\)\.{zero\ instead."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{if} ${}(\\{level}\I\\{tok\_val}){}$\1\5
+\\{scanned\_result}(\T{0})(\\{dimen\_val})\2\6
+\&{else}\1\5
+\\{scanned\_result}(\T{0})(\\{int\_val});\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|m\E\\{vmode}){}$\1\5
+\\{scanned\_result}(\\{prev\_depth})(\\{dimen\_val})\2\6
+\&{else} \\{scanned\_result}(\\{space\_factor})(\\{int\_val})\par
+\U413.\fi
+
+\M{419}\B\X419:Fetch the \\{dead\_cycles} or the \\{insert\_penalties}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|m\E\T{0}){}$\1\5
+${}\\{cur\_val}\K\\{dead\_cycles}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_val}\K\\{insert\_penalties};{}$\2\6
+${}\\{cur\_val\_level}\K\\{int\_val};{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{420}\B\X420:Fetch a box dimension\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\6
+\&{if} ${}(\\{box}(\\{cur\_val})\E\\{null}){}$\1\5
+${}\\{cur\_val}\K\T{0}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_val}\K\\{mem}[\\{box}(\\{cur\_val})+\|m].\\{sc};{}$\2\6
+${}\\{cur\_val\_level}\K\\{dimen\_val};{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{421}Inside an \.{\\output} routine, a user may wish to look at the page totals
+that were present at the moment when output was triggered.
+
+\Y\B\4\D$\\{max\_dimen}$ \5
+\T{\~7777777777}\C{$2^{30}-1$}\par
+\Y\B\4\X421:Fetch something on the \\{page\_so\_far}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\\{page\_contents}\E\\{empty})\W(\R\\{output\_active})){}$\1\6
+\&{if} ${}(\|m\E\T{0}){}$\1\5
+${}\\{cur\_val}\K\\{max\_dimen}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_val}\K\T{0};{}$\2\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{page\_so\_far}[\|m];{}$\2\6
+${}\\{cur\_val\_level}\K\\{dimen\_val};{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{422}\B\X422:Fetch the \\{prev\_graf}\X${}\E{}$\6
+\&{if} ${}(\\{mode}\E\T{0}){}$\1\5
+\\{scanned\_result}(\T{0})(\\{int\_val})\C{$\\{prev\_graf}\E\T{0}$ within \.{\\write}}\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{nest}[\\{nest\_ptr}]\K\\{cur\_list};{}$\5
+${}\|p\K\\{nest\_ptr};{}$\6
+\&{while} ${}(\\{abs}(\\{nest}[\|p].\\{mode\_field})\I\\{vmode}){}$\1\5
+\\{decr}(\|p);\2\6
+${}\\{scanned\_result}(\\{nest}[\|p].\\{pg\_field})(\\{int\_val});{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{423}\B\X423:Fetch the \\{par\_shape} size\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\1\5
+${}\\{cur\_val}\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{info}(\\{par\_shape\_ptr});{}$\2\6
+${}\\{cur\_val\_level}\K\\{int\_val};{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{424}Here is where \.{\\lastpenalty}, \.{\\lastkern}, and \.{\\lastskip} are
+implemented. The reference count for \.{\\lastskip} will be updated later.
+
+We also handle \.{\\inputlineno} and \.{\\badness} here, because they are
+legal in similar contexts.
+
+\Y\B\4\X424:Fetch an item in the current node, if appropriate\X${}\E{}$\6
+\&{if} ${}(\\{cur\_chr}>\\{glue\_val}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_chr}\E\\{input\_line\_no\_code}){}$\1\5
+${}\\{cur\_val}\K\\{line};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{last\_badness}{}$;\C{$\\{cur\_chr}\E\\{badness\_code}$}\2\6
+${}\\{cur\_val\_level}\K\\{int\_val};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_chr}\E\\{glue\_val}){}$\1\5
+${}\\{cur\_val}\K\\{zero\_glue}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_val}\K\T{0};{}$\2\6
+${}\\{cur\_val\_level}\K\\{cur\_chr};{}$\6
+\&{if} ${}(\R\\{is\_char\_node}(\\{tail})\W(\\{mode}\I\T{0})){}$\1\6
+\&{switch} (\\{cur\_chr})\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{penalty\_node}){}$\1\5
+${}\\{cur\_val}\K\\{penalty}(\\{tail}){}$;\5
+\2\&{break};\6
+\4\&{case} \\{dimen\_val}:\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{kern\_node}){}$\1\5
+${}\\{cur\_val}\K\\{width}(\\{tail}){}$;\5
+\2\&{break};\6
+\4\&{case} \\{glue\_val}:\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{glue\_node}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_val}\K\\{glue\_ptr}(\\{tail});{}$\6
+\&{if} ${}(\\{subtype}(\\{tail})\E\\{mu\_glue}){}$\1\5
+${}\\{cur\_val\_level}\K\\{mu\_val};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\2\6
+\&{else} \&{if} ${}((\\{mode}\E\\{vmode})\W(\\{tail}\E\\{head})){}$\1\6
+\&{switch} (\\{cur\_chr})\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\5
+${}\\{cur\_val}\K\\{last\_penalty}{}$;\5
+\&{break};\6
+\4\&{case} \\{dimen\_val}:\5
+${}\\{cur\_val}\K\\{last\_kern}{}$;\5
+\&{break};\6
+\4\&{case} \\{glue\_val}:\6
+\&{if} ${}(\\{last\_glue}\I\\{max\_halfword}){}$\1\5
+${}\\{cur\_val}\K\\{last\_glue};{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\2\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{425}\B\X425:Fetch a font dimension\X${}\E{}$\6
+${}\{{}$\5
+\1\\{find\_font\_dimen}(\\{false});\5
+${}\\{font\_info}[\\{fmem\_ptr}].\\{sc}\K\T{0};{}$\5
+${}\\{scanned\_result}(\\{font\_info}[\\{cur\_val}].\\{sc})(\\{dimen\_val});{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{426}\B\X426:Fetch a font integer\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_font\_ident}(\,);\6
+\&{if} ${}(\|m\E\T{0}){}$\1\5
+\\{scanned\_result}(\\{hyphen\_char}[\\{cur\_val}])(\\{int\_val})\2\6
+\&{else}\1\5
+\\{scanned\_result}(\\{skew\_char}[\\{cur\_val}])(\\{int\_val});\2\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{427}\B\X427:Fetch a register\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\6
+\&{switch} (\|m)\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\5
+${}\\{cur\_val}\K\\{count}(\\{cur\_val}){}$;\5
+\&{break};\6
+\4\&{case} \\{dimen\_val}:\5
+${}\\{cur\_val}\K\\{dimen}(\\{cur\_val}){}$;\5
+\&{break};\6
+\4\&{case} \\{glue\_val}:\5
+${}\\{cur\_val}\K\\{skip}(\\{cur\_val}){}$;\5
+\&{break};\6
+\4\&{case} \\{mu\_val}:\5
+${}\\{cur\_val}\K\\{mu\_skip}(\\{cur\_val});{}$\6
+\4${}\}{}$\C{there are no other cases}\2\6
+${}\\{cur\_val\_level}\K\|m;{}$\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{428}\B\X428:Complain that \.{\\the} can't do this; give zero result\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ `"});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_str}(\.{"'\ after\ "});\5
+\\{print\_esc}(\X1559:\.{"the"}\X);\5
+\\{help1}(\.{"I'm\ forgetting\ what}\)\.{\ you\ said\ and\ using\ }\)\.{zero\ instead."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{if} ${}(\\{level}\I\\{tok\_val}){}$\1\5
+\\{scanned\_result}(\T{0})(\\{dimen\_val})\2\6
+\&{else}\1\5
+\\{scanned\_result}(\T{0})(\\{int\_val});\2\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{429}When a \\{glue\_val} changes to a \\{dimen\_val}, we use the width component
+of the glue; there is no need to decrease the reference count, since it
+has not yet been increased. When a \\{dimen\_val} changes to an \\{int\_val},
+we use scaled points so that the value doesn't actually change. And when a
+\\{mu\_val} changes to a \\{glue\_val}, the value doesn't change either.
+
+\Y\B\4\X429:Convert \(c)\\{cur\_val} to a lower level\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_val\_level}\E\\{glue\_val}){}$\1\5
+${}\\{cur\_val}\K\\{width}(\\{cur\_val});{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_val\_level}\E\\{mu\_val}){}$\1\5
+\\{mu\_error}(\,);\2\6
+\\{decr}(\\{cur\_val\_level});\6
+\4${}\}{}$\2\par
+\U413.\fi
+
+\M{430}If \\{cur\_val} points to a glue specification at this point, the reference
+count for the glue does not yet include the reference by \\{cur\_val}.
+If \\{negative} is \\{true}, \\{cur\_val\_level} is known to be $\Z$ \\{mu\_val}.
+
+\Y\B\4\X430:Fix the reference count, if any, and negate \\{cur\_val} if \\{negative}\X${}\E{}$\6
+\&{if} (\\{negative})\1\6
+\&{if} ${}(\\{cur\_val\_level}\G\\{glue\_val}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_val}\K\\{new\_spec}(\\{cur\_val});{}$\5
+\X431:Negate all three glue components of \\{cur\_val}\X;\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{negate}(\\{cur\_val});\2\2\6
+\&{else} \&{if} ${}((\\{cur\_val\_level}\G\\{glue\_val})\W(\\{cur\_val\_level}\Z\\{mu\_val}))$ \\{add\_glue\_ref}(\\{cur\_val})\par
+\U413.\fi
+
+\M{431}\B\X431:Negate all three glue components of \\{cur\_val}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{negate}(\\{width}(\\{cur\_val}));\5
+\\{negate}(\\{stretch}(\\{cur\_val}));\5
+\\{negate}(\\{shrink}(\\{cur\_val}));\6
+\4${}\}{}$\2\par
+\U430.\fi
+
+\M{432}Our next goal is to write the \\{scan\_int} procedure, which scans anything that
+\TeX\ treats as an integer. But first we might as well look at some simple
+applications of \\{scan\_int} that have already been made inside of
+\\{scan\_something\_internal}.
+
+\fi
+
+\M{433}\B\X433:Declare procedures that scan restricted classes of integers\X${}\E{}$\6
+\&{void} \\{scan\_eight\_bit\_int}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}<\T{0})\V(\\{cur\_val}>\T{255})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ register\ code"});\5
+\\{help2}(\.{"A\ register\ number\ m}\)\.{ust\ be\ between\ 0\ and}\)\.{\ 255."})\6
+(\.{"I\ changed\ this\ one\ }\)\.{to\ zero."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\As434, 435, 436\ETs437.
+\U409.\fi
+
+\M{434}\B\X433:Declare procedures that scan restricted classes of integers\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_char\_num}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}<\T{0})\V(\\{cur\_val}>\T{255})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ character\ code"});\5
+\\{help2}(\.{"A\ character\ number\ }\)\.{must\ be\ between\ 0\ an}\)\.{d\ 255."})\6
+(\.{"I\ changed\ this\ one\ }\)\.{to\ zero."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{435}While we're at it, we might as well deal with similar routines that
+will be needed later.
+
+\Y\B\4\X433:Declare procedures that scan restricted classes of integers\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_four\_bit\_int}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}<\T{0})\V(\\{cur\_val}>\T{15})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ number"});\5
+\\{help2}(\.{"Since\ I\ expected\ to}\)\.{\ read\ a\ number\ betwe}\)\.{en\ 0\ and\ 15,"})\6
+(\.{"I\ changed\ this\ one\ }\)\.{to\ zero."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{436}\B\X433:Declare procedures that scan restricted classes of integers\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_fifteen\_bit\_int}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}<\T{0})\V(\\{cur\_val}>\T{\~77777})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ mathchar"});\5
+\\{help2}(\.{"A\ mathchar\ number\ m}\)\.{ust\ be\ between\ 0\ and}\)\.{\ 32767."})\6
+(\.{"I\ changed\ this\ one\ }\)\.{to\ zero."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{437}\B\X433:Declare procedures that scan restricted classes of integers\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_twenty\_seven\_bit\_int}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}<\T{0})\V(\\{cur\_val}>\T{\~777777777})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ delimiter\ code"});\5
+\\{help2}(\.{"A\ numeric\ delimiter}\)\.{\ code\ must\ be\ betwee}\)\.{n\ 0\ and\ 2\^\{27\}-1."})\6
+(\.{"I\ changed\ this\ one\ }\)\.{to\ zero."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{438}An integer number can be preceded by any number of spaces and `\.+' or
+`\.-' signs. Then comes either a decimal constant (i.e., radix 10), an
+octal constant (i.e., radix 8, preceded by~\.\'), a hexadecimal constant
+(radix 16, preceded by~\."), an alphabetic constant (preceded by~\.\`), or
+an internal variable. After scanning is complete,
+\\{cur\_val} will contain the answer, which must be at most
+$2^{31}-1=2147483647$ in absolute value. The value of \\{radix} is set to
+10, 8, or 16 in the cases of decimal, octal, or hexadecimal constants,
+otherwise \\{radix} is set to zero. An optional space follows a constant.
+
+\Y\B\4\D$\\{octal\_token}$ \5
+$(\\{other\_token}+\.{'\\''}{}$)\C{apostrophe, indicates an octal constant}\par
+\B\4\D$\\{hex\_token}$ \5
+$(\\{other\_token}+\.{'"'}{}$)\C{double quote, indicates a hex constant}\par
+\B\4\D$\\{alpha\_token}$ \5
+$(\\{other\_token}+\.{'`'}{}$)\C{reverse apostrophe, precedes alpha constants}\par
+\B\4\D$\\{point\_token}$ \5
+$(\\{other\_token}+\.{'.'}{}$)\C{decimal point}\par
+\B\4\D$\\{continental\_point\_token}$ \5
+$(\\{other\_token}+\.{','}{}$)\C{decimal point, Eurostyle}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{small\_number} \\{radix};\C{\\{scan\_int} sets this to 8, 10, 16, or zero}\par
+\fi
+
+\M{439}We initialize the following global variables just in case \\{expand}
+comes into action before any of the basic scanning routines has assigned
+them a value.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{cur\_val}\K\T{0};{}$\5
+${}\\{cur\_val\_level}\K\\{int\_val};{}$\5
+${}\\{radix}\K\T{0};{}$\5
+${}\\{cur\_order}\K\\{normal}{}$;\par
+\fi
+
+\M{440}The \\{scan\_int} routine is used also to scan the integer part of a
+fraction; for example, the `\.3' in `\.{3.14159}' will be found by
+\\{scan\_int}. The \\{scan\_dimen} routine assumes that $\\{cur\_tok}\E\\{point\_token}$
+after the integer part of such a fraction has been scanned by \\{scan\_int},
+and that the decimal point has been backed up to be scanned again.
+
+\Y\B\&{void} \\{scan\_int}(\&{void})\C{sets \\{cur\_val} to an integer}\6
+${}\{{}$\5
+\1\&{bool} \\{negative};\C{should the answer be negated?}\6
+\&{int} \|m;\C{$\hbox{$2^{31}$}/$ \\{radix}, the threshold of danger}\6
+\&{small\_number} \|d;\C{the digit just scanned}\6
+\&{bool} \\{vacuous};\C{have no digits appeared?}\6
+\&{bool} \\{OK\_so\_far};\C{has an error message been issued?}\7
+${}\\{radix}\K\T{0};{}$\5
+${}\\{OK\_so\_far}\K\\{true}{}$;\6
+\X441:Get the next non-blank non-sign token; set \\{negative} appropriately\X;\6
+\&{if} ${}(\\{cur\_tok}\E\\{alpha\_token}){}$\1\5
+\X442:Scan an alphabetic character code into \\{cur\_val}\X\2\6
+\&{else} \&{if} ${}((\\{cur\_cmd}\G\\{min\_internal})\W(\\{cur\_cmd}\Z\\{max\_internal})){}$\1\5
+${}\\{scan\_something\_internal}(\\{int\_val},\39\\{false});{}$\2\6
+\&{else}\1\5
+\X444:Scan a numeric constant\X;\2\6
+\&{if} (\\{negative})\1\5
+\\{negate}(\\{cur\_val});\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{441}\B\X441:Get the next non-blank non-sign token; set \\{negative} appropriately\X${}\E{}$\6
+$\\{negative}\K\\{false}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}(\\{cur\_tok}\E\\{other\_token}+\.{'-'}){}$\5
+${}\{{}$\5
+\1${}\\{negative}\K\R\\{negative};{}$\5
+${}\\{cur\_tok}\K\\{other\_token}+\.{'+'};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\\{cur\_tok}\I\\{other\_token}+\.{'+'}){}$)\par
+\Us440, 448\ETs461.\fi
+
+\M{442}A space is ignored after an alphabetic character constant, so that
+such constants behave like numeric ones.
+
+\Y\B\4\X442:Scan an alphabetic character code into \\{cur\_val}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_token}(\,);\C{suppress macro expansion}\6
+\&{if} ${}(\\{cur\_tok}<\\{cs\_token\_flag}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_val}\K\\{cur\_chr};{}$\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{right\_brace}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}\E\\{right\_brace}){}$\1\5
+\\{incr}(\\{align\_state});\2\6
+\&{else}\1\5
+\\{decr}(\\{align\_state});\2\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_tok}<\\{cs\_token\_flag}+\\{single\_base}){}$\1\5
+${}\\{cur\_val}\K\\{cur\_tok}-\\{cs\_token\_flag}-\\{active\_base};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{cur\_tok}-\\{cs\_token\_flag}-\\{single\_base};{}$\2\6
+\&{if} ${}(\\{cur\_val}>\T{255}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ alphabetic}\)\.{\ constant"});\5
+\\{help2}(\.{"A\ one-character\ con}\)\.{trol\ sequence\ belong}\)\.{s\ after\ a\ `\ mark."})\6
+(\.{"So\ I'm\ essentially\ }\)\.{inserting\ \\\\0\ here."});\5
+${}\\{cur\_val}\K\.{'0'};{}$\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\X443:Scan an optional space\X;\2\6
+\4${}\}{}$\2\par
+\U440.\fi
+
+\M{443}\B\X443:Scan an optional space\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\I\\{spacer}){}$\1\5
+\\{back\_input}(\,);\2\6
+\4${}\}{}$\2\par
+\Us442, 448, 455\ETs1200.\fi
+
+\M{444}\B\X444:Scan a numeric constant\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{radix}\K\T{10};{}$\5
+${}\|m\K\T{214748364};{}$\6
+\&{if} ${}(\\{cur\_tok}\E\\{octal\_token}){}$\5
+${}\{{}$\5
+\1${}\\{radix}\K\T{8};{}$\5
+${}\|m\K\T{\~2000000000};{}$\5
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_tok}\E\\{hex\_token}){}$\5
+${}\{{}$\5
+\1${}\\{radix}\K\T{16};{}$\5
+${}\|m\K\T{\~1000000000};{}$\5
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\2\6
+${}\\{vacuous}\K\\{true};{}$\5
+${}\\{cur\_val}\K\T{0}{}$;\6
+\X445:Accumulate the constant until \\{cur\_tok} is not a suitable digit\X;\6
+\&{if} (\\{vacuous})\1\5
+\X446:Express astonishment that no number was here\X\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\I\\{spacer}){}$\1\5
+\\{back\_input}(\,);\2\6
+\4${}\}{}$\2\par
+\U440.\fi
+
+\M{445}\B\D$\\{infinity}$ \5
+\T{\~17777777777}\C{the largest positive value that \TeX\ knows}\par
+\B\4\D$\\{zero\_token}$ \5
+$(\\{other\_token}+\.{'0'}{}$)\C{zero, the smallest digit}\par
+\B\4\D$\\{A\_token}$ \5
+$(\\{letter\_token}+\.{'A'}{}$)\C{the smallest special hex digit}\par
+\B\4\D$\\{other\_A\_token}$ \5
+$(\\{other\_token}+\.{'A'}{}$)\C{special hex digit of type \\{other\_char}}\par
+\Y\B\4\X445:Accumulate the constant until \\{cur\_tok} is not a suitable digit\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{cur\_tok}<\\{zero\_token}+\\{radix})\W(\\{cur\_tok}\G\\{zero\_token})\W(\\{cur\_tok}\Z\\{zero\_token}+\T{9})){}$\1\5
+${}\|d\K\\{cur\_tok}-\\{zero\_token};{}$\2\6
+\&{else} \&{if} ${}(\\{radix}\E\T{16}){}$\1\6
+\&{if} ${}((\\{cur\_tok}\Z\\{A\_token}+\T{5})\W(\\{cur\_tok}\G\\{A\_token})){}$\1\5
+${}\|d\K\\{cur\_tok}-\\{A\_token}+\T{10};{}$\2\6
+\&{else} \&{if} ${}((\\{cur\_tok}\Z\\{other\_A\_token}+\T{5})\W(\\{cur\_tok}\G\\{other\_A\_token})){}$\1\5
+${}\|d\K\\{cur\_tok}-\\{other\_A\_token}+\T{10};{}$\2\6
+\&{else}\1\5
+\&{goto} \\{done};\2\2\6
+\&{else}\1\5
+\&{goto} \\{done};\2\6
+${}\\{vacuous}\K\\{false};{}$\6
+\&{if} ${}((\\{cur\_val}\G\|m)\W((\\{cur\_val}>\|m)\V(\|d>\T{7})\V(\\{radix}\I\T{10}))){}$\5
+${}\{{}$\5
+\1\&{if} (\\{OK\_so\_far})\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Number\ too\ big"});\5
+\\{help2}(\.{"I\ can\ only\ go\ up\ to}\)\.{\ 2147483647='1777777}\)\.{7777=\\"7FFFFFFF,"})\6
+(\.{"so\ I'm\ using\ that\ n}\)\.{umber\ instead\ of\ you}\)\.{rs."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{cur\_val}\K\\{infinity};{}$\5
+${}\\{OK\_so\_far}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{cur\_val}*\\{radix}+\|d;{}$\2\6
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U444.\fi
+
+\M{446}\B\X446:Express astonishment that no number was here\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ number,\ tre}\)\.{ated\ as\ zero"});\5
+\\{help3}(\.{"A\ number\ should\ hav}\)\.{e\ been\ here;\ I\ inser}\)\.{ted\ `0'."})\6
+(\.{"(If\ you\ can't\ figur}\)\.{e\ out\ why\ I\ needed\ t}\)\.{o\ see\ a\ number,"})\6
+(\.{"look\ up\ `weird\ erro}\)\.{r'\ in\ the\ index\ to\ T}\)\.{he\ TeXbook.)"});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\par
+\U444.\fi
+
+\M{447}The \\{scan\_dimen} routine is similar to \\{scan\_int}, but it sets \\{cur\_val} to
+a \&{scaled} value, i.e., an integral number of sp. One of its main tasks
+is therefore to interpret the abbreviations for various kinds of units and
+to convert measurements to scaled points.
+
+There are three parameters: \\{mu} is \\{true} if the finite units must be
+`\.{mu}', while \\{mu} is \\{false} if `\.{mu}' units are disallowed;
+\\{inf} is \\{true} if the infinite units `\.{fil}', `\.{fill}', `\.{filll}'
+are permitted; and \\{shortcut} is \\{true} if \\{cur\_val} already contains
+an integer and only the units need to be considered.
+
+The order of infinity that was found in the case of infinite glue is returned
+in the global variable \\{cur\_order}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{glue\_ord} \\{cur\_order};\C{order of infinity found by \\{scan\_dimen}}\par
+\fi
+
+\M{448}Constructions like `\.{-\'77 pt}' are legal dimensions, so \\{scan\_dimen}
+may begin with \\{scan\_int}. This explains why it is convenient to use
+\\{scan\_int} also for the integer part of a decimal fraction.
+
+Several branches of \\{scan\_dimen} work with \\{cur\_val} as an integer and
+with an auxiliary fraction \|f, so that the actual quantity of interest is
+$\\{cur\_val}+\|f/2^{16}$. At the end of the routine, this ``unpacked''
+representation is put into the single word \\{cur\_val}, which suddenly
+switches significance from \&{int} to \&{scaled}.
+
+\Y\B\4\D$\\{scan\_normal\_dimen}$ \5
+$\\{scan\_dimen}(\\{false},\39\\{false},\39\\{false}{}$)\par
+\Y\B\&{void} \\{scan\_dimen}(\&{bool} \\{mu}${},\39{}$\&{bool} \\{inf}${},\39{}$\&{bool} \\{shortcut})\C{sets \\{cur\_val} to a dimension}\6
+${}\{{}$\5
+\1\&{bool} \\{negative};\C{should the answer be negated?}\6
+\&{int} \|f;\C{numerator of a fraction whose denominator is $2^{16}$}\7
+\X450:Local variables for dimension calculations\X\6
+${}\|f\K\T{0};{}$\5
+${}\\{arith\_error}\K\\{false};{}$\5
+${}\\{cur\_order}\K\\{normal};{}$\5
+${}\\{negative}\K\\{false};{}$\6
+\&{if} ${}(\R\\{shortcut}){}$\5
+${}\{{}$\5
+\1\X441:Get the next non-blank non-sign token; set \\{negative} appropriately\X;\6
+\&{if} ${}((\\{cur\_cmd}\G\\{min\_internal})\W(\\{cur\_cmd}\Z\\{max\_internal})){}$\1\5
+\X449:Fetch an internal dimension and \&{goto} \\{attach\_sign}, or fetch an internal integer\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\6
+\&{if} ${}(\\{cur\_tok}\E\\{continental\_point\_token}){}$\1\5
+${}\\{cur\_tok}\K\\{point\_token};{}$\2\6
+\&{if} ${}(\\{cur\_tok}\I\\{point\_token}){}$\1\5
+\\{scan\_int}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{radix}\K\T{10};{}$\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_tok}\E\\{continental\_point\_token}){}$\1\5
+${}\\{cur\_tok}\K\\{point\_token};{}$\2\6
+\&{if} ${}((\\{radix}\E\T{10})\W(\\{cur\_tok}\E\\{point\_token})){}$\1\5
+\X452:Scan decimal fraction\X;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_val}<\T{0}{}$)\C{in this case $\|f\E\T{0}$}\6
+${}\{{}$\5
+\1${}\\{negative}\K\R\\{negative};{}$\5
+\\{negate}(\\{cur\_val});\6
+\4${}\}{}$\2\6
+\X453:Scan units and set \\{cur\_val} to $x\cdot(\\{cur\_val}+f/2^{16})$, where there are \|x sp per unit; \&{goto} \\{attach\_sign} if the units are internal\X;\6
+\X443:Scan an optional space\X;\6
+\4\\{attach\_sign}:\6
+\&{if} ${}(\\{arith\_error}\V(\\{abs}(\\{cur\_val})\G\T{\~10000000000})){}$\1\5
+\X460:Report that this dimension is out of range\X;\2\6
+\&{if} (\\{negative})\1\5
+\\{negate}(\\{cur\_val});\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{449}\B\X449:Fetch an internal dimension and \&{goto} \\{attach\_sign}, or fetch an internal integer\X${}\E{}$\6
+\&{if} (\\{mu})\5
+${}\{{}$\5
+\1${}\\{scan\_something\_internal}(\\{mu\_val},\39\\{false});{}$\5
+\X451:Coerce glue to a dimension\X;\6
+\&{if} ${}(\\{cur\_val\_level}\E\\{mu\_val}){}$\1\5
+\&{goto} \\{attach\_sign};\2\6
+\&{if} ${}(\\{cur\_val\_level}\I\\{int\_val}){}$\1\5
+\\{mu\_error}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{scan\_something\_internal}(\\{dimen\_val},\39\\{false});{}$\6
+\&{if} ${}(\\{cur\_val\_level}\E\\{dimen\_val}){}$\1\5
+\&{goto} \\{attach\_sign};\2\6
+\4${}\}{}$\2\par
+\U448.\fi
+
+\M{450}\B\X450:Local variables for dimension calculations\X${}\E{}$\6
+\&{uint32\_t} \\{num}${},{}$ \\{denom};\C{conversion ratio for the scanned units}\6
+\&{int} \|k${},{}$ \\{kk};\C{number of digits in a decimal fraction}\6
+\&{pointer} \|p${},{}$ \|q;\C{top of decimal digit stack}\6
+\&{scaled} \|v;\C{an internal dimension}\6
+\&{int} \\{save\_cur\_val};\C{temporary storage of \\{cur\_val}}\par
+\U448.\fi
+
+\M{451}The following code is executed when \\{scan\_something\_internal} was
+called asking for \\{mu\_val}, when we really wanted a ``mudimen'' instead
+of ``muglue.''
+
+\Y\B\4\X451:Coerce glue to a dimension\X${}\E{}$\6
+\&{if} ${}(\\{cur\_val\_level}\G\\{glue\_val}){}$\5
+${}\{{}$\5
+\1${}\|v\K\\{width}(\\{cur\_val});{}$\5
+\\{delete\_glue\_ref}(\\{cur\_val});\5
+${}\\{cur\_val}\K\|v;{}$\6
+\4${}\}{}$\2\par
+\Us449\ET455.\fi
+
+\M{452}When the following code is executed, we have $\\{cur\_tok}\E\\{point\_token}$, but this
+token has been backed up using \\{back\_input}; we must first discard it.
+
+It turns out that a decimal point all by itself is equivalent to `\.{0.0}'.
+Let's hope people don't use that fact.
+
+\Y\B\4\X452:Scan decimal fraction\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|k\K\T{0};{}$\5
+${}\|p\K\\{null};{}$\5
+\\{get\_token}(\,);\C{\\{point\_token} is being re-scanned}\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}((\\{cur\_tok}>\\{zero\_token}+\T{9})\V(\\{cur\_tok}<\\{zero\_token})){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}(\|k<\T{17}{}$)\C{digits for $\|k\G\T{17}$ cannot affect the result}\6
+${}\{{}$\5
+\1${}\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\\{info}(\|q)\K\\{cur\_tok}-\\{zero\_token};{}$\5
+${}\|p\K\|q;{}$\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4\\{done1}:\6
+\&{for} ${}(\\{kk}\K\|k;{}$ ${}\\{kk}\G\T{1};{}$ ${}\\{kk}\MM){}$\5
+${}\{{}$\5
+\1${}\\{dig}[\\{kk}-\T{1}]\K\\{info}(\|p);{}$\5
+${}\|q\K\|p;{}$\5
+${}\|p\K\\{link}(\|p);{}$\5
+\\{free\_avail}(\|q);\6
+\4${}\}{}$\2\6
+${}\|f\K\\{round\_decimals}(\|k);{}$\6
+\&{if} ${}(\\{cur\_cmd}\I\\{spacer}){}$\1\5
+\\{back\_input}(\,);\2\6
+\4${}\}{}$\2\par
+\U448.\fi
+
+\M{453}Now comes the harder part: At this point in the program, \\{cur\_val} is a
+nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1;
+we want to multiply the sum of these two quantities by the appropriate
+factor, based on the specified units, in order to produce a \&{scaled}
+result, and we want to do the calculation with fixed point arithmetic that
+does not overflow.
+
+\Y\B\4\X453:Scan units and set \\{cur\_val} to $x\cdot(\\{cur\_val}+f/2^{16})$, where there are \|x sp per unit; \&{goto} \\{attach\_sign} if the units are internal\X${}\E{}$\6
+\&{if} (\\{inf})\1\5
+\X454:Scan for \(f)\.{fil} units; \&{goto} \\{attach\_fraction} if found\X;\2\6
+\X455:Scan for \(u)units that are internal dimensions; \&{goto} \\{attach\_sign} with \\{cur\_val} set if found\X;\6
+\&{if} (\\{mu})\1\5
+\X456:Scan for \(m)\.{mu} units and \&{goto} \\{attach\_fraction}\X;\2\6
+\&{if} (\\{scan\_keyword}(\X1589:\.{"true"}\X))\1\5
+\X457:Adjust \(f)for the magnification ratio\X;\2\6
+\&{if} (\\{scan\_keyword}(\X1425:\.{"pt"}\X))\1\5
+\&{goto} \\{attach\_fraction};\C{the easy case}\2\6
+\X458:Scan for \(a)all other units and adjust \\{cur\_val} and \|f accordingly; \&{goto} \\{done} in the case of scaled points\X;\6
+\4\\{attach\_fraction}:\6
+\&{if} ${}(\\{cur\_val}\G\T{\~40000}){}$\1\5
+${}\\{arith\_error}\K\\{true};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{cur\_val}*\\{unity}+\|f;{}$\2\6
+\\{done}:\par
+\U448.\fi
+
+\M{454}A specification like `\.{filllll}' or `\.{fill L L L}' will lead to two
+error messages (one for each additional keyword \.{"l"}).
+
+\Y\B\4\X454:Scan for \(f)\.{fil} units; \&{goto} \\{attach\_fraction} if found\X${}\E{}$\6
+\&{if} (\\{scan\_keyword}(\X1387:\.{"fil"}\X))\5
+${}\{{}$\5
+\1${}\\{cur\_order}\K\\{fil};{}$\6
+\&{while} (\\{scan\_keyword}(\.{'l'}))\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_order}\E\\{filll}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ unit\ of\ mea}\)\.{sure\ ("});\5
+\\{print\_str}(\.{"replaced\ by\ filll)"});\5
+\\{help1}(\.{"I\ dddon't\ go\ any\ hi}\)\.{gher\ than\ filll."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{incr}(\\{cur\_order});\2\6
+\4${}\}{}$\2\6
+\&{goto} \\{attach\_fraction};\6
+\4${}\}{}$\2\par
+\U453.\fi
+
+\M{455}\B\X455:Scan for \(u)units that are internal dimensions; \&{goto} \\{attach\_sign} with \\{cur\_val} set if found\X${}\E{}$\6
+$\\{save\_cur\_val}\K\\{cur\_val};{}$\5
+\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}((\\{cur\_cmd}<\\{min\_internal})\V(\\{cur\_cmd}>\\{max\_internal})){}$\1\5
+\\{back\_input}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} (\\{mu})\5
+${}\{{}$\5
+\1${}\\{scan\_something\_internal}(\\{mu\_val},\39\\{false});{}$\5
+\X451:Coerce glue to a dimension\X;\6
+\&{if} ${}(\\{cur\_val\_level}\I\\{mu\_val}){}$\1\5
+\\{mu\_error}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{scan\_something\_internal}(\\{dimen\_val},\39\\{false});{}$\2\6
+${}\|v\K\\{cur\_val};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\&{if} (\\{mu})\1\5
+\&{goto} \\{not\_found};\2\6
+\&{if} (\\{scan\_keyword}(\X1590:\.{"em"}\X))\1\5
+${}\|v\K(\X558:The em width for \\{cur\_font}\X);{}$\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1591:\.{"ex"}\X))\1\5
+${}\|v\K(\X559:The x-height for \\{cur\_font}\X);{}$\2\6
+\&{else}\1\5
+\&{goto} \\{not\_found};\2\6
+\X443:Scan an optional space\X;\6
+\4\\{found}:\5
+${}\\{cur\_val}\K\\{nx\_plus\_y}(\\{save\_cur\_val},\39\|v,\39\\{xn\_over\_d}(\|v,\39\|f,\39\T{\~200000}));{}$\5
+\&{goto} \\{attach\_sign}; \\{not\_found}:\par
+\U453.\fi
+
+\M{456}\B\X456:Scan for \(m)\.{mu} units and \&{goto} \\{attach\_fraction}\X${}\E{}$\6
+\&{if} (\\{scan\_keyword}(\X1394:\.{"mu"}\X))\1\5
+\&{goto} \\{attach\_fraction};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ unit\ of\ mea}\)\.{sure\ ("});\5
+\\{print\_str}(\.{"mu\ inserted)"});\5
+\\{help4}(\.{"The\ unit\ of\ measure}\)\.{ment\ in\ math\ glue\ mu}\)\.{st\ be\ mu."})\6
+(\.{"To\ recover\ graceful}\)\.{ly\ from\ this\ error,\ }\)\.{it's\ best\ to"})\6
+(\.{"delete\ the\ erroneou}\)\.{s\ units;\ e.g.,\ type\ }\)\.{`2'\ to\ delete"})\6
+(\.{"two\ letters.\ (See\ C}\)\.{hapter\ 27\ of\ The\ TeX}\)\.{book.)"});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{attach\_fraction};\6
+\4${}\}{}$\2\par
+\U453.\fi
+
+\M{457}\B\X457:Adjust \(f)for the magnification ratio\X${}\E{}$\6
+${}\{{}$\5
+\1\\{prepare\_mag}(\,);\6
+\&{if} ${}(\\{mag}\I\T{1000}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_val}\K\\{xn\_over\_d}(\\{cur\_val},\39\T{1000},\39\\{mag});{}$\5
+${}\|f\K(\T{1000}*\|f+\T{\~200000}*\\{rem})/\\{mag};{}$\5
+${}\\{cur\_val}\K\\{cur\_val}+(\|f/\T{\~200000});{}$\5
+${}\|f\K\|f\MOD\T{\~200000};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U453.\fi
+
+\M{458}The necessary conversion factors can all be specified exactly as
+fractions whose numerator and denominator sum to 32768 or less.
+According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
+this agrees well with the value $\rm1000.333\,mm$ cited by Bosshard
+in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980).
+
+\Y\B\4\D$\\{set\_conversion\_end}(\|X)$ \5
+$\\{denom}\K\|X;$ $\}{}$\par
+\B\4\D$\\{set\_conversion}(\|X)$ \5
+$\{{}$\5
+$\\{num}\K\|X;$ \\{set\_conversion\_end}\par
+\Y\B\4\X458:Scan for \(a)all other units and adjust \\{cur\_val} and \|f accordingly; \&{goto} \\{done} in the case of scaled points\X${}\E{}$\6
+\&{if} (\\{scan\_keyword}(\X1592:\.{"in"}\X))\1\5
+\\{set\_conversion}(\T{7227})(\T{100})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1593:\.{"pc"}\X))\1\5
+\\{set\_conversion}(\T{12})(\T{1})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1594:\.{"cm"}\X))\1\5
+\\{set\_conversion}(\T{7227})(\T{254})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1595:\.{"mm"}\X))\1\5
+\\{set\_conversion}(\T{7227})(\T{2540})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1596:\.{"bp"}\X))\1\5
+\\{set\_conversion}(\T{7227})(\T{7200})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1597:\.{"dd"}\X))\1\5
+\\{set\_conversion}(\T{1238})(\T{1157})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1598:\.{"cc"}\X))\1\5
+\\{set\_conversion}(\T{14856})(\T{1157})\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1599:\.{"sp"}\X))\1\5
+\&{goto} \\{done};\2\6
+\&{else}\1\5
+\X459:Complain about unknown unit and \&{goto} \\{done2}\X;\2\6
+${}\\{cur\_val}\K\\{xn\_over\_d}(\\{cur\_val},\39\\{num},\39\\{denom});{}$\5
+${}\|f\K(\\{num}*\|f+\T{\~200000}*\\{rem})/\\{denom}{}$;\6
+${}\\{cur\_val}\K\\{cur\_val}+(\|f/\T{\~200000});{}$\5
+${}\|f\K\|f\MOD\T{\~200000};$ \\{done2}:\par
+\U453.\fi
+
+\M{459}\B\X459:Complain about unknown unit and \&{goto} \\{done2}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ unit\ of\ mea}\)\.{sure\ ("});\5
+\\{print\_str}(\.{"pt\ inserted)"});\5
+\\{help6}(\.{"Dimensions\ can\ be\ i}\)\.{n\ units\ of\ em,\ ex,\ i}\)\.{n,\ pt,\ pc,"})\6
+(\.{"cm,\ mm,\ dd,\ cc,\ bp,}\)\.{\ or\ sp;\ but\ yours\ is}\)\.{\ a\ new\ one!"})\6
+(\.{"I'll\ assume\ that\ yo}\)\.{u\ meant\ to\ say\ pt,\ f}\)\.{or\ printer's\ points.}\)\.{"})\6
+(\.{"To\ recover\ graceful}\)\.{ly\ from\ this\ error,\ }\)\.{it's\ best\ to"})\6
+(\.{"delete\ the\ erroneou}\)\.{s\ units;\ e.g.,\ type\ }\)\.{`2'\ to\ delete"})\6
+(\.{"two\ letters.\ (See\ C}\)\.{hapter\ 27\ of\ The\ TeX}\)\.{book.)"});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{done2};\6
+\4${}\}{}$\2\par
+\U458.\fi
+
+\M{460}\B\X460:Report that this dimension is out of range\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Dimension\ too\ large}\)\.{"});\5
+\\{help2}(\.{"I\ can't\ work\ with\ s}\)\.{izes\ bigger\ than\ abo}\)\.{ut\ 19\ feet."})\6
+(\.{"Continue\ and\ I'll\ u}\)\.{se\ the\ largest\ value}\)\.{\ I\ can."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{cur\_val}\K\\{max\_dimen};{}$\5
+${}\\{arith\_error}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\U448.\fi
+
+\M{461}The final member of \TeX's value-scanning trio is \\{scan\_glue}, which
+makes \\{cur\_val} point to a glue specification. The reference count of that
+glue spec will take account of the fact that \\{cur\_val} is pointing to~it.
+
+The \\{level} parameter should be either \\{glue\_val} or \\{mu\_val}.
+
+Since \\{scan\_dimen} was so much more complex than \\{scan\_int}, we might expect
+\\{scan\_glue} to be even worse. But fortunately, it is very simple, since
+most of the work has already been done.
+
+\Y\B\&{void} \\{scan\_glue}(\&{small\_number} \\{level})\C{sets \\{cur\_val} to a glue spec pointer}\6
+${}\{{}$\5
+\1\&{bool} \\{negative};\C{should the answer be negated?}\6
+\&{pointer} \|q;\C{new glue specification}\6
+\&{bool} \\{mu};\C{does $\\{level}\E\\{mu\_val}$?}\7
+${}\\{mu}\K(\\{level}\E\\{mu\_val});{}$\5
+\X441:Get the next non-blank non-sign token; set \\{negative} appropriately\X;\6
+\&{if} ${}((\\{cur\_cmd}\G\\{min\_internal})\W(\\{cur\_cmd}\Z\\{max\_internal})){}$\5
+${}\{{}$\5
+\1${}\\{scan\_something\_internal}(\\{level},\39\\{negative});{}$\6
+\&{if} ${}(\\{cur\_val\_level}\G\\{glue\_val}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_val\_level}\I\\{level}){}$\1\5
+\\{mu\_error}(\,);\2\6
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_val\_level}\E\\{int\_val}){}$\1\5
+${}\\{scan\_dimen}(\\{mu},\39\\{false},\39\\{true});{}$\2\6
+\&{else} \&{if} ${}(\\{level}\E\\{mu\_val}){}$\1\5
+\\{mu\_error}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\\{scan\_dimen}(\\{mu},\39\\{false},\39\\{false});{}$\6
+\&{if} (\\{negative})\1\5
+\\{negate}(\\{cur\_val});\2\6
+\4${}\}{}$\2\6
+\X462:Create a new glue specification whose width is \\{cur\_val}; scan for its stretch and shrink components\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{462}\B\X462:Create a new glue specification whose width is \\{cur\_val}; scan for its stretch and shrink components\X${}\E{}$\6
+$\|q\K\\{new\_spec}(\\{zero\_glue});{}$\5
+${}\\{width}(\|q)\K\\{cur\_val};{}$\6
+\&{if} (\\{scan\_keyword}(\X1600:\.{"plus"}\X))\5
+${}\{{}$\5
+\1${}\\{scan\_dimen}(\\{mu},\39\\{true},\39\\{false});{}$\5
+${}\\{stretch}(\|q)\K\\{cur\_val};{}$\5
+${}\\{stretch\_order}(\|q)\K\\{cur\_order};{}$\6
+\4${}\}{}$\2\6
+\&{if} (\\{scan\_keyword}(\X1601:\.{"minus"}\X))\5
+${}\{{}$\5
+\1${}\\{scan\_dimen}(\\{mu},\39\\{true},\39\\{false});{}$\5
+${}\\{shrink}(\|q)\K\\{cur\_val};{}$\5
+${}\\{shrink\_order}(\|q)\K\\{cur\_order};{}$\6
+\4${}\}{}$\2\6
+$\\{cur\_val}\K{}$\|q\par
+\U461.\fi
+
+\M{463}Here's a similar procedure that returns a pointer to a rule node. This
+routine is called just after \TeX\ has seen \.{\\hrule} or \.{\\vrule};
+therefore \\{cur\_cmd} will be either \\{hrule} or \\{vrule}. The idea is to store
+the default rule dimensions in the node, then to override them if
+`\.{height}' or `\.{width}' or `\.{depth}' specifications are
+found (in any order).
+
+\Y\B\4\D$\\{default\_rule}$ \5
+\T{26214}\C{0.4\thinspace pt}\par
+\Y\B\&{pointer} \\{scan\_rule\_spec}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{the rule node being created}\7
+${}\|q\K\\{new\_rule}(\,){}$;\C{\\{width}, \\{depth}, and \\{height} all equal \\{null\_flag} now}\6
+\&{if} ${}(\\{cur\_cmd}\E\\{vrule}){}$\1\5
+${}\\{width}(\|q)\K\\{default\_rule};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{height}(\|q)\K\\{default\_rule};{}$\5
+${}\\{depth}(\|q)\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4\\{reswitch}:\6
+\&{if} (\\{scan\_keyword}(\X1602:\.{"width"}\X))\5
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{width}(\|q)\K\\{cur\_val};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\&{if} (\\{scan\_keyword}(\X1603:\.{"height"}\X))\5
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{height}(\|q)\K\\{cur\_val};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\&{if} (\\{scan\_keyword}(\X1604:\.{"depth"}\X))\5
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{depth}(\|q)\K\\{cur\_val};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\&{return} \|q;\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{464}Building token lists.
+The token lists for macros and for other things like \.{\\mark} and \.{\\output}
+and \.{\\write} are produced by a procedure called \\{scan\_toks}.
+
+Before we get into the details of \\{scan\_toks}, let's consider a much
+simpler task, that of converting the current string into a token list.
+The \\{str\_toks} function does this; it classifies spaces as type \\{spacer}
+and everything else as type \\{other\_char}.
+
+The token list created by \\{str\_toks} begins at \\{link}(\\{temp\_head}) and ends
+at the value \|p that is returned. (If $\|p\E\\{temp\_head}$, the list is empty.)
+
+\Y\B\&{pointer} \\{str\_toks}(\&{pool\_pointer} \|b)\C{changes the string $\\{str\_pool}[\|b\dotdot\\{pool\_ptr}]$ to a token list}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{tail of the token list}\6
+\&{pointer} \|q;\C{new node being added to the token list via \\{store\_new\_token}}\6
+\&{halfword} \|t;\C{token being appended}\6
+\&{pool\_pointer} \|k;\C{index into \\{str\_pool}}\7
+\\{str\_room}(\T{1});\5
+${}\|p\K\\{temp\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+${}\|k\K\|b;{}$\6
+\&{while} ${}(\|k<\\{pool\_ptr}){}$\5
+${}\{{}$\5
+\1${}\|t\K\\{so}(\\{str\_pool}[\|k]);{}$\6
+\&{if} ${}(\|t\E\.{'\ '}){}$\1\5
+${}\|t\K\\{space\_token};{}$\2\6
+\&{else}\1\5
+${}\|t\K\\{other\_token}+\|t;{}$\2\6
+\\{fast\_store\_new\_token}(\|t);\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+${}\\{pool\_ptr}\K\|b;{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{465}The main reason for wanting \\{str\_toks} is the next function,
+\\{the\_toks}, which has similar input/output characteristics.
+
+This procedure is supposed to scan something like `\.{\\skip\\count12}',
+i.e., whatever can follow `\.{\\the}', and it constructs a token list
+containing something like `\.{-3.0pt minus 0.5fill}'.
+
+\Y\B\&{pointer} \\{the\_toks}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{holds \\{selector} setting}\6
+\&{pointer} \|p${},{}$ \|q${},{}$ \|r;\C{used for copying a token list}\6
+\&{pool\_pointer} \|b;\C{base of temporary string}\7
+\\{get\_x\_token}(\,);\5
+${}\\{scan\_something\_internal}(\\{tok\_val},\39\\{false});{}$\6
+\&{if} ${}(\\{cur\_val\_level}\G\\{ident\_val}){}$\1\5
+\X466:Copy the token list\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+${}\|b\K\\{pool\_ptr};{}$\6
+\&{switch} (\\{cur\_val\_level})\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\5
+\\{print\_int}(\\{cur\_val});\5
+\&{break};\6
+\4\&{case} \\{dimen\_val}:\6
+${}\{{}$\5
+\1\\{print\_scaled}(\\{cur\_val});\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{glue\_val}:\6
+${}\{{}$\5
+\1${}\\{print\_spec}(\\{cur\_val},\39\X1425:\.{"pt"}\X);{}$\5
+\\{delete\_glue\_ref}(\\{cur\_val});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mu\_val}:\6
+${}\{{}$\5
+\1${}\\{print\_spec}(\\{cur\_val},\39\X1394:\.{"mu"}\X);{}$\5
+\\{delete\_glue\_ref}(\\{cur\_val});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\6
+${}\\{selector}\K\\{old\_setting};{}$\5
+\&{return} \\{str\_toks}(\|b);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{466}\B\X466:Copy the token list\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{temp\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\&{if} ${}(\\{cur\_val\_level}\E\\{ident\_val}){}$\1\5
+${}\\{store\_new\_token}(\\{cs\_token\_flag}+\\{cur\_val}){}$\2\6
+\&{else} \&{if} ${}(\\{cur\_val}\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{cur\_val}){}$;\C{do not copy the reference count}\6
+\&{while} ${}(\|r\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{fast\_store\_new\_token}(\\{info}(\|r));\5
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\U465.\fi
+
+\M{467}Here's part of the \\{expand} subroutine that we are now ready to complete:
+
+\Y\B\&{void} \\{ins\_the\_toks}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{link}(\\{garbage})\K\\{the\_toks}(\,);{}$\5
+\\{ins\_list}(\\{link}(\\{temp\_head}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{468}The primitives \.{\\number}, \.{\\romannumeral}, \.{\\string}, \.{\\meaning},
+\.{\\fontname}, and \.{\\jobname} are defined as follows.
+
+\Y\B\4\D$\\{number\_code}$ \5
+\T{0}\C{command code for \.{\\number}}\par
+\B\4\D$\\{roman\_numeral\_code}$ \5
+\T{1}\C{command code for \.{\\romannumeral}}\par
+\B\4\D$\\{string\_code}$ \5
+\T{2}\C{command code for \.{\\string}}\par
+\B\4\D$\\{meaning\_code}$ \5
+\T{3}\C{command code for \.{\\meaning}}\par
+\B\4\D$\\{font\_name\_code}$ \5
+\T{4}\C{command code for \.{\\fontname}}\par
+\B\4\D$\\{job\_name\_code}$ \5
+\T{5}\C{command code for \.{\\jobname}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1605:\.{"number"}\X,\39\\{convert},\39\\{number\_code}){}$;\6
+${}\\{primitive}(\X1606:\.{"romannumeral"}\X,\39\\{convert},\39\\{roman\_numeral\_code}){}$;\6
+${}\\{primitive}(\X1607:\.{"string"}\X,\39\\{convert},\39\\{string\_code}){}$;\6
+${}\\{primitive}(\X1608:\.{"meaning"}\X,\39\\{convert},\39\\{meaning\_code}){}$;\6
+${}\\{primitive}(\X1609:\.{"fontname"}\X,\39\\{convert},\39\\{font\_name\_code}){}$;\6
+${}\\{primitive}(\X1610:\.{"jobname"}\X,\39\\{convert},\39\\{job\_name\_code}){}$;\par
+\fi
+
+\M{469}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{convert}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{number\_code}:\5
+\\{print\_esc}(\X1605:\.{"number"}\X);\5
+\&{break};\6
+\4\&{case} \\{roman\_numeral\_code}:\5
+\\{print\_esc}(\X1606:\.{"romannumeral"}\X);\5
+\&{break};\6
+\4\&{case} \\{string\_code}:\5
+\\{print\_esc}(\X1607:\.{"string"}\X);\5
+\&{break};\6
+\4\&{case} \\{meaning\_code}:\5
+\\{print\_esc}(\X1608:\.{"meaning"}\X);\5
+\&{break};\6
+\4\&{case} \\{font\_name\_code}:\5
+\\{print\_esc}(\X1609:\.{"fontname"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1610:\.{"jobname"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{470}The procedure \\{conv\_toks} uses \\{str\_toks} to insert the token list
+for \\{convert} functions into the scanner; `\.{\\outer}' control sequences
+are allowed to follow `\.{\\string}' and `\.{\\meaning}'.
+
+\Y\B\&{void} \\{conv\_toks}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{holds \\{selector} setting}\6
+\&{uint8\_t} \|c;\C{desired type of conversion}\6
+\&{small\_number} \\{save\_scanner\_status};\C{\\{scanner\_status} upon entry}\6
+\&{pool\_pointer} \|b;\C{base of temporary string}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\X471:Scan the argument for command \|c\X;\6
+${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+${}\|b\K\\{pool\_ptr};{}$\5
+\X472:Print the result of command \|c\X;\6
+${}\\{selector}\K\\{old\_setting};{}$\5
+${}\\{link}(\\{garbage})\K\\{str\_toks}(\|b);{}$\5
+\\{ins\_list}(\\{link}(\\{temp\_head}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{471}\B\X471:Scan the argument for command \|c\X${}\E{}$\6
+\&{switch} (\|c)\5
+${}\{{}$\1\6
+\4\&{case} \\{number\_code}:\5
+\&{case} \\{roman\_numeral\_code}:\5
+\\{scan\_int}(\,);\5
+\&{break};\6
+\4\&{case} \\{string\_code}:\5
+\&{case} \\{meaning\_code}:\6
+${}\{{}$\5
+\1${}\\{save\_scanner\_status}\K\\{scanner\_status};{}$\5
+${}\\{scanner\_status}\K\\{normal};{}$\5
+\\{get\_token}(\,);\5
+${}\\{scanner\_status}\K\\{save\_scanner\_status};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{font\_name\_code}:\5
+\\{scan\_font\_ident}(\,);\5
+\&{break};\6
+\4\&{case} \\{job\_name\_code}:\6
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+\\{open\_log\_file}(\,);\2\6
+\4${}\}{}$\C{there are no other cases}\2\par
+\U470.\fi
+
+\M{472}\B\X472:Print the result of command \|c\X${}\E{}$\6
+\&{switch} (\|c)\5
+${}\{{}$\1\6
+\4\&{case} \\{number\_code}:\5
+\\{print\_int}(\\{cur\_val});\5
+\&{break};\6
+\4\&{case} \\{roman\_numeral\_code}:\5
+\\{print\_roman\_int}(\\{cur\_val});\5
+\&{break};\6
+\4\&{case} \\{string\_code}:\6
+\&{if} ${}(\\{cur\_cs}\I\T{0}){}$\1\5
+\\{sprint\_cs}(\\{cur\_cs});\2\6
+\&{else}\1\5
+\\{print\_char}(\\{cur\_chr});\5
+\2\&{break};\6
+\4\&{case} \\{meaning\_code}:\5
+\\{print\_meaning}(\,);\5
+\&{break};\6
+\4\&{case} \\{font\_name\_code}:\6
+${}\{{}$\5
+\1\\{print}(\\{font\_name}[\\{cur\_val}]);\6
+\&{if} ${}(\\{font\_size}[\\{cur\_val}]\I\\{font\_dsize}[\\{cur\_val}]){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ at\ "});\5
+\\{print\_scaled}(\\{font\_size}[\\{cur\_val}]);\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{job\_name\_code}:\5
+\\{print}(\\{job\_name});\6
+\4${}\}{}$\C{there are no other cases}\2\par
+\U470.\fi
+
+\M{473}Now we can't postpone the difficulties any longer; we must bravely tackle
+\\{scan\_toks}. This function returns a pointer to the tail of a new token
+list, and it also makes \\{def\_ref} point to the reference count at the
+head of that list.
+
+There are two boolean parameters, \\{macro\_def} and \\{xpand}. If \\{macro\_def}
+is true, the goal is to create the token list for a macro definition;
+otherwise the goal is to create the token list for some other \TeX\
+primitive: \.{\\mark}, \.{\\output}, \.{\\everypar}, \.{\\lowercase},
+\.{\\uppercase}, \.{\\message}, \.{\\errmessage}, \.{\\write}, or
+\.{\\special}. In the latter cases a left brace must be scanned next; this
+left brace will not be part of the token list, nor will the matching right
+brace that comes at the end. If \\{xpand} is false, the token list will
+simply be copied from the input using \\{get\_token}. Otherwise all expandable
+tokens will be expanded until unexpandable tokens are left, except that
+the results of expanding `\.{\\the}' are not expanded further.
+If both \\{macro\_def} and \\{xpand} are true, the expansion applies
+only to the macro body (i.e., to the material following the first
+\\{left\_brace} character).
+
+The value of \\{cur\_cs} when \\{scan\_toks} begins should be the \\{eqtb}
+address of the control sequence to display in ``runaway'' error
+messages.
+
+\Y\B\&{pointer} \\{scan\_toks}(\&{bool} \\{macro\_def}${},\39{}$\&{bool} \\{xpand})\1\1\2\2\6
+${}\{{}$\5
+\1\&{halfword} \|t;\C{token representing the highest parameter number}\6
+\&{halfword} \|s;\C{saved token}\6
+\&{pointer} \|p;\C{tail of the token list being built}\6
+\&{pointer} \|q;\C{new node being added to the token list via \\{store\_new\_token}}\6
+\&{halfword} \\{unbalance};\C{number of unmatched left braces}\6
+\&{halfword} \\{hash\_brace};\C{possible `\.{\#\{}' token}\7
+\&{if} (\\{macro\_def})\1\5
+${}\\{scanner\_status}\K\\{defining}{}$;\5
+\2\&{else}\1\5
+${}\\{scanner\_status}\K\\{absorbing};{}$\2\6
+${}\\{warning\_index}\K\\{cur\_cs};{}$\5
+${}\\{def\_ref}\K\\{get\_avail}(\,);{}$\5
+${}\\{token\_ref\_count}(\\{def\_ref})\K\\{null};{}$\5
+${}\|p\K\\{def\_ref};{}$\5
+${}\\{hash\_brace}\K\T{0};{}$\5
+${}\|t\K\\{zero\_token};{}$\6
+\&{if} (\\{macro\_def})\1\5
+\X474:Scan and build the parameter part of the macro definition\X\2\6
+\&{else}\1\5
+\\{scan\_left\_brace}(\,);\C{remove the compulsory left brace}\2\6
+\X477:Scan and build the body of the token list; \&{goto} \\{found} when finished\X;\6
+\4\\{found}:\5
+${}\\{scanner\_status}\K\\{normal};{}$\6
+\&{if} ${}(\\{hash\_brace}\I\T{0}){}$\1\5
+\\{store\_new\_token}(\\{hash\_brace});\2\6
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{474}\B\X474:Scan and build the parameter part of the macro definition\X${}\E{}$\6
+${}\{{}$\5
+\1\&{loop}\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\C{set \\{cur\_cmd}, \\{cur\_chr}, \\{cur\_tok}}\6
+\&{if} ${}(\\{cur\_tok}<\\{right\_brace\_limit}){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{mac\_param}){}$\1\5
+\X476:If the next character is a parameter number, make \\{cur\_tok} a \\{match} token; but if it is a left brace, store `\\{left\_brace}, \\{end\_match}', set \\{hash\_brace}, and \&{goto} \\{done}\X;\2\6
+\\{store\_new\_token}(\\{cur\_tok});\6
+\4${}\}{}$\2\6
+\4\\{done1}:\5
+\\{store\_new\_token}(\\{end\_match\_token});\6
+\&{if} ${}(\\{cur\_cmd}\E\\{right\_brace}){}$\1\5
+\X475:Express shock at the missing left brace; \&{goto} \\{found}\X;\2\6
+\4\\{done}:\5
+;\6
+\4${}\}{}$\2\par
+\U473.\fi
+
+\M{475}\B\X475:Express shock at the missing left brace; \&{goto} \\{found}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \{\ inserted"});\5
+\\{incr}(\\{align\_state});\5
+\\{help2}(\.{"Where\ was\ the\ left\ }\)\.{brace?\ You\ said\ some}\)\.{thing\ like\ `\\\\def\\\\a}\)\.{\}',"})\6
+(\.{"which\ I'm\ going\ to\ }\)\.{interpret\ as\ `\\\\def\\}\)\.{\\a\{\}'."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{found};\6
+\4${}\}{}$\2\par
+\U474.\fi
+
+\M{476}\B\X476:If the next character is a parameter number, make \\{cur\_tok} a \\{match} token; but if it is a left brace, store `\\{left\_brace}, \\{end\_match}', set \\{hash\_brace}, and \&{goto} \\{done}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|s\K\\{match\_token}+\\{cur\_chr};{}$\5
+\\{get\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\E\\{left\_brace}){}$\5
+${}\{{}$\5
+\1${}\\{hash\_brace}\K\\{cur\_tok};{}$\5
+\\{store\_new\_token}(\\{cur\_tok});\5
+\\{store\_new\_token}(\\{end\_match\_token});\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|t\E\\{zero\_token}+\T{9}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ already\ have\ ni}\)\.{ne\ parameters"});\5
+\\{help1}(\.{"I'm\ going\ to\ ignore}\)\.{\ the\ \#\ sign\ you\ just}\)\.{\ used."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{incr}(\|t);\6
+\&{if} ${}(\\{cur\_tok}\I\|t){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Parameters\ must\ be\ }\)\.{numbered\ consecutive}\)\.{ly"});\5
+\\{help2}(\.{"I've\ inserted\ the\ d}\)\.{igit\ you\ should\ have}\)\.{\ used\ after\ the\ \#."})\6
+(\.{"Type\ `1'\ to\ delete\ }\)\.{what\ you\ did\ use."});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\6
+${}\\{cur\_tok}\K\|s;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U474.\fi
+
+\M{477}\B\X477:Scan and build the body of the token list; \&{goto} \\{found} when finished\X${}\E{}$\6
+$\\{unbalance}\K\T{1};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} (\\{xpand})\1\5
+\X478:Expand the next part of the input\X\2\6
+\&{else}\1\5
+\\{get\_token}(\,);\2\6
+\&{if} ${}(\\{cur\_tok}<\\{right\_brace\_limit}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}<\\{right\_brace}){}$\1\5
+\\{incr}(\\{unbalance});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{decr}(\\{unbalance});\6
+\&{if} ${}(\\{unbalance}\E\T{0}){}$\1\5
+\&{goto} \\{found};\2\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{mac\_param}){}$\1\6
+\&{if} (\\{macro\_def})\1\5
+\X479:Look for parameter number or \.{\#\#}\X;\2\2\6
+\\{store\_new\_token}(\\{cur\_tok});\6
+\4${}\}{}$\2\par
+\U473.\fi
+
+\M{478}Here we insert an entire token list created by \\{the\_toks} without
+expanding it further.
+
+\Y\B\4\X478:Expand the next part of the input\X${}\E{}$\6
+${}\{{}$\5
+\1\&{loop}\5
+${}\{{}$\5
+\1\\{get\_next}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{max\_command}){}$\1\5
+\&{goto} \\{done2};\2\6
+\&{if} ${}(\\{cur\_cmd}\I\\{the}){}$\1\5
+\\{expand}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{the\_toks}(\,);{}$\6
+\&{if} ${}(\\{link}(\\{temp\_head})\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\\{link}(\\{temp\_head});{}$\5
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4\\{done2}:\5
+\\{x\_token}(\,);\6
+\4${}\}{}$\2\par
+\U477.\fi
+
+\M{479}\B\X479:Look for parameter number or \.{\#\#}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|s\K\\{cur\_tok};{}$\6
+\&{if} (\\{xpand})\1\5
+\\{get\_x\_token}(\,);\2\6
+\&{else}\1\5
+\\{get\_token}(\,);\2\6
+\&{if} ${}(\\{cur\_cmd}\I\\{mac\_param}){}$\1\6
+\&{if} ${}((\\{cur\_tok}\Z\\{zero\_token})\V(\\{cur\_tok}>\|t)){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ parameter\ n}\)\.{umber\ in\ definition\ }\)\.{of\ "});\5
+\\{sprint\_cs}(\\{warning\_index});\5
+\\{help3}(\.{"You\ meant\ to\ type\ \#}\)\.{\#\ instead\ of\ \#,\ righ}\)\.{t?"})\6
+(\.{"Or\ maybe\ a\ \}\ was\ fo}\)\.{rgotten\ somewhere\ ea}\)\.{rlier,\ and\ things"})\6
+(\.{"are\ all\ screwed\ up?}\)\.{\ I'm\ going\ to\ assume}\)\.{\ that\ you\ meant\ \#\#."});\5
+\\{back\_error}(\,);\5
+${}\\{cur\_tok}\K\|s;{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{cur\_tok}\K\\{out\_param\_token}-\.{'0'}+\\{cur\_chr};{}$\2\2\6
+\4${}\}{}$\2\par
+\U477.\fi
+
+\M{480}Another way to create a token list is via the \.{\\read} command. The
+sixteen files potentially usable for reading appear in the following
+global variables. The value of \\{read\_open}[\|n] will be \\{closed} if
+stream number \|n has not been opened or if it has been fully read;
+\\{just\_open} if an \.{\\openin} but not a \.{\\read} has been done;
+and \\{normal} if it is open and ready to read the next line.
+
+\Y\B\4\D$\\{closed}$ \5
+\T{2}\C{not open, or at end of file}\par
+\B\4\D$\\{just\_open}$ \5
+\T{1}\C{newly opened, first line not yet read}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{alpha\_file} \\{read\_file}[\T{16}];\C{used for \.{\\read}}\6
+\&{uint8\_t} \\{read\_open}[\T{17}];\C{state of \\{read\_file}[\|n]}\par
+\fi
+
+\M{481}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{16};{}$ ${}\|k\PP){}$\1\5
+${}\\{read\_open}[\|k]\K\\{closed}{}$;\2\par
+\fi
+
+\M{482}The \\{read\_toks} procedure constructs a token list like that for any
+macro definition, and makes \\{cur\_val} point to it. Parameter \|r points
+to the control sequence that will receive this token list.
+
+\Y\B\&{void} \\{read\_toks}(\&{int} \|n${},\39{}$\&{pointer} \|r)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{tail of the token list}\6
+\&{pointer} \|q;\C{new node being added to the token list via \\{store\_new\_token}}\6
+\&{int} \|s;\C{saved value of \\{align\_state}}\6
+\&{small\_number} \|m;\C{stream number}\7
+${}\\{scanner\_status}\K\\{defining};{}$\5
+${}\\{warning\_index}\K\|r;{}$\5
+${}\\{def\_ref}\K\\{get\_avail}(\,);{}$\5
+${}\\{token\_ref\_count}(\\{def\_ref})\K\\{null};{}$\5
+${}\|p\K\\{def\_ref}{}$;\C{the reference count}\6
+\\{store\_new\_token}(\\{end\_match\_token});\6
+\&{if} ${}((\|n<\T{0})\V(\|n>\T{15})){}$\1\5
+${}\|m\K\T{16}{}$;\5
+\2\&{else}\1\5
+${}\|m\K\|n;{}$\2\6
+${}\|s\K\\{align\_state};{}$\5
+${}\\{align\_state}\K\T{1000000}{}$;\C{disable tab marks, etc.}\6
+\&{do}\5
+${}\{{}$\1\6
+\X483:Input and store tokens from the next line of the file\X;\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{align\_state}\E\T{1000000}));{}$\5
+${}\\{cur\_val}\K\\{def\_ref};{}$\5
+${}\\{scanner\_status}\K\\{normal};{}$\5
+${}\\{align\_state}\K\|s;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{483}\B\X483:Input and store tokens from the next line of the file\X${}\E{}$\6
+\\{begin\_file\_reading}(\,);\5
+${}\\{name}\K\|m+\T{1};{}$\6
+\&{if} ${}(\\{read\_open}[\|m]\E\\{closed}){}$\1\5
+\X484:Input for \.{\\read} from the terminal\X;\2\6
+\&{else} \&{if} ${}(\\{read\_open}[\|m]\E\\{just\_open}){}$\1\5
+\X485:Input the first line of \\{read\_file}[\|m]\X\2\6
+\&{else}\1\5
+\X486:Input the next line of \\{read\_file}[\|m]\X;\2\6
+${}\\{limit}\K\\{last};{}$\6
+\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{decr}(\\{limit});\2\6
+\&{else}\1\5
+${}\\{buffer}[\\{limit}]\K\\{end\_line\_char};{}$\2\6
+${}\\{first}\K\\{limit}+\T{1};{}$\5
+${}\\{loc}\K\\{start};{}$\5
+${}\\{state}\K\\{new\_line}{}$;\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\6
+\&{if} ${}(\\{cur\_tok}\E\T{0}){}$\1\5
+\&{goto} \\{done};\C{$\\{cur\_cmd}\E\\{cur\_chr}\E\T{0}$ will occur at the end of the line}\2\6
+\&{if} ${}(\\{align\_state}<\T{1000000}{}$)\C{unmatched `\.\}' aborts the line}\6
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_tok}\E\T{0}));{}$\5
+${}\\{align\_state}\K\T{1000000};{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\\{store\_new\_token}(\\{cur\_tok});\6
+\4${}\}{}$\2\6
+\\{done}: \\{end\_file\_reading}(\,)\par
+\U482.\fi
+
+\M{484}Here we input on-line into the \\{buffer} array, prompting the user explicitly
+if $\|n\G\T{0}$. The value of \|n is set negative so that additional prompts
+will not be given in the case of multi-line input.
+
+\Y\B\4\X484:Input for \.{\\read} from the terminal\X${}\E{}$\6
+\&{if} ${}(\\{interaction}>\\{nonstop\_mode}){}$\1\6
+\&{if} ${}(\|n<\T{0}){}$\1\5
+\\{prompt\_input}(\.{""})\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+\\{print\_ln}(\,);\5
+\\{sprint\_cs}(\|r);\5
+\\{prompt\_input}(\.{"="});\5
+${}\|n\K{-}\T{1};{}$\6
+\4${}\}{}$\2\2\6
+\&{else} \\{fatal\_error}(\.{"***\ (cannot\ \\\\read\ }\)\.{from\ terminal\ in\ non}\)\.{stop\ modes)"})\par
+\U483.\fi
+
+\M{485}The first line of a file must be treated specially, since \\{input\_ln}
+must be told not to start with \\{get}.
+
+\Y\B\4\X485:Input the first line of \\{read\_file}[\|m]\X${}\E{}$\6
+\&{if} ${}(\\{input\_ln}({\AND}\\{read\_file}[\|m],\39\\{false})){}$\1\5
+${}\\{read\_open}[\|m]\K\\{normal};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{a\_close}({\AND}\\{read\_file}[\|m]);{}$\5
+${}\\{read\_open}[\|m]\K\\{closed};{}$\6
+\4${}\}{}$\2\par
+\U483.\fi
+
+\M{486}An empty line is appended at the end of a \\{read\_file}.
+
+\Y\B\4\X486:Input the next line of \\{read\_file}[\|m]\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\R\\{input\_ln}({\AND}\\{read\_file}[\|m],\39\\{true})){}$\5
+${}\{{}$\5
+\1${}\\{a\_close}({\AND}\\{read\_file}[\|m]);{}$\5
+${}\\{read\_open}[\|m]\K\\{closed};{}$\6
+\&{if} ${}(\\{align\_state}\I\T{1000000}){}$\5
+${}\{{}$\5
+\1\\{runaway}(\,);\5
+\\{print\_err}(\.{"File\ ended\ within\ "});\5
+\\{print\_esc}(\X1556:\.{"read"}\X);\5
+\\{help1}(\.{"This\ \\\\read\ has\ unb}\)\.{alanced\ braces."});\5
+${}\\{align\_state}\K\T{1000000};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U483.\fi
+
+\N{1}{487}Conditional processing.
+We consider now the way \TeX\ handles various kinds of \.{\\if} commands.
+
+\Y\B\4\D$\\{if\_char\_code}$ \5
+\T{0}\C{ `\.{\\if}' }\par
+\B\4\D$\\{if\_cat\_code}$ \5
+\T{1}\C{ `\.{\\ifcat}' }\par
+\B\4\D$\\{if\_int\_code}$ \5
+\T{2}\C{ `\.{\\ifnum}' }\par
+\B\4\D$\\{if\_dim\_code}$ \5
+\T{3}\C{ `\.{\\ifdim}' }\par
+\B\4\D$\\{if\_odd\_code}$ \5
+\T{4}\C{ `\.{\\ifodd}' }\par
+\B\4\D$\\{if\_vmode\_code}$ \5
+\T{5}\C{ `\.{\\ifvmode}' }\par
+\B\4\D$\\{if\_hmode\_code}$ \5
+\T{6}\C{ `\.{\\ifhmode}' }\par
+\B\4\D$\\{if\_mmode\_code}$ \5
+\T{7}\C{ `\.{\\ifmmode}' }\par
+\B\4\D$\\{if\_inner\_code}$ \5
+\T{8}\C{ `\.{\\ifinner}' }\par
+\B\4\D$\\{if\_void\_code}$ \5
+\T{9}\C{ `\.{\\ifvoid}' }\par
+\B\4\D$\\{if\_hbox\_code}$ \5
+\T{10}\C{ `\.{\\ifhbox}' }\par
+\B\4\D$\\{if\_vbox\_code}$ \5
+\T{11}\C{ `\.{\\ifvbox}' }\par
+\B\4\D$\\{ifx\_code}$ \5
+\T{12}\C{ `\.{\\ifx}' }\par
+\B\4\D$\\{if\_eof\_code}$ \5
+\T{13}\C{ `\.{\\ifeof}' }\par
+\B\4\D$\\{if\_true\_code}$ \5
+\T{14}\C{ `\.{\\iftrue}' }\par
+\B\4\D$\\{if\_false\_code}$ \5
+\T{15}\C{ `\.{\\iffalse}' }\par
+\B\4\D$\\{if\_case\_code}$ \5
+\T{16}\C{ `\.{\\ifcase}' }\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1611:\.{"if"}\X,\39\\{if\_test},\39\\{if\_char\_code});{}$\5
+${}\\{primitive}(\X1612:\.{"ifcat"}\X,\39\\{if\_test},\39\\{if\_cat\_code});{}$\5
+${}\\{primitive}(\X1613:\.{"ifnum"}\X,\39\\{if\_test},\39\\{if\_int\_code});{}$\5
+${}\\{primitive}(\X1614:\.{"ifdim"}\X,\39\\{if\_test},\39\\{if\_dim\_code});{}$\5
+${}\\{primitive}(\X1615:\.{"ifodd"}\X,\39\\{if\_test},\39\\{if\_odd\_code});{}$\5
+${}\\{primitive}(\X1616:\.{"ifvmode"}\X,\39\\{if\_test},\39\\{if\_vmode\_code});{}$\5
+${}\\{primitive}(\X1617:\.{"ifhmode"}\X,\39\\{if\_test},\39\\{if\_hmode\_code});{}$\5
+${}\\{primitive}(\X1618:\.{"ifmmode"}\X,\39\\{if\_test},\39\\{if\_mmode\_code});{}$\5
+${}\\{primitive}(\X1619:\.{"ifinner"}\X,\39\\{if\_test},\39\\{if\_inner\_code});{}$\5
+${}\\{primitive}(\X1620:\.{"ifvoid"}\X,\39\\{if\_test},\39\\{if\_void\_code});{}$\5
+${}\\{primitive}(\X1621:\.{"ifhbox"}\X,\39\\{if\_test},\39\\{if\_hbox\_code});{}$\5
+${}\\{primitive}(\X1622:\.{"ifvbox"}\X,\39\\{if\_test},\39\\{if\_vbox\_code});{}$\5
+${}\\{primitive}(\X1623:\.{"ifx"}\X,\39\\{if\_test},\39\\{ifx\_code});{}$\5
+${}\\{primitive}(\X1624:\.{"ifeof"}\X,\39\\{if\_test},\39\\{if\_eof\_code});{}$\5
+${}\\{primitive}(\X1625:\.{"iftrue"}\X,\39\\{if\_test},\39\\{if\_true\_code});{}$\5
+${}\\{primitive}(\X1626:\.{"iffalse"}\X,\39\\{if\_test},\39\\{if\_false\_code});{}$\5
+${}\\{primitive}(\X1627:\.{"ifcase"}\X,\39\\{if\_test},\39\\{if\_case\_code}){}$;\par
+\fi
+
+\M{488}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{if\_test}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{if\_cat\_code}:\5
+\\{print\_esc}(\X1612:\.{"ifcat"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_int\_code}:\5
+\\{print\_esc}(\X1613:\.{"ifnum"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_dim\_code}:\5
+\\{print\_esc}(\X1614:\.{"ifdim"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_odd\_code}:\5
+\\{print\_esc}(\X1615:\.{"ifodd"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_vmode\_code}:\5
+\\{print\_esc}(\X1616:\.{"ifvmode"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_hmode\_code}:\5
+\\{print\_esc}(\X1617:\.{"ifhmode"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_mmode\_code}:\5
+\\{print\_esc}(\X1618:\.{"ifmmode"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_inner\_code}:\5
+\\{print\_esc}(\X1619:\.{"ifinner"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_void\_code}:\5
+\\{print\_esc}(\X1620:\.{"ifvoid"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_hbox\_code}:\5
+\\{print\_esc}(\X1621:\.{"ifhbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_vbox\_code}:\5
+\\{print\_esc}(\X1622:\.{"ifvbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{ifx\_code}:\5
+\\{print\_esc}(\X1623:\.{"ifx"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_eof\_code}:\5
+\\{print\_esc}(\X1624:\.{"ifeof"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_true\_code}:\5
+\\{print\_esc}(\X1625:\.{"iftrue"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_false\_code}:\5
+\\{print\_esc}(\X1626:\.{"iffalse"}\X);\5
+\&{break};\6
+\4\&{case} \\{if\_case\_code}:\5
+\\{print\_esc}(\X1627:\.{"ifcase"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1611:\.{"if"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{489}Conditions can be inside conditions, and this nesting has a stack
+that is independent of the \\{save\_stack}.
+
+Four global variables represent the top of the condition stack:
+\\{cond\_ptr} points to pushed-down entries, if any; \\{if\_limit} specifies
+the largest code of a \\{fi\_or\_else} command that is syntactically legal;
+\\{cur\_if} is the name of the current type of conditional; and \\{if\_line}
+is the line number at which it began.
+
+If no conditions are currently in progress, the condition stack has the
+special state $\\{cond\_ptr}\E\\{null}$, $\\{if\_limit}\E\\{normal}$, $\\{cur\_if}\E\T{0}$, $\\{if\_line}\E\T{0}$.
+Otherwise \\{cond\_ptr} points to a two-word node; the \\{type}, \\{subtype}, and
+\\{link} fields of the first word contain \\{if\_limit}, \\{cur\_if}, and
+\\{cond\_ptr} at the next level, and the second word contains the
+corresponding \\{if\_line}.
+
+\Y\B\4\D$\\{if\_node\_size}$ \5
+\T{2}\C{number of words in stack entry for conditionals}\par
+\B\4\D$\\{if\_line\_field}(\|X)$ \5
+$\\{mem}[\|X+\T{1}].{}$\|i\par
+\B\4\D$\\{if\_code}$ \5
+\T{1}\C{code for \.{\\if...} being evaluated}\par
+\B\4\D$\\{fi\_code}$ \5
+\T{2}\C{code for \.{\\fi}}\par
+\B\4\D$\\{else\_code}$ \5
+\T{3}\C{code for \.{\\else}}\par
+\B\4\D$\\{or\_code}$ \5
+\T{4}\C{code for \.{\\or}}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{cond\_ptr};\C{top of the condition stack}\6
+\&{uint8\_t} \\{if\_limit};\C{upper bound on \\{fi\_or\_else} codes}\6
+\&{small\_number} \\{cur\_if};\C{type of conditional being worked on}\6
+\&{int} \\{if\_line};\C{line where that conditional began}\par
+\fi
+
+\M{490}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{cond\_ptr}\K\\{null};{}$\5
+${}\\{if\_limit}\K\\{normal};{}$\5
+${}\\{cur\_if}\K\T{0};{}$\5
+${}\\{if\_line}\K\T{0}{}$;\par
+\fi
+
+\M{491}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1628:\.{"fi"}\X,\39\\{fi\_or\_else},\39\\{fi\_code});{}$\5
+${}\\{text}(\\{frozen\_fi})\K\X1628:\.{"fi"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_fi}]\K\\{eqtb}[\\{cur\_val}];{}$\5
+${}\\{primitive}(\X1629:\.{"or"}\X,\39\\{fi\_or\_else},\39\\{or\_code});{}$\5
+${}\\{primitive}(\X1630:\.{"else"}\X,\39\\{fi\_or\_else},\39\\{else\_code}){}$;\par
+\fi
+
+\M{492}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{fi\_or\_else}:\6
+\&{if} ${}(\\{chr\_code}\E\\{fi\_code}){}$\1\5
+\\{print\_esc}(\X1628:\.{"fi"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{or\_code}){}$\1\5
+\\{print\_esc}(\X1629:\.{"or"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1630:\.{"else"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{493}When we skip conditional text, we keep track of the line number
+where skipping began, for use in error messages.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{skip\_line};\C{skipping began here}\par
+\fi
+
+\M{494}Here is a procedure that ignores text until coming to an \.{\\or},
+\.{\\else}, or \.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$
+nesting. After it has acted, \\{cur\_chr} will indicate the token that
+was found, but \\{cur\_tok} will not be set (because this makes the
+procedure run faster).
+
+\Y\B\&{void} \\{pass\_text}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|l;\C{level of $\.{\\if}\ldots\.{\\fi}$ nesting}\6
+\&{small\_number} \\{save\_scanner\_status};\C{\\{scanner\_status} upon entry}\7
+${}\\{save\_scanner\_status}\K\\{scanner\_status};{}$\5
+${}\\{scanner\_status}\K\\{skipping};{}$\5
+${}\|l\K\T{0};{}$\5
+${}\\{skip\_line}\K\\{line};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_next}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\E\\{fi\_or\_else}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|l\E\T{0}){}$\1\5
+\&{goto} \\{done};\2\6
+\&{if} ${}(\\{cur\_chr}\E\\{fi\_code}){}$\1\5
+\\{decr}(\|l);\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{if\_test}){}$\1\5
+\\{incr}(\|l);\2\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+${}\\{scanner\_status}\K\\{save\_scanner\_status};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{495}When we begin to process a new \.{\\if}, we set $\\{if\_limit}\K\\{if\_code}$; then
+if\/ \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if}
+condition has been evaluated, \.{\\relax} will be inserted.
+For example, a sequence of commands like `\.{\\ifvoid1\\else...\\fi}'
+would otherwise require something after the `\.1'.
+
+\Y\B\4\X495:Push the condition stack\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{get\_node}(\\{if\_node\_size});{}$\5
+${}\\{link}(\|p)\K\\{cond\_ptr};{}$\5
+${}\\{type}(\|p)\K\\{if\_limit};{}$\5
+${}\\{subtype}(\|p)\K\\{cur\_if};{}$\5
+${}\\{if\_line\_field}(\|p)\K\\{if\_line};{}$\5
+${}\\{cond\_ptr}\K\|p;{}$\5
+${}\\{cur\_if}\K\\{cur\_chr};{}$\5
+${}\\{if\_limit}\K\\{if\_code};{}$\5
+${}\\{if\_line}\K\\{line};{}$\6
+\4${}\}{}$\2\par
+\U498.\fi
+
+\M{496}\B\X496:Pop the condition stack\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{cond\_ptr};{}$\5
+${}\\{if\_line}\K\\{if\_line\_field}(\|p);{}$\5
+${}\\{cur\_if}\K\\{subtype}(\|p);{}$\5
+${}\\{if\_limit}\K\\{type}(\|p);{}$\5
+${}\\{cond\_ptr}\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\|p,\39\\{if\_node\_size});{}$\6
+\4${}\}{}$\2\par
+\Us498, 500, 509\ETs510.\fi
+
+\M{497}Here's a procedure that changes the \\{if\_limit} code corresponding to
+a given value of \\{cond\_ptr}.
+
+\Y\B\&{void} \\{change\_if\_limit}(\&{small\_number} \|l${},\39{}$\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|q;\7
+\&{if} ${}(\|p\E\\{cond\_ptr}){}$\1\5
+${}\\{if\_limit}\K\|l{}$;\C{that's the easy case}\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{cond\_ptr};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\|q\E\\{null}){}$\1\5
+\\{confusion}(\X1611:\.{"if"}\X);\2\6
+\&{if} ${}(\\{link}(\|q)\E\|p){}$\5
+${}\{{}$\5
+\1${}\\{type}(\|q)\K\|l;{}$\5
+\&{return};\6
+\4${}\}{}$\2\6
+${}\|q\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{498}A condition is started when the \\{expand} procedure encounters
+an \\{if\_test} command; in that case \\{expand} reduces to \\{conditional},
+which is a recursive procedure.
+
+\Y\B\&{void} \\{conditional}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{bool} \|b;\C{is the condition true?}\6
+\&{uint8\_t} \|r;\C{relation to be evaluated}\6
+\&{int} \|m${},{}$ \|n;\C{to be tested against the second operand}\6
+\&{pointer} \|p${},{}$ \|q;\C{for traversing token lists in \.{\\ifx} tests}\6
+\&{small\_number} \\{save\_scanner\_status};\C{\\{scanner\_status} upon entry}\6
+\&{pointer} \\{save\_cond\_ptr};\C{\\{cond\_ptr} corresponding to this conditional}\6
+\&{small\_number} \\{this\_if};\C{type of this conditional}\7
+\X495:Push the condition stack\X;\5
+${}\\{save\_cond\_ptr}\K\\{cond\_ptr};{}$\5
+${}\\{this\_if}\K\\{cur\_chr}{}$;\6
+\X501:Either process \.{\\ifcase} or set \|b to the value of a boolean condition\X;\6
+\&{if} ${}(\\{tracing\_commands}>\T{1}){}$\1\5
+\X502:Display the value of \|b\X;\2\6
+\&{if} (\|b)\5
+${}\{{}$\5
+\1${}\\{change\_if\_limit}(\\{else\_code},\39\\{save\_cond\_ptr});{}$\5
+\&{return};\C{wait for \.{\\else} or \.{\\fi}}\6
+\4${}\}{}$\2\6
+\X500:Skip to \.{\\else} or \.{\\fi}, then \&{goto} \\{common\_ending}\X;\6
+\4\\{common\_ending}:\6
+\&{if} ${}(\\{cur\_chr}\E\\{fi\_code}){}$\1\5
+\X496:Pop the condition stack\X\2\6
+\&{else}\1\5
+${}\\{if\_limit}\K\\{fi\_code}{}$;\C{wait for \.{\\fi}}\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{499}In a construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first
+\.{\\else} that we come to after learning that the \.{\\if} is false is
+not the \.{\\else} we're looking for. Hence the following curious
+logic is needed.
+
+\fi
+
+\M{500}\B\X500:Skip to \.{\\else} or \.{\\fi}, then \&{goto} \\{common\_ending}\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{pass\_text}(\,);\6
+\&{if} ${}(\\{cond\_ptr}\E\\{save\_cond\_ptr}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_chr}\I\\{or\_code}){}$\1\5
+\&{goto} \\{common\_ending};\2\6
+\\{print\_err}(\.{"Extra\ "});\5
+\\{print\_esc}(\X1629:\.{"or"}\X);\5
+\\{help1}(\.{"I'm\ ignoring\ this;\ }\)\.{it\ doesn't\ match\ any}\)\.{\ \\\\if."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\E\\{fi\_code}){}$\1\5
+\X496:Pop the condition stack\X;\2\6
+\4${}\}{}$\2\par
+\U498.\fi
+
+\M{501}\B\X501:Either process \.{\\ifcase} or set \|b to the value of a boolean condition\X${}\E{}$\6
+\&{switch} (\\{this\_if})\5
+${}\{{}$\1\6
+\4\&{case} \\{if\_char\_code}:\5
+\&{case} \\{if\_cat\_code}:\5
+\X506:Test if two characters match\X\5
+\&{break};\6
+\4\&{case} \\{if\_int\_code}:\5
+\&{case} \\{if\_dim\_code}:\5
+\X503:Test relation between integers or dimensions\X\5
+\&{break};\6
+\4\&{case} \\{if\_odd\_code}:\5
+\X504:Test if an integer is odd\X\5
+\&{break};\6
+\4\&{case} \\{if\_vmode\_code}:\5
+${}\|b\K(\\{abs}(\\{mode})\E\\{vmode}){}$;\5
+\&{break};\6
+\4\&{case} \\{if\_hmode\_code}:\5
+${}\|b\K(\\{abs}(\\{mode})\E\\{hmode}){}$;\5
+\&{break};\6
+\4\&{case} \\{if\_mmode\_code}:\5
+${}\|b\K(\\{abs}(\\{mode})\E\\{mmode}){}$;\5
+\&{break};\6
+\4\&{case} \\{if\_inner\_code}:\5
+${}\|b\K(\\{mode}<\T{0}){}$;\5
+\&{break};\6
+\4\&{case} \\{if\_void\_code}:\5
+\&{case} \\{if\_hbox\_code}:\5
+\&{case} \\{if\_vbox\_code}:\5
+\X505:Test box register status\X\5
+\&{break};\6
+\4\&{case} \\{ifx\_code}:\5
+\X507:Test if two tokens match\X\5
+\&{break};\6
+\4\&{case} \\{if\_eof\_code}:\6
+${}\{{}$\5
+\1\\{scan\_four\_bit\_int}(\,);\5
+${}\|b\K(\\{read\_open}[\\{cur\_val}]\E\\{closed});{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{if\_true\_code}:\5
+${}\|b\K\\{true}{}$;\5
+\&{break};\6
+\4\&{case} \\{if\_false\_code}:\5
+${}\|b\K\\{false}{}$;\5
+\&{break};\6
+\4\&{case} \\{if\_case\_code}:\5
+\X509:Select the appropriate case and \&{return} or \&{goto} \\{common\_ending}\X;\6
+\4${}\}{}$\C{there are no other cases}\2\par
+\U498.\fi
+
+\M{502}\B\X502:Display the value of \|b\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\6
+\&{if} (\|b)\1\5
+\\{print\_str}(\.{"\{true\}"});\5
+\2\&{else}\1\5
+\\{print\_str}(\.{"\{false\}"});\2\6
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\par
+\U498.\fi
+
+\M{503}Here we use the fact that \.{'<'}, \.{'='}, and \.{'>'} are consecutive ASCII
+codes.
+
+\Y\B\4\X503:Test relation between integers or dimensions\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{this\_if}\E\\{if\_int\_code}){}$\1\5
+\\{scan\_int}(\,);\5
+\2\&{else}\1\5
+\\{scan\_normal\_dimen};\2\6
+${}\|n\K\\{cur\_val};{}$\5
+\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}((\\{cur\_tok}\G\\{other\_token}+\.{'<'})\W(\\{cur\_tok}\Z\\{other\_token}+\.{'>'})){}$\1\5
+${}\|r\K\\{cur\_tok}-\\{other\_token};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ =\ inserted\ }\)\.{for\ "});\5
+${}\\{print\_cmd\_chr}(\\{if\_test},\39\\{this\_if});{}$\5
+\\{help1}(\.{"I\ was\ expecting\ to\ }\)\.{see\ `<',\ `=',\ or\ `>'}\)\.{.\ Didn't."});\5
+\\{back\_error}(\,);\5
+${}\|r\K\.{'='};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{this\_if}\E\\{if\_int\_code}){}$\1\5
+\\{scan\_int}(\,);\5
+\2\&{else}\1\5
+\\{scan\_normal\_dimen};\2\6
+\&{switch} (\|r)\5
+${}\{{}$\1\6
+\4\&{case} \.{'<'}:\5
+${}\|b\K(\|n<\\{cur\_val}){}$;\5
+\&{break};\6
+\4\&{case} \.{'='}:\5
+${}\|b\K(\|n\E\\{cur\_val}){}$;\5
+\&{break};\6
+\4\&{case} \.{'>'}:\5
+${}\|b\K(\|n>\\{cur\_val});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{504}\B\X504:Test if an integer is odd\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\5
+${}\|b\K\\{odd}(\\{cur\_val});{}$\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{505}\B\X505:Test box register status\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\|p\K\\{box}(\\{cur\_val});{}$\6
+\&{if} ${}(\\{this\_if}\E\\{if\_void\_code}){}$\1\5
+${}\|b\K(\|p\E\\{null});{}$\2\6
+\&{else} \&{if} ${}(\|p\E\\{null}){}$\1\5
+${}\|b\K\\{false};{}$\2\6
+\&{else} \&{if} ${}(\\{this\_if}\E\\{if\_hbox\_code}){}$\1\5
+${}\|b\K(\\{type}(\|p)\E\\{hlist\_node});{}$\2\6
+\&{else}\1\5
+${}\|b\K(\\{type}(\|p)\E\\{vlist\_node});{}$\2\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{506}An active character will be treated as category 13 following
+\.{\\if\\noexpand} or following \.{\\ifcat\\noexpand}. We use the fact that
+active characters have the smallest tokens, among all control sequences.
+
+\Y\B\4\D$\\{get\_x\_token\_or\_active\_char}$ \5
+\hbox{}\6
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\E\\{relax}){}$\1\6
+\&{if} ${}(\\{cur\_chr}\E\\{no\_expand\_flag}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_cmd}\K\\{active\_char};{}$\5
+${}\\{cur\_chr}\K\\{cur\_tok}-\\{cs\_token\_flag}-\\{active\_base};{}$\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X506:Test if two characters match\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_x\_token\_or\_active\_char};\6
+\&{if} ${}((\\{cur\_cmd}>\\{active\_char})\V(\\{cur\_chr}>\T{255}){}$)\C{not a character}\6
+${}\{{}$\5
+\1${}\|m\K\\{relax};{}$\5
+${}\|n\K\T{256};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|m\K\\{cur\_cmd};{}$\5
+${}\|n\K\\{cur\_chr};{}$\6
+\4${}\}{}$\2\6
+\\{get\_x\_token\_or\_active\_char};\6
+\&{if} ${}((\\{cur\_cmd}>\\{active\_char})\V(\\{cur\_chr}>\T{255})){}$\5
+${}\{{}$\5
+\1${}\\{cur\_cmd}\K\\{relax};{}$\5
+${}\\{cur\_chr}\K\T{256};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{this\_if}\E\\{if\_char\_code}){}$\1\5
+${}\|b\K(\|n\E\\{cur\_chr}){}$;\5
+\2\&{else}\1\5
+${}\|b\K(\|m\E\\{cur\_cmd});{}$\2\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{507}Note that `\.{\\ifx}' will declare two macros different if one is \\{long}
+or \\{outer} and the other isn't, even though the texts of the macros are
+the same.
+
+We need to reset \\{scanner\_status}, since \.{\\outer} control sequences
+are allowed, but we might be scanning a macro definition or preamble.
+
+\Y\B\4\X507:Test if two tokens match\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{save\_scanner\_status}\K\\{scanner\_status};{}$\5
+${}\\{scanner\_status}\K\\{normal};{}$\5
+\\{get\_next}(\,);\5
+${}\|n\K\\{cur\_cs};{}$\5
+${}\|p\K\\{cur\_cmd};{}$\5
+${}\|q\K\\{cur\_chr};{}$\5
+\\{get\_next}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\I\|p){}$\1\5
+${}\|b\K\\{false};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}<\\{call}){}$\1\5
+${}\|b\K(\\{cur\_chr}\E\|q);{}$\2\6
+\&{else}\1\5
+\X508:Test if two macro texts match\X;\2\6
+${}\\{scanner\_status}\K\\{save\_scanner\_status};{}$\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{508}Note also that `\.{\\ifx}' decides that macros \.{\\a} and \.{\\b} are
+different in examples like this:
+$$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr
+{}\\def\\a\{\\c\}&
+{}\\def\\c\{\}\cr
+{}\\def\\b\{\\d\}&
+{}\\def\\d\{\}\cr}}$$
+
+\Y\B\4\X508:Test if two macro texts match\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{link}(\\{cur\_chr});{}$\5
+${}\|q\K\\{link}(\\{equiv}(\|n)){}$;\C{omit reference counts}\6
+\&{if} ${}(\|p\E\|q){}$\1\5
+${}\|b\K\\{true};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{while} ${}((\|p\I\\{null})\W(\|q\I\\{null})){}$\1\6
+\&{if} ${}(\\{info}(\|p)\I\\{info}(\|q)){}$\1\5
+${}\|p\K\\{null};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{link}(\|p);{}$\5
+${}\|q\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\2\6
+${}\|b\K((\|p\E\\{null})\W(\|q\E\\{null}));{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U507.\fi
+
+\M{509}\B\X509:Select the appropriate case and \&{return} or \&{goto} \\{common\_ending}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\5
+${}\|n\K\\{cur\_val}{}$;\C{\|n is the number of cases to pass}\6
+\&{if} ${}(\\{tracing\_commands}>\T{1}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_str}(\.{"\{case\ "});\5
+\\{print\_int}(\|n);\5
+\\{print\_char}(\.{'\}'});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\&{while} ${}(\|n\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{pass\_text}(\,);\6
+\&{if} ${}(\\{cond\_ptr}\E\\{save\_cond\_ptr}){}$\1\6
+\&{if} ${}(\\{cur\_chr}\E\\{or\_code}){}$\1\5
+\\{decr}(\|n);\2\6
+\&{else}\1\5
+\&{goto} \\{common\_ending};\2\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\E\\{fi\_code}){}$\1\5
+\X496:Pop the condition stack\X;\2\6
+\4${}\}{}$\2\6
+${}\\{change\_if\_limit}(\\{or\_code},\39\\{save\_cond\_ptr});{}$\5
+\&{return};\C{wait for \.{\\or}, \.{\\else}, or \.{\\fi}}\6
+\4${}\}{}$\2\par
+\U501.\fi
+
+\M{510}The processing of conditionals is complete except for the following
+code, which is actually part of \\{expand}. It comes into play when
+\.{\\or}, \.{\\else}, or \.{\\fi} is scanned.
+
+\Y\B\4\X510:Terminate the current conditional and skip to \.{\\fi}\X${}\E{}$\6
+\&{if} ${}(\\{cur\_chr}>\\{if\_limit}){}$\1\6
+\&{if} ${}(\\{if\_limit}\E\\{if\_code}){}$\1\5
+\\{insert\_relax}(\,);\C{condition not yet evaluated}\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Extra\ "});\5
+${}\\{print\_cmd\_chr}(\\{fi\_or\_else},\39\\{cur\_chr});{}$\5
+\\{help1}(\.{"I'm\ ignoring\ this;\ }\)\.{it\ doesn't\ match\ any}\)\.{\ \\\\if."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{while} ${}(\\{cur\_chr}\I\\{fi\_code}){}$\1\5
+\\{pass\_text}(\,);\C{skip to \.{\\fi}}\2\6
+\X496:Pop the condition stack\X;\6
+\4${}\}{}$\2\par
+\U367.\fi
+
+\N{1}{511}File names.
+It's time now to fret about file names. Besides the fact that different
+operating systems treat files in different ways, we must cope with the
+fact that completely different naming conventions are used by different
+groups of people. The following programs show what is required for one
+particular operating system; similar routines for other systems are not
+difficult to devise.
+
+\TeX\ assumes that a file name has three parts: the name proper; its
+``extension''; and a ``file area'' where it is found in an external file
+system. The extension of an input file or a write file is assumed to be
+`\.{.tex}' unless otherwise specified; it is `\.{.log}' on the
+transcript file that records each run of \TeX; it is `\.{.tfm}' on the font
+metric files that describe characters in the fonts \TeX\ uses; it is
+`\.{.dvi}' on the output files that specify typesetting information; and it
+is `\.{.fmt}' on the format files written by \.{INITEX} to initialize \TeX.
+The file area can be arbitrary on input files, but files are usually
+output to the user's current area. If an input file cannot be
+found on the specified area, \TeX\ will look for it on a special system
+area; this special area is intended for commonly used input files like
+\.{webmac.tex}.
+
+Simple uses of \TeX\ refer only to file names that have no explicit
+extension or area. For example, a person usually says `\.{\\input} \.{paper}'
+or `\.{\\font\\tenrm} \.= \.{helvetica}' instead of `\.{\\input}
+\.{paper.new}' or `\.{\\font\\tenrm} \.= \.{<csd.knuth>test}'. Simple file
+names are best, because they make the \TeX\ source files portable;
+whenever a file name consists entirely of letters and digits, it should be
+treated in the same way by all implementations of \TeX. However, users
+need the ability to refer to other files in their environment, especially
+when responding to error messages concerning unopenable files; therefore
+we want to let them use the syntax that appears in their favorite
+operating system.
+
+The following procedures don't allow spaces to be part of
+file names; but some users seem to like names that are spaced-out.
+System-dependent changes to allow such things should probably
+be made with reluctance, and only when an entire file name that
+includes spaces is ``quoted'' somehow.
+
+\fi
+
+\M{512}In order to isolate the system-dependent aspects of file names, the
+system-independent parts of \TeX\ are expressed in terms
+of three system-dependent
+procedures called \\{begin\_name}, \\{more\_name}, and \\{end\_name}. In
+essence, if the user-specified characters of the file name are $c_1\ldots c_n$,
+the system-independent driver program does the operations
+$$\\{begin\_name};\,\\{more\_name}(c_1);\,\ldots\,;\,\\{more\_name}(c_n);
+\,\\{end\_name}.$$
+These three procedures communicate with each other via global variables.
+Afterwards the file name will appear in the string pool as three strings
+called \\{cur\_name}\penalty10000\hskip-.05em,
+\\{cur\_area}, and \\{cur\_ext}; the latter two are null (i.e.,
+\\{empty\_string}), unless they were explicitly specified by the user.
+
+Actually the situation is slightly more complicated, because \TeX\ needs
+to know when the file name ends. The \\{more\_name} routine is a function
+(with side effects) that returns \\{true} on the calls \\{more\_name}$(c_1)$,
+\dots, \\{more\_name}$(c_{n-1})$. The final call \\{more\_name}$(c_n)$
+returns \\{false}; or, it returns \\{true} and the token following $c_n$ is
+something like `\.{\\hbox}' (i.e., not a character). In other words,
+\\{more\_name} is supposed to return \\{true} unless it is sure that the
+file name has been completely scanned; and \\{end\_name} is supposed to be able
+to finish the assembly of \\{cur\_name}, \\{cur\_area}, and \\{cur\_ext} regardless of
+whether $\\{more\_name}(c_n)$ returned \\{true} or \\{false}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{str\_number} \\{cur\_name};\C{name of file just scanned}\6
+\&{str\_number} \\{cur\_area};\C{file area just scanned, or \.{""}}\6
+\&{str\_number} \\{cur\_ext};\C{file extension just scanned, or \.{""}}\par
+\fi
+
+\M{513}The file names we shall deal with for illustrative purposes have the
+following structure: If the name contains `\.>' or `\.:', the file area
+consists of all characters up to and including the final such character;
+otherwise the file area is null. If the remaining file name contains
+`\..', the file extension consists of all such characters from the first
+remaining `\..' to the end, otherwise the file extension is null.
+
+We can scan such file names easily by using two global variables that keep track
+of the occurrences of area and extension delimiters:
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pool\_pointer} \\{area\_delimiter};\C{the most recent `\.>' or `\.:', if any}\6
+\&{pool\_pointer} \\{ext\_delimiter};\C{the relevant `\..', if any}\par
+\fi
+
+\M{514}Input files that can't be found in the user's area may appear in a standard
+system area called \\{TEX\_area}. Font metric files whose areas are not given
+explicitly are assumed to appear in a standard system area called
+\\{TEX\_font\_area}. These system area names will, of course, vary from place
+to place.
+
+\fi
+
+\M{515}Here now is the first of the system-dependent routines for file name scanning.
+
+\Y\B\&{void} \\{begin\_name}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{area\_delimiter}\K\T{0};{}$\5
+${}\\{ext\_delimiter}\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{516}And here's the second. The string pool might change as the file name is
+being scanned, since a new \.{\\csname} might be entered; therefore we keep
+\\{area\_delimiter} and \\{ext\_delimiter} relative to the beginning of the current
+string, instead of assigning an absolute address like \\{pool\_ptr} to them.
+
+\Y\B\&{bool} \\{more\_name}(\&{ASCII\_code} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|c\E\.{'\ '}){}$\1\5
+\&{return} \\{false};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{str\_room}(\T{1});\5
+\\{append\_char}(\|c);\C{contribute \|c to the current string}\6
+\&{if} ${}((\|c\E\.{'>'})\V(\|c\E\.{':'})){}$\5
+${}\{{}$\5
+\1${}\\{area\_delimiter}\K\\{cur\_length};{}$\5
+${}\\{ext\_delimiter}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\|c\E\.{'.'})\W(\\{ext\_delimiter}\E\T{0})){}$\1\5
+${}\\{ext\_delimiter}\K\\{cur\_length};{}$\2\6
+\&{return} \\{true};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{517}The third.
+
+\Y\B\&{void} \\{end\_name}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{str\_ptr}+\T{3}>\\{max\_strings}){}$\1\5
+${}\\{overflow}(\.{"number\ of\ strings"},\39\\{max\_strings}-\\{init\_str\_ptr});{}$\2\6
+\&{if} ${}(\\{area\_delimiter}\E\T{0}){}$\1\5
+${}\\{cur\_area}\K\\{empty\_string};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_area}\K\\{str\_ptr};{}$\5
+${}\\{str\_start}[\\{str\_ptr}+\T{1}]\K\\{str\_start}[\\{str\_ptr}]+\\{area\_delimiter};{}$\5
+\\{incr}(\\{str\_ptr});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{ext\_delimiter}\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_ext}\K\\{empty\_string};{}$\5
+${}\\{cur\_name}\K\\{make\_string}(\,);{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_name}\K\\{str\_ptr};{}$\5
+${}\\{str\_start}[\\{str\_ptr}+\T{1}]\K\\{str\_start}[\\{str\_ptr}]+\\{ext\_delimiter}-\\{area\_delimiter}-\T{1};{}$\5
+\\{incr}(\\{str\_ptr});\5
+${}\\{cur\_ext}\K\\{make\_string}(\,);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{518}Conversely, here is a routine that takes three strings and prints a file
+name that might have produced them. (The routine is system dependent, because
+some operating systems put the file area last instead of first.)
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_file\_name}(\&{int} \|n${},\39{}$\&{int} \|a${},\39{}$\&{int} \|e)\1\1\2\2\6
+${}\{{}$\5
+\1\\{slow\_print}(\|a);\5
+\\{slow\_print}(\|n);\5
+\\{slow\_print}(\|e);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{519}Another system-dependent routine is needed to convert three internal
+\TeX\ strings
+into the \\{name\_of\_file} value that is used to open files. The present code
+allows both lowercase and uppercase letters in the file name.
+
+\Y\B\4\D$\\{append\_to\_name}(\|X)$ \6
+${}\{{}$\5
+\1${}\|c\K\|X;{}$\5
+\\{incr}(\|k);\6
+\&{if} ${}(\|k\Z\\{file\_name\_size}){}$\1\5
+${}\\{name\_of\_file}[\|k]\K\\{xchr}[\|c];{}$\2\6
+\4${}\}{}$\2\par
+\Y\B\&{void} \\{pack\_file\_name}(\&{str\_number} \|n${},\39{}$\&{str\_number} \|a${},\39{}$\&{str\_number} \|e)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{number of positions filled in \\{name\_of\_file}}\6
+\&{ASCII\_code} \|c;\C{character being packed}\6
+\&{int} \|j;\C{index into \\{str\_pool}}\7
+${}\|k\K\T{0};{}$\6
+\&{for} ${}(\|j\K\\{str\_start}[\|a];{}$ ${}\|j\Z\\{str\_start}[\|a+\T{1}]-\T{1};{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]));\2\6
+\&{for} ${}(\|j\K\\{str\_start}[\|n];{}$ ${}\|j\Z\\{str\_start}[\|n+\T{1}]-\T{1};{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]));\2\6
+\&{for} ${}(\|j\K\\{str\_start}[\|e];{}$ ${}\|j\Z\\{str\_start}[\|e+\T{1}]-\T{1};{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]));\2\6
+\&{if} ${}(\|k\Z\\{file\_name\_size}){}$\1\5
+${}\\{name\_length}\K\|k{}$;\5
+\2\&{else}\1\5
+${}\\{name\_length}\K\\{file\_name\_size};{}$\2\6
+${}\\{name\_of\_file}[\\{name\_length}+\T{1}]\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{520}A messier routine is also needed, since format file names must be scanned
+before \TeX's string mechanism has been initialized. We shall use the
+global variable \\{TEX\_format\_default} to supply the text for default system areas
+and extensions related to format files.
+
+\Y\B\4\D$\\{format\_default\_length}$ \5
+\T{20}\C{length of the \\{TEX\_format\_default} string}\par
+\B\4\D$\\{format\_area\_length}$ \5
+\T{11}\C{length of its area part}\par
+\B\4\D$\\{format\_ext\_length}$ \5
+\T{4}\C{length of its `\.{.fmt}' part}\par
+\B\4\D$\\{format\_extension\_str}$ \5
+\.{".fmt"}\C{the extension, as a \.{WEB} constant}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{ASCII\_code} ${}\\{TEX\_format\_default}[\T{1}+\\{format\_default\_length}+\T{1}]\K\.{"\ TeXformats/plain.f}\)\.{mt"}{}$;\par
+\fi
+
+\M{521}\B\X14:Check the ``constant'' values for consistency\X${}\mathrel+\E{}$\6
+\&{if} ${}(\\{format\_default\_length}>\\{file\_name\_size}){}$\1\5
+${}\\{bad}\K\T{31}{}$;\2\par
+\fi
+
+\M{522}Here is the messy routine that was just mentioned. It sets \\{name\_of\_file}
+from the first \|n characters of \\{TEX\_format\_default}, followed by
+$\\{buffer}[\|a\dotdot\|b]$, followed by the last \\{format\_ext\_length} characters of
+\\{TEX\_format\_default}.
+
+We dare not give error messages here, since \TeX\ calls this routine before
+the \&{error} routine is ready to roll. Instead, we simply drop excess characters,
+since the error will be detected in another way when a strange file name
+isn't found.
+
+\Y\B\&{void} \\{pack\_buffered\_name}(\&{small\_number} \|n${},\39{}$\&{int} \|a${},\39{}$\&{int} \|b)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{number of positions filled in \\{name\_of\_file}}\6
+\&{ASCII\_code} \|c;\C{character being packed}\6
+\&{int} \|j;\C{index into \\{buffer} or \\{TEX\_format\_default}}\7
+\&{if} ${}(\|n+\|b-\|a+\T{1}+\\{format\_ext\_length}>\\{file\_name\_size}){}$\1\5
+${}\|b\K\|a+\\{file\_name\_size}-\|n-\T{1}-\\{format\_ext\_length};{}$\2\6
+${}\|k\K\T{0};{}$\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\|n;{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{xord}[\\{TEX\_format\_default}[\|j]]);\2\6
+\&{for} ${}(\|j\K\|a;{}$ ${}\|j\Z\|b;{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{buffer}[\|j]);\2\6
+\&{for} ${}(\|j\K\\{format\_default\_length}-\\{format\_ext\_length}+\T{1};{}$ ${}\|j\Z\\{format\_default\_length};{}$ ${}\|j\PP){}$\1\5
+\\{append\_to\_name}(\\{xord}[\\{TEX\_format\_default}[\|j]]);\2\6
+\&{if} ${}(\|k\Z\\{file\_name\_size}){}$\1\5
+${}\\{name\_length}\K\|k{}$;\5
+\2\&{else}\1\5
+${}\\{name\_length}\K\\{file\_name\_size};{}$\2\6
+${}\\{name\_of\_file}[\\{name\_length}+\T{1}]\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{523}Here is the only place we use \\{pack\_buffered\_name}. This part of the program
+becomes active when a ``virgin'' \TeX\ is trying to get going, just after
+the preliminary initialization, or when the user is substituting another
+format file by typing `\.\&' after the initial `\.{**}' prompt. The buffer
+contains the first line of input in $\\{buffer}[\\{loc}\dotdot(\\{last}-\T{1})]$, where
+$\\{loc}<\\{last}$ and $\\{buffer}[\\{loc}]\I\.{'\ '}$.
+
+\Y\B\4\X523:Declare the function called \\{open\_fmt\_file}\X${}\E{}$\6
+\&{bool} \\{open\_fmt\_file}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint16\_t} \|j;\C{the first space after the format file name}\7
+${}\|j\K\\{loc};{}$\6
+\&{if} ${}(\\{buffer}[\\{loc}]\E\.{'\&'}){}$\5
+${}\{{}$\5
+\1\\{incr}(\\{loc});\5
+${}\|j\K\\{loc};{}$\5
+${}\\{buffer}[\\{last}]\K\.{'\ '};{}$\6
+\&{while} ${}(\\{buffer}[\|j]\I\.{'\ '}){}$\1\5
+\\{incr}(\|j);\2\6
+${}\\{pack\_buffered\_name}(\T{0},\39\\{loc},\39\|j-\T{1}){}$;\C{try first without the system file area}\6
+\&{if} ${}(\\{w\_open\_in}({\AND}\\{fmt\_file})){}$\1\5
+\&{goto} \\{found};\2\6
+${}\\{pack\_buffered\_name}(\\{format\_area\_length},\39\\{loc},\39\|j-\T{1}){}$;\C{now try the system format file area}\6
+\&{if} ${}(\\{w\_open\_in}({\AND}\\{fmt\_file})){}$\1\5
+\&{goto} \\{found};\2\6
+\\{wake\_up\_terminal};\5
+\\{wterm\_ln}(\.{"Sorry,\ I\ can't\ find}\)\.{\ that\ format;\ will\ t}\)\.{ry\ PLAIN."});\5
+\\{update\_terminal};\6
+\4${}\}{}$\C{now pull out all the stops: try for the system \.{plain} file}\2\6
+${}\\{pack\_buffered\_name}(\\{format\_default\_length}-\\{format\_ext\_length},\39\T{1},\39\T{0});{}$\6
+\&{if} ${}(\R\\{w\_open\_in}({\AND}\\{fmt\_file})){}$\5
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+\\{wterm\_ln}(\.{"I\ can't\ find\ the\ PL}\)\.{AIN\ format\ file!"});\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\6
+\4\\{found}:\5
+${}\\{loc}\K\|j;{}$\5
+\&{return} \\{true};\6
+\4${}\}{}$\2\par
+\U1303.\fi
+
+\M{524}Operating systems often make it possible to determine the exact name (and
+possible version number) of a file that has been opened. The following routine,
+which simply makes a \TeX\ string from the value of \\{name\_of\_file}, should
+ideally be changed to deduce the full name of file~\|f, which is the file
+most recently opened, if it is possible to do this in a \PASCAL\ program.
+
+This routine might be called after string memory has overflowed, hence
+we dare not use `\\{str\_room}'.
+
+\Y\B\&{str\_number} \\{make\_name\_string}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{index into \\{name\_of\_file}}\7
+\&{if} ${}((\\{pool\_ptr}+\\{name\_length}>\\{pool\_size})\V(\\{str\_ptr}\E\\{max\_strings})\V(\\{cur\_length}>\T{0})){}$\1\5
+\&{return} \.{'?'};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{name\_length};{}$ ${}\|k\PP){}$\1\5
+\\{append\_char}(\\{xord}[\\{name\_of\_file}[\|k]]);\2\6
+\&{return} \\{make\_string}(\,);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\7
+\&{str\_number} \\{a\_make\_name\_string}(\&{alpha\_file} ${}{*}\|f){}$\1\1\2\2\6
+${}\{{}$\5
+\1\&{return} \\{make\_name\_string}(\,);\6
+\4${}\}{}$\2\7
+\&{str\_number} \\{b\_make\_name\_string}(\&{byte\_file} ${}{*}\|f){}$\1\1\2\2\6
+${}\{{}$\5
+\1\&{return} \\{make\_name\_string}(\,);\6
+\4${}\}{}$\2\7
+\&{str\_number} \\{w\_make\_name\_string}(\&{word\_file} ${}{*}\|f){}$\1\1\2\2\6
+${}\{{}$\5
+\1\&{return} \\{make\_name\_string}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{525}Now let's consider the ``driver''
+routines by which \TeX\ deals with file names
+in a system-independent manner. First comes a procedure that looks for a
+file name in the input by calling \\{get\_x\_token} for the information.
+
+\Y\B\&{void} \\{scan\_file\_name}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{name\_in\_progress}\K\\{true};{}$\5
+\\{begin\_name}(\,);\5
+\X406:Get the next non-blank non-call token\X;\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{cur\_cmd}>\\{other\_char})\V(\\{cur\_chr}>\T{255}){}$)\C{not a character}\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\R\\{more\_name}(\\{cur\_chr})){}$\1\5
+\&{goto} \\{done};\2\6
+\\{get\_x\_token}(\,);\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+\\{end\_name}(\,);\5
+${}\\{name\_in\_progress}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{526}The global variable \\{name\_in\_progress} is used to prevent recursive
+use of \\{scan\_file\_name}, since the \\{begin\_name} and other procedures
+communicate via global variables. Recursion would arise only by
+devious tricks like `\.{\\input\\input f}'; such attempts at sabotage
+must be thwarted. Furthermore, \\{name\_in\_progress} prevents \.{\\input}
+from being initiated when a font size specification is being scanned.
+
+Another global variable, \\{job\_name}, contains the file name that was first
+\.{\\input} by the user. This name is extended by `\.{.log}' and `\.{.dvi}'
+and `\.{.fmt}' in the names of \TeX's output files.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{name\_in\_progress};\C{is a file name being scanned?}\6
+\&{str\_number} \\{job\_name};\C{principal file name}\6
+\&{bool} \\{log\_opened};\C{has the transcript file been opened?}\par
+\fi
+
+\M{527}Initially $\\{job\_name}\E\T{0}$; it becomes nonzero as soon as the true name is known.
+We have $\\{job\_name}\E\T{0}$ if and only if the `\.{log}' file has not been opened,
+except of course for a short time just after \\{job\_name} has become nonzero.
+
+\Y\B\4\X55:Initialize the output routines\X${}\mathrel+\E{}$\6
+$\\{job\_name}\K\T{0};{}$\5
+${}\\{name\_in\_progress}\K\\{false};{}$\5
+${}\\{log\_opened}\K\\{false}{}$;\par
+\fi
+
+\M{528}Here is a routine that manufactures the output file names, assuming that
+$\\{job\_name}\I\T{0}$. It ignores and changes the current settings of \\{cur\_area}
+and \\{cur\_ext}.
+
+\Y\B\4\D$\\{pack\_cur\_name}$ \5
+$\\{pack\_file\_name}(\\{cur\_name},\39\\{cur\_area},\39\\{cur\_ext}{}$)\par
+\Y\B\&{void} \\{pack\_job\_name}(\&{str\_number} \|s)\C{$\|s\E\X1634:\.{".log"}\X$, $\X1635:\.{".dvi"}\X$, or \\{format\_extension}}\6
+${}\{{}$\5
+\1${}\\{cur\_area}\K\\{empty\_string};{}$\5
+${}\\{cur\_ext}\K\|s;{}$\5
+${}\\{cur\_name}\K\\{job\_name};{}$\5
+\\{pack\_cur\_name};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{529}If some trouble arises when \TeX\ tries to open a file, the following
+routine calls upon the user to supply another file name. Parameter~\|s
+is used in the error message to identify the type of file; parameter~\|e
+is the default extension if none is given. Upon exit from the routine,
+variables \\{cur\_name}, \\{cur\_area}, \\{cur\_ext}, and \\{name\_of\_file} are
+ready for another attempt at file opening.
+
+\Y\B\&{void} \\{prompt\_file\_name}(\&{char} ${}{*}\|s,\39{}$\&{str\_number} \|e)\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint16\_t} \|k;\C{index into \\{buffer}}\7
+\&{if} ${}(\\{interaction}\E\\{scroll\_mode}){}$\1\5
+\\{wake\_up\_terminal};\2\6
+\&{if} ${}(\\{strcmp}(\|s,\39\.{"input\ file\ name"})\E\T{0}){}$\1\5
+\\{print\_err}(\.{"I\ can't\ find\ file\ `}\)\.{"})\2\6
+\&{else}\1\5
+\\{print\_err}(\.{"I\ can't\ write\ on\ fi}\)\.{le\ `"});\2\6
+${}\\{print\_file\_name}(\\{cur\_name},\39\\{cur\_area},\39\\{cur\_ext});{}$\5
+\\{print\_str}(\.{"'."});\6
+\&{if} ${}(\|e\E\X1637:\.{".tex"}\X){}$\1\5
+\\{show\_context}(\,);\2\6
+\\{print\_nl}(\.{"Please\ type\ another}\)\.{\ "});\5
+\\{print\_str}(\|s);\6
+\&{if} ${}(\\{interaction}<\\{scroll\_mode}){}$\1\5
+\\{fatal\_error}(\.{"***\ (job\ aborted,\ f}\)\.{ile\ error\ in\ nonstop}\)\.{\ mode)"});\2\6
+\\{clear\_terminal};\5
+\\{prompt\_input}(\.{":\ "});\5
+\X530:Scan file name in the buffer\X;\6
+\&{if} ${}(\\{cur\_ext}\E\\{empty\_string}){}$\1\5
+${}\\{cur\_ext}\K\|e;{}$\2\6
+\\{pack\_cur\_name};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{530}\B\X530:Scan file name in the buffer\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_name}(\,);\5
+${}\|k\K\\{first};{}$\6
+\&{while} ${}((\\{buffer}[\|k]\E\.{'\ '})\W(\|k<\\{last})){}$\1\5
+\\{incr}(\|k);\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\|k\E\\{last}){}$\1\5
+\&{goto} \\{done};\2\6
+\&{if} ${}(\R\\{more\_name}(\\{buffer}[\|k])){}$\1\5
+\&{goto} \\{done};\2\6
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+\\{end\_name}(\,);\6
+\4${}\}{}$\2\par
+\U529.\fi
+
+\M{531}Here's an example of how these conventions are used. Whenever it is time to
+ship out a box of stuff, we shall use $\X531:ensure dvi open\X$.
+
+\Y\B\4\X531:ensure dvi open\X${}\E{}$\6
+\&{if} ${}(\\{output\_file\_name}\E\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+\\{open\_log\_file}(\,);\2\6
+\\{pack\_job\_name}(\X1635:\.{".dvi"}\X);\6
+\&{while} ${}(\R\\{b\_open\_out}({\AND}\\{dvi\_file})){}$\1\5
+${}\\{prompt\_file\_name}(\.{"file\ name\ for\ outpu}\)\.{t"},\39\X1635:\.{".dvi"}\X);{}$\2\6
+${}\\{output\_file\_name}\K\\{b\_make\_name\_string}({\AND}\\{dvi\_file});{}$\6
+\4${}\}{}$\2\par
+\Q531.
+\U617.\fi
+
+\M{532}\B\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{byte\_file} \\{dvi\_file};\C{the device-independent output goes here}\6
+\&{str\_number} \\{output\_file\_name};\C{full name of the output file}\6
+\&{str\_number} \\{log\_name};\C{full name of the log file}\par
+\fi
+
+\M{533}\B\X55:Initialize the output routines\X${}\mathrel+\E{}$\6
+$\\{output\_file\_name}\K\T{0}{}$;\par
+\fi
+
+\M{534}The \\{open\_log\_file} routine is used to open the transcript file and to help
+it catch up to what has previously been printed on the terminal.
+
+\Y\B\&{void} \\{open\_log\_file}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{previous \\{selector} setting}\6
+\&{int} \|k;\C{index into \\{months} and \\{buffer}}\6
+\&{uint16\_t} \|l;\C{end of first input line}\6
+\&{ASCII\_code} \\{months}[\,]${}\K\.{"\ JANFEBMARAPRMAYJUN}\)\.{JULAUGSEPOCTNOVDEC"}{}$;\C{abbreviations of month names}\7
+${}\\{old\_setting}\K\\{selector};{}$\6
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+${}\\{job\_name}\K\X1638:\.{"texput"}\X;{}$\2\6
+\\{pack\_job\_name}(\X1634:\.{".log"}\X);\6
+\&{while} ${}(\R\\{a\_open\_out}({\AND}\\{log\_file})){}$\1\5
+\X535:Try to get a different log file name\X;\2\6
+${}\\{log\_name}\K\\{a\_make\_name\_string}({\AND}\\{log\_file});{}$\5
+${}\\{selector}\K\\{log\_only};{}$\5
+${}\\{log\_opened}\K\\{true};{}$\5
+\X536:Print the banner line, including the date and time\X;\6
+${}\\{input\_stack}[\\{input\_ptr}]\K\\{cur\_input}{}$;\C{make sure bottom level is in memory}\6
+\\{print\_nl}(\.{"**"});\5
+${}\|l\K\\{input\_stack}[\T{0}].\\{limit\_field}{}$;\C{last position of first line}\6
+\&{if} ${}(\\{buffer}[\|l]\E\\{end\_line\_char}){}$\1\5
+\\{decr}(\|l);\2\6
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\|l;{}$ ${}\|k\PP){}$\1\5
+\\{print}(\\{buffer}[\|k]);\2\6
+\\{print\_ln}(\,);\C{now the transcript file contains the first line of input}\6
+${}\\{selector}\K\\{old\_setting}+\T{2}{}$;\C{\\{log\_only} or \\{term\_and\_log}}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{535}Sometimes \\{open\_log\_file} is called at awkward moments when \TeX\ is
+unable to print error messages or even to \\{show\_context}.
+The \\{prompt\_file\_name} routine can result in a \\{fatal\_error}, but the \&{error}
+routine will not be invoked because \\{log\_opened} will be false.
+
+The normal idea of \\{batch\_mode} is that nothing at all should be written
+on the terminal. However, in the unusual case that
+no log file could be opened, we make an exception and allow
+an explanatory message to be seen.
+
+Incidentally, the program always refers to the log file as a `\.{transcript
+file}', because some systems cannot use the extension `\.{.log}' for
+this file.
+
+\Y\B\4\X535:Try to get a different log file name\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{selector}\K\\{term\_only};{}$\5
+${}\\{prompt\_file\_name}(\.{"transcript\ file\ nam}\)\.{e"},\39\X1634:\.{".log"}\X);{}$\6
+\4${}\}{}$\2\par
+\U534.\fi
+
+\M{536}\B\X536:Print the banner line, including the date and time\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{wlog}(\.{"\%s"},\39\\{banner});{}$\5
+\\{slow\_print}(\\{format\_ident});\5
+\\{print\_str}(\.{"\ \ "});\5
+\\{print\_int}(\\{day});\5
+\\{print\_char}(\.{'\ '});\6
+\&{for} ${}(\|k\K\T{3}*\\{month}-\T{2};{}$ ${}\|k\Z\T{3}*\\{month};{}$ ${}\|k\PP){}$\1\5
+${}\\{wlog}(\.{"\%c"},\39\\{months}[\|k]);{}$\2\6
+\\{print\_char}(\.{'\ '});\5
+\\{print\_int}(\\{year});\5
+\\{print\_char}(\.{'\ '});\5
+${}\\{print\_two}(\\{time}/\T{60});{}$\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_two}(\\{time}\MOD\T{60});{}$\6
+\4${}\}{}$\2\par
+\U534.\fi
+
+\M{537}Let's turn now to the procedure that is used to initiate file reading
+when an `\.{\\input}' command is being processed.
+
+\Y\B\&{void} \\{start\_input}(\&{void})\C{\TeX\ will \.{\\input} something}\6
+${}\{{}$\5
+\1\\{scan\_file\_name}(\,);\C{set \\{cur\_name} to desired file name}\6
+\&{if} ${}(\\{cur\_ext}\E\\{empty\_string}){}$\1\5
+${}\\{cur\_ext}\K\X1637:\.{".tex"}\X;{}$\2\6
+\\{pack\_cur\_name};\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{begin\_file\_reading}(\,);\C{set up \\{cur\_file} and new level of input}\6
+\&{if} ${}(\\{a\_open\_in}({\AND}\\{cur\_file})){}$\1\5
+\&{goto} \\{done};\2\6
+\&{if} ${}(\\{cur\_area}\E\\{empty\_string}){}$\5
+${}\{{}$\5
+\1${}\\{pack\_file\_name}(\\{cur\_name},\39\\{TEX\_area},\39\\{cur\_ext});{}$\6
+\&{if} ${}(\\{a\_open\_in}({\AND}\\{cur\_file})){}$\1\5
+\&{goto} \\{done};\2\6
+\4${}\}{}$\2\6
+\\{end\_file\_reading}(\,);\C{remove the level that didn't work}\6
+${}\\{prompt\_file\_name}(\.{"input\ file\ name"},\39\X1637:\.{".tex"}\X);{}$\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+${}\\{name}\K\\{a\_make\_name\_string}({\AND}\\{cur\_file});{}$\6
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{job\_name}\K\\{cur\_name};{}$\5
+\\{open\_log\_file}(\,);\6
+\4${}\}{}$\C{\\{open\_log\_file} doesn't \\{show\_context}, so \\{limit} and \\{loc} needn't be set to meaningful values yet}\2\6
+\&{if} ${}(\\{term\_offset}+\\{length}(\\{name})>\\{max\_print\_line}-\T{2}){}$\1\5
+\\{print\_ln}(\,);\2\6
+\&{else} \&{if} ${}((\\{term\_offset}>\T{0})\V(\\{file\_offset}>\T{0})){}$\1\5
+\\{print\_char}(\.{'\ '});\2\6
+\\{print\_char}(\.{'('});\5
+\\{incr}(\\{open\_parens});\5
+\\{slow\_print}(\\{name});\5
+\\{update\_terminal};\5
+${}\\{state}\K\\{new\_line};{}$\6
+\&{if} ${}(\\{name}\E\\{str\_ptr}-\T{1}{}$)\C{we can conserve string pool space now}\6
+${}\{{}$\5
+\1\\{flush\_string};\5
+${}\\{name}\K\\{cur\_name};{}$\6
+\4${}\}{}$\2\6
+\X538:Read the first line of the new file\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{538}Here we have to remember to tell the \\{input\_ln} routine not to
+start with a \\{get}. If the file is empty, it is considered to
+contain a single blank line.
+
+\Y\B\4\X538:Read the first line of the new file\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{line}\K\T{1};{}$\6
+\&{if} ${}(\\{input\_ln}({\AND}\\{cur\_file},\39\\{false})){}$\1\5
+\\{do\_nothing};\2\6
+\\{firm\_up\_the\_line}(\,);\6
+\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{decr}(\\{limit});\2\6
+\&{else}\1\5
+${}\\{buffer}[\\{limit}]\K\\{end\_line\_char};{}$\2\6
+${}\\{first}\K\\{limit}+\T{1};{}$\5
+${}\\{loc}\K\\{start};{}$\6
+\4${}\}{}$\2\par
+\U537.\fi
+
+\N{1}{539}Font metric data.
+\TeX\ gets its knowledge about fonts from font metric files, also called
+\.{TFM} files; the `\.T' in `\.{TFM}' stands for \TeX,
+but other programs know about them too.
+
+The information in a \.{TFM} file appears in a sequence of 8-bit bytes.
+Since the number of bytes is always a multiple of 4, we could
+also regard the file as a sequence of 32-bit words, but \TeX\ uses the
+byte interpretation. The format of \.{TFM} files was designed by
+Lyle Ramshaw in 1980. The intent is to convey a lot of different kinds
+of information in a compact but useful form.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{byte\_file} \\{tfm\_file};\par
+\fi
+
+\M{540}The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
+integers that give the lengths of the various subsequent portions
+of the file. These twelve integers are, in order:
+$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr
+\\{lf}&length of the entire file, in words;\cr
+\\{lh}&length of the header data, in words;\cr
+\\{bc}&smallest character code in the font;\cr
+\\{ec}&largest character code in the font;\cr
+\\{nw}&number of words in the width table;\cr
+\\{nh}&number of words in the height table;\cr
+\\{nd}&number of words in the depth table;\cr
+\\{ni}&number of words in the italic correction table;\cr
+\\{nl}&number of words in the lig/kern table;\cr
+\\{nk}&number of words in the kern table;\cr
+\\{ne}&number of words in the extensible character table;\cr
+\\{np}&number of font parameter words.\cr}}$$
+They are all nonnegative and less than $2^{15}$. We must have $\\{bc}-\T{1}\Z\\{ec}\Z\T{255}$,
+and
+$$\hbox{$\\{lf}\E\T{6}+\\{lh}+(\\{ec}-\\{bc}+\T{1})+\\{nw}+\\{nh}+\\{nd}+\\{ni}+\\{nl}+\\{nk}+\\{ne}+\\{np}$.}$$
+Note that a font may contain as many as 256 characters (if $\\{bc}\E\T{0}$ and $\\{ec}\E\T{255}$),
+and as few as 0 characters (if $\\{bc}\E\\{ec}+\T{1}$).
+
+Incidentally, when two or more 8-bit bytes are combined to form an integer of
+16 or more bits, the most significant bytes appear first in the file.
+This is called BigEndian order.
+
+\fi
+
+\M{541}The rest of the \.{TFM} file may be regarded as a sequence of ten data
+arrays having the informal specification
+$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
+\def\PB#1{\arr#1}
+\vbox{\halign{\hfil\\{#}&$\,:\,$#\hfil\cr
+header&$[\T{0}\dotdot\\{lh}-\T{1}]\hbox{\\{stuff}}$\cr
+char\_info&$[\\{bc}\dotdot\\{ec}]\\{char\_info\_word}$\cr
+width&$[\T{0}\dotdot\\{nw}-\T{1}]\\{fix\_word}$\cr
+height&$[\T{0}\dotdot\\{nh}-\T{1}]\\{fix\_word}$\cr
+depth&$[\T{0}\dotdot\\{nd}-\T{1}]\\{fix\_word}$\cr
+italic&$[\T{0}\dotdot\\{ni}-\T{1}]\\{fix\_word}$\cr
+lig\_kern&$[\T{0}\dotdot\\{nl}-\T{1}]\\{lig\_kern\_command}$\cr
+kern&$[\T{0}\dotdot\\{nk}-\T{1}]\\{fix\_word}$\cr
+exten&$[\T{0}\dotdot\\{ne}-\T{1}]\\{extensible\_recipe}$\cr
+param&$[\T{1}\dotdot\\{np}]\\{fix\_word}$\cr}}$$
+The most important data type used here is a \\{fix\_word}, which is
+a 32-bit representation of a binary fraction. A \\{fix\_word} is a signed
+quantity, with the two's complement of the entire word used to represent
+negation. Of the 32 bits in a \\{fix\_word}, exactly 12 are to the left of the
+binary point; thus, the largest \\{fix\_word} value is $2048-2^{-20}$, and
+the smallest is $-2048$. We will see below, however, that all but two of
+the \\{fix\_word} values must lie between $-16$ and $+16$.
+
+\fi
+
+\M{542}The first data array is a block of header information, which contains
+general facts about the font. The header must contain at least two words,
+\\{header}[\T{0}] and \\{header}[\T{1}], whose meaning is explained below.
+Additional header information of use to other software routines might
+also be included, but \TeX82 does not need to know about such details.
+For example, 16 more words of header information are in use at the Xerox
+Palo Alto Research Center; the first ten specify the character coding
+scheme used (e.g., `\.{XEROX text}' or `\.{TeX math symbols}'), the next five
+give the font identifier (e.g., `\.{HELVETICA}' or `\.{CMSY}'), and the
+last gives the ``face byte.'' The program that converts \.{DVI} files
+to Xerox printing format gets this information by looking at the \.{TFM}
+file, which it needs to read anyway because of other information that
+is not explicitly repeated in \.{DVI}~format.
+
+\yskip\hang\\{header}[\T{0}] is a 32-bit check sum that \TeX\ will copy into
+the \.{DVI} output file. Later on when the \.{DVI} file is printed,
+possibly on another computer, the actual font that gets used is supposed
+to have a check sum that agrees with the one in the \.{TFM} file used by
+\TeX. In this way, users will be warned about potential incompatibilities.
+(However, if the check sum is zero in either the font file or the \.{TFM}
+file, no check is made.) The actual relation between this check sum and
+the rest of the \.{TFM} file is not important; the check sum is simply an
+identification number with the property that incompatible fonts almost
+always have distinct check sums.
+
+\yskip\hang\\{header}[\T{1}] is a \\{fix\_word} containing the design size of
+the font, in units of \TeX\ points. This number must be at least 1.0; it is
+fairly arbitrary, but usually the design size is 10.0 for a ``10 point''
+font, i.e., a font that was designed to look best at a 10-point size,
+whatever that really means. When a \TeX\ user asks for a font
+`\.{at} $\delta$ \.{pt}', the effect is to override the design size
+and replace it by $\delta$, and to multiply the $x$ and~$y$ coordinates
+of the points in the font image by a factor of $\delta$ divided by the
+design size. {\sl All other dimensions in the\/ \.{TFM} file are
+\\{fix\_word}\kern-1pt\ numbers in design-size units}, with the exception of
+\\{param}[\T{1}] (which denotes the slant ratio). Thus, for example, the value
+of \\{param}[\T{6}], which defines the \.{em} unit, is often the \\{fix\_word} value
+$2^{20}=1.0$, since many fonts have a design size equal to one em.
+The other dimensions must be less than 16 design-size units in absolute
+value; thus, \\{header}[\T{1}] and \\{param}[\T{1}] are the only \\{fix\_word}
+entries in the whole \.{TFM} file whose first byte might be something
+besides 0 or 255.
+
+\fi
+
+\M{543}Next comes the \\{char\_info} array, which contains one \\{char\_info\_word}
+per character. Each word in this part of the file contains six fields
+packed into four bytes as follows.
+
+\yskip\hang first byte: \\{width\_index} (8 bits)\par
+\hang second byte: \\{height\_index} (4 bits) times 16, plus \\{depth\_index}
+(4~bits)\par
+\hang third byte: \\{italic\_index} (6 bits) times 4, plus \\{tag}
+(2~bits)\par
+\hang fourth byte: \\{rem} (8 bits)\par
+\yskip\noindent
+The actual width of a character is \\{width}[\\{width\_index}], in design-size
+units; this is a device for compressing information, since many characters
+have the same width. Since it is quite common for many characters
+to have the same height, depth, or italic correction, the \.{TFM} format
+imposes a limit of 16 different heights, 16 different depths, and
+64 different italic corrections.
+
+The italic correction of a character has two different uses.
+(a)~In ordinary text, the italic correction is added to the width only if
+the \TeX\ user specifies `\.{\\/}' after the character.
+(b)~In math formulas, the italic correction is always added to the width,
+except with respect to the positioning of subscripts.
+
+Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]=
+\\{italic}[0]=0$ should always hold, so that an index of zero implies a
+value of zero. The \\{width\_index} should never be zero unless the
+character does not exist in the font, since a character is valid if and
+only if it lies between \\{bc} and \\{ec} and has a nonzero \\{width\_index}.
+
+\fi
+
+\M{544}The \\{tag} field in a \\{char\_info\_word} has four values that explain how to
+interpret the \\{rem} field.
+
+\yskip\hangg$\\{tag}\E\T{0}$ (\\{no\_tag}) means that \\{rem} is unused.\par
+\hangg$\\{tag}\E\T{1}$ (\\{lig\_tag}) means that this character has a ligature/kerning
+program starting at position \\{rem} in the \\{lig\_kern} array.\par
+\hangg$\\{tag}\E\T{2}$ (\\{list\_tag}) means that this character is part of a chain of
+characters of ascending sizes, and not the largest in the chain. The
+\\{rem} field gives the character code of the next larger character.\par
+\hangg$\\{tag}\E\T{3}$ (\\{ext\_tag}) means that this character code represents an
+extensible character, i.e., a character that is built up of smaller pieces
+so that it can be made arbitrarily large. The pieces are specified in
+\\{exten}[\\{rem}].\par
+\yskip\noindent
+Characters with $\\{tag}\E\T{2}$ and $\\{tag}\E\T{3}$ are treated as characters with $\\{tag}\E\T{0}$
+unless they are used in special circumstances in math formulas. For example,
+the \.{\\sum} operation looks for a \\{list\_tag}, and the \.{\\left}
+operation looks for both \\{list\_tag} and \\{ext\_tag}.
+
+\Y\B\4\D$\\{no\_tag}$ \5
+\T{0}\C{vanilla character}\par
+\B\4\D$\\{lig\_tag}$ \5
+\T{1}\C{character has a ligature/kerning program}\par
+\B\4\D$\\{list\_tag}$ \5
+\T{2}\C{character has a successor in a charlist}\par
+\B\4\D$\\{ext\_tag}$ \5
+\T{3}\C{character is extensible}\par
+\fi
+
+\M{545}The \\{lig\_kern} array contains instructions in a simple programming language
+that explains what to do for special letter pairs. Each word in this array is a
+\\{lig\_kern\_command} of four bytes.
+
+\yskip\hang first byte: \\{skip\_byte}, indicates that this is the final program
+step if the byte is 128 or more, otherwise the next step is obtained by
+skipping this number of intervening steps.\par
+\hang second byte: \\{next\_char}, ``if \\{next\_char} follows the current character,
+then perform the operation and stop, otherwise continue.''\par
+\hang third byte: \\{op\_byte}, indicates a ligature step if less than~128,
+a kern step otherwise.\par
+\hang fourth byte: \\{rem}.\par
+\yskip\noindent
+In a kern step, an
+additional space equal to $\\{kern}[\T{256}*(\\{op\_byte}-\T{128})+\\{rem}]$ is inserted
+between the current character and \\{next\_char}. This amount is
+often negative, so that the characters are brought closer together
+by kerning; but it might be positive.
+
+There are eight kinds of ligature steps, having \\{op\_byte} codes $4a+2b+c$ where
+$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is
+\\{rem} is inserted between the current character and \\{next\_char};
+then the current character is deleted if $b=0$, and \\{next\_char} is
+deleted if $c=0$; then we pass over $a$~characters to reach the next
+current character (which may have a ligature/kerning program of its own).
+
+If the very first instruction of the \\{lig\_kern} array has $\\{skip\_byte}\E\T{255}$,
+the \\{next\_char} byte is the so-called right boundary character of this font;
+the value of \\{next\_char} need not lie between \\{bc} and~\\{ec}.
+If the very last instruction of the \\{lig\_kern} array has $\\{skip\_byte}\E\T{255}$,
+there is a special ligature/kerning program for a left boundary character,
+beginning at location $\T{256}*\\{op\_byte}+\\{rem}$.
+The interpretation is that \TeX\ puts implicit boundary characters
+before and after each consecutive string of characters from the same font.
+These implicit characters do not appear in the output, but they can affect
+ligatures and kerning.
+
+If the very first instruction of a character's \\{lig\_kern} program has
+$\\{skip\_byte}>\T{128}$, the program actually begins in location
+$\T{256}*\\{op\_byte}+\\{rem}$. This feature allows access to large \\{lig\_kern}
+arrays, because the first instruction must otherwise
+appear in a location $\Z$ \T{255}.
+
+Any instruction with $\\{skip\_byte}>\T{128}$ in the \\{lig\_kern} array must satisfy
+the condition
+$$\hbox{$\T{256}*\\{op\_byte}+\\{rem}<\\{nl}$.}$$
+If such an instruction is encountered during
+normal program execution, it denotes an unconditional halt; no ligature
+or kerning command is performed.
+
+\Y\B\4\D$\\{stop\_flag}$ \5
+\\{qi}(\T{128})\C{value indicating `\.{STOP}' in a lig/kern program}\par
+\B\4\D$\\{kern\_flag}$ \5
+\\{qi}(\T{128})\C{op code for a kern step}\par
+\B\4\D$\\{skip\_byte}(\|X)$ \5
+$\|X.{}$\\{b0}\par
+\B\4\D$\\{next\_char}(\|X)$ \5
+$\|X.{}$\\{b1}\par
+\B\4\D$\\{op\_byte}(\|X)$ \5
+$\|X.{}$\\{b2}\par
+\B\4\D$\\{rem\_byte}(\|X)$ \5
+$\|X.{}$\\{b3}\par
+\fi
+
+\M{546}Extensible characters are specified by an \\{extensible\_recipe}, which
+consists of four bytes called \\{top}, \\{mid}, \\{bot}, and \\{rep} (in this
+order). These bytes are the character codes of individual pieces used to
+build up a large symbol. If \\{top}, \\{mid}, or \\{bot} are zero, they are not
+present in the built-up result. For example, an extensible vertical line is
+like an extensible bracket, except that the top and bottom pieces are missing.
+
+Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box
+if the piece isn't present. Then the extensible characters have the form
+$TR^kMR^kB$ from top to bottom, for some $\|k\G\T{0}$, unless $M$ is absent;
+in the latter case we can have $TR^kB$ for both even and odd values of~\|k.
+The width of the extensible character is the width of $R$; and the
+height-plus-depth is the sum of the individual height-plus-depths of the
+components used, since the pieces are butted together in a vertical list.
+
+\Y\B\4\D$\\{ext\_top}(\|X)$ \5
+$\|X.{}$\\{b0}\C{\\{top} piece in a recipe}\par
+\B\4\D$\\{ext\_mid}(\|X)$ \5
+$\|X.{}$\\{b1}\C{\\{mid} piece in a recipe}\par
+\B\4\D$\\{ext\_bot}(\|X)$ \5
+$\|X.{}$\\{b2}\C{\\{bot} piece in a recipe}\par
+\B\4\D$\\{ext\_rep}(\|X)$ \5
+$\|X.{}$\\{b3}\C{\\{rep} piece in a recipe}\par
+\fi
+
+\M{547}The final portion of a \.{TFM} file is the \\{param} array, which is another
+sequence of \\{fix\_word} values.
+
+\yskip\hang$\\{param}[\T{1}]\E\\{slant}$ is the amount of italic slant, which is used
+to help position accents. For example, $\\{slant}\E\T{.25}$ means that when you go
+up one unit, you also go .25 units to the right. The \\{slant} is a pure
+number; it's the only \\{fix\_word} other than the design size itself that is
+not scaled by the design size.
+
+\hang$\\{param}[\T{2}]\E\\{space}$ is the normal spacing between words in text.
+Note that character \.{'\ '} in the font need not have anything to do with
+blank spaces.
+
+\hang$\\{param}[\T{3}]\E\\{space\_stretch}$ is the amount of glue stretching between words.
+
+\hang$\\{param}[\T{4}]\E\\{space\_shrink}$ is the amount of glue shrinking between words.
+
+\hang$\\{param}[\T{5}]\E\\{x\_height}$ is the size of one ex in the font; it is also
+the height of letters for which accents don't have to be raised or lowered.
+
+\hang$\\{param}[\T{6}]\E\\{quad}$ is the size of one em in the font.
+
+\hang$\\{param}[\T{7}]\E\\{extra\_space}$ is the amount added to \\{param}[\T{2}] at the
+ends of sentences.
+
+\yskip\noindent
+If fewer than seven parameters are present, \TeX\ sets the missing parameters
+to zero. Fonts used for math symbols are required to have
+additional parameter information, which is explained later.
+
+\Y\B\4\D$\\{slant\_code}$ \5
+\T{1}\par
+\B\4\D$\\{space\_code}$ \5
+\T{2}\par
+\B\4\D$\\{space\_stretch\_code}$ \5
+\T{3}\par
+\B\4\D$\\{space\_shrink\_code}$ \5
+\T{4}\par
+\B\4\D$\\{x\_height\_code}$ \5
+\T{5}\par
+\B\4\D$\\{quad\_code}$ \5
+\T{6}\par
+\B\4\D$\\{extra\_space\_code}$ \5
+\T{7}\par
+\fi
+
+\M{548}So that is what \.{TFM} files hold. Since \TeX\ has to absorb such information
+about lots of fonts, it stores most of the data in a large array called
+\\{font\_info}. Each item of \\{font\_info} is a \&{memory\_word}; the \\{fix\_word}
+data gets converted into \&{scaled} entries, while everything else goes into
+words of type \&{four\_quarters}.
+
+When the user defines \.{\\font\\f}, say, \TeX\ assigns an internal number
+to the user's font~\.{\\f}. Adding this number to \\{font\_id\_base} gives the
+\\{eqtb} location of a ``frozen'' control sequence that will always select
+the font.
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint8\_t} \&{internal\_font\_number};\C{\\{font} in a \\{char\_node}}\6
+\&{typedef} \&{uint16\_t} \&{font\_index};\C{index into \\{font\_info}}\par
+\fi
+
+\M{549}Here now is the (rather formidable) array of font arrays.
+
+\Y\B\4\D$\\{non\_char}$ \5
+\\{qi}(\T{256})\C{a \&{halfword} code that can't match a real character}\par
+\B\4\D$\\{non\_address}$ \5
+\T{0}\C{a spurious \\{bchar\_label}}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{memory\_word} ${}\\{font\_info}[\\{font\_mem\_size}+\T{1}]{}$;\C{the big collection of font data}\6
+\&{font\_index} \\{fmem\_ptr};\C{first unused word of \\{font\_info}}\6
+\&{internal\_font\_number} \\{font\_ptr};\C{largest internal font number in use}\6
+\&{four\_quarters} ${}\\{font\_check0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_check}\K\\{font\_check0}-\\{font\_base}{}$;\C{check sum}\6
+\&{scaled} ${}\\{font\_size0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_size}\K\\{font\_size0}-\\{font\_base}{}$;\C{``at'' size}\6
+\&{scaled} ${}\\{font\_dsize0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_dsize}\K\\{font\_dsize0}-\\{font\_base}{}$;\C{``design'' size}\6
+\&{font\_index} ${}\\{font\_params0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_params}\K\\{font\_params0}-\\{font\_base}{}$;\C{how many font parameters are present}\6
+\&{str\_number} ${}\\{font\_name0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_name}\K\\{font\_name0}-\\{font\_base}{}$;\C{name of the font}\6
+\&{str\_number} ${}\\{font\_area0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_area}\K\\{font\_area0}-\\{font\_base}{}$;\C{area of the font}\6
+\&{eight\_bits} ${}\\{font\_bc0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_bc}\K\\{font\_bc0}-\\{font\_base}{}$;\C{beginning (smallest) character code}\6
+\&{eight\_bits} ${}\\{font\_ec0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_ec}\K\\{font\_ec0}-\\{font\_base}{}$;\C{ending (largest) character code}\6
+\&{pointer} ${}\\{font\_glue0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_glue}\K\\{font\_glue0}-\\{font\_base}{}$;\C{glue specification for interword space, \\{null} if not allocated}\6
+\&{bool} ${}\\{font\_used0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_used}\K\\{font\_used0}-\\{font\_base}{}$;\C{has a character from this font actually appeared in the output?}\6
+\&{int} ${}\\{hyphen\_char0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{hyphen\_char}\K\\{hyphen\_char0}-\\{font\_base}{}$;\C{current \.{\\hyphenchar} values}\6
+\&{int} ${}\\{skew\_char0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{skew\_char}\K\\{skew\_char0}-\\{font\_base}{}$;\C{current \.{\\skewchar} values}\6
+\&{font\_index} ${}\\{bchar\_label0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{bchar\_label}\K\\{bchar\_label0}-\\{font\_base}{}$;\C{start of \\{lig\_kern} program for left boundary character, \\{non\_address} if there is none}\6
+\&{uint16\_t} ${}\\{font\_bchar0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_bchar}\K\\{font\_bchar0}-\\{font\_base}{}$;\C{right boundary character, \\{non\_char} if there is none}\6
+\&{uint16\_t} ${}\\{font\_false\_bchar0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{font\_false\_bchar}\K\\{font\_false\_bchar0}-\\{font\_base}{}$;\C{\\{font\_bchar} if it doesn't exist in the font, otherwise \\{non\_char}}\par
+\fi
+
+\M{550}Besides the arrays just enumerated, we have directory arrays that make it
+easy to get at the individual entries in \\{font\_info}. For example, the
+\\{char\_info} data for character \|c in font \|f will be in
+$\\{font\_info}[\\{char\_base}[\|f]+\|c].\\{qqqq}$; and if \|w is the \\{width\_index}
+part of this word (the \\{b0} field), the width of the character is
+$\\{font\_info}[\\{width\_base}[\|f]+\|w].\\{sc}$. (These formulas assume that
+\\{min\_quarterword} has already been added to \|c and to \|w, since \TeX\
+stores its quarterwords that way.)
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} ${}\\{char\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{char\_base}\K\\{char\_base0}-\\{font\_base}{}$;\C{base addresses for \\{char\_info}}\6
+\&{int} ${}\\{width\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{width\_base}\K\\{width\_base0}-\\{font\_base}{}$;\C{base addresses for widths}\6
+\&{int} ${}\\{height\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{height\_base}\K\\{height\_base0}-\\{font\_base}{}$;\C{base addresses for heights}\6
+\&{int} ${}\\{depth\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{depth\_base}\K\\{depth\_base0}-\\{font\_base}{}$;\C{base addresses for depths}\6
+\&{int} ${}\\{italic\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{italic\_base}\K\\{italic\_base0}-\\{font\_base}{}$;\C{base addresses for italic corrections}\6
+\&{int} ${}\\{lig\_kern\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{lig\_kern\_base}\K\\{lig\_kern\_base0}-\\{font\_base}{}$;\C{base addresses for ligature/kerning programs}\6
+\&{int} ${}\\{kern\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{kern\_base}\K\\{kern\_base0}-\\{font\_base}{}$;\C{base addresses for kerns}\6
+\&{int} ${}\\{exten\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{exten\_base}\K\\{exten\_base0}-\\{font\_base}{}$;\C{base addresses for extensible recipes}\6
+\&{int} ${}\\{param\_base0}[\\{font\_max}-\\{font\_base}+\T{1}],{}$ ${}{*\&{const}\ }\\{param\_base}\K\\{param\_base0}-\\{font\_base}{}$;\C{base addresses for font parameters}\par
+\fi
+
+\M{551}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\\{font\_base};{}$ ${}\|k\Z\\{font\_max};{}$ ${}\|k\PP){}$\1\5
+${}\\{font\_used}[\|k]\K\\{false}{}$;\2\par
+\fi
+
+\M{552}\TeX\ always knows at least one font, namely the null font. It has no
+characters, and its seven parameters are all equal to zero.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{font\_ptr}\K\\{null\_font};{}$\5
+${}\\{fmem\_ptr}\K\T{7};{}$\5
+${}\\{font\_name}[\\{null\_font}]\K\X1639:\.{"nullfont"}\X;{}$\5
+${}\\{font\_area}[\\{null\_font}]\K\\{empty\_string};{}$\5
+${}\\{hyphen\_char}[\\{null\_font}]\K\.{'-'};{}$\5
+${}\\{skew\_char}[\\{null\_font}]\K{-}\T{1};{}$\5
+${}\\{bchar\_label}[\\{null\_font}]\K\\{non\_address};{}$\5
+${}\\{font\_bchar}[\\{null\_font}]\K\\{non\_char};{}$\5
+${}\\{font\_false\_bchar}[\\{null\_font}]\K\\{non\_char};{}$\5
+${}\\{font\_bc}[\\{null\_font}]\K\T{1};{}$\5
+${}\\{font\_ec}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{font\_size}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{font\_dsize}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{char\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{width\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{height\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{depth\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{italic\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{lig\_kern\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{kern\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{exten\_base}[\\{null\_font}]\K\T{0};{}$\5
+${}\\{font\_glue}[\\{null\_font}]\K\\{null};{}$\5
+${}\\{font\_params}[\\{null\_font}]\K\T{7};{}$\5
+${}\\{param\_base}[\\{null\_font}]\K{-}\T{1};{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{6};{}$ ${}\|k\PP){}$\1\5
+${}\\{font\_info}[\|k].\\{sc}\K\T{0}{}$;\2\par
+\fi
+
+\M{553}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1639:\.{"nullfont"}\X,\39\\{set\_font},\39\\{null\_font});{}$\5
+${}\\{text}(\\{frozen\_null\_font})\K\X1639:\.{"nullfont"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_null\_font}]\K\\{eqtb}[\\{cur\_val}]{}$;\par
+\fi
+
+\M{554}Of course we want to define macros that suppress the detail of how font
+information is actually packed, so that we don't have to write things like
+$$\hbox{$\\{font\_info}[\\{width\_base}[\|f]+\\{font\_info}[\\{char\_base}[\|f]+\|c].\\{qqqq}.\\{b0}].\\{sc}$}$$
+too often. The \.{WEB} definitions here make \\{char\_info}(\|f)(\|c) the
+\&{four\_quarters} word of font information corresponding to character
+\|c of font \|f. If \|q is such a word, \\{char\_width}(\|f)(\|q) will be
+the character's width; hence the long formula above is at least
+abbreviated to
+$$\hbox{\\{char\_width}(\|f)(\\{char\_info}(\|f)(\|c)).}$$
+Usually, of course, we will fetch \|q first and look at several of its
+fields at the same time.
+
+The italic correction of a character will be denoted by
+\\{char\_italic}(\|f)(\|q), so it is analogous to \\{char\_width}. But we will get
+at the height and depth in a slightly different way, since we usually want
+to compute both height and depth if we want either one. The value of
+\\{height\_depth}(\|q) will be the 8-bit quantity
+$$b=\\{height\_index}\times16+\\{depth\_index},$$ and if \|b is such a byte we
+will write \\{char\_height}(\|f)(\|b) and \\{char\_depth}(\|f)(\|b) for the height and
+depth of the character \|c for which $\|q\E\\{char\_info}(\|f)(\|c)$. Got that?
+
+The tag field will be called \\{char\_tag}(\|q); the remainder byte will be
+called \\{rem\_byte}(\|q), using a macro that we have already defined above.
+
+Access to a character's \\{width}, \\{height}, \\{depth}, and \\{tag} fields is
+part of \TeX's inner loop, so we want these macros to produce code that is
+as fast as possible under the circumstances.
+
+\Y\B\4\D$\\{char\_info\_end}(\|X)$ \5
+\|X ] $.$ \\{qqqq}\par
+\B\4\D$\\{char\_info}(\|X)$ \5
+\\{font\_info} [ $\\{char\_base}[\|X]+{}$\\{char\_info\_end}\par
+\B\4\D$\\{char\_width\_end}(\|X)$ \5
+$\|X.\\{b0}$ ] $.$ \\{sc}\par
+\B\4\D$\\{char\_width}(\|X)$ \5
+\\{font\_info} [ $\\{width\_base}[\|X]+{}$\\{char\_width\_end}\par
+\B\4\D$\\{char\_exists}(\|X)$ \5
+$(\|X.\\{b0}>\\{min\_quarterword}{}$)\par
+\B\4\D$\\{char\_italic\_end}(\|X)$ \5
+$(\\{qo}(\|X.\\{b2}))/\T{4}$ ] $.$ \\{sc}\par
+\B\4\D$\\{char\_italic}(\|X)$ \5
+\\{font\_info} [ $\\{italic\_base}[\|X]+{}$\\{char\_italic\_end}\par
+\B\4\D$\\{height\_depth}(\|X)$ \5
+$\\{qo}(\|X.\\{b1}{}$)\par
+\B\4\D$\\{char\_height\_end}(\|X)$ \5
+$(\|X)/\T{16}$ ] $.$ \\{sc}\par
+\B\4\D$\\{char\_height}(\|X)$ \5
+\\{font\_info} [ $\\{height\_base}[\|X]+{}$\\{char\_height\_end}\par
+\B\4\D$\\{char\_depth\_end}(\|X)$ \5
+$(\|X)\MOD\T{16}$ ] $.$ \\{sc}\par
+\B\4\D$\\{char\_depth}(\|X)$ \5
+\\{font\_info} [ $\\{depth\_base}[\|X]+{}$\\{char\_depth\_end}\par
+\B\4\D$\\{char\_tag}(\|X)$ \5
+$((\\{qo}(\|X.\\{b2}))\MOD\T{4}{}$)\par
+\fi
+
+\M{555}The global variable \\{null\_character} is set up to be a word of
+\\{char\_info} for a character that doesn't exist. Such a word provides a
+convenient way to deal with erroneous situations.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{four\_quarters} \\{null\_character};\C{nonexistent character information}\par
+\fi
+
+\M{556}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{null\_character}.\\{b0}\K\\{min\_quarterword};{}$\5
+${}\\{null\_character}.\\{b1}\K\\{min\_quarterword};{}$\5
+${}\\{null\_character}.\\{b2}\K\\{min\_quarterword};{}$\5
+${}\\{null\_character}.\\{b3}\K\\{min\_quarterword}{}$;\par
+\fi
+
+\M{557}Here are some macros that help process ligatures and kerns.
+We write \\{char\_kern}(\|f)(\|j) to find the amount of kerning specified by
+kerning command~\|j in font~\|f. If \|j is the \\{char\_info} for a character
+with a ligature/kern program, the first instruction of that program is either
+$\|i\E\\{font\_info}[\\{lig\_kern\_start}(\|f)(\|j)]$ or \\{font\_info}[\\{lig\_kern\_restart}(\|f)(\|i)],
+depending on whether or not $\\{skip\_byte}(\|i)\Z\\{stop\_flag}$.
+
+The constant \\{kern\_base\_offset} should be simplified, for \PASCAL\ compilers
+that do not do local optimization.
+
+\Y\B\4\D$\\{char\_kern\_end}(\|X)$ \5
+$\T{256}*\\{op\_byte}(\|X)+\\{rem\_byte}(\|X)$ ] $.$ \\{sc}\par
+\B\4\D$\\{char\_kern}(\|X)$ \5
+\\{font\_info} [ $\\{kern\_base}[\|X]+{}$\\{char\_kern\_end}\par
+\B\4\D$\\{kern\_base\_offset}$ \5
+$\T{256}*(\T{128}+\\{min\_quarterword}{}$)\par
+\B\4\D$\\{lig\_kern\_start}(\|X)$ \5
+$\\{lig\_kern\_base}[\|X]+{}$\\{rem\_byte}\C{beginning of lig/kern program}\par
+\B\4\D$\\{lig\_kern\_restart\_end}(\|X)$ \5
+$\T{256}*\\{op\_byte}(\|X)+\\{rem\_byte}(\|X)+\T{32768}-{}$\\{kern\_base\_offset}\par
+\B\4\D$\\{lig\_kern\_restart}(\|X)$ \5
+$\\{lig\_kern\_base}[\|X]+{}$\\{lig\_kern\_restart\_end}\par
+\fi
+
+\M{558}Font parameters are referred to as \\{slant}(\|f), \\{space}(\|f), etc.
+
+\Y\B\4\D$\\{param\_end}(\|X)$ \5
+\\{param\_base}[\|X] ] $.$ \\{sc}\par
+\B\4\D$\\{param}(\|X)$ \5
+\\{font\_info} [ $\|X+{}$\\{param\_end}\par
+\B\4\D$\\{slant}$ \5
+\\{param}(\\{slant\_code})\C{slant to the right, per unit distance upward}\par
+\B\4\D$\\{space}$ \5
+\\{param}(\\{space\_code})\C{normal space between words}\par
+\B\4\D$\\{space\_stretch}$ \5
+\\{param}(\\{space\_stretch\_code})\C{stretch between words}\par
+\B\4\D$\\{space\_shrink}$ \5
+\\{param}(\\{space\_shrink\_code})\C{shrink between words}\par
+\B\4\D$\\{x\_height}$ \5
+\\{param}(\\{x\_height\_code})\C{one ex}\par
+\B\4\D$\\{quad}$ \5
+\\{param}(\\{quad\_code})\C{one em}\par
+\B\4\D$\\{extra\_space}$ \5
+\\{param}(\\{extra\_space\_code})\C{additional space at end of sentence}\par
+\Y\B\4\X558:The em width for \\{cur\_font}\X${}\E{}$\6
+\\{quad}(\\{cur\_font})\par
+\U455.\fi
+
+\M{559}\B\X559:The x-height for \\{cur\_font}\X${}\E{}$\6
+\\{x\_height}(\\{cur\_font})\par
+\U455.\fi
+
+\M{560}\TeX\ checks the information of a \.{TFM} file for validity as the
+file is being read in, so that no further checks will be needed when
+typesetting is going on. The somewhat tedious subroutine that does this
+is called \\{read\_font\_info}. It has four parameters: the user font
+identifier~\|u, the file name and area strings \\{nom} and \\{aire}, and the
+``at'' size~\|s. If \|s~is negative, it's the negative of a scale factor
+to be applied to the design size; $\|s\E{-}\T{1000}$ is the normal case.
+Otherwise \|s will be substituted for the design size; in this
+case, \|s must be positive and less than $2048\rm\,pt$
+(i.e., it must be less than $2^{27}$ when considered as an integer).
+
+The subroutine opens and closes a global file variable called \\{tfm\_file}.
+It returns the value of the internal font number that was just loaded.
+If an error is detected, an error message is issued and no font
+information is stored; \\{null\_font} is returned in this case.
+
+\Y\B\4\D$\\{abort}$ \5
+\&{goto} \\{bad\_tfm}\C{do this when the \.{TFM} data is wrong}\par
+\Y\B\&{internal\_font\_number} \\{read\_font\_info}(\&{pointer} \|u${},\39{}$\&{str\_number} \\{nom}${},\39{}$\&{str\_number} \\{aire}${},\39{}$\&{scaled} \|s)\C{input a \.{TFM} file}\6
+${}\{{}$\5
+\1\&{font\_index} \|k;\C{index into \\{font\_info}}\6
+\&{bool} \\{file\_opened};\C{was \\{tfm\_file} successfully opened?}\6
+\&{halfword} \\{lf}${},{}$ \\{lh}${},{}$ \\{bc}${},{}$ \\{ec}${},{}$ \\{nw}${},{}$ \\{nh}${},{}$ \\{nd}${},{}$ \\{ni}${},{}$ \\{nl}${},{}$ \\{nk}${},{}$ \\{ne}${},{}$ \\{np};\C{sizes of subfiles}\6
+\&{internal\_font\_number} \|f;\C{the new font's number}\6
+\&{internal\_font\_number} \|g;\C{the number to return}\6
+\&{eight\_bits} \|a${},{}$ \|b${},{}$ \|c${},{}$ \|d;\C{byte variables}\6
+\&{four\_quarters} \\{qw};\6
+\&{scaled} \\{sw};\C{accumulators}\6
+\&{int} \\{bch\_label};\C{left boundary start location, or infinity}\6
+\&{uint16\_t} \\{bchar};\C{right boundary character, or 256}\6
+\&{scaled} \|z;\C{the design size or the ``at'' size}\6
+\&{int} \\{alpha};\6
+\&{uint8\_t} \\{beta};\C{auxiliary quantities used in fixed-point multiplication}\7
+${}\|g\K\\{null\_font}{}$;\6
+\X562:Read and check the font data; \\{abort} if the \.{TFM} file is malformed; if there's no room for this font, say so and \&{goto} \\{done}; otherwise \\{incr}(\\{font\_ptr}) and \&{goto} \\{done}\X;\6
+\4\\{bad\_tfm}:\5
+\X561:Report that the font won't be loaded\X;\6
+\4\\{done}:\6
+\&{if} (\\{file\_opened})\1\5
+${}\\{b\_close}({\AND}\\{tfm\_file});{}$\2\6
+\&{return} \|g;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{561}There are programs called \.{TFtoPL} and \.{PLtoTF} that convert
+between the \.{TFM} format and a symbolic property-list format
+that can be easily edited. These programs contain extensive
+diagnostic information, so \TeX\ does not have to bother giving
+precise details about why it rejects a particular \.{TFM} file.
+
+\Y\B\4\D$\\{start\_font\_error\_message}$ \5
+\\{print\_err}(\.{"Font\ "});\5
+\\{sprint\_cs}(\|u);\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_file\_name}(\\{nom},\39\\{aire},\39\\{empty\_string});{}$\6
+\&{if} ${}(\|s\G\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ at\ "});\5
+\\{print\_scaled}(\|s);\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|s\I{-}\T{1000}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ scaled\ "});\5
+${}\\{print\_int}({-}\|s);{}$\6
+\4${}\}{}$\2\par
+\Y\B\4\X561:Report that the font won't be loaded\X${}\E{}$\6
+\\{start\_font\_error\_message};\6
+\&{if} (\\{file\_opened})\1\5
+\\{print\_str}(\.{"\ not\ loadable:\ Bad\ }\)\.{metric\ (TFM)\ file"});\2\6
+\&{else}\1\5
+\\{print\_str}(\.{"\ not\ loadable:\ Metr}\)\.{ic\ (TFM)\ file\ not\ fo}\)\.{und"});\2\6
+\\{help5}(\.{"I\ wasn't\ able\ to\ re}\)\.{ad\ the\ size\ data\ for}\)\.{\ this\ font,"})\6
+(\.{"so\ I\ will\ ignore\ th}\)\.{e\ font\ specification}\)\.{."})\6
+(\.{"[Wizards\ can\ fix\ TF}\)\.{M\ files\ using\ TFtoPL}\)\.{/PLtoTF.]"})\6
+(\.{"You\ might\ try\ inser}\)\.{ting\ a\ different\ fon}\)\.{t\ spec;"})\6
+(\.{"e.g.,\ type\ `I\\\\font}\)\.{<same\ font\ id>=<subs}\)\.{titute\ font\ name>'."}); \&{error} (\,)\par
+\U560.\fi
+
+\M{562}\B\X562:Read and check the font data; \\{abort} if the \.{TFM} file is malformed; if there's no room for this font, say so and \&{goto} \\{done}; otherwise \\{incr}(\\{font\_ptr}) and \&{goto} \\{done}\X${}\E{}$\6
+\X563:Open \\{tfm\_file} for input\X;\6
+\X565:Read the {\.{TFM}} size fields\X;\6
+\X566:Use size fields to allocate font information\X;\6
+\X568:Read the {\.{TFM}} header\X;\6
+\X569:Read character data\X;\6
+\X571:Read box dimensions\X;\6
+\X573:Read ligature/kern program\X;\6
+\X574:Read extensible character recipes\X;\6
+\X575:Read font parameters\X;\6
+\X576:Make final adjustments and \&{goto} \\{done}\X\par
+\U560.\fi
+
+\M{563}\B\X563:Open \\{tfm\_file} for input\X${}\E{}$\6
+$\\{file\_opened}\K\\{false};{}$\6
+\&{if} ${}(\\{aire}\E\\{empty\_string}){}$\1\5
+${}\\{pack\_file\_name}(\\{nom},\39\\{TEX\_font\_area},\39\X1640:\.{".tfm"}\X);{}$\2\6
+\&{else}\1\5
+${}\\{pack\_file\_name}(\\{nom},\39\\{aire},\39\X1640:\.{".tfm"}\X);{}$\2\6
+\&{if} ${}(\R\\{b\_open\_in}({\AND}\\{tfm\_file})){}$\1\5
+\\{abort};\2\6
+$\\{file\_opened}\K{}$\\{true}\par
+\U562.\fi
+
+\M{564}Note: A malformed \.{TFM} file might be shorter than it claims to be;
+thus \\{eof}(\\{tfm\_file}) might be true when \\{read\_font\_info} refers to
+$\\{tfm\_file}.\|d$ or when it says \\{get}(\\{tfm\_file}). If such circumstances
+cause system error messages, you will have to defeat them somehow,
+for example by defining \\{fget} to be `\ignorespaces$\{{}$ \\{get}(\\{tfm\_file});
+ \&{if} (\\{eof}(\\{tfm\_file})) \\{abort}; $\}$\unskip'.
+
+\Y\B\4\D$\\{fget}$ \5
+\\{get}(\\{tfm\_file})\par
+\B\4\D$\\{fbyte}$ \5
+$\\{tfm\_file}.{}$\|d\par
+\B\4\D$\\{read\_sixteen}(\|X)$ \6
+${}\{{}$\5
+\1${}\|X\K\\{fbyte};{}$\6
+\&{if} ${}(\|X>\T{127}){}$\1\5
+\\{abort};\2\6
+\\{fget};\5
+${}\|X\K\|X*\T{\~400}+\\{fbyte};{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{store\_four\_quarters}(\|X)$ \6
+${}\{{}$\5
+\1\\{fget};\5
+${}\|a\K\\{fbyte};{}$\5
+${}\\{qw}.\\{b0}\K\\{qi}(\|a);{}$\5
+\\{fget};\5
+${}\|b\K\\{fbyte};{}$\5
+${}\\{qw}.\\{b1}\K\\{qi}(\|b);{}$\5
+\\{fget};\5
+${}\|c\K\\{fbyte};{}$\5
+${}\\{qw}.\\{b2}\K\\{qi}(\|c);{}$\5
+\\{fget};\5
+${}\|d\K\\{fbyte};{}$\5
+${}\\{qw}.\\{b3}\K\\{qi}(\|d);{}$\5
+${}\|X\K\\{qw};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{565}\B\X565:Read the {\.{TFM}} size fields\X${}\E{}$\6
+${}\{{}$\5
+\1\\{read\_sixteen}(\\{lf});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{lh});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{bc});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{ec});\6
+\&{if} ${}((\\{bc}>\\{ec}+\T{1})\V(\\{ec}>\T{255})){}$\1\5
+\\{abort};\2\6
+\&{if} ${}(\\{bc}>\T{255}{}$)\C{$\\{bc}\E\T{256}$ and $\\{ec}\E\T{255}$}\6
+${}\{{}$\5
+\1${}\\{bc}\K\T{1};{}$\5
+${}\\{ec}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\\{fget};\5
+\\{read\_sixteen}(\\{nw});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{nh});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{nd});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{ni});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{nl});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{nk});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{ne});\5
+\\{fget};\5
+\\{read\_sixteen}(\\{np});\6
+\&{if} ${}(\\{lf}\I\T{6}+\\{lh}+(\\{ec}-\\{bc}+\T{1})+\\{nw}+\\{nh}+\\{nd}+\\{ni}+\\{nl}+\\{nk}+\\{ne}+\\{np}){}$\1\5
+\\{abort};\2\6
+\&{if} ${}((\\{nw}\E\T{0})\V(\\{nh}\E\T{0})\V(\\{nd}\E\T{0})\V(\\{ni}\E\T{0})){}$\1\5
+\\{abort};\2\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{566}The preliminary settings of the index-offset variables \\{char\_base},
+\\{width\_base}, \\{lig\_kern\_base}, \\{kern\_base}, and \\{exten\_base} will be
+corrected later by subtracting \\{min\_quarterword} from them; and we will
+subtract 1 from \\{param\_base} too. It's best to forget about such anomalies
+until later.
+
+\Y\B\4\X566:Use size fields to allocate font information\X${}\E{}$\6
+$\\{lf}\K\\{lf}-\T{6}-\\{lh}{}$;\C{\\{lf} words should be loaded into \\{font\_info}}\6
+\&{if} ${}(\\{np}<\T{7}){}$\1\5
+${}\\{lf}\K\\{lf}+\T{7}-\\{np}{}$;\C{at least seven parameters will appear}\2\6
+\&{if} ${}((\\{font\_ptr}\E\\{font\_max})\V(\\{fmem\_ptr}+\\{lf}>\\{font\_mem\_size})){}$\1\5
+\X567:Apologize for not loading the font, \&{goto} \\{done}\X;\2\6
+${}\|f\K\\{font\_ptr}+\T{1};{}$\5
+${}\\{char\_base}[\|f]\K\\{fmem\_ptr}-\\{bc};{}$\5
+${}\\{width\_base}[\|f]\K\\{char\_base}[\|f]+\\{ec}+\T{1};{}$\5
+${}\\{height\_base}[\|f]\K\\{width\_base}[\|f]+\\{nw};{}$\5
+${}\\{depth\_base}[\|f]\K\\{height\_base}[\|f]+\\{nh};{}$\5
+${}\\{italic\_base}[\|f]\K\\{depth\_base}[\|f]+\\{nd};{}$\5
+${}\\{lig\_kern\_base}[\|f]\K\\{italic\_base}[\|f]+\\{ni};{}$\5
+${}\\{kern\_base}[\|f]\K\\{lig\_kern\_base}[\|f]+\\{nl}-\\{kern\_base\_offset};{}$\5
+${}\\{exten\_base}[\|f]\K\\{kern\_base}[\|f]+\\{kern\_base\_offset}+\\{nk};$ $\\{param\_base}[\|f]\K\\{exten\_base}[\|f]+{}$\\{ne}\par
+\U562.\fi
+
+\M{567}\B\X567:Apologize for not loading the font, \&{goto} \\{done}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{start\_font\_error\_message};\5
+\\{print\_str}(\.{"\ not\ loaded:\ Not\ en}\)\.{ough\ room\ left"});\5
+\\{help4}(\.{"I'm\ afraid\ I\ won't\ }\)\.{be\ able\ to\ make\ use\ }\)\.{of\ this\ font,"})\6
+(\.{"because\ my\ memory\ f}\)\.{or\ character-size\ da}\)\.{ta\ is\ too\ small."})\6
+(\.{"If\ you're\ really\ st}\)\.{uck,\ ask\ a\ wizard\ to}\)\.{\ enlarge\ me."})\6
+(\.{"Or\ maybe\ try\ `I\\\\fo}\)\.{nt<same\ font\ id>=<na}\)\.{me\ of\ loaded\ font>'.}\)\.{"});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{done};\6
+\4${}\}{}$\2\par
+\U566.\fi
+
+\M{568}Only the first two words of the header are needed by \TeX82.
+
+\Y\B\4\X568:Read the {\.{TFM}} header\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{lh}<\T{2}){}$\1\5
+\\{abort};\2\6
+\\{store\_four\_quarters}(\\{font\_check}[\|f]);\5
+\\{fget};\5
+\\{read\_sixteen}(\|z);\C{this rejects a negative design size}\6
+\\{fget};\5
+${}\|z\K\|z*\T{\~400}+\\{fbyte};{}$\5
+\\{fget};\5
+${}\|z\K(\|z*\T{\~20})+(\\{fbyte}/\T{\~20});{}$\6
+\&{if} ${}(\|z<\\{unity}){}$\1\5
+\\{abort};\2\6
+\&{while} ${}(\\{lh}>\T{2}){}$\5
+${}\{{}$\5
+\1\\{fget};\5
+\\{fget};\5
+\\{fget};\5
+\\{fget};\5
+\\{decr}(\\{lh});\C{ignore the rest of the header}\6
+\4${}\}{}$\2\6
+${}\\{font\_dsize}[\|f]\K\|z;{}$\6
+\&{if} ${}(\|s\I{-}\T{1000}){}$\1\6
+\&{if} ${}(\|s\G\T{0}){}$\1\5
+${}\|z\K\|s;{}$\2\6
+\&{else}\1\5
+${}\|z\K\\{xn\_over\_d}(\|z,\39{-}\|s,\39\T{1000});{}$\2\2\6
+${}\\{font\_size}[\|f]\K\|z;{}$\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{569}\B\X569:Read character data\X${}\E{}$\6
+\&{for} ${}(\|k\K\\{fmem\_ptr};{}$ ${}\|k\Z\\{width\_base}[\|f]-\T{1};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\\{store\_four\_quarters}(\\{font\_info}[\|k].\\{qqqq});{}$\6
+\&{if} ${}((\|a\G\\{nw})\V(\|b/\T{\~20}\G\\{nh})\V(\|b\MOD\T{\~20}\G\\{nd})\V(\|c/\T{4}\G\\{ni})){}$\1\5
+\\{abort};\2\6
+\&{switch} ${}(\|c\MOD\T{4}){}$\5
+${}\{{}$\1\6
+\4\&{case} \\{lig\_tag}:\6
+\&{if} ${}(\|d\G\\{nl}){}$\1\5
+\\{abort};\5
+\2\&{break};\6
+\4\&{case} \\{ext\_tag}:\6
+\&{if} ${}(\|d\G\\{ne}){}$\1\5
+\\{abort};\5
+\2\&{break};\6
+\4\&{case} \\{list\_tag}:\5
+\X570:Check for charlist cycle\X\5
+\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\C{\\{no\_tag}}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{570}We want to make sure that there is no cycle of characters linked together
+by \\{list\_tag} entries, since such a cycle would get \TeX\ into an endless
+loop. If such a cycle exists, the routine here detects it when processing
+the largest character code in the cycle.
+
+\Y\B\4\D$\\{check\_byte\_range}(\|X)$ \6
+${}\{{}$\5
+\1\&{if} ${}((\|X<\\{bc})\V(\|X>\\{ec})){}$\1\5
+\\{abort};\5
+\2${}\}{}$\2\par
+\B\4\D$\\{current\_character\_being\_worked\_on}$ \5
+$\|k+\\{bc}-{}$\\{fmem\_ptr}\par
+\Y\B\4\X570:Check for charlist cycle\X${}\E{}$\6
+${}\{{}$\5
+\1\\{check\_byte\_range}(\|d);\6
+\&{while} ${}(\|d<\\{current\_character\_being\_worked\_on}){}$\5
+${}\{{}$\5
+\1${}\\{qw}\K\\{char\_info}(\|f)(\|d){}$;\C{N.B.: not \\{qi}(\|d), since \\{char\_base}[\|f] hasn't been adjusted yet}\6
+\&{if} ${}(\\{char\_tag}(\\{qw})\I\\{list\_tag}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+${}\|d\K\\{qo}(\\{rem\_byte}(\\{qw})){}$;\C{next character on the list}\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|d\E\\{current\_character\_being\_worked\_on}){}$\1\5
+\\{abort};\C{yes, there's a cycle}\2\6
+\4\\{not\_found}:\5
+;\6
+\4${}\}{}$\2\par
+\U569.\fi
+
+\M{571}A \\{fix\_word} whose four bytes are $(a,b,c,d)$ from left to right represents
+the number
+$$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr
+b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=0;\cr
+-16+b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=255.\cr}}\right.$$
+(No other choices of \|a are allowed, since the magnitude of a number in
+design-size units must be less than 16.) We want to multiply this
+quantity by the integer~\|z, which is known to be less than $2^{27}$.
+If $\|z<2^{23}$, the individual multiplications $b\cdot z$,
+$c\cdot z$, $d\cdot z$ cannot overflow; otherwise we will divide \|z by 2,
+4, 8, or 16, to obtain a multiplier less than $2^{23}$, and we can
+compensate for this later. If \|z has thereby been replaced by
+$\|z^\prime=\|z/2^e$, let $\beta=2^{4-e}$; we shall compute
+$$\lfloor(b+c\cdot2^{-8}+d\cdot2^{-16})\,z^\prime/\beta\rfloor$$
+if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$.
+This calculation must be done exactly, in order to guarantee portability
+of \TeX\ between computers.
+
+\Y\B\4\D$\\{store\_scaled}(\|X)$ \6
+${}\{{}$\5
+\1\\{fget};\5
+${}\|a\K\\{fbyte};{}$\5
+\\{fget};\5
+${}\|b\K\\{fbyte};{}$\5
+\\{fget};\5
+${}\|c\K\\{fbyte};{}$\5
+\\{fget};\5
+${}\|d\K\\{fbyte}{}$;\6
+${}\\{sw}\K(((((\|d*\|z)/\T{\~400})+(\|c*\|z))/\T{\~400})+(\|b*\|z))/\\{beta};{}$\6
+\&{if} ${}(\|a\E\T{0}){}$\1\5
+${}\|X\K\\{sw}{}$;\5
+\2\&{else} \&{if} ${}(\|a\E\T{255}){}$\1\5
+${}\|X\K\\{sw}-\\{alpha}{}$;\5
+\2\&{else}\1\5
+\\{abort};\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X571:Read box dimensions\X${}\E{}$\6
+${}\{{}$\5
+\1\X572:Replace \|z by $\|z^\prime$ and compute $\alpha,\beta$\X;\6
+\&{for} ${}(\|k\K\\{width\_base}[\|f];{}$ ${}\|k\Z\\{lig\_kern\_base}[\|f]-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{store\_scaled}(\\{font\_info}[\|k].\\{sc});{}$\2\6
+\&{if} ${}(\\{font\_info}[\\{width\_base}[\|f]].\\{sc}\I\T{0}){}$\1\5
+\\{abort};\C{\\{width}[0] must be zero}\2\6
+\&{if} ${}(\\{font\_info}[\\{height\_base}[\|f]].\\{sc}\I\T{0}){}$\1\5
+\\{abort};\C{\\{height}[0] must be zero}\2\6
+\&{if} ${}(\\{font\_info}[\\{depth\_base}[\|f]].\\{sc}\I\T{0}){}$\1\5
+\\{abort};\C{\\{depth}[0] must be zero}\2\6
+\&{if} ${}(\\{font\_info}[\\{italic\_base}[\|f]].\\{sc}\I\T{0}){}$\1\5
+\\{abort};\C{\\{italic}[0] must be zero}\2\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{572}\B\X572:Replace \|z by $\|z^\prime$ and compute $\alpha,\beta$\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{alpha}\K\T{16};{}$\6
+\&{while} ${}(\|z\G\T{\~40000000}){}$\5
+${}\{{}$\5
+\1${}\|z\K\|z/\T{2};{}$\5
+${}\\{alpha}\K\\{alpha}+\\{alpha};{}$\6
+\4${}\}{}$\2\6
+${}\\{beta}\K\T{256}/\\{alpha};{}$\5
+${}\\{alpha}\K\\{alpha}*\|z;{}$\6
+\4${}\}{}$\2\par
+\U571.\fi
+
+\M{573}\B\D$\\{check\_existence}(\|X)$ \5
+\hbox{}\6
+${}\{{}$\5
+\1\\{check\_byte\_range}(\|X);\5
+${}\\{qw}\K\\{char\_info}(\|f)(\|X){}$;\C{N.B.: not \\{qi}(\|X)}\6
+\&{if} ${}(\R\\{char\_exists}(\\{qw})){}$\1\5
+\\{abort};\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X573:Read ligature/kern program\X${}\E{}$\6
+$\\{bch\_label}\K\T{\~77777};{}$\5
+${}\\{bchar}\K\T{256};{}$\6
+\&{if} ${}(\\{nl}>\T{0}){}$\5
+${}\{{}$\5
+\1\&{for} ${}(\|k\K\\{lig\_kern\_base}[\|f];{}$ ${}\|k\Z\\{kern\_base}[\|f]+\\{kern\_base\_offset}-\T{1};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\\{store\_four\_quarters}(\\{font\_info}[\|k].\\{qqqq});{}$\6
+\&{if} ${}(\|a>\T{128}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\T{256}*\|c+\|d\G\\{nl}){}$\1\5
+\\{abort};\2\6
+\&{if} ${}(\|a\E\T{255}){}$\1\6
+\&{if} ${}(\|k\E\\{lig\_kern\_base}[\|f]){}$\1\5
+${}\\{bchar}\K\|b;{}$\2\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\|b\I\\{bchar}){}$\1\5
+\\{check\_existence}(\|b);\2\6
+\&{if} ${}(\|c<\T{128}){}$\1\5
+\\{check\_existence}(\|d)\C{check ligature}\2\6
+\&{else} \&{if} ${}(\T{256}*(\|c-\T{128})+\|d\G\\{nk}){}$\1\5
+\\{abort};\C{check kern}\2\6
+\&{if} ${}(\|a<\T{128}){}$\1\6
+\&{if} ${}(\|k-\\{lig\_kern\_base}[\|f]+\|a+\T{1}\G\\{nl}){}$\1\5
+\\{abort};\2\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|a\E\T{255}){}$\1\5
+${}\\{bch\_label}\K\T{256}*\|c+\|d;{}$\2\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|k\K\\{kern\_base}[\|f]+\\{kern\_base\_offset};{}$ ${}\|k\Z\\{exten\_base}[\|f]-\T{1};{}$ ${}\|k\PP){}$\1\5
+${}\\{store\_scaled}(\\{font\_info}[\|k].\\{sc}){}$;\2\par
+\U562.\fi
+
+\M{574}\B\X574:Read extensible character recipes\X${}\E{}$\6
+\&{for} ${}(\|k\K\\{exten\_base}[\|f];{}$ ${}\|k\Z\\{param\_base}[\|f]-\T{1};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1${}\\{store\_four\_quarters}(\\{font\_info}[\|k].\\{qqqq});{}$\6
+\&{if} ${}(\|a\I\T{0}){}$\1\5
+\\{check\_existence}(\|a);\2\6
+\&{if} ${}(\|b\I\T{0}){}$\1\5
+\\{check\_existence}(\|b);\2\6
+\&{if} ${}(\|c\I\T{0}){}$\1\5
+\\{check\_existence}(\|c);\2\6
+\\{check\_existence}(\|d);\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{575}We check to see that the \.{TFM} file doesn't end prematurely; but
+no error message is given for files having more than \\{lf} words.
+
+\Y\B\4\X575:Read font parameters\X${}\E{}$\6
+${}\{{}$\5
+\1\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{np};{}$ ${}\|k\PP){}$\1\6
+\&{if} ${}(\|k\E\T{1}{}$)\C{the \\{slant} parameter is a pure number}\6
+${}\{{}$\5
+\1\\{fget};\5
+${}\\{sw}\K\\{fbyte};{}$\6
+\&{if} ${}(\\{sw}>\T{127}){}$\1\5
+${}\\{sw}\K\\{sw}-\T{256};{}$\2\6
+\\{fget};\5
+${}\\{sw}\K\\{sw}*\T{\~400}+\\{fbyte};{}$\5
+\\{fget};\5
+${}\\{sw}\K\\{sw}*\T{\~400}+\\{fbyte};{}$\5
+\\{fget};\5
+${}\\{font\_info}[\\{param\_base}[\|f]].\\{sc}\K(\\{sw}*\T{\~20})+(\\{fbyte}/\T{\~20});{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{store\_scaled}(\\{font\_info}[\\{param\_base}[\|f]+\|k-\T{1}].\\{sc});{}$\2\2\6
+\&{if} (\\{eof}(\\{tfm\_file}))\1\5
+\\{abort};\2\6
+\&{for} ${}(\|k\K\\{np}+\T{1};{}$ ${}\|k\Z\T{7};{}$ ${}\|k\PP){}$\1\5
+${}\\{font\_info}[\\{param\_base}[\|f]+\|k-\T{1}].\\{sc}\K\T{0};{}$\2\6
+\4${}\}{}$\2\par
+\U562.\fi
+
+\M{576}Now to wrap it up, we have checked all the necessary things about the \.{TFM}
+file, and all we need to do is put the finishing touches on the data for
+the new font.
+
+\Y\B\4\D$\\{adjust}(\|X)$ \5
+$\|X[\|f]\K\\{qo}{}$(\|X[\|f])\C{correct for the excess \\{min\_quarterword} that was added}\par
+\Y\B\4\X576:Make final adjustments and \&{goto} \\{done}\X${}\E{}$\6
+\&{if} ${}(\\{np}\G\T{7}){}$\1\5
+${}\\{font\_params}[\|f]\K\\{np}{}$;\5
+\2\&{else}\1\5
+${}\\{font\_params}[\|f]\K\T{7};{}$\2\6
+${}\\{hyphen\_char}[\|f]\K\\{default\_hyphen\_char};{}$\5
+${}\\{skew\_char}[\|f]\K\\{default\_skew\_char};{}$\6
+\&{if} ${}(\\{bch\_label}<\\{nl}){}$\1\5
+${}\\{bchar\_label}[\|f]\K\\{bch\_label}+\\{lig\_kern\_base}[\|f];{}$\2\6
+\&{else}\1\5
+${}\\{bchar\_label}[\|f]\K\\{non\_address};{}$\2\6
+${}\\{font\_bchar}[\|f]\K\\{qi}(\\{bchar});{}$\5
+${}\\{font\_false\_bchar}[\|f]\K\\{qi}(\\{bchar});{}$\6
+\&{if} ${}(\\{bchar}\Z\\{ec}){}$\1\6
+\&{if} ${}(\\{bchar}\G\\{bc}){}$\5
+${}\{{}$\5
+\1${}\\{qw}\K\\{char\_info}(\|f)(\\{bchar}){}$;\C{N.B.: not \\{qi}(\\{bchar})}\6
+\&{if} (\\{char\_exists}(\\{qw}))\1\5
+${}\\{font\_false\_bchar}[\|f]\K\\{non\_char};{}$\2\6
+\4${}\}{}$\2\2\6
+${}\\{font\_name}[\|f]\K\\{nom};{}$\5
+${}\\{font\_area}[\|f]\K\\{aire};{}$\5
+${}\\{font\_bc}[\|f]\K\\{bc};{}$\5
+${}\\{font\_ec}[\|f]\K\\{ec};{}$\5
+${}\\{font\_glue}[\|f]\K\\{null};{}$\5
+\\{adjust}(\\{char\_base});\5
+\\{adjust}(\\{width\_base});\5
+\\{adjust}(\\{lig\_kern\_base});\5
+\\{adjust}(\\{kern\_base});\5
+\\{adjust}(\\{exten\_base});\5
+\\{decr}(\\{param\_base}[\|f]);\5
+${}\\{fmem\_ptr}\K\\{fmem\_ptr}+\\{lf};{}$\5
+${}\\{font\_ptr}\K\|f;{}$\5
+${}\|g\K\|f;$ \&{goto} \\{done}\par
+\U562.\fi
+
+\M{577}Before we forget about the format of these tables, let's deal with two
+of \TeX's basic scanning routines related to font information.
+
+\Y\B\4\X577:Declare procedures that scan font-related stuff\X${}\E{}$\6
+\&{void} \\{scan\_font\_ident}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{internal\_font\_number} \|f;\6
+\&{halfword} \|m;\7
+\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\E\\{def\_font}){}$\1\5
+${}\|f\K\\{cur\_font};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{set\_font}){}$\1\5
+${}\|f\K\\{cur\_chr};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{def\_family}){}$\5
+${}\{{}$\5
+\1${}\|m\K\\{cur\_chr};{}$\5
+\\{scan\_four\_bit\_int}(\,);\5
+${}\|f\K\\{equiv}(\|m+\\{cur\_val});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ font\ identi}\)\.{fier"});\5
+\\{help2}(\.{"I\ was\ looking\ for\ a}\)\.{\ control\ sequence\ wh}\)\.{ose"})\6
+(\.{"current\ meaning\ has}\)\.{\ been\ defined\ by\ \\\\f}\)\.{ont."});\5
+\\{back\_error}(\,);\5
+${}\|f\K\\{null\_font};{}$\6
+\4${}\}{}$\2\6
+${}\\{cur\_val}\K\|f;{}$\6
+\4${}\}{}$\2\par
+\A578.
+\U409.\fi
+
+\M{578}The following routine is used to implement `\.{\\fontdimen} \|n \|f'.
+The boolean parameter \\{writing} is set \\{true} if the calling program
+intends to change the parameter value.
+
+\Y\B\4\X577:Declare procedures that scan font-related stuff\X${}\mathrel+\E{}$\6
+\&{void} \\{find\_font\_dimen}(\&{bool} \\{writing})\C{sets \\{cur\_val} to \\{font\_info} location}\6
+${}\{{}$\5
+\1\&{internal\_font\_number} \|f;\6
+\&{int} \|n;\C{the parameter number}\7
+\\{scan\_int}(\,);\5
+${}\|n\K\\{cur\_val};{}$\5
+\\{scan\_font\_ident}(\,);\5
+${}\|f\K\\{cur\_val};{}$\6
+\&{if} ${}(\|n\Z\T{0}){}$\1\5
+${}\\{cur\_val}\K\\{fmem\_ptr};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{writing}\W(\|n\Z\\{space\_shrink\_code})\W\30(\|n\G\\{space\_code})\W(\\{font\_glue}[\|f]\I\\{null})){}$\5
+${}\{{}$\5
+\1\\{delete\_glue\_ref}(\\{font\_glue}[\|f]);\5
+${}\\{font\_glue}[\|f]\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|n>\\{font\_params}[\|f]){}$\1\6
+\&{if} ${}(\|f<\\{font\_ptr}){}$\1\5
+${}\\{cur\_val}\K\\{fmem\_ptr};{}$\2\6
+\&{else}\1\5
+\X580:Increase the number of parameters in the last font\X\2\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\|n+\\{param\_base}[\|f];{}$\2\6
+\4${}\}{}$\2\6
+\X579:Issue an error message if $\\{cur\_val}\K\\{fmem\_ptr}$\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{579}\B\X579:Issue an error message if $\\{cur\_val}\K\\{fmem\_ptr}$\X${}\E{}$\6
+\&{if} ${}(\\{cur\_val}\E\\{fmem\_ptr}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Font\ "});\5
+\\{print\_esc}(\\{font\_id\_text}(\|f));\5
+\\{print\_str}(\.{"\ has\ only\ "});\5
+\\{print\_int}(\\{font\_params}[\|f]);\5
+\\{print\_str}(\.{"\ fontdimen\ paramete}\)\.{rs"});\5
+\\{help2}(\.{"To\ increase\ the\ num}\)\.{ber\ of\ font\ paramete}\)\.{rs,\ you\ must"})\6
+(\.{"use\ \\\\fontdimen\ imm}\)\.{ediately\ after\ the\ \\}\)\.{\\font\ is\ loaded."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U578.\fi
+
+\M{580}\B\X580:Increase the number of parameters in the last font\X${}\E{}$\6
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{fmem\_ptr}\E\\{font\_mem\_size}){}$\1\5
+${}\\{overflow}(\.{"font\ memory"},\39\\{font\_mem\_size});{}$\2\6
+${}\\{font\_info}[\\{fmem\_ptr}].\\{sc}\K\T{0};{}$\5
+\\{incr}(\\{fmem\_ptr});\5
+\\{incr}(\\{font\_params}[\|f]);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|n\E\\{font\_params}[\|f]));{}$\5
+${}\\{cur\_val}\K\\{fmem\_ptr}-\T{1}{}$;\C{this equals $\\{param\_base}[\|f]+\\{font\_params}[\|f]$}\6
+\4${}\}{}$\2\par
+\U578.\fi
+
+\M{581}When \TeX\ wants to typeset a character that doesn't exist, the
+character node is not created; thus the output routine can assume
+that characters exist when it sees them. The following procedure
+prints a warning message unless the user has suppressed it.
+
+\Y\B\&{void} \\{char\_warning}(\&{internal\_font\_number} \|f${},\39{}$\&{eight\_bits} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{tracing\_lost\_chars}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"Missing\ character:\ }\)\.{There\ is\ no\ "});\5
+\\{print\_ASCII}(\|c);\5
+\\{print\_str}(\.{"\ in\ font\ "});\5
+\\{slow\_print}(\\{font\_name}[\|f]);\5
+\\{print\_char}(\.{'!'});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{582}Here is a function that returns a pointer to a character node for a
+given character in a given font. If that character doesn't exist,
+\\{null} is returned instead.
+
+\Y\B\&{pointer} \\{new\_character}(\&{internal\_font\_number} \|f${},\39{}$\&{eight\_bits} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{newly allocated node}\7
+\&{if} ${}(\\{font\_bc}[\|f]\Z\|c){}$\1\6
+\&{if} ${}(\\{font\_ec}[\|f]\G\|c){}$\1\6
+\&{if} (\\{char\_exists}(\\{char\_info}(\|f)(\\{qi}(\|c))))\5
+${}\{{}$\5
+\1${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{font}(\|p)\K\|f;{}$\5
+${}\\{character}(\|p)\K\\{qi}(\|c);{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\2\2\6
+${}\\{char\_warning}(\|f,\39\|c);{}$\5
+\&{return} \\{null};\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{583}Device-independent file format.
+The most important output produced by a run of \TeX\ is the ``device
+independent'' (\.{DVI}) file that specifies where characters and rules
+are to appear on printed pages. The form of these files was designed by
+David R. Fuchs in 1979. Almost any reasonable typesetting device can be
+driven by a program that takes \.{DVI} files as input, and dozens of such
+\.{DVI}-to-whatever programs have been written. Thus, it is possible to
+print the output of \TeX\ on many different kinds of equipment, using \TeX\
+as a device-independent ``front end.''
+
+A \.{DVI} file is a stream of 8-bit bytes, which may be regarded as a
+series of commands in a machine-like language. The first byte of each command
+is the operation code, and this code is followed by zero or more bytes
+that provide parameters to the command. The parameters themselves may consist
+of several consecutive bytes; for example, the `\\{set\_rule}' command has two
+parameters, each of which is four bytes long. Parameters are usually
+regarded as nonnegative integers; but four-byte-long parameters,
+and shorter parameters that denote distances, can be
+either positive or negative. Such parameters are given in two's complement
+notation. For example, a two-byte-long distance parameter has a value between
+$-2^{15}$ and $2^{15}-1$. As in \.{TFM} files, numbers that occupy
+more than one byte position appear in BigEndian order.
+
+A \.{DVI} file consists of a ``preamble,'' followed by a sequence of one
+or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
+\\{pre} command, with its parameters that define the dimensions used in the
+file; this must come first. Each ``page'' consists of a \\{bop} command,
+followed by any number of other commands that tell where characters are to
+be placed on a physical page, followed by an \\{eop} command. The pages
+appear in the order that \TeX\ generated them. If we ignore \\{nop} commands
+and \\{fnt\_def} commands (which are allowed between any two commands in
+the file), each \\{eop} command is immediately followed by a \\{bop} command,
+or by a \\{post} command; in the latter case, there are no more pages in the
+file, and the remaining bytes form the postamble. Further details about
+the postamble will be explained later.
+
+Some parameters in \.{DVI} commands are ``pointers.'' These are four-byte
+quantities that give the location number of some other byte in the file;
+the first byte is number~0, then comes number~1, and so on. For example,
+one of the parameters of a \\{bop} command points to the previous \\{bop};
+this makes it feasible to read the pages in backwards order, in case the
+results are being directed to a device that stacks its output face up.
+Suppose the preamble of a \.{DVI} file occupies bytes 0 to 99. Now if the
+first page occupies bytes 100 to 999, say, and if the second
+page occupies bytes 1000 to 1999, then the \\{bop} that starts in byte 1000
+points to 100 and the \\{bop} that starts in byte 2000 points to 1000. (The
+very first \\{bop}, i.e., the one starting in byte 100, has a pointer of~$-1$.)
+
+\fi
+
+\M{584}The \.{DVI} format is intended to be both compact and easily interpreted
+by a machine. Compactness is achieved by making most of the information
+implicit instead of explicit. When a \.{DVI}-reading program reads the
+commands for a page, it keeps track of several quantities: (a)~The current
+font \|f is an integer; this value is changed only
+by \\{fnt} and \\{fnt\_num} commands. (b)~The current position on the page
+is given by two numbers called the horizontal and vertical coordinates,
+\|h and \|v. Both coordinates are zero at the upper left corner of the page;
+moving to the right corresponds to increasing the horizontal coordinate, and
+moving down corresponds to increasing the vertical coordinate. Thus, the
+coordinates are essentially Cartesian, except that vertical directions are
+flipped; the Cartesian version of $(\|h,\|v)$ would be $(\|h,{-}\|v)$. (c)~The
+current spacing amounts are given by four numbers \|w, \|x, \|y, and \|z,
+where \|w and~\|x are used for horizontal spacing and where \|y and~\|z
+are used for vertical spacing. (d)~There is a stack containing
+$(\|h,\|v,\|w,\|x,\|y,\|z)$ values; the \.{DVI} commands \\{push} and \\{pop} are used to
+change the current level of operation. Note that the current font~\|f is
+not pushed and popped; the stack contains only information about
+positioning.
+
+The values of \|h, \|v, \|w, \|x, \|y, and \|z are signed integers having up
+to 32 bits, including the sign. Since they represent physical distances,
+there is a small unit of measurement such that increasing \|h by~1 means
+moving a certain tiny distance to the right. The actual unit of
+measurement is variable, as explained below; \TeX\ sets things up so that
+its \.{DVI} output is in sp units, i.e., scaled points, in agreement with
+all the \&{scaled} dimensions in \TeX's data structures.
+
+\fi
+
+\M{585}Here is a list of all the commands that may appear in a \.{DVI} file. Each
+command is specified by its symbolic name (e.g., \\{bop}), its opcode byte
+(e.g., 139), and its parameters (if any). The parameters are followed
+by a bracketed number telling how many bytes they occupy; for example,
+`\|p[\T{4}]' means that parameter \|p is four bytes long.
+
+\yskip\hang\\{set\_char\_0} 0. Typeset character number~0 from font~\|f
+such that the reference point of the character is at $(\|h,\|v)$. Then
+increase \|h by the width of that character. Note that a character may
+have zero or negative width, so one cannot be sure that \|h will advance
+after this command; but \|h usually does increase.
+
+\yskip\hang\\{set\_char\_1} through \\{set\_char\_127} (opcodes 1 to 127).
+Do the operations of \\{set\_char\_0}; but use the character whose number
+matches the opcode, instead of character~0.
+
+\yskip\hang\\{set1} 128 \|c[\T{1}]. Same as \\{set\_char\_0}, except that character
+number~\|c is typeset. \TeX82 uses this command for characters in the
+range $\T{128}\Z\|c<\T{256}$.
+
+\yskip\hang\\{set2} 129 \|c[\T{2}]. Same as \\{set1}, except that \|c~is two
+bytes long, so it is in the range $\T{0}\Z\|c<\T{65536}$. \TeX82 never uses this
+command, but it should come in handy for extensions of \TeX\ that deal
+with oriental languages.
+
+\yskip\hang\\{set3} 130 \|c[\T{3}]. Same as \\{set1}, except that \|c~is three
+bytes long, so it can be as large as $2^{24}-1$. Not even the Chinese
+language has this many characters, but this command might prove useful
+in some yet unforeseen extension.
+
+\yskip\hang\\{set4} 131 \|c[\T{4}]. Same as \\{set1}, except that \|c~is four
+bytes long. Imagine that.
+
+\yskip\hang\\{set\_rule} 132 \|a[\T{4}] \|b[\T{4}]. Typeset a solid black rectangle
+of height~\|a and width~\|b, with its bottom left corner at $(\|h,\|v)$. Then
+set $\|h\K\|h+\|b$. If either $\|a\Z\T{0}$ or $\|b\Z\T{0}$, nothing should be typeset. Note
+that if $\|b<\T{0}$, the value of \|h will decrease even though nothing else happens.
+See below for details about how to typeset rules so that consistency with
+\MF\ is guaranteed.
+
+\yskip\hang\\{put1} 133 \|c[\T{1}]. Typeset character number~\|c from font~\|f
+such that the reference point of the character is at $(\|h,\|v)$. (The `put'
+commands are exactly like the `set' commands, except that they simply put out a
+character or a rule without moving the reference point afterwards.)
+
+\yskip\hang\\{put2} 134 \|c[\T{2}]. Same as \\{set2}, except that \|h is not changed.
+
+\yskip\hang\\{put3} 135 \|c[\T{3}]. Same as \\{set3}, except that \|h is not changed.
+
+\yskip\hang\\{put4} 136 \|c[\T{4}]. Same as \\{set4}, except that \|h is not changed.
+
+\yskip\hang\\{put\_rule} 137 \|a[\T{4}] \|b[\T{4}]. Same as \\{set\_rule}, except that
+\|h is not changed.
+
+\yskip\hang\\{nop} 138. No operation, do nothing. Any number of \\{nop}'s
+may occur between \.{DVI} commands, but a \\{nop} cannot be inserted between
+a command and its parameters or between two parameters.
+
+\yskip\hang\\{bop} 139 $c_0[4]$ $c_1[4]$ $\ldots$ $c_9[4]$ $p[4]$. Beginning
+of a page: Set $(\|h,\|v,\|w,\|x,\|y,\|z)\K(\T{0},\T{0},\T{0},\T{0},\T{0},\T{0})$ and set the stack empty. Set
+the current font \|f to an undefined value. The ten $c_i$ parameters hold
+the values of \.{\\count0} $\ldots$ \.{\\count9} in \TeX\ at the time
+\.{\\shipout} was invoked for this page; they can be used to identify
+pages, if a user wants to print only part of a \.{DVI} file. The parameter
+\|p points to the previous \\{bop} in the file; the first
+\\{bop} has $p=-1$.
+
+\yskip\hang\\{eop} 140. End of page: Print what you have read since the
+previous \\{bop}. At this point the stack should be empty. (The \.{DVI}-reading
+programs that drive most output devices will have kept a buffer of the
+material that appears on the page that has just ended. This material is
+largely, but not entirely, in order by \|v coordinate and (for fixed \|v) by
+\|h~coordinate; so it usually needs to be sorted into some order that is
+appropriate for the device in question.)
+
+\yskip\hang\\{push} 141. Push the current values of $(\|h,\|v,\|w,\|x,\|y,\|z)$ onto the
+top of the stack; do not change any of these values. Note that \|f is
+not pushed.
+
+\yskip\hang\\{pop} 142. Pop the top six values off of the stack and assign
+them respectively to $(\|h,\|v,\|w,\|x,\|y,\|z)$. The number of pops should never
+exceed the number of pushes, since it would be highly embarrassing if the
+stack were empty at the time of a \\{pop} command.
+
+\yskip\hang\\{right1} 143 \|b[\T{1}]. Set $\|h\K\|h+\|b$, i.e., move right \|b units.
+The parameter is a signed number in two's complement notation, ${-}\T{128}\Z\|b<\T{128}$;
+if $\|b<\T{0}$, the reference point moves left.
+
+\yskip\hang\\{right2} 144 \|b[\T{2}]. Same as \\{right1}, except that \|b is a
+two-byte quantity in the range ${-}\T{32768}\Z\|b<\T{32768}$.
+
+\yskip\hang\\{right3} 145 \|b[\T{3}]. Same as \\{right1}, except that \|b is a
+three-byte quantity in the range $\hbox{$-2^{23}$}\Z$ \|b $<$.
+
+\yskip\hang\\{right4} 146 \|b[\T{4}]. Same as \\{right1}, except that \|b is a
+four-byte quantity in the range $\hbox{$-2^{31}$}\Z$ \|b $<$.
+
+\yskip\hang\\{w0} 147. Set $\|h\K\|h+\|w$; i.e., move right \|w units. With luck,
+this parameterless command will usually suffice, because the same kind of motion
+will occur several times in succession; the following commands explain how
+\|w gets particular values.
+
+\yskip\hang\\{w1} 148 \|b[\T{1}]. Set $\|w\K\|b$ and $\|h\K\|h+\|b$. The value of \|b is a
+signed quantity in two's complement notation, ${-}\T{128}\Z\|b<\T{128}$. This command
+changes the current \|w~spacing and moves right by \|b.
+
+\yskip\hang\\{w2} 149 \|b[\T{2}]. Same as \\{w1}, but \|b is two bytes long,
+${-}\T{32768}\Z\|b<\T{32768}$.
+
+\yskip\hang\\{w3} 150 \|b[\T{3}]. Same as \\{w1}, but \|b is three bytes long,
+$\hbox{$-2^{23}$}\Z$ \|b $<$.
+
+\yskip\hang\\{w4} 151 \|b[\T{4}]. Same as \\{w1}, but \|b is four bytes long,
+$\hbox{$-2^{31}$}\Z$ \|b $<$.
+
+\yskip\hang\\{x0} 152. Set $\|h\K\|h+\|x$; i.e., move right \|x units. The `\|x'
+commands are like the `\|w' commands except that they involve \|x instead
+of \|w.
+
+\yskip\hang\\{x1} 153 \|b[\T{1}]. Set $\|x\K\|b$ and $\|h\K\|h+\|b$. The value of \|b is a
+signed quantity in two's complement notation, ${-}\T{128}\Z\|b<\T{128}$. This command
+changes the current \|x~spacing and moves right by \|b.
+
+\yskip\hang\\{x2} 154 \|b[\T{2}]. Same as \\{x1}, but \|b is two bytes long,
+${-}\T{32768}\Z\|b<\T{32768}$.
+
+\yskip\hang\\{x3} 155 \|b[\T{3}]. Same as \\{x1}, but \|b is three bytes long,
+$\hbox{$-2^{23}$}\Z$ \|b $<$.
+
+\yskip\hang\\{x4} 156 \|b[\T{4}]. Same as \\{x1}, but \|b is four bytes long,
+$\hbox{$-2^{31}$}\Z$ \|b $<$.
+
+\yskip\hang\\{down1} 157 \|a[\T{1}]. Set $\|v\K\|v+\|a$, i.e., move down \|a units.
+The parameter is a signed number in two's complement notation, ${-}\T{128}\Z\|a<\T{128}$;
+if $\|a<\T{0}$, the reference point moves up.
+
+\yskip\hang\\{down2} 158 \|a[\T{2}]. Same as \\{down1}, except that \|a is a
+two-byte quantity in the range ${-}\T{32768}\Z\|a<\T{32768}$.
+
+\yskip\hang\\{down3} 159 \|a[\T{3}]. Same as \\{down1}, except that \|a is a
+three-byte quantity in the range $\hbox{$-2^{23}$}\Z$ \|a $<$.
+
+\yskip\hang\\{down4} 160 \|a[\T{4}]. Same as \\{down1}, except that \|a is a
+four-byte quantity in the range $\hbox{$-2^{31}$}\Z$ \|a $<$.
+
+\yskip\hang\\{y0} 161. Set $\|v\K\|v+\|y$; i.e., move down \|y units. With luck,
+this parameterless command will usually suffice, because the same kind of motion
+will occur several times in succession; the following commands explain how
+\|y gets particular values.
+
+\yskip\hang\\{y1} 162 \|a[\T{1}]. Set $\|y\K\|a$ and $\|v\K\|v+\|a$. The value of \|a is a
+signed quantity in two's complement notation, ${-}\T{128}\Z\|a<\T{128}$. This command
+changes the current \|y~spacing and moves down by \|a.
+
+\yskip\hang\\{y2} 163 \|a[\T{2}]. Same as \\{y1}, but \|a is two bytes long,
+${-}\T{32768}\Z\|a<\T{32768}$.
+
+\yskip\hang\\{y3} 164 \|a[\T{3}]. Same as \\{y1}, but \|a is three bytes long,
+$\hbox{$-2^{23}$}\Z$ \|a $<$.
+
+\yskip\hang\\{y4} 165 \|a[\T{4}]. Same as \\{y1}, but \|a is four bytes long,
+$\hbox{$-2^{31}$}\Z$ \|a $<$.
+
+\yskip\hang\\{z0} 166. Set $\|v\K\|v+\|z$; i.e., move down \|z units. The `\|z' commands
+are like the `\|y' commands except that they involve \|z instead of \|y.
+
+\yskip\hang\\{z1} 167 \|a[\T{1}]. Set $\|z\K\|a$ and $\|v\K\|v+\|a$. The value of \|a is a
+signed quantity in two's complement notation, ${-}\T{128}\Z\|a<\T{128}$. This command
+changes the current \|z~spacing and moves down by \|a.
+
+\yskip\hang\\{z2} 168 \|a[\T{2}]. Same as \\{z1}, but \|a is two bytes long,
+${-}\T{32768}\Z\|a<\T{32768}$.
+
+\yskip\hang\\{z3} 169 \|a[\T{3}]. Same as \\{z1}, but \|a is three bytes long,
+$\hbox{$-2^{23}$}\Z$ \|a $<$.
+
+\yskip\hang\\{z4} 170 \|a[\T{4}]. Same as \\{z1}, but \|a is four bytes long,
+$\hbox{$-2^{31}$}\Z$ \|a $<$.
+
+\yskip\hang\\{fnt\_num\_0} 171. Set $\|f\K\T{0}$. Font 0 must previously have been
+defined by a \\{fnt\_def} instruction, as explained below.
+
+\yskip\hang\\{fnt\_num\_1} through \\{fnt\_num\_63} (opcodes 172 to 234). Set
+$\|f\K\T{1}$, \dots, \hbox{$\|f\K\T{63}$}, respectively.
+
+\yskip\hang\\{fnt1} 235 \|k[\T{1}]. Set $\|f\K\|k$. \TeX82 uses this command for font
+numbers in the range $\T{64}\Z\|k<\T{256}$.
+
+\yskip\hang\\{fnt2} 236 \|k[\T{2}]. Same as \\{fnt1}, except that \|k~is two
+bytes long, so it is in the range $\T{0}\Z\|k<\T{65536}$. \TeX82 never generates this
+command, but large font numbers may prove useful for specifications of
+color or texture, or they may be used for special fonts that have fixed
+numbers in some external coding scheme.
+
+\yskip\hang\\{fnt3} 237 \|k[\T{3}]. Same as \\{fnt1}, except that \|k~is three
+bytes long, so it can be as large as $2^{24}-1$.
+
+\yskip\hang\\{fnt4} 238 \|k[\T{4}]. Same as \\{fnt1}, except that \|k~is four
+bytes long; this is for the really big font numbers (and for the negative ones).
+
+\yskip\hang\\{xxx1} 239 \|k[\T{1}] \|x[\|k]. This command is undefined in
+general; it functions as a $(k+2)$-byte \\{nop} unless special \.{DVI}-reading
+programs are being used. \TeX82 generates \\{xxx1} when a short enough
+\.{\\special} appears, setting \|k to the number of bytes being sent. It
+is recommended that \|x be a string having the form of a keyword followed
+by possible parameters relevant to that keyword.
+
+\yskip\hang\\{xxx2} 240 \|k[\T{2}] \|x[\|k]. Like \\{xxx1}, but $\T{0}\Z\|k<\T{65536}$.
+
+\yskip\hang\\{xxx3} 241 \|k[\T{3}] \|x[\|k]. Like \\{xxx1}, but $\T{0}\Z\|k$ $<$.
+
+\yskip\hang\\{xxx4} 242 \|k[\T{4}] \|x[\|k]. Like \\{xxx1}, but \|k can be ridiculously
+large. \TeX82 uses \\{xxx4} when sending a string of length 256 or more.
+
+\yskip\hang\\{fnt\_def1} 243 \|k[\T{1}] \|c[\T{4}] \|s[\T{4}] \|d[\T{4}] \|a[\T{1}] \|l[\T{1}] $\|n[\|a+\|l]$.
+Define font \|k, where $\T{0}\Z\|k<\T{256}$; font definitions will be explained shortly.
+
+\yskip\hang\\{fnt\_def2} 244 \|k[\T{2}] \|c[\T{4}] \|s[\T{4}] \|d[\T{4}] \|a[\T{1}] \|l[\T{1}] $\|n[\|a+\|l]$.
+Define font \|k, where $\T{0}\Z\|k<\T{65536}$.
+
+\yskip\hang\\{fnt\_def3} 245 \|k[\T{3}] \|c[\T{4}] \|s[\T{4}] \|d[\T{4}] \|a[\T{1}] \|l[\T{1}] $\|n[\|a+\|l]$.
+Define font \|k, where $\T{0}\Z\|k$ $<$.
+
+\yskip\hang\\{fnt\_def4} 246 \|k[\T{4}] \|c[\T{4}] \|s[\T{4}] \|d[\T{4}] \|a[\T{1}] \|l[\T{1}] $\|n[\|a+\|l]$.
+Define font \|k, where $\hbox{$-2^{31}$}\Z$ \|k $<$.
+
+\yskip\hang\\{pre} 247 \|i[\T{1}] \\{num}[\T{4}] \\{den}[\T{4}] \\{mag}[\T{4}] \|k[\T{1}] \|x[\|k].
+Beginning of the preamble; this must come at the very beginning of the
+file. Parameters \|i, \\{num}, \\{den}, \\{mag}, \|k, and \|x are explained below.
+
+\yskip\hang\\{post} 248. Beginning of the postamble, see below.
+
+\yskip\hang\\{post\_post} 249. Ending of the postamble, see below.
+
+\yskip\noindent Commands 250--255 are undefined at the present time.
+
+\fi
+
+\M{586}\B\D$\\{set\_char\_0}$ \5
+\T{0}\C{typeset character 0 and move right}\par
+\B\4\D$\\{set1}$ \5
+\T{128}\C{typeset a character and move right}\par
+\B\4\D$\\{set\_rule}$ \5
+\T{132}\C{typeset a rule and move right}\par
+\B\4\D$\\{put\_rule}$ \5
+\T{137}\C{typeset a rule}\par
+\B\4\D$\\{nop}$ \5
+\T{138}\C{no operation}\par
+\B\4\D$\\{bop}$ \5
+\T{139}\C{beginning of page}\par
+\B\4\D$\\{eop}$ \5
+\T{140}\C{ending of page}\par
+\B\4\D$\\{push}$ \5
+\T{141}\C{save the current positions}\par
+\B\4\D$\\{pop}$ \5
+\T{142}\C{restore previous positions}\par
+\B\4\D$\\{right1}$ \5
+\T{143}\C{move right}\par
+\B\4\D$\\{w0}$ \5
+\T{147}\C{move right by \|w}\par
+\B\4\D$\\{w1}$ \5
+\T{148}\C{move right and set \|w}\par
+\B\4\D$\\{x0}$ \5
+\T{152}\C{move right by \|x}\par
+\B\4\D$\\{x1}$ \5
+\T{153}\C{move right and set \|x}\par
+\B\4\D$\\{down1}$ \5
+\T{157}\C{move down}\par
+\B\4\D$\\{y0}$ \5
+\T{161}\C{move down by \|y}\par
+\B\4\D$\\{y1}$ \5
+\T{162}\C{move down and set \|y}\par
+\B\4\D$\\{z0}$ \5
+\T{166}\C{move down by \|z}\par
+\B\4\D$\\{z1}$ \5
+\T{167}\C{move down and set \|z}\par
+\B\4\D$\\{fnt\_num\_0}$ \5
+\T{171}\C{set current font to 0}\par
+\B\4\D$\\{fnt1}$ \5
+\T{235}\C{set current font}\par
+\B\4\D$\\{xxx1}$ \5
+\T{239}\C{extension to \.{DVI} primitives}\par
+\B\4\D$\\{xxx4}$ \5
+\T{242}\C{potentially long extension to \.{DVI} primitives}\par
+\B\4\D$\\{fnt\_def1}$ \5
+\T{243}\C{define the meaning of a font number}\par
+\B\4\D$\\{pre}$ \5
+\T{247}\C{preamble}\par
+\B\4\D$\\{post}$ \5
+\T{248}\C{postamble beginning}\par
+\B\4\D$\\{post\_post}$ \5
+\T{249}\C{postamble ending}\par
+\fi
+
+\M{587}The preamble contains basic information about the file as a whole. As
+stated above, there are six parameters:
+$$\hbox{\|i[\T{1}] \\{num}[\T{4}] \\{den}[\T{4}] \\{mag}[\T{4}] \|k[\T{1}] \|x[\|k].}$$
+The \|i byte identifies \.{DVI} format; currently this byte is always set
+to~2. (The value $\|i\E\T{3}$ is currently used for an extended format that
+allows a mixture of right-to-left and left-to-right typesetting.
+Some day we will set $\|i\E\T{4}$, when \.{DVI} format makes another
+incompatible change---perhaps in the year 2048.)
+
+The next two parameters, \\{num} and \\{den}, are positive integers that define
+the units of measurement; they are the numerator and denominator of a
+fraction by which all dimensions in the \.{DVI} file could be multiplied
+in order to get lengths in units of $10^{-7}$ meters. Since $\rm 7227{pt} =
+254{cm}$, and since \TeX\ works with scaled points where there are $2^{16}$
+sp in a point, \TeX\ sets
+$\\{num}/\\{den}=(254\cdot10^5)/(7227\cdot2^{16})=25400000/473628672$.
+
+The \\{mag} parameter is what \TeX\ calls \.{\\mag}, i.e., 1000 times the
+desired magnification. The actual fraction by which dimensions are
+multiplied is therefore $\\{mag}\cdot\\{num}/1000\\{den}$. Note that if a \TeX\
+source document does not call for any `\.{true}' dimensions, and if you
+change it only by specifying a different \.{\\mag} setting, the \.{DVI}
+file that \TeX\ creates will be completely unchanged except for the value
+of \\{mag} in the preamble and postamble. (Fancy \.{DVI}-reading programs allow
+users to override the \\{mag}~setting when a \.{DVI} file is being printed.)
+
+Finally, \|k and \|x allow the \.{DVI} writer to include a comment, which is not
+interpreted further. The length of comment \|x is \|k, where $\T{0}\Z\|k<\T{256}$.
+
+\Y\B\4\D$\\{id\_byte}$ \5
+\T{2}\C{identifies the kind of \.{DVI} files described here}\par
+\fi
+
+\M{588}Font definitions for a given font number \|k contain further parameters
+$$\hbox{\|c[\T{4}] \|s[\T{4}] \|d[\T{4}] \|a[\T{1}] \|l[\T{1}] $\|n[\|a+\|l]$.}$$
+The four-byte value \|c is the check sum that \TeX\ found in the \.{TFM}
+file for this font; \|c should match the check sum of the font found by
+programs that read this \.{DVI} file.
+
+Parameter \|s contains a fixed-point scale factor that is applied to
+the character widths in font \|k; font dimensions in \.{TFM} files and
+other font files are relative to this quantity, which is called the
+``at size'' elsewhere in this documentation. The value of \|s is
+always positive and less than $2^{27}$. It is given in the same units
+as the other \.{DVI} dimensions, i.e., in sp when \TeX82 has made the
+file. Parameter \|d is similar to \|s; it is the ``design size,'' and
+(like~\|s) it is given in \.{DVI} units. Thus, font \|k is to be used
+at $\\{mag}\cdot s/1000d$ times its normal size.
+
+The remaining part of a font definition gives the external name of the font,
+which is an ASCII string of length $\|a+\|l$. The number \|a is the length
+of the ``area'' or directory, and \|l is the length of the font name itself;
+the standard local system font area is supposed to be used when $\|a\E\T{0}$.
+The \|n field contains the area in its first \|a bytes.
+
+Font definitions must appear before the first use of a particular font number.
+Once font \|k is defined, it must not be defined again; however, we
+shall see below that font definitions appear in the postamble as well as
+in the pages, so in this sense each font number is defined exactly twice,
+if at all. Like \\{nop} commands, font definitions can
+appear before the first \\{bop}, or between an \\{eop} and a \\{bop}.
+
+\fi
+
+\M{589}Sometimes it is desirable to make horizontal or vertical rules line up
+precisely with certain features in characters of a font. It is possible to
+guarantee the correct matching between \.{DVI} output and the characters
+generated by \MF\ by adhering to the following principles: (1)~The \MF\
+characters should be positioned so that a bottom edge or left edge that is
+supposed to line up with the bottom or left edge of a rule appears at the
+reference point, i.e., in row~0 and column~0 of the \MF\ raster. This
+ensures that the position of the rule will not be rounded differently when
+the pixel size is not a perfect multiple of the units of measurement in
+the \.{DVI} file. (2)~A typeset rule of height $a>0$ and width $b>0$
+should be equivalent to a \MF-generated character having black pixels in
+precisely those raster positions whose \MF\ coordinates satisfy
+$\T{0}\Z\|x<\hbox{$\alpha$}\|b$ and $\T{0}\Z\|y<\hbox{$\alpha$}\|a$, where $\alpha$ is the number
+of pixels per \.{DVI} unit.
+
+\fi
+
+\M{590}The last page in a \.{DVI} file is followed by `\\{post}'; this command
+introduces the postamble, which summarizes important facts that \TeX\ has
+accumulated about the file, making it possible to print subsets of the data
+with reasonable efficiency. The postamble has the form
+$$\vbox{\halign{\hbox{#\hfil}\cr
+\\{post} \|p[\T{4}] \\{num}[\T{4}] \\{den}[\T{4}] \\{mag}[\T{4}] \|l[\T{4}] \|u[\T{4}] \|s[\T{2}] \|t[\T{2}]\cr
+$\langle\,$font definitions$\,\rangle$\cr
+\\{post\_post} \|q[\T{4}] \|i[\T{1}] 223's$[{\G}4]$\cr}}$$
+Here \|p is a pointer to the final \\{bop} in the file. The next three
+parameters, \\{num}, \\{den}, and \\{mag}, are duplicates of the quantities that
+appeared in the preamble.
+
+Parameters \|l and \|u give respectively the height-plus-depth of the tallest
+page and the width of the widest page, in the same units as other dimensions
+of the file. These numbers might be used by a \.{DVI}-reading program to
+position individual ``pages'' on large sheets of film or paper; however,
+the standard convention for output on normal size paper is to position each
+page so that the upper left-hand corner is exactly one inch from the left
+and the top. Experience has shown that it is unwise to design \.{DVI}-to-printer
+software that attempts cleverly to center the output; a fixed position of
+the upper left corner is easiest for users to understand and to work with.
+Therefore \|l and~\|u are often ignored.
+
+Parameter \|s is the maximum stack depth (i.e., the largest excess of
+\\{push} commands over \\{pop} commands) needed to process this file. Then
+comes \|t, the total number of pages (\\{bop} commands) present.
+
+The postamble continues with font definitions, which are any number of
+\\{fnt\_def} commands as described above, possibly interspersed with \\{nop}
+commands. Each font number that is used in the \.{DVI} file must be defined
+exactly twice: Once before it is first selected by a \\{fnt} command, and once
+in the postamble.
+
+\fi
+
+\M{591}The last part of the postamble, following the \\{post\_post} byte that
+signifies the end of the font definitions, contains \|q, a pointer to the
+\\{post} command that started the postamble. An identification byte, \|i,
+comes next; this currently equals~2, as in the preamble.
+
+The \|i byte is followed by four or more bytes that are all equal to
+the decimal number 223 (i.e., 0337 in octal). \TeX\ puts out four to seven of
+these trailing bytes, until the total length of the file is a multiple of
+four bytes, since this works out best on machines that pack four bytes per
+word; but any number of 223's is allowed, as long as there are at least four
+of them. In effect, 223 is a sort of signature that is added at the very end.
+
+This curious way to finish off a \.{DVI} file makes it feasible for
+\.{DVI}-reading programs to find the postamble first, on most computers,
+even though \TeX\ wants to write the postamble last. Most operating
+systems permit random access to individual words or bytes of a file, so
+the \.{DVI} reader can start at the end and skip backwards over the 223's
+until finding the identification byte. Then it can back up four bytes, read
+\|q, and move to byte \|q of the file. This byte should, of course,
+contain the value 248 (\\{post}); now the postamble can be read, so the
+\.{DVI} reader can discover all the information needed for typesetting the
+pages. Note that it is also possible to skip through the \.{DVI} file at
+reasonably high speed to locate a particular page, if that proves
+desirable. This saves a lot of time, since \.{DVI} files used in production
+jobs tend to be large.
+
+Unfortunately, however, standard \PASCAL\ does not include the ability to
+access a random position in a file, or even to determine the length of a file.
+Almost all systems nowadays provide the necessary capabilities, so \.{DVI}
+format has been designed to work most efficiently with modern operating systems.
+But if \.{DVI} files have to be processed under the restrictions of standard
+\PASCAL, one can simply read them from front to back, since the necessary
+header information is present in the preamble and in the font definitions.
+(The \|l and \|u and \|s and \|t parameters, which appear only in the
+postamble, are ``frills'' that are handy but not absolutely necessary.)
+
+\fi
+
+\N{1}{592}Shipping pages out.
+After considering \TeX's eyes and stomach, we come now to the bowels.
+
+The \\{ship\_out} procedure is given a pointer to a box; its mission is
+to describe that box in \.{DVI} form, outputting a ``page'' to \\{dvi\_file}.
+The \.{DVI} coordinates $(h,v)=(0,0)$ should correspond to the upper left
+corner of the box being shipped.
+
+Since boxes can be inside of boxes inside of boxes, the main work of
+\\{ship\_out} is done by two mutually recursive routines, \\{hlist\_out}
+and \\{vlist\_out}, which traverse the hlists and vlists inside of horizontal
+and vertical boxes.
+
+As individual pages are being processed, we need to accumulate
+information about the entire set of pages, since such statistics must be
+reported in the postamble. The global variables \\{total\_pages}, \\{max\_v},
+\\{max\_h}, \\{max\_push}, and \\{last\_bop} are used to record this information.
+
+The variable \\{doing\_leaders} is \\{true} while leaders are being output.
+The variable \\{dead\_cycles} contains the number of times an output routine
+has been initiated since the last \\{ship\_out}.
+
+A few additional global variables are also defined here for use in
+\\{vlist\_out} and \\{hlist\_out}. They could have been local variables, but
+that would waste stack space when boxes are deeply nested, since the
+values of these variables are not needed during recursive calls.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{total\_pages};\C{the number of pages that have been shipped out}\6
+\&{scaled} \\{max\_v};\C{maximum height-plus-depth of pages shipped so far}\6
+\&{scaled} \\{max\_h};\C{maximum width of pages shipped so far}\6
+\&{int} \\{max\_push};\C{deepest nesting of \\{push} commands encountered so far}\6
+\&{int} \\{last\_bop};\C{location of previous \\{bop} in the \.{DVI} output}\6
+\&{int} \\{dead\_cycles};\C{recent outputs that didn't ship anything out}\6
+\&{bool} \\{doing\_leaders};\C{are we inside a leader box?}\7
+\&{quarterword} \|c${},{}$ \|f;\C{character and font in current \\{char\_node}}\6
+\&{scaled} \\{rule\_ht}${},{}$ \\{rule\_dp}${},{}$ \\{rule\_wd};\C{size of current rule being output}\6
+\&{pointer} \|g;\C{current glue specification}\6
+\&{int} \\{lq}${},{}$ \\{lr};\C{quantities used in calculations for leaders}\par
+\fi
+
+\M{593}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{total\_pages}\K\T{0};{}$\5
+${}\\{max\_v}\K\T{0};{}$\5
+${}\\{max\_h}\K\T{0};{}$\5
+${}\\{max\_push}\K\T{0};{}$\5
+${}\\{last\_bop}\K{-}\T{1};{}$\5
+${}\\{doing\_leaders}\K\\{false};{}$\5
+${}\\{dead\_cycles}\K\T{0};{}$\5
+${}\\{cur\_s}\K{-}\T{1}{}$;\par
+\fi
+
+\M{594}The \.{DVI} bytes are output to a buffer instead of being written directly
+to the output file. This makes it possible to reduce the overhead of
+subroutine calls, thereby measurably speeding up the computation, since
+output of \.{DVI} bytes is part of \TeX's inner loop. And it has another
+advantage as well, since we can change instructions in the buffer in order to
+make the output more compact. For example, a `\\{down2}' command can be
+changed to a `\\{y2}', thereby making a subsequent `\\{y0}' command possible,
+saving two bytes.
+
+The output buffer is divided into two parts of equal size; the bytes found
+in $\\{dvi\_buf}[\T{0}\dotdot\\{half\_buf}-\T{1}]$ constitute the first half, and those in
+$\\{dvi\_buf}[\\{half\_buf}\dotdot\\{dvi\_buf\_size}-\T{1}]$ constitute the second. The global
+variable \\{dvi\_ptr} points to the position that will receive the next
+output byte. When \\{dvi\_ptr} reaches \\{dvi\_limit}, which is always equal
+to one of the two values \\{half\_buf} or \\{dvi\_buf\_size}, the half buffer that
+is about to be invaded next is sent to the output and \\{dvi\_limit} is
+changed to its other value. Thus, there is always at least a half buffer's
+worth of information present, except at the very beginning of the job.
+
+Bytes of the \.{DVI} file are numbered sequentially starting with 0;
+the next byte to be generated will be number $\\{dvi\_offset}+\\{dvi\_ptr}$.
+A byte is present in the buffer only if its number is $\G$ \\{dvi\_gone}.
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint16\_t} \&{dvi\_index};\C{an index into the output buffer}\par
+\fi
+
+\M{595}Some systems may find it more efficient to make \\{dvi\_buf} a
+array, since output of four bytes at once may be facilitated.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{eight\_bits} ${}\\{dvi\_buf}[\\{dvi\_buf\_size}+\T{1}]{}$;\C{buffer for \.{DVI} output}\6
+\&{dvi\_index} \\{half\_buf};\C{half of \\{dvi\_buf\_size}}\6
+\&{dvi\_index} \\{dvi\_limit};\C{end of the current half buffer}\6
+\&{dvi\_index} \\{dvi\_ptr};\C{the next available buffer address}\6
+\&{int} \\{dvi\_offset};\C{\\{dvi\_buf\_size} times the number of times the output buffer has been fully emptied}\6
+\&{int} \\{dvi\_gone};\C{the number of bytes already output to \\{dvi\_file}}\par
+\fi
+
+\M{596}Initially the buffer is all in one piece; we will output half of it only
+after it first fills up.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{half\_buf}\K\\{dvi\_buf\_size}/\T{2};{}$\5
+${}\\{dvi\_limit}\K\\{dvi\_buf\_size};{}$\5
+${}\\{dvi\_ptr}\K\T{0};{}$\5
+${}\\{dvi\_offset}\K\T{0};{}$\5
+${}\\{dvi\_gone}\K\T{0}{}$;\par
+\fi
+
+\M{597}The actual output of $\\{dvi\_buf}[\|a\dotdot\|b]$ to \\{dvi\_file} is performed by calling
+$\\{write\_dvi}(\|a,\|b)$. For best results, this procedure should be optimized to
+run as fast as possible on each particular system, since it is part of
+\TeX's inner loop. It is safe to assume that \|a and $\|b+\T{1}$ will both be
+multiples of 4 when $\\{write\_dvi}(\|a,\|b)$ is called; therefore it is possible on
+many machines to use efficient methods to pack four bytes per word and to
+output an array of words with one system call.
+
+\Y\B\&{void} \\{write\_dvi}(\&{dvi\_index} \|a${},\39{}$\&{dvi\_index} \|b)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\7
+\&{for} ${}(\|k\K\|a;{}$ ${}\|k\Z\|b;{}$ ${}\|k\PP){}$\1\5
+${}\\{write}(\\{dvi\_file},\39\.{"\%c"},\39\\{dvi\_buf}[\|k]);{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{598}To put a byte in the buffer without paying the cost of invoking a procedure
+each time, we use the macro \\{dvi\_out}.
+
+\Y\B\4\D$\\{dvi\_out}(\|X)$ \5
+${}\{{}$\5
+\1${}\\{dvi\_buf}[\\{dvi\_ptr}]\K\|X;{}$\5
+\\{incr}(\\{dvi\_ptr});\6
+\&{if} ${}(\\{dvi\_ptr}\E\\{dvi\_limit}){}$\1\5
+\\{dvi\_swap}(\,);\2\6
+\4${}\}{}$\2\par
+\Y\B\&{void} \\{dvi\_swap}(\&{void})\C{outputs half of the buffer}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{dvi\_limit}\E\\{dvi\_buf\_size}){}$\5
+${}\{{}$\5
+\1${}\\{write\_dvi}(\T{0},\39\\{half\_buf}-\T{1});{}$\5
+${}\\{dvi\_limit}\K\\{half\_buf};{}$\5
+${}\\{dvi\_offset}\K\\{dvi\_offset}+\\{dvi\_buf\_size};{}$\5
+${}\\{dvi\_ptr}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{write\_dvi}(\\{half\_buf},\39\\{dvi\_buf\_size}-\T{1});{}$\5
+${}\\{dvi\_limit}\K\\{dvi\_buf\_size};{}$\6
+\4${}\}{}$\2\6
+${}\\{dvi\_gone}\K\\{dvi\_gone}+\\{half\_buf};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{599}Here is how we clean out the buffer when \TeX\ is all through; \\{dvi\_ptr}
+will be a multiple of~4.
+
+\Y\B\4\X599:Empty the last bytes out of \\{dvi\_buf}\X${}\E{}$\6
+\&{if} ${}(\\{dvi\_limit}\E\\{half\_buf}){}$\1\5
+${}\\{write\_dvi}(\\{half\_buf},\39\\{dvi\_buf\_size}-\T{1});{}$\2\6
+\&{if} ${}(\\{dvi\_ptr}>\T{0})$ $\\{write\_dvi}(\T{0},\39\\{dvi\_ptr}-\T{1}{}$)\par
+\U642.\fi
+
+\M{600}The \\{dvi\_four} procedure outputs four bytes in two's complement notation,
+without risking arithmetic overflow.
+
+\Y\B\&{void} \\{dvi\_four}(\&{int} \|x)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|x\G\T{0}){}$\1\5
+${}\\{dvi\_out}(\|x/\T{\~100000000}){}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|x\K\|x+\T{\~10000000000};{}$\5
+${}\|x\K\|x+\T{\~10000000000};{}$\5
+${}\\{dvi\_out}((\|x/\T{\~100000000})+\T{128});{}$\6
+\4${}\}{}$\2\6
+${}\|x\K\|x\MOD\T{\~100000000};{}$\5
+${}\\{dvi\_out}(\|x/\T{\~200000});{}$\5
+${}\|x\K\|x\MOD\T{\~200000};{}$\5
+${}\\{dvi\_out}(\|x/\T{\~400});{}$\5
+${}\\{dvi\_out}(\|x\MOD\T{\~400});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{601}A mild optimization of the output is performed by the \\{dvi\_pop}
+routine, which issues a \\{pop} unless it is possible to cancel a
+`\\{push} \\{pop}' pair. The parameter to \\{dvi\_pop} is the byte address
+following the old \\{push} that matches the new \\{pop}.
+
+\Y\B\&{void} \\{dvi\_pop}(\&{int} \|l)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}((\|l\E\\{dvi\_offset}+\\{dvi\_ptr})\W(\\{dvi\_ptr}>\T{0})){}$\1\5
+\\{decr}(\\{dvi\_ptr});\2\6
+\&{else}\1\5
+\\{dvi\_out}(\\{pop});\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{602}Here's a procedure that outputs a font definition. Since \TeX82 uses at
+most 256 different fonts per job, \\{fnt\_def1} is always used as the command code.
+
+\Y\B\&{void} \\{dvi\_font\_def}(\&{internal\_font\_number} \|f)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{index into \\{str\_pool}}\7
+\\{dvi\_out}(\\{fnt\_def1});\5
+${}\\{dvi\_out}(\|f-\\{font\_base}-\T{1}){}$;\6
+${}\\{dvi\_out}(\\{qo}(\\{font\_check}[\|f].\\{b0}));{}$\5
+${}\\{dvi\_out}(\\{qo}(\\{font\_check}[\|f].\\{b1}));{}$\5
+${}\\{dvi\_out}(\\{qo}(\\{font\_check}[\|f].\\{b2}));{}$\5
+${}\\{dvi\_out}(\\{qo}(\\{font\_check}[\|f].\\{b3})){}$;\6
+\\{dvi\_four}(\\{font\_size}[\|f]);\5
+\\{dvi\_four}(\\{font\_dsize}[\|f]);\6
+\\{dvi\_out}(\\{length}(\\{font\_area}[\|f]));\5
+\\{dvi\_out}(\\{length}(\\{font\_name}[\|f]));\5
+\X603:Output the font name whose internal number is \|f\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{603}\B\X603:Output the font name whose internal number is \|f\X${}\E{}$\6
+\&{for} ${}(\|k\K\\{str\_start}[\\{font\_area}[\|f]];{}$ ${}\|k\Z\\{str\_start}[\\{font\_area}[\|f]+\T{1}]-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{dvi\_out}(\\{so}(\\{str\_pool}[\|k]));\2\6
+\&{for} ${}(\|k\K\\{str\_start}[\\{font\_name}[\|f]];{}$ ${}\|k\Z\\{str\_start}[\\{font\_name}[\|f]+\T{1}]-\T{1};{}$ ${}\|k\PP)$ \\{dvi\_out}(\\{so}(\\{str\_pool}[\|k]))\par
+\U602.\fi
+
+\M{604}Versions of \TeX\ intended for small computers might well choose to omit
+the ideas in the next few parts of this program, since it is not really
+necessary to optimize the \.{DVI} code by making use of the \\{w0}, \\{x0},
+\\{y0}, and \\{z0} commands. Furthermore, the algorithm that we are about to
+describe does not pretend to give an optimum reduction in the length
+of the \.{DVI} code; after all, speed is more important than compactness.
+But the method is surprisingly effective, and it takes comparatively little
+time.
+
+We can best understand the basic idea by first considering a simpler problem
+that has the same essential characteristics. Given a sequence of digits,
+say $3\,1\,4\,1\,5\,9\,2\,6\,5\,3\,5\,8\,9$, we want to assign subscripts
+$d$, $y$, or $z$ to each digit so as to maximize the number of ``$y$-hits''
+and ``$z$-hits''; a $y$-hit is an instance of two appearances of the same
+digit with the subscript $y$, where no $y$'s intervene between the two
+appearances, and a $z$-hit is defined similarly. For example, the sequence
+above could be decorated with subscripts as follows:
+$$3_z\,1_y\,4_d\,1_y\,5_y\,9_d\,2_d\,6_d\,5_y\,3_z\,5_y\,8_d\,9_d.$$
+There are three $y$-hits ($1_y\ldots1_y$ and $5_y\ldots5_y\ldots5_y$) and
+one $z$-hit ($3_z\ldots3_z$); there are no $d$-hits, since the two appearances
+of $9_d$ have $d$'s between them, but we don't count $d$-hits so it doesn't
+matter how many there are. These subscripts are analogous to the \.{DVI}
+commands called \\{down}, $y$, and $z$, and the digits are analogous to
+different amounts of vertical motion; a $y$-hit or $z$-hit corresponds to
+the opportunity to use the one-byte commands \\{y0} or \\{z0} in a \.{DVI} file.
+
+\TeX's method of assigning subscripts works like this: Append a new digit,
+say $\delta$, to the right of the sequence. Now look back through the
+sequence until one of the following things happens: (a)~You see
+$\delta_y$ or $\delta_z$, and this was the first time you encountered a
+$y$ or $z$ subscript, respectively. Then assign $y$ or $z$ to the new
+$\delta$; you have scored a hit. (b)~You see $\delta_d$, and no $y$
+subscripts have been encountered so far during this search. Then change
+the previous $\delta_d$ to $\delta_y$ (this corresponds to changing a
+command in the output buffer), and assign $y$ to the new $\delta$; it's
+another hit. (c)~You see $\delta_d$, and a $y$ subscript has been seen
+but not a $z$. Change the previous $\delta_d$ to $\delta_z$ and assign
+$z$ to the new $\delta$. (d)~You encounter both $y$ and $z$ subscripts
+before encountering a suitable $\delta$, or you scan all the way to the
+front of the sequence. Assign $d$ to the new $\delta$; this assignment may
+be changed later.
+
+The subscripts $3_z\,1_y\,4_d\ldots\,$ in the example above were, in fact,
+produced by this procedure, as the reader can verify. (Go ahead and try it.)
+
+\fi
+
+\M{605}In order to implement such an idea, \TeX\ maintains a stack of pointers
+to the \\{down}, $y$, and $z$ commands that have been generated for the
+current page. And there is a similar stack for \\{right}, \|w, and \|x
+commands. These stacks are called the down stack and right stack, and their
+top elements are maintained in the variables \\{down\_ptr} and \\{right\_ptr}.
+
+Each entry in these stacks contains four fields: The \\{width} field is
+the amount of motion down or to the right; the \\{location} field is the
+byte number of the \.{DVI} command in question (including the appropriate
+\\{dvi\_offset}); the \\{link} field points to the next item below this one
+on the stack; and the \\{info} field encodes the options for possible change
+in the \.{DVI} command.
+
+\Y\B\4\D$\\{movement\_node\_size}$ \5
+\T{3}\C{number of words per entry in the down and right stacks}\par
+\B\4\D$\\{location}(\|X)$ \5
+$\\{mem}[\|X+\T{2}].{}$\|i\C{\.{DVI} byte number for a movement command}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{down\_ptr}${},{}$ \\{right\_ptr};\C{heads of the down and right stacks}\par
+\fi
+
+\M{606}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{down\_ptr}\K\\{null};{}$\5
+${}\\{right\_ptr}\K\\{null}{}$;\par
+\fi
+
+\M{607}Here is a subroutine that produces a \.{DVI} command for some specified
+downward or rightward motion. It has two parameters: \|w is the amount
+of motion, and \|o is either \\{down1} or \\{right1}. We use the fact that
+the command codes have convenient arithmetic properties: $\\{y1}-\\{down1}\E\\{w1}-\\{right1}$
+and $\\{z1}-\\{down1}\E\\{x1}-\\{right1}$.
+
+\Y\B\&{void} \\{movement}(\&{scaled} \|w${},\39{}$\&{eight\_bits} \|o)\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \\{mstate};\C{have we seen a \|y or \|z?}\6
+\&{pointer} \|p${},{}$ \|q;\C{current and top nodes on the stack}\6
+\&{int} \|k;\C{index into \\{dvi\_buf}, modulo \\{dvi\_buf\_size}}\7
+${}\|q\K\\{get\_node}(\\{movement\_node\_size}){}$;\C{new node for the top of the stack}\6
+${}\\{width}(\|q)\K\|w;{}$\5
+${}\\{location}(\|q)\K\\{dvi\_offset}+\\{dvi\_ptr};{}$\6
+\&{if} ${}(\|o\E\\{down1}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{down\_ptr};{}$\5
+${}\\{down\_ptr}\K\|q;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{right\_ptr};{}$\5
+${}\\{right\_ptr}\K\|q;{}$\6
+\4${}\}{}$\2\6
+\X611:Look at the other stack entries until deciding what sort of \.{DVI} command to generate; \&{goto} \\{found} if node \|p is a ``hit''\X;\6
+\X610:Generate a \\{down} or \\{right} command for \|w and \&{return}\X;\6
+\4\\{found}:\5
+\X609:Generate a \\{y0} or \\{z0} command in order to reuse a previous appearance of~\|w\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{608}The \\{info} fields in the entries of the down stack or the right stack
+have six possible settings: \\{y\_here} or \\{z\_here} mean that the \.{DVI}
+command refers to \|y or \|z, respectively (or to \|w or \|x, in the
+case of horizontal motion); \\{yz\_OK} means that the \.{DVI} command is
+\\{down} (or \\{right}) but can be changed to either \|y or \|z (or
+to either \|w or \|x); \\{y\_OK} means that it is \\{down} and can be changed
+to \|y but not \|z; \\{z\_OK} is similar; and \\{d\_fixed} means it must stay
+\\{down}.
+
+The four settings \\{yz\_OK}, \\{y\_OK}, \\{z\_OK}, \\{d\_fixed} would not need to
+be distinguished from each other if we were simply solving the
+digit-subscripting problem mentioned above. But in \TeX's case there is
+a complication because of the nested structure of \\{push} and \\{pop}
+commands. Suppose we add parentheses to the digit-subscripting problem,
+redefining hits so that $\delta_y\ldots \delta_y$ is a hit if all $y$'s between
+the $\delta$'s are enclosed in properly nested parentheses, and if the
+parenthesis level of the right-hand $\delta_y$ is deeper than or equal to
+that of the left-hand one. Thus, `(' and `)' correspond to `\\{push}'
+and `\\{pop}'. Now if we want to assign a subscript to the final 1 in the
+sequence
+$$2_y\,7_d\,1_d\,(\,8_z\,2_y\,8_z\,)\,1$$
+we cannot change the previous $1_d$ to $1_y$, since that would invalidate
+the $2_y\ldots2_y$ hit. But we can change it to $1_z$, scoring a hit
+since the intervening $8_z$'s are enclosed in parentheses.
+
+The program below removes movement nodes that are introduced after a \\{push},
+before it outputs the corresponding \\{pop}.
+
+\Y\B\4\D$\\{y\_here}$ \5
+\T{1}\C{\\{info} when the movement entry points to a \|y command}\par
+\B\4\D$\\{z\_here}$ \5
+\T{2}\C{\\{info} when the movement entry points to a \|z command}\par
+\B\4\D$\\{yz\_OK}$ \5
+\T{3}\C{\\{info} corresponding to an unconstrained \\{down} command}\par
+\B\4\D$\\{y\_OK}$ \5
+\T{4}\C{\\{info} corresponding to a \\{down} that can't become a \|z}\par
+\B\4\D$\\{z\_OK}$ \5
+\T{5}\C{\\{info} corresponding to a \\{down} that can't become a \|y}\par
+\B\4\D$\\{d\_fixed}$ \5
+\T{6}\C{\\{info} corresponding to a \\{down} that can't change}\par
+\fi
+
+\M{609}When the \\{movement} procedure gets to the label \\{found}, the value of
+\\{info}(\|p) will be either \\{y\_here} or \\{z\_here}. If it is, say, \\{y\_here},
+the procedure generates a \\{y0} command (or a \\{w0} command), and marks
+all \\{info} fields between \|q and \|p so that \|y is not OK in that range.
+
+\Y\B\4\X609:Generate a \\{y0} or \\{z0} command in order to reuse a previous appearance of~\|w\X${}\E{}$\6
+$\\{info}(\|q)\K\\{info}(\|p);{}$\6
+\&{if} ${}(\\{info}(\|q)\E\\{y\_here}){}$\5
+${}\{{}$\5
+\1${}\\{dvi\_out}(\|o+\\{y0}-\\{down1}){}$;\C{\\{y0} or \\{w0}}\6
+\&{while} ${}(\\{link}(\|q)\I\|p){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{link}(\|q);{}$\6
+\&{switch} (\\{info}(\|q))\5
+${}\{{}$\1\6
+\4\&{case} \\{yz\_OK}:\5
+${}\\{info}(\|q)\K\\{z\_OK}{}$;\5
+\&{break};\6
+\4\&{case} \\{y\_OK}:\5
+${}\\{info}(\|q)\K\\{d\_fixed}{}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{dvi\_out}(\|o+\\{z0}-\\{down1}){}$;\C{\\{z0} or \\{x0}}\6
+\&{while} ${}(\\{link}(\|q)\I\|p){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{link}(\|q);{}$\6
+\&{switch} (\\{info}(\|q))\5
+${}\{{}$\1\6
+\4\&{case} \\{yz\_OK}:\5
+${}\\{info}(\|q)\K\\{y\_OK}{}$;\5
+\&{break};\6
+\4\&{case} \\{z\_OK}:\5
+${}\\{info}(\|q)\K\\{d\_fixed}{}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U607.\fi
+
+\M{610}\B\X610:Generate a \\{down} or \\{right} command for \|w and \&{return}\X${}\E{}$\6
+$\\{info}(\|q)\K\\{yz\_OK};{}$\6
+\&{if} ${}(\\{abs}(\|w)\G\T{\~40000000}){}$\5
+${}\{{}$\5
+\1${}\\{dvi\_out}(\|o+\T{3}){}$;\C{\\{down4} or \\{right4}}\6
+\\{dvi\_four}(\|w);\5
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{abs}(\|w)\G\T{\~100000}){}$\5
+${}\{{}$\5
+\1${}\\{dvi\_out}(\|o+\T{2}){}$;\C{\\{down3} or \\{right3}}\6
+\&{if} ${}(\|w<\T{0}){}$\1\5
+${}\|w\K\|w+\T{\~100000000};{}$\2\6
+${}\\{dvi\_out}(\|w/\T{\~200000});{}$\5
+${}\|w\K\|w\MOD\T{\~200000};{}$\5
+\&{goto} \\{label2};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{abs}(\|w)\G\T{\~200}){}$\5
+${}\{{}$\5
+\1${}\\{dvi\_out}(\|o+\T{1}){}$;\C{\\{down2} or \\{right2}}\6
+\&{if} ${}(\|w<\T{0}){}$\1\5
+${}\|w\K\|w+\T{\~200000};{}$\2\6
+\&{goto} \\{label2};\6
+\4${}\}{}$\2\6
+\\{dvi\_out}(\|o);\C{\\{down1} or \\{right1}}\6
+\&{if} ${}(\|w<\T{0}){}$\1\5
+${}\|w\K\|w+\T{\~400};{}$\2\6
+\&{goto} \\{label1};\6
+\4\\{label2}:\5
+${}\\{dvi\_out}(\|w/\T{\~400});{}$\6
+\4\\{label1}:\5
+${}\\{dvi\_out}(\|w\MOD\T{\~400});$ \&{return}\par
+\U607.\fi
+
+\M{611}As we search through the stack, we are in one of three states,
+\\{y\_seen}, \\{z\_seen}, or \\{none\_seen}, depending on whether we have
+encountered \\{y\_here} or \\{z\_here} nodes. These states are encoded as
+multiples of 6, so that they can be added to the \\{info} fields for quick
+decision-making.
+
+\Y\B\4\D$\\{none\_seen}$ \5
+\T{0}\C{no \\{y\_here} or \\{z\_here} nodes have been encountered yet}\par
+\B\4\D$\\{y\_seen}$ \5
+\T{6}\C{we have seen \\{y\_here} but not \\{z\_here}}\par
+\B\4\D$\\{z\_seen}$ \5
+\T{12}\C{we have seen \\{z\_here} but not \\{y\_here}}\par
+\Y\B\4\X611:Look at the other stack entries until deciding what sort of \.{DVI} command to generate; \&{goto} \\{found} if node \|p is a ``hit''\X${}\E{}$\6
+$\|p\K\\{link}(\|q);{}$\5
+${}\\{mstate}\K\\{none\_seen};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{width}(\|p)\E\|w){}$\1\5
+\X612:Consider a node with matching width; \&{goto} \\{found} if it's a hit\X\2\6
+\&{else}\1\6
+\&{switch} ${}(\\{mstate}+\\{info}(\|p)){}$\5
+${}\{{}$\1\6
+\4\&{case} \\{none\_seen}${}+\\{y\_here}{}$:\5
+${}\\{mstate}\K\\{y\_seen}{}$;\5
+\&{break};\6
+\4\&{case} \\{none\_seen}${}+\\{z\_here}{}$:\5
+${}\\{mstate}\K\\{z\_seen}{}$;\5
+\&{break};\6
+\4\&{case} \\{y\_seen}${}+\\{z\_here}{}$:\5
+\&{case} \\{z\_seen}${}+\\{y\_here}{}$:\5
+\&{goto} \\{not\_found};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\\{not\_found}:\par
+\U607.\fi
+
+\M{612}We might find a valid hit in a \|y or \|z byte that is already gone
+from the buffer. But we can't change bytes that are gone forever; ``the
+moving finger writes, $\ldots\,\,$.''
+
+\Y\B\4\X612:Consider a node with matching width; \&{goto} \\{found} if it's a hit\X${}\E{}$\6
+\&{switch} ${}(\\{mstate}+\\{info}(\|p)){}$\5
+${}\{{}$\1\6
+\4\&{case} \\{none\_seen}${}+\\{yz\_OK}{}$:\5
+\&{case} \\{none\_seen}${}+\\{y\_OK}{}$:\5
+\&{case} \\{z\_seen}${}+\\{yz\_OK}{}$:\5
+\&{case} \\{z\_seen}${}+\\{y\_OK}{}$:\5
+\hbox{}\6
+\&{if} ${}(\\{location}(\|p)<\\{dvi\_gone}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\&{else}\1\5
+\X613:Change buffered instruction to \|y or \|w and \&{goto} \\{found}\X\5
+\2\&{break};\6
+\4\&{case} \\{none\_seen}${}+\\{z\_OK}{}$:\5
+\&{case} \\{y\_seen}${}+\\{yz\_OK}{}$:\5
+\&{case} \\{y\_seen}${}+\\{z\_OK}{}$:\5
+\hbox{}\6
+\&{if} ${}(\\{location}(\|p)<\\{dvi\_gone}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\&{else}\1\5
+\X614:Change buffered instruction to \|z or \|x and \&{goto} \\{found}\X\5
+\2\&{break};\6
+\4\&{case} \\{none\_seen}${}+\\{y\_here}{}$:\5
+\&{case} \\{none\_seen}${}+\\{z\_here}{}$:\5
+\&{case} \\{y\_seen}${}+\\{z\_here}{}$:\5
+\&{case} \\{z\_seen}${}+\\{y\_here}{}$:\5
+\&{goto} \\{found};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\par
+\U611.\fi
+
+\M{613}\B\X613:Change buffered instruction to \|y or \|w and \&{goto} \\{found}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|k\K\\{location}(\|p)-\\{dvi\_offset};{}$\6
+\&{if} ${}(\|k<\T{0}){}$\1\5
+${}\|k\K\|k+\\{dvi\_buf\_size};{}$\2\6
+${}\\{dvi\_buf}[\|k]\K\\{dvi\_buf}[\|k]+\\{y1}-\\{down1};{}$\5
+${}\\{info}(\|p)\K\\{y\_here};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\par
+\U612.\fi
+
+\M{614}\B\X614:Change buffered instruction to \|z or \|x and \&{goto} \\{found}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|k\K\\{location}(\|p)-\\{dvi\_offset};{}$\6
+\&{if} ${}(\|k<\T{0}){}$\1\5
+${}\|k\K\|k+\\{dvi\_buf\_size};{}$\2\6
+${}\\{dvi\_buf}[\|k]\K\\{dvi\_buf}[\|k]+\\{z1}-\\{down1};{}$\5
+${}\\{info}(\|p)\K\\{z\_here};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\par
+\U612.\fi
+
+\M{615}In case you are wondering when all the movement nodes are removed from
+\TeX's memory, the answer is that they are recycled just before
+\\{hlist\_out} and \\{vlist\_out} finish outputting a box. This restores the
+down and right stacks to the state they were in before the box was output,
+except that some \\{info}'s may have become more restrictive.
+
+\Y\B\&{void} \\{prune\_movements}(\&{int} \|l)\C{delete movement nodes with $\\{location}\G\|l$}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{node being deleted}\7
+\&{while} ${}(\\{down\_ptr}\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{location}(\\{down\_ptr})<\|l){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|p\K\\{down\_ptr};{}$\5
+${}\\{down\_ptr}\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\|p,\39\\{movement\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\4\\{done}:\6
+\&{while} ${}(\\{right\_ptr}\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{location}(\\{right\_ptr})<\|l){}$\1\5
+\&{return};\2\6
+${}\|p\K\\{right\_ptr};{}$\5
+${}\\{right\_ptr}\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\|p,\39\\{movement\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{616}The actual distances by which we want to move might be computed as the
+sum of several separate movements. For example, there might be several
+glue nodes in succession, or we might want to move right by the width of
+some box plus some amount of glue. More importantly, the baselineskip
+distances are computed in terms of glue together with the depth and
+height of adjacent boxes, and we want the \.{DVI} file to lump these
+three quantities together into a single motion.
+
+Therefore, \TeX\ maintains two pairs of global variables: \\{dvi\_h} and \\{dvi\_v}
+are the \|h and \|v coordinates corresponding to the commands actually
+output to the \.{DVI} file, while \\{cur\_h} and \\{cur\_v} are the coordinates
+corresponding to the current state of the output routines. Coordinate
+changes will accumulate in \\{cur\_h} and \\{cur\_v} without being reflected
+in the output, until such a change becomes necessary or desirable; we
+can call the \\{movement} procedure whenever we want to make $\\{dvi\_h}\E\\{cur\_h}$
+or $\\{dvi\_v}\E\\{cur\_v}$.
+
+The current font reflected in the \.{DVI} output is called \\{dvi\_f};
+there is no need for a `\\{cur\_f}' variable.
+
+The depth of nesting of \\{hlist\_out} and \\{vlist\_out} is called \\{cur\_s};
+this is essentially the depth of \\{push} commands in the \.{DVI} output.
+
+\Y\B\4\D$\\{synch\_h}$ \6
+\&{if} ${}(\\{cur\_h}\I\\{dvi\_h}){}$\5
+${}\{{}$\5
+\1${}\\{movement}(\\{cur\_h}-\\{dvi\_h},\39\\{right1});{}$\5
+${}\\{dvi\_h}\K\\{cur\_h};{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{synch\_v}$ \6
+\&{if} ${}(\\{cur\_v}\I\\{dvi\_v}){}$\5
+${}\{{}$\5
+\1${}\\{movement}(\\{cur\_v}-\\{dvi\_v},\39\\{down1});{}$\5
+${}\\{dvi\_v}\K\\{cur\_v};{}$\6
+\4${}\}{}$\2\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} \\{dvi\_h}${},{}$ \\{dvi\_v};\C{a \.{DVI} reader program thinks we are here}\6
+\&{scaled} \\{cur\_h}${},{}$ \\{cur\_v};\C{\TeX\ thinks we are here}\6
+\&{internal\_font\_number} \\{dvi\_f};\C{the current font}\6
+\&{int} \\{cur\_s};\C{current depth of output box nesting, initially $-1$}\par
+\fi
+
+\M{617}\B\X617:Initialize variables as \\{ship\_out} begins\X${}\E{}$\6
+$\\{dvi\_h}\K\T{0};{}$\5
+${}\\{dvi\_v}\K\T{0};{}$\5
+${}\\{cur\_h}\K\\{h\_offset};{}$\5
+${}\\{dvi\_f}\K\\{null\_font};{}$\5
+\X531:ensure dvi open\X;\6
+\&{if} ${}(\\{total\_pages}\E\T{0}){}$\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{pre});\5
+\\{dvi\_out}(\\{id\_byte});\C{output the preamble}\6
+\\{dvi\_four}(\T{25400000});\5
+\\{dvi\_four}(\T{473628672});\C{conversion ratio for sp}\6
+\\{prepare\_mag}(\,);\5
+\\{dvi\_four}(\\{mag});\C{magnification factor is frozen}\6
+${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+\\{print\_str}(\.{"\ TeX\ output\ "});\5
+\\{print\_int}(\\{year});\5
+\\{print\_char}(\.{'.'});\5
+\\{print\_two}(\\{month});\5
+\\{print\_char}(\.{'.'});\5
+\\{print\_two}(\\{day});\5
+\\{print\_char}(\.{':'});\5
+${}\\{print\_two}(\\{time}/\T{60});{}$\5
+${}\\{print\_two}(\\{time}\MOD\T{60});{}$\5
+${}\\{selector}\K\\{old\_setting};{}$\5
+\\{dvi\_out}(\\{cur\_length});\6
+\&{for} ${}(\|s\K\\{str\_start}[\\{str\_ptr}];{}$ ${}\|s\Z\\{pool\_ptr}-\T{1};{}$ ${}\|s\PP){}$\1\5
+\\{dvi\_out}(\\{so}(\\{str\_pool}[\|s]));\2\6
+${}\\{pool\_ptr}\K\\{str\_start}[\\{str\_ptr}]{}$;\C{flush the current string}\6
+\4${}\}{}$\2\par
+\U640.\fi
+
+\M{618}When \\{hlist\_out} is called, its duty is to output the box represented
+by the \\{hlist\_node} pointed to by \\{temp\_ptr}. The reference point of that
+box has coordinates $(\\{cur\_h},\\{cur\_v})$.
+
+Similarly, when \\{vlist\_out} is called, its duty is to output the box represented
+by the \\{vlist\_node} pointed to by \\{temp\_ptr}. The reference point of that
+box has coordinates $(\\{cur\_h},\\{cur\_v})$.
+
+\Y\B\&{void} \\{vlist\_out}(\&{void});\C{\\{hlist\_out} and \\{vlist\_out} are mutually recursive}\par
+\fi
+
+\M{619}The recursive procedures \\{hlist\_out} and \\{vlist\_out} each have local variables
+\\{save\_h} and \\{save\_v} to hold the values of \\{dvi\_h} and \\{dvi\_v} just before
+entering a new level of recursion. In effect, the values of \\{save\_h} and
+\\{save\_v} on \TeX's run-time stack correspond to the values of \|h and \|v
+that a \.{DVI}-reading program will push onto its coordinate stack.
+
+\Y\B\hbox{\4}\X1368:Declare procedures needed in \\{hlist\_out}, \\{vlist\_out}\X\hbox{}\1\1\6
+\&{void} \\{hlist\_out}(\&{void})\C{output an \\{hlist\_node} box}\6
+${}\{{}$\5
+\1\&{scaled} \\{base\_line};\C{the baseline coordinate for this box}\6
+\&{scaled} \\{left\_edge};\C{the left coordinate for this box}\6
+\&{scaled} \\{save\_h}${},{}$ \\{save\_v};\C{what \\{dvi\_h} and \\{dvi\_v} should pop to}\6
+\&{pointer} \\{this\_box};\C{pointer to containing box}\6
+\&{glue\_ord} \\{g\_order};\C{applicable order of infinity for glue}\6
+\&{uint8\_t} \\{g\_sign};\C{selects type of glue}\6
+\&{pointer} \|p;\C{current position in the hlist}\6
+\&{int} \\{save\_loc};\C{\.{DVI} byte location upon entry}\6
+\&{pointer} \\{leader\_box};\C{the leader box being replicated}\6
+\&{scaled} \\{leader\_wd};\C{width of leader box being replicated}\6
+\&{scaled} \\{lx};\C{extra space between leader boxes}\6
+\&{bool} \\{outer\_doing\_leaders};\C{were we doing leaders?}\6
+\&{scaled} \\{edge};\C{left edge of sub-box, or right edge of leader space}\6
+\&{double} \\{glue\_temp};\C{glue value before rounding}\6
+\&{double} \\{cur\_glue};\C{glue seen so far}\6
+\&{scaled} \\{cur\_g};\C{rounded equivalent of \\{cur\_glue} times the glue ratio}\7
+${}\\{cur\_g}\K\T{0};{}$\5
+${}\\{cur\_glue}\K\\{float\_constant}(\T{0});{}$\5
+${}\\{this\_box}\K\\{temp\_ptr};{}$\5
+${}\\{g\_order}\K\\{glue\_order}(\\{this\_box});{}$\5
+${}\\{g\_sign}\K\\{glue\_sign}(\\{this\_box});{}$\5
+${}\|p\K\\{list\_ptr}(\\{this\_box});{}$\5
+\\{incr}(\\{cur\_s});\6
+\&{if} ${}(\\{cur\_s}>\T{0}){}$\1\5
+\\{dvi\_out}(\\{push});\2\6
+\&{if} ${}(\\{cur\_s}>\\{max\_push}){}$\1\5
+${}\\{max\_push}\K\\{cur\_s};{}$\2\6
+${}\\{save\_loc}\K\\{dvi\_offset}+\\{dvi\_ptr};{}$\5
+${}\\{base\_line}\K\\{cur\_v};{}$\5
+${}\\{left\_edge}\K\\{cur\_h};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\1\5
+\X620:Output node \|p for \\{hlist\_out} and move to the next node, maintaining the condition $\\{cur\_v}\K\\{base\_line}$\X;\2\6
+\\{prune\_movements}(\\{save\_loc});\6
+\&{if} ${}(\\{cur\_s}>\T{0}){}$\1\5
+\\{dvi\_pop}(\\{save\_loc});\2\6
+\\{decr}(\\{cur\_s});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{620}We ought to give special care to the efficiency of one part of \\{hlist\_out},
+since it belongs to \TeX's inner loop. When a \\{char\_node} is encountered,
+we save a little time by processing several nodes in succession until
+reaching a non-\\{char\_node}. The program uses the fact that $\\{set\_char\_0}\E\T{0}$.
+
+\Y\B\4\X620:Output node \|p for \\{hlist\_out} and move to the next node, maintaining the condition $\\{cur\_v}\K\\{base\_line}$\X${}\E{}$\6
+\4\\{reswitch}:\6
+\&{if} (\\{is\_char\_node}(\|p))\5
+${}\{{}$\5
+\1\\{synch\_h};\5
+\\{synch\_v};\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|f\K\\{font}(\|p);{}$\5
+${}\|c\K\\{character}(\|p);{}$\6
+\&{if} ${}(\|f\I\\{dvi\_f}){}$\1\5
+\X621:Change font \\{dvi\_f} to \|f\X;\2\6
+\&{if} ${}(\|c\G\\{qi}(\T{128})){}$\1\5
+\\{dvi\_out}(\\{set1});\2\6
+\\{dvi\_out}(\\{qo}(\|c));\6
+${}\\{cur\_h}\K\\{cur\_h}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\|c));{}$\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\R\\{is\_char\_node}(\|p)));{}$\5
+${}\\{dvi\_h}\K\\{cur\_h};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\X622:Output the non-\\{char\_node} \|p for \\{hlist\_out} and move to the next node\X\2\par
+\U619.\fi
+
+\M{621}\B\X621:Change font \\{dvi\_f} to \|f\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\R\\{font\_used}[\|f]){}$\5
+${}\{{}$\5
+\1\\{dvi\_font\_def}(\|f);\5
+${}\\{font\_used}[\|f]\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|f\Z\T{64}+\\{font\_base}){}$\1\5
+${}\\{dvi\_out}(\|f-\\{font\_base}-\T{1}+\\{fnt\_num\_0}){}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{fnt1});\5
+${}\\{dvi\_out}(\|f-\\{font\_base}-\T{1});{}$\6
+\4${}\}{}$\2\6
+${}\\{dvi\_f}\K\|f;{}$\6
+\4${}\}{}$\2\par
+\U620.\fi
+
+\M{622}\B\X622:Output the non-\\{char\_node} \|p for \\{hlist\_out} and move to the next node\X${}\E{}$\6
+${}\{{}$\5
+\1\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\X623:Output a box in an hlist\X\5
+\&{break};\6
+\4\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1${}\\{rule\_ht}\K\\{height}(\|p);{}$\5
+${}\\{rule\_dp}\K\\{depth}(\|p);{}$\5
+${}\\{rule\_wd}\K\\{width}(\|p);{}$\5
+\&{goto} \\{fin\_rule};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1367:Output the whatsit node \|p in an hlist\X;\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X625:Move right or output leaders\X\6
+\4\&{case} \\{kern\_node}:\5
+\&{case} \\{math\_node}:\5
+${}\\{cur\_h}\K\\{cur\_h}+\\{width}(\|p){}$;\5
+\&{break};\6
+\4\&{case} \\{ligature\_node}:\5
+\X652:Make node \|p look like a \\{char\_node} and \&{goto} \\{reswitch}\X\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\&{goto} \\{next\_p};\6
+\4\\{fin\_rule}:\5
+\X624:Output a rule in an hlist\X;\6
+\4\\{move\_past}:\5
+${}\\{cur\_h}\K\\{cur\_h}+\\{rule\_wd};{}$\6
+\4\\{next\_p}:\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\par
+\U620.\fi
+
+\M{623}\B\X623:Output a box in an hlist\X${}\E{}$\6
+\&{if} ${}(\\{list\_ptr}(\|p)\E\\{null}){}$\1\5
+${}\\{cur\_h}\K\\{cur\_h}+\\{width}(\|p);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{save\_h}\K\\{dvi\_h};{}$\5
+${}\\{save\_v}\K\\{dvi\_v};{}$\5
+${}\\{cur\_v}\K\\{base\_line}+\\{shift\_amount}(\|p){}$;\C{shift the box down}\6
+${}\\{temp\_ptr}\K\|p;{}$\5
+${}\\{edge}\K\\{cur\_h};{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{vlist\_node}){}$\1\5
+\\{vlist\_out}(\,);\5
+\2\&{else}\1\5
+\\{hlist\_out}(\,);\2\6
+${}\\{dvi\_h}\K\\{save\_h};{}$\5
+${}\\{dvi\_v}\K\\{save\_v};{}$\5
+${}\\{cur\_h}\K\\{edge}+\\{width}(\|p);{}$\5
+${}\\{cur\_v}\K\\{base\_line};{}$\6
+\4${}\}{}$\2\par
+\U622.\fi
+
+\M{624}\B\X624:Output a rule in an hlist\X${}\E{}$\6
+\&{if} (\\{is\_running}(\\{rule\_ht}))\1\5
+${}\\{rule\_ht}\K\\{height}(\\{this\_box});{}$\2\6
+\&{if} (\\{is\_running}(\\{rule\_dp}))\1\5
+${}\\{rule\_dp}\K\\{depth}(\\{this\_box});{}$\2\6
+${}\\{rule\_ht}\K\\{rule\_ht}+\\{rule\_dp}{}$;\C{this is the rule thickness}\6
+\&{if} ${}((\\{rule\_ht}>\T{0})\W(\\{rule\_wd}>\T{0}){}$)\C{we don't output empty rules}\6
+${}\{{}$\5
+\1\\{synch\_h};\5
+${}\\{cur\_v}\K\\{base\_line}+\\{rule\_dp};{}$\5
+\\{synch\_v};\5
+\\{dvi\_out}(\\{set\_rule});\5
+\\{dvi\_four}(\\{rule\_ht});\5
+\\{dvi\_four}(\\{rule\_wd});\5
+${}\\{cur\_v}\K\\{base\_line};{}$\5
+${}\\{dvi\_h}\K\\{dvi\_h}+\\{rule\_wd};{}$\6
+\4${}\}{}$\2\par
+\U622.\fi
+
+\M{625}\B\D$\\{billion}$ \5
+\\{float\_constant}(\T{1000000000})\par
+\B\4\D$\\{vet\_glue}(\|X)$ \5
+$\\{glue\_temp}\K\|X;$ \6
+\&{if} ${}(\\{glue\_temp}>\\{billion}){}$\1\5
+${}\\{glue\_temp}\K\\{billion};{}$\2\6
+\&{else} \&{if} ${}(\\{glue\_temp}<{-}\\{billion})$ $\\{glue\_temp}\K{-}{}$\\{billion}\par
+\Y\B\4\X625:Move right or output leaders\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|g\K\\{glue\_ptr}(\|p);{}$\5
+${}\\{rule\_wd}\K\\{width}(\|g)-\\{cur\_g};{}$\6
+\&{if} ${}(\\{g\_sign}\I\\{normal}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{g\_sign}\E\\{stretching}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{stretch\_order}(\|g)\E\\{g\_order}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_glue}\K\\{cur\_glue}+\\{stretch}(\|g);{}$\5
+${}\\{vet\_glue}(\&{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue});{}$\5
+${}\\{cur\_g}\K\\{round}(\\{glue\_temp});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{shrink\_order}(\|g)\E\\{g\_order}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_glue}\K\\{cur\_glue}-\\{shrink}(\|g);{}$\5
+${}\\{vet\_glue}(\&{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue});{}$\5
+${}\\{cur\_g}\K\\{round}(\\{glue\_temp});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{rule\_wd}\K\\{rule\_wd}+\\{cur\_g};{}$\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\1\5
+\X626:Output leaders in an hlist, \&{goto} \\{fin\_rule} if a rule or to \\{next\_p} if done\X;\2\6
+\&{goto} \\{move\_past};\6
+\4${}\}{}$\2\par
+\U622.\fi
+
+\M{626}\B\X626:Output leaders in an hlist, \&{goto} \\{fin\_rule} if a rule or to \\{next\_p} if done\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{leader\_box}\K\\{leader\_ptr}(\|p);{}$\6
+\&{if} ${}(\\{type}(\\{leader\_box})\E\\{rule\_node}){}$\5
+${}\{{}$\5
+\1${}\\{rule\_ht}\K\\{height}(\\{leader\_box});{}$\5
+${}\\{rule\_dp}\K\\{depth}(\\{leader\_box});{}$\5
+\&{goto} \\{fin\_rule};\6
+\4${}\}{}$\2\6
+${}\\{leader\_wd}\K\\{width}(\\{leader\_box});{}$\6
+\&{if} ${}((\\{leader\_wd}>\T{0})\W(\\{rule\_wd}>\T{0})){}$\5
+${}\{{}$\5
+\1${}\\{rule\_wd}\K\\{rule\_wd}+\T{10}{}$;\C{compensate for floating-point rounding}\6
+${}\\{edge}\K\\{cur\_h}+\\{rule\_wd};{}$\5
+${}\\{lx}\K\T{0};{}$\5
+\X627:Let \\{cur\_h} be the position of the first box, and set $\\{leader\_wd}+\\{lx}$ to the spacing between corresponding parts of boxes\X;\6
+\&{while} ${}(\\{cur\_h}+\\{leader\_wd}\Z\\{edge}){}$\1\5
+\X628:Output a leader box at \\{cur\_h}, then advance \\{cur\_h} by $\\{leader\_wd}+\\{lx}$\X;\2\6
+${}\\{cur\_h}\K\\{edge}-\T{10};{}$\5
+\&{goto} \\{next\_p};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U625.\fi
+
+\M{627}The calculations related to leaders require a bit of care. First, in the
+case of \\{a\_leaders} (aligned leaders), we want to move \\{cur\_h} to
+\\{left\_edge} plus the smallest multiple of \\{leader\_wd} for which the result
+is not less than the current value of \\{cur\_h}; i.e., \\{cur\_h} should become
+$\\{left\_edge}+\\{leader\_wd}\times\lceil
+(\\{cur\_h}-\\{left\_edge})/\\{leader\_wd}\rceil$. The program here should work in
+all cases even though some implementations of \PASCAL\ give nonstandard
+results for the $/$ operation when \\{cur\_h} is less than \\{left\_edge}.
+
+In the case of \\{c\_leaders} (centered leaders), we want to increase \\{cur\_h}
+by half of the excess space not occupied by the leaders; and in the
+case of \\{x\_leaders} (expanded leaders) we increase \\{cur\_h}
+by $1/(q+1)$ of this excess space, where $q$ is the number of times the
+leader box will be replicated. Slight inaccuracies in the division might
+accumulate; half of this rounding error is placed at each end of the leaders.
+
+\Y\B\4\X627:Let \\{cur\_h} be the position of the first box, and set $\\{leader\_wd}+\\{lx}$ to the spacing between corresponding parts of boxes\X${}\E{}$\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{a\_leaders}){}$\5
+${}\{{}$\5
+\1${}\\{save\_h}\K\\{cur\_h};{}$\5
+${}\\{cur\_h}\K\\{left\_edge}+\\{leader\_wd}*((\\{cur\_h}-\\{left\_edge})/\\{leader\_wd});{}$\6
+\&{if} ${}(\\{cur\_h}<\\{save\_h}){}$\1\5
+${}\\{cur\_h}\K\\{cur\_h}+\\{leader\_wd};{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{lq}\K\\{rule\_wd}/\\{leader\_wd}{}$;\C{the number of box copies}\6
+${}\\{lr}\K\\{rule\_wd}\MOD\\{leader\_wd}{}$;\C{the remaining space}\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{c\_leaders}){}$\1\5
+${}\\{cur\_h}\K\\{cur\_h}+(\\{lr}/\T{2});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{lx}\K\\{lr}/(\\{lq}+\T{1});{}$\5
+${}\\{cur\_h}\K\\{cur\_h}+((\\{lr}-(\\{lq}-\T{1})*\\{lx})/\T{2});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U626.\fi
+
+\M{628}The `\\{synch}' operations here are intended to decrease the number of
+bytes needed to specify horizontal and vertical motion in the \.{DVI} output.
+
+\Y\B\4\X628:Output a leader box at \\{cur\_h}, then advance \\{cur\_h} by $\\{leader\_wd}+\\{lx}$\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_v}\K\\{base\_line}+\\{shift\_amount}(\\{leader\_box});{}$\5
+\\{synch\_v};\5
+${}\\{save\_v}\K\\{dvi\_v}{}$;\6
+\\{synch\_h};\5
+${}\\{save\_h}\K\\{dvi\_h};{}$\5
+${}\\{temp\_ptr}\K\\{leader\_box};{}$\5
+${}\\{outer\_doing\_leaders}\K\\{doing\_leaders};{}$\5
+${}\\{doing\_leaders}\K\\{true};{}$\6
+\&{if} ${}(\\{type}(\\{leader\_box})\E\\{vlist\_node}){}$\1\5
+\\{vlist\_out}(\,);\5
+\2\&{else}\1\5
+\\{hlist\_out}(\,);\2\6
+${}\\{doing\_leaders}\K\\{outer\_doing\_leaders};{}$\5
+${}\\{dvi\_v}\K\\{save\_v};{}$\5
+${}\\{dvi\_h}\K\\{save\_h};{}$\5
+${}\\{cur\_v}\K\\{base\_line};{}$\5
+${}\\{cur\_h}\K\\{save\_h}+\\{leader\_wd}+\\{lx};{}$\6
+\4${}\}{}$\2\par
+\U626.\fi
+
+\M{629}The \\{vlist\_out} routine is similar to \\{hlist\_out}, but a bit simpler.
+
+\Y\B\&{void} \\{vlist\_out}(\&{void})\C{output a \\{vlist\_node} box}\6
+${}\{{}$\5
+\1\&{scaled} \\{left\_edge};\C{the left coordinate for this box}\6
+\&{scaled} \\{top\_edge};\C{the top coordinate for this box}\6
+\&{scaled} \\{save\_h}${},{}$ \\{save\_v};\C{what \\{dvi\_h} and \\{dvi\_v} should pop to}\6
+\&{pointer} \\{this\_box};\C{pointer to containing box}\6
+\&{glue\_ord} \\{g\_order};\C{applicable order of infinity for glue}\6
+\&{uint8\_t} \\{g\_sign};\C{selects type of glue}\6
+\&{pointer} \|p;\C{current position in the vlist}\6
+\&{int} \\{save\_loc};\C{\.{DVI} byte location upon entry}\6
+\&{pointer} \\{leader\_box};\C{the leader box being replicated}\6
+\&{scaled} \\{leader\_ht};\C{height of leader box being replicated}\6
+\&{scaled} \\{lx};\C{extra space between leader boxes}\6
+\&{bool} \\{outer\_doing\_leaders};\C{were we doing leaders?}\6
+\&{scaled} \\{edge};\C{bottom boundary of leader space}\6
+\&{double} \\{glue\_temp};\C{glue value before rounding}\6
+\&{double} \\{cur\_glue};\C{glue seen so far}\6
+\&{scaled} \\{cur\_g};\C{rounded equivalent of \\{cur\_glue} times the glue ratio}\7
+${}\\{cur\_g}\K\T{0};{}$\5
+${}\\{cur\_glue}\K\\{float\_constant}(\T{0});{}$\5
+${}\\{this\_box}\K\\{temp\_ptr};{}$\5
+${}\\{g\_order}\K\\{glue\_order}(\\{this\_box});{}$\5
+${}\\{g\_sign}\K\\{glue\_sign}(\\{this\_box});{}$\5
+${}\|p\K\\{list\_ptr}(\\{this\_box});{}$\5
+\\{incr}(\\{cur\_s});\6
+\&{if} ${}(\\{cur\_s}>\T{0}){}$\1\5
+\\{dvi\_out}(\\{push});\2\6
+\&{if} ${}(\\{cur\_s}>\\{max\_push}){}$\1\5
+${}\\{max\_push}\K\\{cur\_s};{}$\2\6
+${}\\{save\_loc}\K\\{dvi\_offset}+\\{dvi\_ptr};{}$\5
+${}\\{left\_edge}\K\\{cur\_h};{}$\5
+${}\\{cur\_v}\K\\{cur\_v}-\\{height}(\\{this\_box});{}$\5
+${}\\{top\_edge}\K\\{cur\_v};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\1\5
+\X630:Output node \|p for \\{vlist\_out} and move to the next node, maintaining the condition $\\{cur\_h}\K\\{left\_edge}$\X;\2\6
+\\{prune\_movements}(\\{save\_loc});\6
+\&{if} ${}(\\{cur\_s}>\T{0}){}$\1\5
+\\{dvi\_pop}(\\{save\_loc});\2\6
+\\{decr}(\\{cur\_s});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{630}\B\X630:Output node \|p for \\{vlist\_out} and move to the next node, maintaining the condition $\\{cur\_h}\K\\{left\_edge}$\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{is\_char\_node}(\|p))\1\5
+\\{confusion}(\X1641:\.{"vlistout"}\X);\2\6
+\&{else}\1\5
+\X631:Output the non-\\{char\_node} \|p for \\{vlist\_out}\X;\2\6
+\4\\{next\_p}:\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\par
+\U629.\fi
+
+\M{631}\B\X631:Output the non-\\{char\_node} \|p for \\{vlist\_out}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\X632:Output a box in a vlist\X\5
+\&{break};\6
+\4\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1${}\\{rule\_ht}\K\\{height}(\|p);{}$\5
+${}\\{rule\_dp}\K\\{depth}(\|p);{}$\5
+${}\\{rule\_wd}\K\\{width}(\|p);{}$\5
+\&{goto} \\{fin\_rule};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1366:Output the whatsit node \|p in a vlist\X;\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X634:Move down or output leaders\X\6
+\4\&{case} \\{kern\_node}:\5
+${}\\{cur\_v}\K\\{cur\_v}+\\{width}(\|p){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+\&{goto} \\{next\_p};\6
+\4\\{fin\_rule}:\5
+\X633:Output a rule in a vlist, \&{goto} \\{next\_p}\X;\6
+\4\\{move\_past}:\5
+${}\\{cur\_v}\K\\{cur\_v}+\\{rule\_ht};{}$\6
+\4${}\}{}$\2\par
+\U630.\fi
+
+\M{632}The \\{synch\_v} here allows the \.{DVI} output to use one-byte commands
+for adjusting \|v in most cases, since the baselineskip distance will
+usually be constant.
+
+\Y\B\4\X632:Output a box in a vlist\X${}\E{}$\6
+\&{if} ${}(\\{list\_ptr}(\|p)\E\\{null}){}$\1\5
+${}\\{cur\_v}\K\\{cur\_v}+\\{height}(\|p)+\\{depth}(\|p);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_v}\K\\{cur\_v}+\\{height}(\|p);{}$\5
+\\{synch\_v};\5
+${}\\{save\_h}\K\\{dvi\_h};{}$\5
+${}\\{save\_v}\K\\{dvi\_v};{}$\5
+${}\\{cur\_h}\K\\{left\_edge}+\\{shift\_amount}(\|p){}$;\C{shift the box right}\6
+${}\\{temp\_ptr}\K\|p;{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{vlist\_node}){}$\1\5
+\\{vlist\_out}(\,);\5
+\2\&{else}\1\5
+\\{hlist\_out}(\,);\2\6
+${}\\{dvi\_h}\K\\{save\_h};{}$\5
+${}\\{dvi\_v}\K\\{save\_v};{}$\5
+${}\\{cur\_v}\K\\{save\_v}+\\{depth}(\|p);{}$\5
+${}\\{cur\_h}\K\\{left\_edge};{}$\6
+\4${}\}{}$\2\par
+\U631.\fi
+
+\M{633}\B\X633:Output a rule in a vlist, \&{goto} \\{next\_p}\X${}\E{}$\6
+\&{if} (\\{is\_running}(\\{rule\_wd}))\1\5
+${}\\{rule\_wd}\K\\{width}(\\{this\_box});{}$\2\6
+${}\\{rule\_ht}\K\\{rule\_ht}+\\{rule\_dp}{}$;\C{this is the rule thickness}\6
+${}\\{cur\_v}\K\\{cur\_v}+\\{rule\_ht};{}$\6
+\&{if} ${}((\\{rule\_ht}>\T{0})\W(\\{rule\_wd}>\T{0}){}$)\C{we don't output empty rules}\6
+${}\{{}$\5
+\1\\{synch\_h};\5
+\\{synch\_v};\5
+\\{dvi\_out}(\\{put\_rule});\5
+\\{dvi\_four}(\\{rule\_ht});\5
+\\{dvi\_four}(\\{rule\_wd});\6
+\4${}\}{}$\2\6
+\&{goto} \\{next\_p}\par
+\U631.\fi
+
+\M{634}\B\X634:Move down or output leaders\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|g\K\\{glue\_ptr}(\|p);{}$\5
+${}\\{rule\_ht}\K\\{width}(\|g)-\\{cur\_g};{}$\6
+\&{if} ${}(\\{g\_sign}\I\\{normal}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{g\_sign}\E\\{stretching}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{stretch\_order}(\|g)\E\\{g\_order}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_glue}\K\\{cur\_glue}+\\{stretch}(\|g);{}$\5
+${}\\{vet\_glue}(\&{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue});{}$\5
+${}\\{cur\_g}\K\\{round}(\\{glue\_temp});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{shrink\_order}(\|g)\E\\{g\_order}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_glue}\K\\{cur\_glue}-\\{shrink}(\|g);{}$\5
+${}\\{vet\_glue}(\&{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue});{}$\5
+${}\\{cur\_g}\K\\{round}(\\{glue\_temp});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{rule\_ht}\K\\{rule\_ht}+\\{cur\_g};{}$\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\1\5
+\X635:Output leaders in a vlist, \&{goto} \\{fin\_rule} if a rule or to \\{next\_p} if done\X;\2\6
+\&{goto} \\{move\_past};\6
+\4${}\}{}$\2\par
+\U631.\fi
+
+\M{635}\B\X635:Output leaders in a vlist, \&{goto} \\{fin\_rule} if a rule or to \\{next\_p} if done\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{leader\_box}\K\\{leader\_ptr}(\|p);{}$\6
+\&{if} ${}(\\{type}(\\{leader\_box})\E\\{rule\_node}){}$\5
+${}\{{}$\5
+\1${}\\{rule\_wd}\K\\{width}(\\{leader\_box});{}$\5
+${}\\{rule\_dp}\K\T{0};{}$\5
+\&{goto} \\{fin\_rule};\6
+\4${}\}{}$\2\6
+${}\\{leader\_ht}\K\\{height}(\\{leader\_box})+\\{depth}(\\{leader\_box});{}$\6
+\&{if} ${}((\\{leader\_ht}>\T{0})\W(\\{rule\_ht}>\T{0})){}$\5
+${}\{{}$\5
+\1${}\\{rule\_ht}\K\\{rule\_ht}+\T{10}{}$;\C{compensate for floating-point rounding}\6
+${}\\{edge}\K\\{cur\_v}+\\{rule\_ht};{}$\5
+${}\\{lx}\K\T{0};{}$\5
+\X636:Let \\{cur\_v} be the position of the first box, and set $\\{leader\_ht}+\\{lx}$ to the spacing between corresponding parts of boxes\X;\6
+\&{while} ${}(\\{cur\_v}+\\{leader\_ht}\Z\\{edge}){}$\1\5
+\X637:Output a leader box at \\{cur\_v}, then advance \\{cur\_v} by $\\{leader\_ht}+\\{lx}$\X;\2\6
+${}\\{cur\_v}\K\\{edge}-\T{10};{}$\5
+\&{goto} \\{next\_p};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U634.\fi
+
+\M{636}\B\X636:Let \\{cur\_v} be the position of the first box, and set $\\{leader\_ht}+\\{lx}$ to the spacing between corresponding parts of boxes\X${}\E{}$\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{a\_leaders}){}$\5
+${}\{{}$\5
+\1${}\\{save\_v}\K\\{cur\_v};{}$\5
+${}\\{cur\_v}\K\\{top\_edge}+\\{leader\_ht}*((\\{cur\_v}-\\{top\_edge})/\\{leader\_ht});{}$\6
+\&{if} ${}(\\{cur\_v}<\\{save\_v}){}$\1\5
+${}\\{cur\_v}\K\\{cur\_v}+\\{leader\_ht};{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{lq}\K\\{rule\_ht}/\\{leader\_ht}{}$;\C{the number of box copies}\6
+${}\\{lr}\K\\{rule\_ht}\MOD\\{leader\_ht}{}$;\C{the remaining space}\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{c\_leaders}){}$\1\5
+${}\\{cur\_v}\K\\{cur\_v}+(\\{lr}/\T{2});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{lx}\K\\{lr}/(\\{lq}+\T{1});{}$\5
+${}\\{cur\_v}\K\\{cur\_v}+((\\{lr}-(\\{lq}-\T{1})*\\{lx})/\T{2});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U635.\fi
+
+\M{637}When we reach this part of the program, \\{cur\_v} indicates the top of a
+leader box, not its baseline.
+
+\Y\B\4\X637:Output a leader box at \\{cur\_v}, then advance \\{cur\_v} by $\\{leader\_ht}+\\{lx}$\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_h}\K\\{left\_edge}+\\{shift\_amount}(\\{leader\_box});{}$\5
+\\{synch\_h};\5
+${}\\{save\_h}\K\\{dvi\_h}{}$;\6
+${}\\{cur\_v}\K\\{cur\_v}+\\{height}(\\{leader\_box});{}$\5
+\\{synch\_v};\5
+${}\\{save\_v}\K\\{dvi\_v};{}$\5
+${}\\{temp\_ptr}\K\\{leader\_box};{}$\5
+${}\\{outer\_doing\_leaders}\K\\{doing\_leaders};{}$\5
+${}\\{doing\_leaders}\K\\{true};{}$\6
+\&{if} ${}(\\{type}(\\{leader\_box})\E\\{vlist\_node}){}$\1\5
+\\{vlist\_out}(\,);\5
+\2\&{else}\1\5
+\\{hlist\_out}(\,);\2\6
+${}\\{doing\_leaders}\K\\{outer\_doing\_leaders};{}$\5
+${}\\{dvi\_v}\K\\{save\_v};{}$\5
+${}\\{dvi\_h}\K\\{save\_h};{}$\5
+${}\\{cur\_h}\K\\{left\_edge};{}$\5
+${}\\{cur\_v}\K\\{save\_v}-\\{height}(\\{leader\_box})+\\{leader\_ht}+\\{lx};{}$\6
+\4${}\}{}$\2\par
+\U635.\fi
+
+\M{638}The \\{hlist\_out} and \\{vlist\_out} procedures are now complete, so we are
+ready for the \\{ship\_out} routine that gets them started in the first place.
+
+\Y\B\&{void} \\{ship\_out}(\&{pointer} \|p)\C{output the box \|p}\6
+${}\{{}$\5
+\1\&{int} \\{page\_loc};\C{location of the current \\{bop}}\6
+\&{uint8\_t} \|j${},{}$ \|k;\C{indices to first ten count registers}\6
+\&{int} \|s;\C{index into \\{str\_pool}}\6
+\&{uint8\_t} \\{old\_setting};\C{saved \\{selector} setting}\7
+\&{if} ${}(\\{tracing\_output}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{""});\5
+\\{print\_ln}(\,);\5
+\\{print\_str}(\.{"Completed\ box\ being}\)\.{\ shipped\ out"});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{term\_offset}>\\{max\_print\_line}-\T{9}){}$\1\5
+\\{print\_ln}(\,);\2\6
+\&{else} \&{if} ${}((\\{term\_offset}>\T{0})\V(\\{file\_offset}>\T{0})){}$\1\5
+\\{print\_char}(\.{'\ '});\2\6
+\\{print\_char}(\.{'['});\5
+${}\|j\K\T{9};{}$\6
+\&{while} ${}((\\{count}(\|j)\E\T{0})\W(\|j>\T{0})){}$\1\5
+\\{decr}(\|j);\2\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\|j;{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1\\{print\_int}(\\{count}(\|k));\6
+\&{if} ${}(\|k<\|j){}$\1\5
+\\{print\_char}(\.{'.'});\2\6
+\4${}\}{}$\2\6
+\\{update\_terminal};\6
+\&{if} ${}(\\{tracing\_output}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_char}(\.{']'});\5
+\\{begin\_diagnostic}(\,);\5
+\\{show\_box}(\|p);\5
+\\{end\_diagnostic}(\\{true});\6
+\4${}\}{}$\2\6
+\X640:Ship box \|p out\X;\6
+\&{if} ${}(\\{tracing\_output}\Z\T{0}){}$\1\5
+\\{print\_char}(\.{']'});\2\6
+${}\\{dead\_cycles}\K\T{0};{}$\5
+\\{update\_terminal};\C{progress report}\6
+\X639:Flush the box from memory, showing statistics if requested\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{639}\B\X639:Flush the box from memory, showing statistics if requested\X${}\E{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_stats}>\T{1}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Memory\ usage\ before}\)\.{:\ "});\5
+\\{print\_int}(\\{var\_used});\5
+\\{print\_char}(\.{'\&'});\5
+\\{print\_int}(\\{dyn\_used});\5
+\\{print\_char}(\.{';'});\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\6
+\\{flush\_node\_list}(\|p);\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_stats}>\T{1}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ after:\ "});\5
+\\{print\_int}(\\{var\_used});\5
+\\{print\_char}(\.{'\&'});\5
+\\{print\_int}(\\{dyn\_used});\5
+\\{print\_str}(\.{";\ still\ untouched:\ }\)\.{"});\5
+${}\\{print\_int}(\\{hi\_mem\_min}-\\{lo\_mem\_max}-\T{1});{}$\5
+\\{print\_ln}(\,);\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\U638.\fi
+
+\M{640}\B\X640:Ship box \|p out\X${}\E{}$\6
+\X641:Update the values of \\{max\_h} and \\{max\_v}; but if the page is too large, \&{goto} \\{done}\X;\6
+\X617:Initialize variables as \\{ship\_out} begins\X;\6
+${}\\{page\_loc}\K\\{dvi\_offset}+\\{dvi\_ptr};{}$\5
+\\{dvi\_out}(\\{bop});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{9};{}$ ${}\|k\PP){}$\1\5
+\\{dvi\_four}(\\{count}(\|k));\2\6
+\\{dvi\_four}(\\{last\_bop});\5
+${}\\{last\_bop}\K\\{page\_loc};{}$\5
+${}\\{cur\_v}\K\\{height}(\|p)+\\{v\_offset};{}$\5
+${}\\{temp\_ptr}\K\|p;{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{vlist\_node}){}$\1\5
+\\{vlist\_out}(\,);\5
+\2\&{else}\1\5
+\\{hlist\_out}(\,);\2\6
+\\{dvi\_out}(\\{eop});\5
+\\{incr}(\\{total\_pages});\5
+${}\\{cur\_s}\K{-}\T{1};$ \\{done}:\par
+\U638.\fi
+
+\M{641}Sometimes the user will generate a huge page because other error messages
+are being ignored. Such pages are not output to the \.{dvi} file, since they
+may confuse the printing software.
+
+\Y\B\4\X641:Update the values of \\{max\_h} and \\{max\_v}; but if the page is too large, \&{goto} \\{done}\X${}\E{}$\6
+\&{if} ${}((\\{height}(\|p)>\\{max\_dimen})\V\30(\\{depth}(\|p)>\\{max\_dimen})\V\30(\\{height}(\|p)+\\{depth}(\|p)+\\{v\_offset}>\\{max\_dimen})\V\30(\\{width}(\|p)+\\{h\_offset}>\\{max\_dimen})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Huge\ page\ cannot\ be}\)\.{\ shipped\ out"});\5
+\\{help2}(\.{"The\ page\ just\ creat}\)\.{ed\ is\ more\ than\ 18\ f}\)\.{eet\ tall\ or"})\6
+(\.{"more\ than\ 18\ feet\ w}\)\.{ide,\ so\ I\ suspect\ so}\)\.{mething\ went\ wrong."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{if} ${}(\\{tracing\_output}\Z\T{0}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"The\ following\ box\ h}\)\.{as\ been\ deleted:"});\5
+\\{show\_box}(\|p);\5
+\\{end\_diagnostic}(\\{true});\6
+\4${}\}{}$\2\6
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{height}(\|p)+\\{depth}(\|p)+\\{v\_offset}>\\{max\_v}){}$\1\5
+${}\\{max\_v}\K\\{height}(\|p)+\\{depth}(\|p)+\\{v\_offset};{}$\2\6
+\&{if} ${}(\\{width}(\|p)+\\{h\_offset}>\\{max\_h})$ $\\{max\_h}\K\\{width}(\|p)+{}$\\{h\_offset}\par
+\U640.\fi
+
+\M{642}At the end of the program, we must finish things off by writing the
+post\-amble. If $\\{total\_pages}\E\T{0}$, the \.{DVI} file was never opened.
+If $\\{total\_pages}\G\T{65536}$, the \.{DVI} file will lie. And if
+$\\{max\_push}\G\T{65536}$, the user deserves whatever chaos might ensue.
+
+An integer variable \|k will be declared for use by this routine.
+
+\Y\B\4\X642:Finish the \.{DVI} file\X${}\E{}$\6
+\&{while} ${}(\\{cur\_s}>{-}\T{1}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_s}>\T{0}){}$\1\5
+\\{dvi\_out}(\\{pop})\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{eop});\5
+\\{incr}(\\{total\_pages});\6
+\4${}\}{}$\2\6
+\\{decr}(\\{cur\_s});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{total\_pages}\E\T{0}){}$\1\5
+\\{print\_nl}(\.{"No\ pages\ of\ output.}\)\.{"});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{post});\C{beginning of the postamble}\6
+\\{dvi\_four}(\\{last\_bop});\5
+${}\\{last\_bop}\K\\{dvi\_offset}+\\{dvi\_ptr}-\T{5}{}$;\C{\\{post} location}\6
+\\{dvi\_four}(\T{25400000});\5
+\\{dvi\_four}(\T{473628672});\C{conversion ratio for sp}\6
+\\{prepare\_mag}(\,);\5
+\\{dvi\_four}(\\{mag});\C{magnification factor}\6
+\\{dvi\_four}(\\{max\_v});\5
+\\{dvi\_four}(\\{max\_h});\6
+${}\\{dvi\_out}(\\{max\_push}/\T{256});{}$\5
+${}\\{dvi\_out}(\\{max\_push}\MOD\T{256}){}$;\6
+${}\\{dvi\_out}((\\{total\_pages}/\T{256})\MOD\T{256});{}$\5
+${}\\{dvi\_out}(\\{total\_pages}\MOD\T{256}){}$;\6
+\X643:Output the font definitions for all fonts that were used\X;\6
+\\{dvi\_out}(\\{post\_post});\5
+\\{dvi\_four}(\\{last\_bop});\5
+\\{dvi\_out}(\\{id\_byte});\6
+${}\|k\K\T{4}+((\\{dvi\_buf\_size}-\\{dvi\_ptr})\MOD\T{4}){}$;\C{the number of 223's}\6
+\&{while} ${}(\|k>\T{0}){}$\5
+${}\{{}$\5
+\1\\{dvi\_out}(\T{223});\5
+\\{decr}(\|k);\6
+\4${}\}{}$\2\6
+\X599:Empty the last bytes out of \\{dvi\_buf}\X;\6
+\\{print\_nl}(\.{"Output\ written\ on\ "});\5
+\\{slow\_print}(\\{output\_file\_name});\5
+\\{print\_str}(\.{"\ ("});\5
+\\{print\_int}(\\{total\_pages});\5
+\\{print\_str}(\.{"\ page"});\6
+\&{if} ${}(\\{total\_pages}\I\T{1}){}$\1\5
+\\{print\_char}(\.{'s'});\2\6
+\\{print\_str}(\.{",\ "});\5
+${}\\{print\_int}(\\{dvi\_offset}+\\{dvi\_ptr});{}$\5
+\\{print\_str}(\.{"\ bytes)."});\5
+${}\\{b\_close}({\AND}\\{dvi\_file});{}$\6
+\4${}\}{}$\2\par
+\U1333.\fi
+
+\M{643}\B\X643:Output the font definitions for all fonts that were used\X${}\E{}$\6
+\&{while} ${}(\\{font\_ptr}>\\{font\_base}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{font\_used}[\\{font\_ptr}])\1\5
+\\{dvi\_font\_def}(\\{font\_ptr});\2\6
+\\{decr}(\\{font\_ptr});\6
+\4${}\}{}$\2\par
+\U642.\fi
+
+\N{1}{644}Packaging.
+We're essentially done with the parts of \TeX\ that are concerned with
+the input (\\{get\_next}) and the output (\\{ship\_out}). So it's time to
+get heavily into the remaining part, which does the real work of typesetting.
+
+After lists are constructed, \TeX\ wraps them up and puts them into boxes.
+Two major subroutines are given the responsibility for this task: \\{hpack}
+applies to horizontal lists (hlists) and \\{vpack} applies to vertical lists
+(vlists). The main duty of \\{hpack} and \\{vpack} is to compute the dimensions
+of the resulting boxes, and to adjust the glue if one of those dimensions
+is pre-specified. The computed sizes normally enclose all of the material
+inside the new box; but some items may stick out if negative glue is used,
+if the box is overfull, or if a \.{\\vbox} includes other boxes that have
+been shifted left.
+
+The subroutine call $\\{hpack}(\|p,\|w,\|m)$ returns a pointer to an \\{hlist\_node}
+for a box containing the hlist that starts at \|p. Parameter \|w specifies
+a width; and parameter \|m is either `\\{exactly}' or `\\{additional}'. Thus,
+$\\{hpack}(\|p,\|w,\\{exactly})$ produces a box whose width is exactly \|w, while
+$\\{hpack}(\|p,\|w,\\{additional})$ yields a box whose width is the natural width plus
+\|w. It is convenient to define a macro called `\\{natural}' to cover the
+most common case, so that we can say $\\{hpack}(\|p,\\{natural})$ to get a box that
+has the natural width of list \|p.
+
+Similarly, $\\{vpack}(\|p,\|w,\|m)$ returns a pointer to a \\{vlist\_node} for a
+box containing the vlist that starts at \|p. In this case \|w represents
+a height instead of a width; the parameter \|m is interpreted as in \\{hpack}.
+
+\Y\B\4\D$\\{exactly}$ \5
+\T{0}\C{a box dimension is pre-specified}\par
+\B\4\D$\\{additional}$ \5
+\T{1}\C{a box dimension is increased from the natural one}\par
+\B\4\D$\\{natural}$ \5
+$\T{0},\39{}$\\{additional}\C{shorthand for parameters to \\{hpack} and \\{vpack}}\par
+\fi
+
+\M{645}The parameters to \\{hpack} and \\{vpack} correspond to \TeX's primitives
+like `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note
+that `\.{\\hbox}' with no dimension following it is equivalent to
+`\.{\\hbox} \.{spread} \.{0pt}'. The \\{scan\_spec} subroutine scans such
+constructions in the user's input, including the mandatory left brace that
+follows them, and it puts the specification onto \\{save\_stack} so that the
+desired box can later be obtained by executing the following code:
+$$\vbox{\halign{#\hfil\cr
+$\\{save\_ptr}\K\\{save\_ptr}-\T{2};$\cr
+$\\{hpack}(\|p,\\{saved}(\T{1}),\\{saved}(\T{0}))$ $.$\cr}}$$
+Special care is necessary to ensure that the special \\{save\_stack} codes
+are placed just below the new group code, because scanning can change
+\\{save\_stack} when \.{\\csname} appears.
+
+\Y\B\&{void} \\{scan\_spec}(\&{group\_code} \|c${},\39{}$\&{bool} \\{three\_codes})\C{scans a box specification and left brace}\6
+${}\{{}$\5
+\1\&{int} \|s;\C{temporarily saved value}\6
+\&{uint8\_t} \\{spec\_code};\7
+\&{if} (\\{three\_codes})\1\5
+${}\|s\K\\{saved}(\T{0});{}$\2\6
+\&{if} (\\{scan\_keyword}(\X1642:\.{"to"}\X))\1\5
+${}\\{spec\_code}\K\\{exactly};{}$\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1643:\.{"spread"}\X))\1\5
+${}\\{spec\_code}\K\\{additional};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{spec\_code}\K\\{additional};{}$\5
+${}\\{cur\_val}\K\T{0};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\\{scan\_normal\_dimen};\6
+\4\\{found}:\6
+\&{if} (\\{three\_codes})\5
+${}\{{}$\5
+\1${}\\{saved}(\T{0})\K\|s;{}$\5
+\\{incr}(\\{save\_ptr});\6
+\4${}\}{}$\2\6
+${}\\{saved}(\T{0})\K\\{spec\_code};{}$\5
+${}\\{saved}(\T{1})\K\\{cur\_val};{}$\5
+${}\\{save\_ptr}\K\\{save\_ptr}+\T{2};{}$\5
+\\{new\_save\_level}(\|c);\5
+\\{scan\_left\_brace}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{646}To figure out the glue setting, \\{hpack} and \\{vpack} determine how much
+stretchability and shrinkability are present, considering all four orders
+of infinity. The highest order of infinity that has a nonzero coefficient
+is then used as if no other orders were present.
+
+For example, suppose that the given list contains six glue nodes with
+the respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill.
+Then the total is essentially 2fil; and if a total additional space of 6pt
+is to be achieved by stretching, the actual amounts of stretch will be
+0pt, 0pt, 15pt, 0pt, $-9$pt, and 0pt, since only `fil' glue will be
+considered. (The `fill' glue is therefore not really stretching infinitely
+with respect to `fil'; nobody would actually want that to happen.)
+
+The arrays \\{total\_stretch} and \\{total\_shrink} are used to determine how much
+glue of each kind is present. A global variable \\{last\_badness} is used
+to implement \.{\\badness}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} ${}\\{total\_stretch0}[\\{filll}-\\{normal}+\T{1}],{}$ ${}{*\&{const}\ }\\{total\_stretch}\K\\{total\_stretch0}-\\{normal},{}$ ${}\\{total\_shrink0}[\\{filll}-\\{normal}+\T{1}],{}$ ${}{*\&{const}\ }\\{total\_shrink}\K\\{total\_shrink0}-%
+\\{normal}{}$;\C{glue found by \\{hpack} or \\{vpack}}\6
+\&{int} \\{last\_badness};\C{badness of the most recently packaged box}\par
+\fi
+
+\M{647}If the global variable \\{adjust\_tail} is non-null, the \\{hpack} routine
+also removes all occurrences of \\{ins\_node}, \\{mark\_node}, and \\{adjust\_node}
+items and appends the resulting material onto the list that ends at
+location \\{adjust\_tail}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{adjust\_tail};\C{tail of adjustment list}\par
+\fi
+
+\M{648}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{adjust\_tail}\K\\{null};{}$\5
+${}\\{last\_badness}\K\T{0}{}$;\par
+\fi
+
+\M{649}Here now is \\{hpack}, which contains few if any surprises.
+
+\Y\B\&{pointer} \\{hpack}(\&{pointer} \|p${},\39{}$\&{scaled} \|w${},\39{}$\&{small\_number} \|m)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|r;\C{the box node that will be returned}\6
+\&{pointer} \|q;\C{trails behind \|p}\6
+\&{scaled} \|h${},{}$ \|d${},{}$ \|x;\C{height, depth, and natural width}\6
+\&{scaled} \|s;\C{shift amount}\6
+\&{pointer} \|g;\C{points to a glue specification}\6
+\&{glue\_ord} \|o;\C{order of infinity}\6
+\&{internal\_font\_number} \|f;\C{the font in a \\{char\_node}}\6
+\&{four\_quarters} \|i;\C{font information about a \\{char\_node}}\6
+\&{eight\_bits} \\{hd};\C{height and depth indices for a character}\7
+${}\\{last\_badness}\K\T{0};{}$\5
+${}\|r\K\\{get\_node}(\\{box\_node\_size});{}$\5
+${}\\{type}(\|r)\K\\{hlist\_node};{}$\5
+${}\\{subtype}(\|r)\K\\{min\_quarterword};{}$\5
+${}\\{shift\_amount}(\|r)\K\T{0};{}$\5
+${}\|q\K\|r+\\{list\_offset};{}$\5
+${}\\{link}(\|q)\K\|p{}$;\6
+${}\|h\K\T{0};{}$\5
+\X650:Clear dimensions to zero\X;\6
+\&{while} ${}(\|p\I\\{null}){}$\1\5
+\X651:Examine node \|p in the hlist, taking account of its effect on the dimensions of the new box, or moving it to the adjustment list; then advance \|p to the next node\X;\2\6
+\&{if} ${}(\\{adjust\_tail}\I\\{null}){}$\1\5
+${}\\{link}(\\{adjust\_tail})\K\\{null};{}$\2\6
+${}\\{height}(\|r)\K\|h;{}$\5
+${}\\{depth}(\|r)\K\|d{}$;\6
+\X657:Determine the value of \\{width}(\|r) and the appropriate glue setting; then \&{return} or \&{goto} \\{common\_ending}\X;\6
+\4\\{common\_ending}:\5
+\X663:Finish issuing a diagnostic message for an overfull or underfull hbox\X;\6
+\4\\{end}:\5
+\&{return} \|r;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{650}\B\X650:Clear dimensions to zero\X${}\E{}$\6
+$\|d\K\T{0};{}$\5
+${}\|x\K\T{0};{}$\5
+${}\\{total\_stretch}[\\{normal}]\K\T{0};{}$\5
+${}\\{total\_shrink}[\\{normal}]\K\T{0};{}$\5
+${}\\{total\_stretch}[\\{fil}]\K\T{0};{}$\5
+${}\\{total\_shrink}[\\{fil}]\K\T{0};{}$\5
+${}\\{total\_stretch}[\\{fill}]\K\T{0};{}$\5
+${}\\{total\_shrink}[\\{fill}]\K\T{0};{}$\5
+${}\\{total\_stretch}[\\{filll}]\K\T{0};$ $\\{total\_shrink}[\\{filll}]\K{}$\T{0}\par
+\Us649\ET668.\fi
+
+\M{651}\B\X651:Examine node \|p in the hlist, taking account of its effect on the dimensions of the new box, or moving it to the adjustment list; then advance \|p to the next node\X${}\E{}$\6
+${}\{{}$\5
+\1\\{reswitch}:\6
+\&{while} (\\{is\_char\_node}(\|p))\1\5
+\X654:Incorporate character dimensions into the dimensions of the hbox that will contain~it, then move to the next node\X;\2\6
+\&{if} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{unset\_node}:\5
+\X653:Incorporate box dimensions into the dimensions of the hbox that will contain~it\X\5
+\&{break};\6
+\4\&{case} \\{ins\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{case} \\{adjust\_node}:\6
+\&{if} ${}(\\{adjust\_tail}\I\\{null}){}$\1\5
+\X655:Transfer node \|p to the adjustment list\X\5
+\2\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1360:Incorporate a whatsit node into an hbox\X;\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X656:Incorporate glue into the horizontal totals\X\5
+\&{break};\6
+\4\&{case} \\{kern\_node}:\5
+\&{case} \\{math\_node}:\5
+${}\|x\K\|x+\\{width}(\|p){}$;\5
+\&{break};\6
+\4\&{case} \\{ligature\_node}:\5
+\X652:Make node \|p look like a \\{char\_node} and \&{goto} \\{reswitch}\X\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U649.\fi
+
+\M{652}\B\X652:Make node \|p look like a \\{char\_node} and \&{goto} \\{reswitch}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{mem}[\\{lig\_trick}]\K\\{mem}[\\{lig\_char}(\|p)];{}$\5
+${}\\{link}(\\{lig\_trick})\K\\{link}(\|p);{}$\5
+${}\|p\K\\{lig\_trick};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\par
+\Us622, 651\ETs1147.\fi
+
+\M{653}The code here implicitly uses the fact that running dimensions are
+indicated by \\{null\_flag}, which will be ignored in the calculations
+because it is a highly negative number.
+
+\Y\B\4\X653:Incorporate box dimensions into the dimensions of the hbox that will contain~it\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\|x+\\{width}(\|p);{}$\6
+\&{if} ${}(\\{type}(\|p)\G\\{rule\_node}){}$\1\5
+${}\|s\K\T{0}{}$;\5
+\2\&{else}\1\5
+${}\|s\K\\{shift\_amount}(\|p);{}$\2\6
+\&{if} ${}(\\{height}(\|p)-\|s>\|h){}$\1\5
+${}\|h\K\\{height}(\|p)-\|s;{}$\2\6
+\&{if} ${}(\\{depth}(\|p)+\|s>\|d){}$\1\5
+${}\|d\K\\{depth}(\|p)+\|s;{}$\2\6
+\4${}\}{}$\2\par
+\U651.\fi
+
+\M{654}The following code is part of \TeX's inner loop; i.e., adding another
+character of text to the user's input will cause each of these instructions
+to be exercised one more time.
+
+\Y\B\4\X654:Incorporate character dimensions into the dimensions of the hbox that will contain~it, then move to the next node\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|p);{}$\5
+${}\|i\K\\{char\_info}(\|f)(\\{character}(\|p));{}$\5
+${}\\{hd}\K\\{height\_depth}(\|i);{}$\5
+${}\|x\K\|x+\\{char\_width}(\|f)(\|i){}$;\6
+${}\|s\K\\{char\_height}(\|f)(\\{hd}){}$;\5
+\&{if} ${}(\|s>\|h){}$\1\5
+${}\|h\K\|s;{}$\2\6
+${}\|s\K\\{char\_depth}(\|f)(\\{hd}){}$;\5
+\&{if} ${}(\|s>\|d){}$\1\5
+${}\|d\K\|s;{}$\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\par
+\U651.\fi
+
+\M{655}Although node \|q is not necessarily the immediate predecessor of node \|p,
+it always points to some node in the list preceding \|p. Thus, we can delete
+nodes by moving \|q when necessary. The algorithm takes linear time, and the
+extra computation does not intrude on the inner loop unless it is necessary
+to make a deletion.
+
+\Y\B\4\X655:Transfer node \|p to the adjustment list\X${}\E{}$\6
+${}\{{}$\5
+\1\&{while} ${}(\\{link}(\|q)\I\|p){}$\1\5
+${}\|q\K\\{link}(\|q);{}$\2\6
+\&{if} ${}(\\{type}(\|p)\E\\{adjust\_node}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{adjust\_tail})\K\\{adjust\_ptr}(\|p);{}$\6
+\&{while} ${}(\\{link}(\\{adjust\_tail})\I\\{null}){}$\1\5
+${}\\{adjust\_tail}\K\\{link}(\\{adjust\_tail});{}$\2\6
+${}\|p\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\\{link}(\|q),\39\\{small\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\\{adjust\_tail})\K\|p;{}$\5
+${}\\{adjust\_tail}\K\|p;{}$\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U651.\fi
+
+\M{656}\B\X656:Incorporate glue into the horizontal totals\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|g\K\\{glue\_ptr}(\|p);{}$\5
+${}\|x\K\|x+\\{width}(\|g){}$;\6
+${}\|o\K\\{stretch\_order}(\|g);{}$\5
+${}\\{total\_stretch}[\|o]\K\\{total\_stretch}[\|o]+\\{stretch}(\|g);{}$\5
+${}\|o\K\\{shrink\_order}(\|g);{}$\5
+${}\\{total\_shrink}[\|o]\K\\{total\_shrink}[\|o]+\\{shrink}(\|g);{}$\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\5
+${}\{{}$\5
+\1${}\|g\K\\{leader\_ptr}(\|p);{}$\6
+\&{if} ${}(\\{height}(\|g)>\|h){}$\1\5
+${}\|h\K\\{height}(\|g);{}$\2\6
+\&{if} ${}(\\{depth}(\|g)>\|d){}$\1\5
+${}\|d\K\\{depth}(\|g);{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U651.\fi
+
+\M{657}When we get to the present part of the program, \|x is the natural width
+of the box being packaged.
+
+\Y\B\4\X657:Determine the value of \\{width}(\|r) and the appropriate glue setting; then \&{return} or \&{goto} \\{common\_ending}\X${}\E{}$\6
+\&{if} ${}(\|m\E\\{additional}){}$\1\5
+${}\|w\K\|x+\|w;{}$\2\6
+${}\\{width}(\|r)\K\|w;{}$\5
+${}\|x\K\|w-\|x{}$;\C{now \|x is the excess to be made up}\6
+\&{if} ${}(\|x\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+${}\\{glue\_order}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\5
+\&{goto} \\{end};\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|x>\T{0}){}$\1\5
+\X658:Determine horizontal glue stretch setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X\2\6
+\&{else}\1\5
+\X664:Determine horizontal glue shrink setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X\2\par
+\U649.\fi
+
+\M{658}\B\X658:Determine horizontal glue stretch setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X${}\E{}$\6
+${}\{{}$\5
+\1\X659:Determine the stretch order\X;\6
+${}\\{glue\_order}(\|r)\K\|o;{}$\5
+${}\\{glue\_sign}(\|r)\K\\{stretching};{}$\6
+\&{if} ${}(\\{total\_stretch}[\|o]\I\T{0}){}$\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}(\|x/{}$(\&{double}) \\{total\_stretch}[\|o]);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\C{there's nothing to stretch}\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|o\E\\{normal}){}$\1\6
+\&{if} ${}(\\{list\_ptr}(\|r)\I\\{null}){}$\1\5
+\X660:Report an underfull hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\2\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\U657.\fi
+
+\M{659}\B\X659:Determine the stretch order\X${}\E{}$\6
+\&{if} ${}(\\{total\_stretch}[\\{filll}]\I\T{0}){}$\1\5
+${}\|o\K\\{filll};{}$\2\6
+\&{else} \&{if} ${}(\\{total\_stretch}[\\{fill}]\I\T{0}){}$\1\5
+${}\|o\K\\{fill};{}$\2\6
+\&{else} \&{if} ${}(\\{total\_stretch}[\\{fil}]\I\T{0}){}$\1\5
+${}\|o\K\\{fil};{}$\2\6
+\&{else} $\|o\K{}$\\{normal}\par
+\Us658, 673\ETs796.\fi
+
+\M{660}\B\X660:Report an underfull hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{last\_badness}\K\\{badness}(\|x,\39\\{total\_stretch}[\\{normal}]);{}$\6
+\&{if} ${}(\\{last\_badness}>\\{hbadness}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\6
+\&{if} ${}(\\{last\_badness}>\T{100}){}$\1\5
+\\{print\_nl}(\.{"Underfull"});\5
+\2\&{else}\1\5
+\\{print\_nl}(\.{"Loose"});\2\6
+\\{print\_str}(\.{"\ \\\\hbox\ (badness\ "});\5
+\\{print\_int}(\\{last\_badness});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U658.\fi
+
+\M{661}In order to provide a decent indication of where an overfull or underfull
+box originated, we use a global variable \\{pack\_begin\_line} that is
+set nonzero only when \\{hpack} is being called by the paragraph builder
+or the alignment finishing routine.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{pack\_begin\_line};\C{source file line where the current paragraph or alignment began; a negative value denotes alignment}\par
+\fi
+
+\M{662}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{pack\_begin\_line}\K\T{0}{}$;\par
+\fi
+
+\M{663}\B\X663:Finish issuing a diagnostic message for an overfull or underfull hbox\X${}\E{}$\6
+\&{if} (\\{output\_active})\1\5
+\\{print\_str}(\.{")\ has\ occurred\ whil}\)\.{e\ \\\\output\ is\ active}\)\.{"});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{pack\_begin\_line}\I\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{pack\_begin\_line}>\T{0}){}$\1\5
+\\{print\_str}(\.{")\ in\ paragraph\ at\ l}\)\.{ines\ "});\2\6
+\&{else}\1\5
+\\{print\_str}(\.{")\ in\ alignment\ at\ l}\)\.{ines\ "});\2\6
+\\{print\_int}(\\{abs}(\\{pack\_begin\_line}));\5
+\\{print\_str}(\.{"--"});\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{print\_str}(\.{")\ detected\ at\ line\ }\)\.{"});\2\6
+\\{print\_int}(\\{line});\6
+\4${}\}{}$\2\6
+\\{print\_ln}(\,);\6
+${}\\{font\_in\_short\_display}\K\\{null\_font};{}$\5
+\\{short\_display}(\\{list\_ptr}(\|r));\5
+\\{print\_ln}(\,);\6
+\\{begin\_diagnostic}(\,);\5
+\\{show\_box}(\|r); \\{end\_diagnostic}(\\{true})\par
+\U649.\fi
+
+\M{664}\B\X664:Determine horizontal glue shrink setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X${}\E{}$\6
+${}\{{}$\5
+\1\X665:Determine the shrink order\X;\6
+${}\\{glue\_order}(\|r)\K\|o;{}$\5
+${}\\{glue\_sign}(\|r)\K\\{shrinking};{}$\6
+\&{if} ${}(\\{total\_shrink}[\|o]\I\T{0}){}$\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}(({-}\|x)/{}$(\&{double}) \\{total\_shrink}[\|o]);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\C{there's nothing to shrink}\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{total\_shrink}[\|o]<{-}\|x)\W(\|o\E\\{normal})\W(\\{list\_ptr}(\|r)\I\\{null})){}$\5
+${}\{{}$\5
+\1${}\\{last\_badness}\K\T{1000000};{}$\5
+\\{set\_glue\_ratio\_one}(\\{glue\_set}(\|r));\C{use the maximum shrinkage}\6
+\X666:Report an overfull hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|o\E\\{normal}){}$\1\6
+\&{if} ${}(\\{list\_ptr}(\|r)\I\\{null}){}$\1\5
+\X667:Report a tight hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\2\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\U657.\fi
+
+\M{665}\B\X665:Determine the shrink order\X${}\E{}$\6
+\&{if} ${}(\\{total\_shrink}[\\{filll}]\I\T{0}){}$\1\5
+${}\|o\K\\{filll};{}$\2\6
+\&{else} \&{if} ${}(\\{total\_shrink}[\\{fill}]\I\T{0}){}$\1\5
+${}\|o\K\\{fill};{}$\2\6
+\&{else} \&{if} ${}(\\{total\_shrink}[\\{fil}]\I\T{0}){}$\1\5
+${}\|o\K\\{fil};{}$\2\6
+\&{else} $\|o\K{}$\\{normal}\par
+\Us664, 676\ETs796.\fi
+
+\M{666}\B\X666:Report an overfull hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+\&{if} ${}(({-}\|x-\\{total\_shrink}[\\{normal}]>\\{hfuzz})\V(\\{hbadness}<\T{100})){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{overfull\_rule}>\T{0})\W({-}\|x-\\{total\_shrink}[\\{normal}]>\\{hfuzz})){}$\5
+${}\{{}$\5
+\1\&{while} ${}(\\{link}(\|q)\I\\{null}){}$\1\5
+${}\|q\K\\{link}(\|q);{}$\2\6
+${}\\{link}(\|q)\K\\{new\_rule}(\,);{}$\5
+${}\\{width}(\\{link}(\|q))\K\\{overfull\_rule};{}$\6
+\4${}\}{}$\2\6
+\\{print\_ln}(\,);\5
+\\{print\_nl}(\.{"Overfull\ \\\\hbox\ ("});\5
+${}\\{print\_scaled}({-}\|x-\\{total\_shrink}[\\{normal}]);{}$\5
+\\{print\_str}(\.{"pt\ too\ wide"});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\par
+\U664.\fi
+
+\M{667}\B\X667:Report a tight hbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{last\_badness}\K\\{badness}({-}\|x,\39\\{total\_shrink}[\\{normal}]);{}$\6
+\&{if} ${}(\\{last\_badness}>\\{hbadness}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_nl}(\.{"Tight\ \\\\hbox\ (badne}\)\.{ss\ "});\5
+\\{print\_int}(\\{last\_badness});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U664.\fi
+
+\M{668}The \\{vpack} subroutine is actually a special case of a slightly more
+general routine called \\{vpackage}, which has four parameters. The fourth
+parameter, which is \\{max\_dimen} in the case of \\{vpack}, specifies the
+maximum depth of the page box that is constructed. The depth is first
+computed by the normal rules; if it exceeds this limit, the reference
+point is simply moved down until the limiting depth is attained.
+
+\Y\B\8\#\&{define} ${}\\{vpack}(\,\ldots\,) \5\\{vpackage}(\.{\_\_VA\_ARGS\_\_},\39\\{max\_dimen}){}$\C{special case of unconstrained depth}\6
+\&{pointer} \\{vpackage}(\&{pointer} \|p${},\39{}$\&{scaled} \|h${},\39{}$\&{small\_number} \|m${},\39{}$\&{scaled} \|l)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|r;\C{the box node that will be returned}\6
+\&{scaled} \|w${},{}$ \|d${},{}$ \|x;\C{width, depth, and natural height}\6
+\&{scaled} \|s;\C{shift amount}\6
+\&{pointer} \|g;\C{points to a glue specification}\6
+\&{glue\_ord} \|o;\C{order of infinity}\7
+${}\\{last\_badness}\K\T{0};{}$\5
+${}\|r\K\\{get\_node}(\\{box\_node\_size});{}$\5
+${}\\{type}(\|r)\K\\{vlist\_node};{}$\5
+${}\\{subtype}(\|r)\K\\{min\_quarterword};{}$\5
+${}\\{shift\_amount}(\|r)\K\T{0};{}$\5
+${}\\{list\_ptr}(\|r)\K\|p{}$;\6
+${}\|w\K\T{0};{}$\5
+\X650:Clear dimensions to zero\X;\6
+\&{while} ${}(\|p\I\\{null}){}$\1\5
+\X669:Examine node \|p in the vlist, taking account of its effect on the dimensions of the new box; then advance \|p to the next node\X;\2\6
+${}\\{width}(\|r)\K\|w;{}$\6
+\&{if} ${}(\|d>\|l){}$\5
+${}\{{}$\5
+\1${}\|x\K\|x+\|d-\|l;{}$\5
+${}\\{depth}(\|r)\K\|l;{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{depth}(\|r)\K\|d;{}$\2\6
+\X672:Determine the value of \\{height}(\|r) and the appropriate glue setting; then \&{return} or \&{goto} \\{common\_ending}\X;\6
+\4\\{common\_ending}:\5
+\X675:Finish issuing a diagnostic message for an overfull or underfull vbox\X;\6
+\4\\{end}:\5
+\&{return} \|r;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{669}\B\X669:Examine node \|p in the vlist, taking account of its effect on the dimensions of the new box; then advance \|p to the next node\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{is\_char\_node}(\|p))\1\5
+\\{confusion}(\X1644:\.{"vpack"}\X);\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{unset\_node}:\5
+\X670:Incorporate box dimensions into the dimensions of the vbox that will contain~it\X\5
+\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1359:Incorporate a whatsit node into a vbox\X;\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X671:Incorporate glue into the vertical totals\X\5
+\&{break};\6
+\4\&{case} \\{kern\_node}:\6
+${}\{{}$\5
+\1${}\|x\K\|x+\|d+\\{width}(\|p);{}$\5
+${}\|d\K\T{0};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\2\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\par
+\U668.\fi
+
+\M{670}\B\X670:Incorporate box dimensions into the dimensions of the vbox that will contain~it\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\|x+\|d+\\{height}(\|p);{}$\5
+${}\|d\K\\{depth}(\|p);{}$\6
+\&{if} ${}(\\{type}(\|p)\G\\{rule\_node}){}$\1\5
+${}\|s\K\T{0}{}$;\5
+\2\&{else}\1\5
+${}\|s\K\\{shift\_amount}(\|p);{}$\2\6
+\&{if} ${}(\\{width}(\|p)+\|s>\|w){}$\1\5
+${}\|w\K\\{width}(\|p)+\|s;{}$\2\6
+\4${}\}{}$\2\par
+\U669.\fi
+
+\M{671}\B\X671:Incorporate glue into the vertical totals\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\|x+\|d;{}$\5
+${}\|d\K\T{0}{}$;\6
+${}\|g\K\\{glue\_ptr}(\|p);{}$\5
+${}\|x\K\|x+\\{width}(\|g){}$;\6
+${}\|o\K\\{stretch\_order}(\|g);{}$\5
+${}\\{total\_stretch}[\|o]\K\\{total\_stretch}[\|o]+\\{stretch}(\|g);{}$\5
+${}\|o\K\\{shrink\_order}(\|g);{}$\5
+${}\\{total\_shrink}[\|o]\K\\{total\_shrink}[\|o]+\\{shrink}(\|g);{}$\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\5
+${}\{{}$\5
+\1${}\|g\K\\{leader\_ptr}(\|p);{}$\6
+\&{if} ${}(\\{width}(\|g)>\|w){}$\1\5
+${}\|w\K\\{width}(\|g);{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U669.\fi
+
+\M{672}When we get to the present part of the program, \|x is the natural height
+of the box being packaged.
+
+\Y\B\4\X672:Determine the value of \\{height}(\|r) and the appropriate glue setting; then \&{return} or \&{goto} \\{common\_ending}\X${}\E{}$\6
+\&{if} ${}(\|m\E\\{additional}){}$\1\5
+${}\|h\K\|x+\|h;{}$\2\6
+${}\\{height}(\|r)\K\|h;{}$\5
+${}\|x\K\|h-\|x{}$;\C{now \|x is the excess to be made up}\6
+\&{if} ${}(\|x\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+${}\\{glue\_order}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\5
+\&{goto} \\{end};\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|x>\T{0}){}$\1\5
+\X673:Determine vertical glue stretch setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X\2\6
+\&{else}\1\5
+\X676:Determine vertical glue shrink setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X\2\par
+\U668.\fi
+
+\M{673}\B\X673:Determine vertical glue stretch setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X${}\E{}$\6
+${}\{{}$\5
+\1\X659:Determine the stretch order\X;\6
+${}\\{glue\_order}(\|r)\K\|o;{}$\5
+${}\\{glue\_sign}(\|r)\K\\{stretching};{}$\6
+\&{if} ${}(\\{total\_stretch}[\|o]\I\T{0}){}$\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}(\|x/{}$(\&{double}) \\{total\_stretch}[\|o]);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\C{there's nothing to stretch}\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|o\E\\{normal}){}$\1\6
+\&{if} ${}(\\{list\_ptr}(\|r)\I\\{null}){}$\1\5
+\X674:Report an underfull vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\2\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\U672.\fi
+
+\M{674}\B\X674:Report an underfull vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{last\_badness}\K\\{badness}(\|x,\39\\{total\_stretch}[\\{normal}]);{}$\6
+\&{if} ${}(\\{last\_badness}>\\{vbadness}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\6
+\&{if} ${}(\\{last\_badness}>\T{100}){}$\1\5
+\\{print\_nl}(\.{"Underfull"});\5
+\2\&{else}\1\5
+\\{print\_nl}(\.{"Loose"});\2\6
+\\{print\_str}(\.{"\ \\\\vbox\ (badness\ "});\5
+\\{print\_int}(\\{last\_badness});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U673.\fi
+
+\M{675}\B\X675:Finish issuing a diagnostic message for an overfull or underfull vbox\X${}\E{}$\6
+\&{if} (\\{output\_active})\1\5
+\\{print\_str}(\.{")\ has\ occurred\ whil}\)\.{e\ \\\\output\ is\ active}\)\.{"});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{pack\_begin\_line}\I\T{0}{}$)\C{it's actually negative}\6
+${}\{{}$\5
+\1\\{print\_str}(\.{")\ in\ alignment\ at\ l}\)\.{ines\ "});\5
+\\{print\_int}(\\{abs}(\\{pack\_begin\_line}));\5
+\\{print\_str}(\.{"--"});\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{print\_str}(\.{")\ detected\ at\ line\ }\)\.{"});\2\6
+\\{print\_int}(\\{line});\5
+\\{print\_ln}(\,);\6
+\4${}\}{}$\2\6
+\\{begin\_diagnostic}(\,);\5
+\\{show\_box}(\|r); \\{end\_diagnostic}(\\{true})\par
+\U668.\fi
+
+\M{676}\B\X676:Determine vertical glue shrink setting, then \&{return} or \hbox{\&{goto} \\{common\_ending}}\X${}\E{}$\6
+${}\{{}$\5
+\1\X665:Determine the shrink order\X;\6
+${}\\{glue\_order}(\|r)\K\|o;{}$\5
+${}\\{glue\_sign}(\|r)\K\\{shrinking};{}$\6
+\&{if} ${}(\\{total\_shrink}[\|o]\I\T{0}){}$\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}(({-}\|x)/{}$(\&{double}) \\{total\_shrink}[\|o]);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\C{there's nothing to shrink}\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{total\_shrink}[\|o]<{-}\|x)\W(\|o\E\\{normal})\W(\\{list\_ptr}(\|r)\I\\{null})){}$\5
+${}\{{}$\5
+\1${}\\{last\_badness}\K\T{1000000};{}$\5
+\\{set\_glue\_ratio\_one}(\\{glue\_set}(\|r));\C{use the maximum shrinkage}\6
+\X677:Report an overfull vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|o\E\\{normal}){}$\1\6
+\&{if} ${}(\\{list\_ptr}(\|r)\I\\{null}){}$\1\5
+\X678:Report a tight vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X;\2\2\6
+\&{goto} \\{end};\6
+\4${}\}{}$\2\par
+\U672.\fi
+
+\M{677}\B\X677:Report an overfull vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+\&{if} ${}(({-}\|x-\\{total\_shrink}[\\{normal}]>\\{vfuzz})\V(\\{vbadness}<\T{100})){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_nl}(\.{"Overfull\ \\\\vbox\ ("});\5
+${}\\{print\_scaled}({-}\|x-\\{total\_shrink}[\\{normal}]);{}$\5
+\\{print\_str}(\.{"pt\ too\ high"});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\par
+\U676.\fi
+
+\M{678}\B\X678:Report a tight vbox and \&{goto} \\{common\_ending}, if this box is sufficiently bad\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{last\_badness}\K\\{badness}({-}\|x,\39\\{total\_shrink}[\\{normal}]);{}$\6
+\&{if} ${}(\\{last\_badness}>\\{vbadness}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_nl}(\.{"Tight\ \\\\vbox\ (badne}\)\.{ss\ "});\5
+\\{print\_int}(\\{last\_badness});\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U676.\fi
+
+\M{679}When a box is being appended to the current vertical list, the
+baselineskip calculation is handled by the \\{append\_to\_vlist} routine.
+
+\Y\B\&{void} \\{append\_to\_vlist}(\&{pointer} \|b)\1\1\2\2\6
+${}\{{}$\5
+\1\&{scaled} \|d;\C{deficiency of space between baselines}\6
+\&{pointer} \|p;\C{a new glue node}\7
+\&{if} ${}(\\{prev\_depth}>\\{ignore\_depth}){}$\5
+${}\{{}$\5
+\1${}\|d\K\\{width}(\\{baseline\_skip})-\\{prev\_depth}-\\{height}(\|b);{}$\6
+\&{if} ${}(\|d<\\{line\_skip\_limit}){}$\1\5
+${}\|p\K\\{new\_param\_glue}(\\{line\_skip\_code});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_skip\_param}(\\{baseline\_skip\_code});{}$\5
+${}\\{width}(\\{temp\_ptr})\K\|d{}$;\C{$\\{temp\_ptr}\E\\{glue\_ptr}(\|p)$}\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\|b;{}$\5
+${}\\{tail}\K\|b;{}$\5
+${}\\{prev\_depth}\K\\{depth}(\|b);{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{680}Data structures for math mode.
+When \TeX\ reads a formula that is enclosed between \.\$'s, it constructs an
+{\sl mlist}, which is essentially a tree structure representing that
+formula. An mlist is a linear sequence of items, but we can regard it as
+a tree structure because mlists can appear within mlists. For example, many
+of the entries can be subscripted or superscripted, and such ``scripts''
+are mlists in their own right.
+
+An entire formula is parsed into such a tree before any of the actual
+typesetting is done, because the current style of type is usually not
+known until the formula has been fully scanned. For example, when the
+formula `\.{\$a+b \\over c+d\$}' is being read, there is no way to tell
+that `\.{a+b}' will be in script size until `\.{\\over}' has appeared.
+
+During the scanning process, each element of the mlist being built is
+classified as a relation, a binary operator, an open parenthesis, etc.,
+or as a construct like `\.{\\sqrt}' that must be built up. This classification
+appears in the mlist data structure.
+
+After a formula has been fully scanned, the mlist is converted to an hlist
+so that it can be incorporated into the surrounding text. This conversion is
+controlled by a recursive procedure that decides all of the appropriate
+styles by a ``top-down'' process starting at the outermost level and working
+in towards the subformulas. The formula is ultimately pasted together using
+combinations of horizontal and vertical boxes, with glue and penalty nodes
+inserted as necessary.
+
+An mlist is represented internally as a linked list consisting chiefly
+of ``noads'' (pronounced ``no-adds''), to distinguish them from the somewhat
+similar ``nodes'' in hlists and vlists. Certain kinds of ordinary nodes are
+allowed to appear in mlists together with the noads; \TeX\ tells the difference
+by means of the \\{type} field, since a noad's \\{type} is always greater than
+that of a node. An mlist does not contain character nodes, hlist nodes, vlist
+nodes, math nodes, ligature nodes,
+or unset nodes; in particular, each mlist item appears in the
+variable-size part of \\{mem}, so the \\{type} field is always present.
+
+\fi
+
+\M{681}Each noad is four or more words long. The first word contains the \\{type}
+and \\{subtype} and \\{link} fields that are already so familiar to us; the
+second, third, and fourth words are called the noad's \\{nucleus}, \\{subscr},
+and \\{supscr} fields.
+
+Consider, for example, the simple formula `\.{\$x\^2\$}', which would be
+parsed into an mlist containing a single element called an \\{ord\_noad}.
+The \\{nucleus} of this noad is a representation of `\.x', the \\{subscr} is
+empty, and the \\{supscr} is a representation of `\.2'.
+
+The \\{nucleus}, \\{subscr}, and \\{supscr} fields are further broken into
+subfields. If \|p points to a noad, and if \|q is one of its principal
+fields (e.g., $\|q\E\\{subscr}(\|p)$), there are several possibilities for the
+subfields, depending on the \\{math\_type} of \|q.
+
+\yskip\hang$\\{math\_type}(\|q)\E\\{math\_char}$ means that \\{fam}(\|q) refers to one of
+the sixteen font families, and \\{character}(\|q) is the number of a character
+within a font of that family, as in a character node.
+
+\yskip\hang$\\{math\_type}(\|q)\E\\{math\_text\_char}$ is similar, but the character is
+unsubscripted and unsuperscripted and it is followed immediately by another
+character from the same font. (This \\{math\_type} setting appears only
+briefly during the processing; it is used to suppress unwanted italic
+corrections.)
+
+\yskip\hang$\\{math\_type}(\|q)\E\\{empty}$ indicates a field with no value (the
+corresponding attribute of noad \|p is not present).
+
+\yskip\hang$\\{math\_type}(\|q)\E\\{sub\_box}$ means that \\{info}(\|q) points to a box
+node (either an \\{hlist\_node} or a \\{vlist\_node}) that should be used as the
+value of the field. The \\{shift\_amount} in the subsidiary box node is the
+amount by which that box will be shifted downward.
+
+\yskip\hang$\\{math\_type}(\|q)\E\\{sub\_mlist}$ means that \\{info}(\|q) points to
+an mlist; the mlist must be converted to an hlist in order to obtain
+the value of this field.
+
+\yskip\noindent In the latter case, we might have $\\{info}(\|q)\E\\{null}$. This
+is not the same as $\\{math\_type}(\|q)\E\\{empty}$; for example, `\.{\$P\_\{\}\$}'
+and `\.{\$P\$}' produce different results (the former will not have the
+``italic correction'' added to the width of \|P, but the ``script skip''
+will be added).
+
+The definitions of subfields given here are evidently wasteful of space,
+since a halfword is being used for the \\{math\_type} although only three
+bits would be needed. However, there are hardly ever many noads present at
+once, since they are soon converted to nodes that take up even more space,
+so we can afford to represent them in whatever way simplifies the
+programming.
+
+\Y\B\4\D$\\{noad\_size}$ \5
+\T{4}\C{number of words in a normal noad}\par
+\B\4\D$\\{nucleus}(\|X)$ \5
+$\|X+{}$\T{1}\C{the \\{nucleus} field of a noad}\par
+\B\4\D$\\{supscr}(\|X)$ \5
+$\|X+{}$\T{2}\C{the \\{supscr} field of a noad}\par
+\B\4\D$\\{subscr}(\|X)$ \5
+$\|X+{}$\T{3}\C{the \\{subscr} field of a noad}\par
+\B\4\D$\\{math\_type}$ \5
+\\{link}\C{a \&{halfword} in \\{mem}}\par
+\B\4\D$\\{fam}$ \5
+\\{font}\C{a \&{quarterword} in \\{mem}}\par
+\B\4\D$\\{math\_char}$ \5
+\T{1}\C{\\{math\_type} when the attribute is simple}\par
+\B\4\D$\\{sub\_box}$ \5
+\T{2}\C{\\{math\_type} when the attribute is a box}\par
+\B\4\D$\\{sub\_mlist}$ \5
+\T{3}\C{\\{math\_type} when the attribute is a formula}\par
+\B\4\D$\\{math\_text\_char}$ \5
+\T{4}\C{\\{math\_type} when italic correction is dubious}\par
+\fi
+
+\M{682}Each portion of a formula is classified as Ord, Op, Bin, Rel, Ope,
+Clo, Pun, or Inn, for purposes of spacing and line breaking. An
+\\{ord\_noad}, \\{op\_noad}, \\{bin\_noad}, \\{rel\_noad}, \\{open\_noad}, \\{close\_noad},
+\\{punct\_noad}, or \\{inner\_noad} is used to represent portions of the various
+types. For example, an `\.=' sign in a formula leads to the creation of a
+\\{rel\_noad} whose \\{nucleus} field is a representation of an equals sign
+(usually $\\{fam}\E\T{0}$, $\\{character}\E\T{\~75}$). A formula preceded by \.{\\mathrel}
+also results in a \\{rel\_noad}. When a \\{rel\_noad} is followed by an
+\\{op\_noad}, say, and possibly separated by one or more ordinary nodes (not
+noads), \TeX\ will insert a penalty node (with the current \\{rel\_penalty})
+just after the formula that corresponds to the \\{rel\_noad}, unless there
+already was a penalty immediately following; and a ``thick space'' will be
+inserted just before the formula that corresponds to the \\{op\_noad}.
+
+A noad of type \\{ord\_noad}, \\{op\_noad}, \dots, \\{inner\_noad} usually
+has a $\\{subtype}\E\\{normal}$. The only exception is that an \\{op\_noad} might
+have $\\{subtype}\E\\{limits}$ or \\{no\_limits}, if the normal positioning of
+limits has been overridden for this operator.
+
+\Y\B\4\D$\\{ord\_noad}$ \5
+$(\\{unset\_node}+\T{3}{}$)\C{\\{type} of a noad classified Ord}\par
+\B\4\D$\\{op\_noad}$ \5
+$(\\{ord\_noad}+\T{1}{}$)\C{\\{type} of a noad classified Op}\par
+\B\4\D$\\{bin\_noad}$ \5
+$(\\{ord\_noad}+\T{2}{}$)\C{\\{type} of a noad classified Bin}\par
+\B\4\D$\\{rel\_noad}$ \5
+$(\\{ord\_noad}+\T{3}{}$)\C{\\{type} of a noad classified Rel}\par
+\B\4\D$\\{open\_noad}$ \5
+$(\\{ord\_noad}+\T{4}{}$)\C{\\{type} of a noad classified Ope}\par
+\B\4\D$\\{close\_noad}$ \5
+$(\\{ord\_noad}+\T{5}{}$)\C{\\{type} of a noad classified Clo}\par
+\B\4\D$\\{punct\_noad}$ \5
+$(\\{ord\_noad}+\T{6}{}$)\C{\\{type} of a noad classified Pun}\par
+\B\4\D$\\{inner\_noad}$ \5
+$(\\{ord\_noad}+\T{7}{}$)\C{\\{type} of a noad classified Inn}\par
+\B\4\D$\\{limits}$ \5
+\T{1}\C{\\{subtype} of \\{op\_noad} whose scripts are to be above, below}\par
+\B\4\D$\\{no\_limits}$ \5
+\T{2}\C{\\{subtype} of \\{op\_noad} whose scripts are to be normal}\par
+\fi
+
+\M{683}A \\{radical\_noad} is five words long; the fifth word is the \\{left\_delimiter}
+field, which usually represents a square root sign.
+
+A \\{fraction\_noad} is six words long; it has a \\{right\_delimiter} field
+as well as a \\{left\_delimiter}.
+
+Delimiter fields are of type \&{four\_quarters}, and they have four subfields
+called \\{small\_fam}, \\{small\_char}, \\{large\_fam}, \\{large\_char}. These subfields
+represent variable-size delimiters by giving the ``small'' and ``large''
+starting characters, as explained in Chapter~17 of {\sl The \TeX book}.
+
+A \\{fraction\_noad} is actually quite different from all other noads. Not
+only does it have six words, it has \\{thickness}, \\{denominator}, and
+\\{numerator} fields instead of \\{nucleus}, \\{subscr}, and \\{supscr}. The
+\\{thickness} is a scaled value that tells how thick to make a fraction
+rule; however, the special value \\{default\_code} is used to stand for the
+\\{default\_rule\_thickness} of the current size. The \\{numerator} and
+\\{denominator} point to mlists that define a fraction; we always have
+$$\hbox{$\\{math\_type}(\\{numerator})\E\\{math\_type}(\\{denominator})\E\\{sub\_mlist}$}.$$ The
+\\{left\_delimiter} and \\{right\_delimiter} fields specify delimiters that will
+be placed at the left and right of the fraction. In this way, a
+\\{fraction\_noad} is able to represent all of \TeX's operators \.{\\over},
+\.{\\atop}, \.{\\above}, \.{\\overwithdelims}, \.{\\atopwithdelims}, and
+\.{\\abovewithdelims}.
+
+\Y\B\4\D$\\{left\_delimiter}(\|X)$ \5
+$\|X+{}$\T{4}\C{first delimiter field of a noad}\par
+\B\4\D$\\{right\_delimiter}(\|X)$ \5
+$\|X+{}$\T{5}\C{second delimiter field of a fraction noad}\par
+\B\4\D$\\{radical\_noad}$ \5
+$(\\{inner\_noad}+\T{1}{}$)\C{\\{type} of a noad for square roots}\par
+\B\4\D$\\{radical\_noad\_size}$ \5
+\T{5}\C{number of \\{mem} words in a radical noad}\par
+\B\4\D$\\{fraction\_noad}$ \5
+$(\\{radical\_noad}+\T{1}{}$)\C{\\{type} of a noad for generalized fractions}\par
+\B\4\D$\\{fraction\_noad\_size}$ \5
+\T{6}\C{number of \\{mem} words in a fraction noad}\par
+\B\4\D$\\{small\_fam}(\|X)$ \5
+$\\{mem}[\|X].\\{qqqq}.{}$\\{b0}\C{\\{fam} for ``small'' delimiter}\par
+\B\4\D$\\{small\_char}(\|X)$ \5
+$\\{mem}[\|X].\\{qqqq}.{}$\\{b1}\C{\\{character} for ``small'' delimiter}\par
+\B\4\D$\\{large\_fam}(\|X)$ \5
+$\\{mem}[\|X].\\{qqqq}.{}$\\{b2}\C{\\{fam} for ``large'' delimiter}\par
+\B\4\D$\\{large\_char}(\|X)$ \5
+$\\{mem}[\|X].\\{qqqq}.{}$\\{b3}\C{\\{character} for ``large'' delimiter}\par
+\B\4\D$\\{thickness}$ \5
+\\{width}\C{\\{thickness} field in a fraction noad}\par
+\B\4\D$\\{default\_code}$ \5
+\T{\~10000000000}\C{denotes \\{default\_rule\_thickness}}\par
+\B\4\D$\\{numerator}$ \5
+\\{supscr}\C{\\{numerator} field in a fraction noad}\par
+\B\4\D$\\{denominator}$ \5
+\\{subscr}\C{\\{denominator} field in a fraction noad}\par
+\fi
+
+\M{684}The global variable \\{empty\_field} is set up for initialization of empty
+fields in new noads. Similarly, \\{null\_delimiter} is for the initialization
+of delimiter fields.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{two\_halves} \\{empty\_field};\6
+\&{four\_quarters} \\{null\_delimiter};\par
+\fi
+
+\M{685}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{empty\_field}.\\{rh}\K\\{empty};{}$\5
+${}\\{empty\_field}.\\{lh}\K\\{null}{}$;\6
+${}\\{null\_delimiter}.\\{b0}\K\T{0};{}$\5
+${}\\{null\_delimiter}.\\{b1}\K\\{min\_quarterword}{}$;\6
+${}\\{null\_delimiter}.\\{b2}\K\T{0};{}$\5
+${}\\{null\_delimiter}.\\{b3}\K\\{min\_quarterword}{}$;\par
+\fi
+
+\M{686}The \\{new\_noad} function creates an \\{ord\_noad} that is completely null.
+
+\Y\B\&{pointer} \\{new\_noad}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\7
+${}\|p\K\\{get\_node}(\\{noad\_size});{}$\5
+${}\\{type}(\|p)\K\\{ord\_noad};{}$\5
+${}\\{subtype}(\|p)\K\\{normal};{}$\5
+${}\\{mem}[\\{nucleus}(\|p)].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{subscr}(\|p)].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{supscr}(\|p)].\\{hh}\K\\{empty\_field};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{687}A few more kinds of noads will complete the set: An \\{under\_noad} has its
+nucleus underlined; an \\{over\_noad} has it overlined. An \\{accent\_noad} places
+an accent over its nucleus; the accent character appears as
+\\{fam}(\\{accent\_chr}(\|p)) and \\{character}(\\{accent\_chr}(\|p)). A \\{vcenter\_noad}
+centers its nucleus vertically with respect to the axis of the formula;
+in such noads we always have $\\{math\_type}(\\{nucleus}(\|p))\E\\{sub\_box}$.
+
+And finally, we have \\{left\_noad} and \\{right\_noad} types, to implement
+\TeX's \.{\\left} and \.{\\right}. The \\{nucleus} of such noads is
+replaced by a \\{delimiter} field; thus, for example, `\.{\\left(}' produces
+a \\{left\_noad} such that \\{delimiter}(\|p) holds the family and character
+codes for all left parentheses. A \\{left\_noad} never appears in an mlist
+except as the first element, and a \\{right\_noad} never appears in an mlist
+except as the last element; furthermore, we either have both a \\{left\_noad}
+and a \\{right\_noad}, or neither one is present. The \\{subscr} and \\{supscr}
+fields are always \\{empty} in a \\{left\_noad} and a \\{right\_noad}.
+
+\Y\B\4\D$\\{under\_noad}$ \5
+$(\\{fraction\_noad}+\T{1}{}$)\C{\\{type} of a noad for underlining}\par
+\B\4\D$\\{over\_noad}$ \5
+$(\\{under\_noad}+\T{1}{}$)\C{\\{type} of a noad for overlining}\par
+\B\4\D$\\{accent\_noad}$ \5
+$(\\{over\_noad}+\T{1}{}$)\C{\\{type} of a noad for accented subformulas}\par
+\B\4\D$\\{accent\_noad\_size}$ \5
+\T{5}\C{number of \\{mem} words in an accent noad}\par
+\B\4\D$\\{accent\_chr}(\|X)$ \5
+$\|X+{}$\T{4}\C{the \\{accent\_chr} field of an accent noad}\par
+\B\4\D$\\{vcenter\_noad}$ \5
+$(\\{accent\_noad}+\T{1}{}$)\C{\\{type} of a noad for \.{\\vcenter}}\par
+\B\4\D$\\{left\_noad}$ \5
+$(\\{vcenter\_noad}+\T{1}{}$)\C{\\{type} of a noad for \.{\\left}}\par
+\B\4\D$\\{right\_noad}$ \5
+$(\\{left\_noad}+\T{1}{}$)\C{\\{type} of a noad for \.{\\right}}\par
+\B\4\D$\\{delimiter}$ \5
+\\{nucleus}\C{\\{delimiter} field in left and right noads}\par
+\B\4\D$\\{scripts\_allowed}(\|X)$ \5
+$(\\{type}(\|X)\G\\{ord\_noad})\W(\\{type}(\|X)<\\{left\_noad}{}$)\par
+\fi
+
+\M{688}Math formulas can also contain instructions like \.{\\textstyle} that
+override \TeX's normal style rules. A \\{style\_node} is inserted into the
+data structure to record such instructions; it is three words long, so it
+is considered a node instead of a noad. The \\{subtype} is either \\{display\_style}
+or \\{text\_style} or \\{script\_style} or \\{script\_script\_style}. The
+second and third words of a \\{style\_node} are not used, but they are
+present because a \\{choice\_node} is converted to a \\{style\_node}.
+
+\TeX\ uses even numbers 0, 2, 4, 6 to encode the basic styles
+\\{display\_style}, \dots, \\{script\_script\_style}, and adds~1 to get the
+``cramped'' versions of these styles. This gives a numerical order that
+is backwards from the convention of Appendix~G in {\sl The \TeX book\/};
+i.e., a smaller style has a larger numerical value.
+
+\Y\B\4\D$\\{style\_node}$ \5
+$(\\{unset\_node}+\T{1}{}$)\C{\\{type} of a style node}\par
+\B\4\D$\\{style\_node\_size}$ \5
+\T{3}\C{number of words in a style node}\par
+\B\4\D$\\{display\_style}$ \5
+\T{0}\C{\\{subtype} for \.{\\displaystyle}}\par
+\B\4\D$\\{text\_style}$ \5
+\T{2}\C{\\{subtype} for \.{\\textstyle}}\par
+\B\4\D$\\{script\_style}$ \5
+\T{4}\C{\\{subtype} for \.{\\scriptstyle}}\par
+\B\4\D$\\{script\_script\_style}$ \5
+\T{6}\C{\\{subtype} for \.{\\scriptscriptstyle}}\par
+\B\4\D$\\{cramped}$ \5
+\T{1}\C{add this to an uncramped style if you want to cramp it}\par
+\Y\B\&{pointer} \\{new\_style}(\&{small\_number} \|s)\C{create a style node}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{style\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{style\_node};{}$\5
+${}\\{subtype}(\|p)\K\|s;{}$\5
+${}\\{width}(\|p)\K\T{0};{}$\5
+${}\\{depth}(\|p)\K\T{0}{}$;\C{the \\{width} and \\{depth} are not used}\6
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{689}Finally, the \.{\\mathchoice} primitive creates a \\{choice\_node}, which
+has special subfields \\{display\_mlist}, \\{text\_mlist}, \\{script\_mlist},
+and \\{script\_script\_mlist} pointing to the mlists for each style.
+
+\Y\B\4\D$\\{choice\_node}$ \5
+$(\\{unset\_node}+\T{2}{}$)\C{\\{type} of a choice node}\par
+\B\4\D$\\{display\_mlist}(\|X)$ \5
+$\\{info}(\|X+\T{1}{}$)\C{mlist to be used in display style}\par
+\B\4\D$\\{text\_mlist}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{mlist to be used in text style}\par
+\B\4\D$\\{script\_mlist}(\|X)$ \5
+$\\{info}(\|X+\T{2}{}$)\C{mlist to be used in script style}\par
+\B\4\D$\\{script\_script\_mlist}(\|X)$ \5
+$\\{link}(\|X+\T{2}{}$)\C{mlist to be used in scriptscript style}\par
+\Y\B\&{pointer} \\{new\_choice}(\&{void})\C{create a choice node}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\\{style\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{choice\_node};{}$\5
+${}\\{subtype}(\|p)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+${}\\{display\_mlist}(\|p)\K\\{null};{}$\5
+${}\\{text\_mlist}(\|p)\K\\{null};{}$\5
+${}\\{script\_mlist}(\|p)\K\\{null};{}$\5
+${}\\{script\_script\_mlist}(\|p)\K\\{null};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{690}Let's consider now the previously unwritten part of \\{show\_node\_list}
+that displays the things that can only be present in mlists; this
+program illustrates how to access the data structures just defined.
+
+In the context of the following program, \|p points to a node or noad that
+should be displayed, and the current string contains the ``recursion history''
+that leads to this point. The recursion history consists of a dot for each
+outer level in which \|p is subsidiary to some node, or in which \|p is
+subsidiary to the \\{nucleus} field of some noad; the dot is replaced by
+`\.\_' or `\.\^' or `\./' or `\.\\' if \|p is descended from the \\{subscr}
+or \\{supscr} or \\{denominator} or \\{numerator} fields of noads. For example,
+the current string would be `\.{.\^.\_/}' if \|p points to the \\{ord\_noad} for
+\|x in the (ridiculous) formula
+`\.{\$\\sqrt\{a\^\{\\mathinner\{b\_\{c\\over x+y\}\}\}\}\$}'.
+
+\Y\B\4\X690:Cases of \\{show\_node\_list} that arise in mlists only\X${}\E{}$\6
+\4\&{case} \\{style\_node}:\5
+\\{print\_style}(\\{subtype}(\|p));\5
+\&{break};\6
+\4\&{case} \\{choice\_node}:\5
+\X695:Display choice node \|p\X\5
+\&{break};\6
+\4\&{case} \\{ord\_noad}:\5
+\&{case} \\{op\_noad}:\5
+\&{case} \\{bin\_noad}:\5
+\&{case} \\{rel\_noad}:\5
+\&{case} \\{open\_noad}:\5
+\&{case} \\{close\_noad}:\5
+\&{case} \\{punct\_noad}:\5
+\&{case} \\{inner\_noad}:\5
+\&{case} \\{radical\_noad}:\5
+\&{case} \\{over\_noad}:\5
+\&{case} \\{under\_noad}:\5
+\&{case} \\{vcenter\_noad}:\5
+\&{case} \\{accent\_noad}:\5
+\&{case} \\{left\_noad}:\5
+\&{case} \\{right\_noad}:\5
+\X696:Display normal noad \|p\X\5
+\&{break};\6
+\4\&{case} \\{fraction\_noad}:\5
+\X697:Display fraction noad \|p\X\5
+\&{break};\par
+\U183.\fi
+
+\M{691}Here are some simple routines used in the display of noads.
+
+\Y\B\4\X691:Declare procedures needed for displaying the elements of mlists\X${}\E{}$\6
+\&{void} \\{print\_fam\_and\_char}(\&{pointer} \|p)\C{prints family and character}\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1490:\.{"fam"}\X);\5
+\\{print\_int}(\\{fam}(\|p));\5
+\\{print\_char}(\.{'\ '});\5
+\\{print\_ASCII}(\\{qo}(\\{character}(\|p)));\6
+\4${}\}{}$\2\7
+\&{void} \\{print\_delimiter}(\&{pointer} \|p)\C{prints a delimiter as 24-bit hex value}\6
+${}\{{}$\5
+\1\&{int} \|a;\C{accumulator}\7
+${}\|a\K\\{small\_fam}(\|p)*\T{256}+\\{qo}(\\{small\_char}(\|p));{}$\5
+${}\|a\K\|a*\T{\^1000}+\\{large\_fam}(\|p)*\T{256}+\\{qo}(\\{large\_char}(\|p));{}$\6
+\&{if} ${}(\|a<\T{0}){}$\1\5
+\\{print\_int}(\|a);\C{this should never happen}\2\6
+\&{else}\1\5
+\\{print\_hex}(\|a);\2\6
+\4${}\}{}$\2\par
+\As692\ET694.
+\U179.\fi
+
+\M{692}The next subroutine will descend to another level of recursion when a
+subsidiary mlist needs to be displayed. The parameter \|c indicates what
+character is to become part of the recursion history. An empty mlist is
+distinguished from a field with $\\{math\_type}(\|p)\E\\{empty}$, because these are
+not equivalent (as explained above).
+
+\Y\B\4\X691:Declare procedures needed for displaying the elements of mlists\X${}\mathrel+\E{}$\6
+\&{void} \\{show\_info}(\&{void});\C{\\{show\_node\_list}(\\{info}(\\{temp\_ptr}))}\7
+\&{void} \\{print\_subsidiary\_data}(\&{pointer} \|p${},\39{}$\&{ASCII\_code} \|c)\C{display a noad field}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_length}\G\\{depth\_threshold}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{math\_type}(\|p)\I\\{empty}){}$\1\5
+\\{print\_str}(\.{"\ []"});\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{append\_char}(\|c);\C{include \|c in the recursion history}\6
+${}\\{temp\_ptr}\K\|p{}$;\C{prepare for \\{show\_info} if recursion is needed}\6
+\&{switch} (\\{math\_type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{math\_char}:\6
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_current\_string}(\,);\5
+\\{print\_fam\_and\_char}(\|p);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{sub\_box}:\5
+\\{show\_info}(\,);\5
+\&{break};\C{recursive call}\6
+\4\&{case} \\{sub\_mlist}:\6
+\&{if} ${}(\\{info}(\|p)\E\\{null}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_current\_string}(\,);\5
+\\{print\_str}(\.{"\{\}"});\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{show\_info}(\,);\5
+\2\&{break};\C{recursive call}\6
+\4\&{default}:\5
+\\{do\_nothing};\C{\\{empty}}\6
+\4${}\}{}$\2\6
+\\{flush\_char};\C{remove \|c from the recursion history}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{693}The inelegant introduction of \\{show\_info} in the code above seems better
+than the alternative of using \PASCAL's strange \\{forward} declaration for a
+procedure with parameters. The \PASCAL\ convention about dropping parameters
+from a post-\\{forward} procedure is, frankly, so intolerable to the author
+of \TeX\ that he would rather stoop to communication via a global temporary
+variable. (A similar stoopidity occurred with respect to \\{hlist\_out} and
+\\{vlist\_out} above, and it will occur with respect to \\{mlist\_to\_hlist} below.)
+
+\Y\B\&{void} \\{show\_info}(\&{void})\C{the reader will kindly forgive this}\6
+${}\{{}$\5
+\1\\{show\_node\_list}(\\{info}(\\{temp\_ptr}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{694}\B\X691:Declare procedures needed for displaying the elements of mlists\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_style}(\&{int} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{switch} ${}(\|c/\T{2}){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+\\{print\_esc}(\X1645:\.{"displaystyle"}\X);\5
+\&{break};\C{$\\{display\_style}\E\T{0}$}\6
+\4\&{case} \T{1}:\5
+\\{print\_esc}(\X1646:\.{"textstyle"}\X);\5
+\&{break};\C{$\\{text\_style}\E\T{2}$}\6
+\4\&{case} \T{2}:\5
+\\{print\_esc}(\X1647:\.{"scriptstyle"}\X);\5
+\&{break};\C{$\\{script\_style}\E\T{4}$}\6
+\4\&{case} \T{3}:\5
+\\{print\_esc}(\X1648:\.{"scriptscriptstyle"}\X);\5
+\&{break};\C{$\\{script\_script\_style}\E\T{6}$}\6
+\4\&{default}:\5
+\\{print\_str}(\.{"Unknown\ style!"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{695}\B\X695:Display choice node \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1547:\.{"mathchoice"}\X);\5
+\\{append\_char}(\.{'D'});\5
+\\{show\_node\_list}(\\{display\_mlist}(\|p));\5
+\\{flush\_char};\5
+\\{append\_char}(\.{'T'});\5
+\\{show\_node\_list}(\\{text\_mlist}(\|p));\5
+\\{flush\_char};\5
+\\{append\_char}(\.{'S'});\5
+\\{show\_node\_list}(\\{script\_mlist}(\|p));\5
+\\{flush\_char};\5
+\\{append\_char}(\.{'s'});\5
+\\{show\_node\_list}(\\{script\_script\_mlist}(\|p));\5
+\\{flush\_char};\6
+\4${}\}{}$\2\par
+\U690.\fi
+
+\M{696}\B\X696:Display normal noad \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{ord\_noad}:\5
+\\{print\_esc}(\X1649:\.{"mathord"}\X);\5
+\&{break};\6
+\4\&{case} \\{op\_noad}:\5
+\\{print\_esc}(\X1650:\.{"mathop"}\X);\5
+\&{break};\6
+\4\&{case} \\{bin\_noad}:\5
+\\{print\_esc}(\X1651:\.{"mathbin"}\X);\5
+\&{break};\6
+\4\&{case} \\{rel\_noad}:\5
+\\{print\_esc}(\X1652:\.{"mathrel"}\X);\5
+\&{break};\6
+\4\&{case} \\{open\_noad}:\5
+\\{print\_esc}(\X1653:\.{"mathopen"}\X);\5
+\&{break};\6
+\4\&{case} \\{close\_noad}:\5
+\\{print\_esc}(\X1654:\.{"mathclose"}\X);\5
+\&{break};\6
+\4\&{case} \\{punct\_noad}:\5
+\\{print\_esc}(\X1655:\.{"mathpunct"}\X);\5
+\&{break};\6
+\4\&{case} \\{inner\_noad}:\5
+\\{print\_esc}(\X1656:\.{"mathinner"}\X);\5
+\&{break};\6
+\4\&{case} \\{over\_noad}:\5
+\\{print\_esc}(\X1657:\.{"overline"}\X);\5
+\&{break};\6
+\4\&{case} \\{under\_noad}:\5
+\\{print\_esc}(\X1658:\.{"underline"}\X);\5
+\&{break};\6
+\4\&{case} \\{vcenter\_noad}:\5
+\\{print\_esc}(\X1561:\.{"vcenter"}\X);\5
+\&{break};\6
+\4\&{case} \\{radical\_noad}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1555:\.{"radical"}\X);\5
+\\{print\_delimiter}(\\{left\_delimiter}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{accent\_noad}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1530:\.{"accent"}\X);\5
+\\{print\_fam\_and\_char}(\\{accent\_chr}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{left\_noad}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1659:\.{"left"}\X);\5
+\\{print\_delimiter}(\\{delimiter}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{right\_noad}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1660:\.{"right"}\X);\5
+\\{print\_delimiter}(\\{delimiter}(\|p));\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{subtype}(\|p)\I\\{normal}){}$\1\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{limits}){}$\1\5
+\\{print\_esc}(\X1661:\.{"limits"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1662:\.{"nolimits"}\X);\2\2\6
+\&{if} ${}(\\{type}(\|p)<\\{left\_noad}){}$\1\5
+${}\\{print\_subsidiary\_data}(\\{nucleus}(\|p),\39\.{'.'});{}$\2\6
+${}\\{print\_subsidiary\_data}(\\{supscr}(\|p),\39\.{'\^'});{}$\5
+${}\\{print\_subsidiary\_data}(\\{subscr}(\|p),\39\.{'\_'});{}$\6
+\4${}\}{}$\2\par
+\U690.\fi
+
+\M{697}\B\X697:Display fraction noad \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1663:\.{"fraction,\ thickness}\)\.{\ "}\X);\6
+\&{if} ${}(\\{thickness}(\|p)\E\\{default\_code}){}$\1\5
+\\{print\_str}(\.{"=\ default"});\2\6
+\&{else}\1\5
+\\{print\_scaled}(\\{thickness}(\|p));\2\6
+\&{if} ${}((\\{small\_fam}(\\{left\_delimiter}(\|p))\I\T{0})\V{}$\5
+${}(\\{small\_char}(\\{left\_delimiter}(\|p))\I\\{min\_quarterword})\V\30(\\{large\_fam}(\\{left\_delimiter}(\|p))\I\T{0})\V\30(\\{large\_char}(\\{left\_delimiter}(\|p))\I\\{min\_quarterword})){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ left-delimiter\ "});\5
+\\{print\_delimiter}(\\{left\_delimiter}(\|p));\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{small\_fam}(\\{right\_delimiter}(\|p))\I\T{0})\V\30(\\{small\_char}(\\{right\_delimiter}(\|p))\I\\{min\_quarterword})\V\30(\\{large\_fam}(\\{right\_delimiter}(\|p))\I\T{0})\V\30(\\{large\_char}(\\{right\_delimiter}(\|p))\I\\{min%
+\_quarterword})){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{",\ right-delimiter\ "});\5
+\\{print\_delimiter}(\\{right\_delimiter}(\|p));\6
+\4${}\}{}$\2\6
+${}\\{print\_subsidiary\_data}(\\{numerator}(\|p),\39\.{'\\\\'});{}$\5
+${}\\{print\_subsidiary\_data}(\\{denominator}(\|p),\39\.{'/'});{}$\6
+\4${}\}{}$\2\par
+\U690.\fi
+
+\M{698}That which can be displayed can also be destroyed.
+
+\Y\B\4\X698:Cases of \\{flush\_node\_list} that arise in mlists only\X${}\E{}$\6
+\4\&{case} \\{style\_node}:\6
+${}\{{}$\5
+\1${}\\{free\_node}(\|p,\39\\{style\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{choice\_node}:\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{display\_mlist}(\|p));\5
+\\{flush\_node\_list}(\\{text\_mlist}(\|p));\5
+\\{flush\_node\_list}(\\{script\_mlist}(\|p));\5
+\\{flush\_node\_list}(\\{script\_script\_mlist}(\|p));\5
+${}\\{free\_node}(\|p,\39\\{style\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{ord\_noad}:\5
+\&{case} \\{op\_noad}:\5
+\&{case} \\{bin\_noad}:\5
+\&{case} \\{rel\_noad}:\5
+\&{case} \\{open\_noad}:\5
+\&{case} \\{close\_noad}:\5
+\&{case} \\{punct\_noad}:\5
+\&{case} \\{inner\_noad}:\5
+\&{case} \\{radical\_noad}:\5
+\&{case} \\{over\_noad}:\5
+\&{case} \\{under\_noad}:\5
+\&{case} \\{vcenter\_noad}:\5
+\&{case} \\{accent\_noad}:\5
+\hbox{}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{math\_type}(\\{nucleus}(\|p))\G\\{sub\_box}){}$\1\5
+\\{flush\_node\_list}(\\{info}(\\{nucleus}(\|p)));\2\6
+\&{if} ${}(\\{math\_type}(\\{supscr}(\|p))\G\\{sub\_box}){}$\1\5
+\\{flush\_node\_list}(\\{info}(\\{supscr}(\|p)));\2\6
+\&{if} ${}(\\{math\_type}(\\{subscr}(\|p))\G\\{sub\_box}){}$\1\5
+\\{flush\_node\_list}(\\{info}(\\{subscr}(\|p)));\2\6
+\&{if} ${}(\\{type}(\|p)\E\\{radical\_noad}){}$\1\5
+${}\\{free\_node}(\|p,\39\\{radical\_noad\_size});{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|p)\E\\{accent\_noad}){}$\1\5
+${}\\{free\_node}(\|p,\39\\{accent\_noad\_size});{}$\2\6
+\&{else}\1\5
+${}\\{free\_node}(\|p,\39\\{noad\_size});{}$\2\6
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{left\_noad}:\5
+\&{case} \\{right\_noad}:\6
+${}\{{}$\5
+\1${}\\{free\_node}(\|p,\39\\{noad\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{fraction\_noad}:\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{info}(\\{numerator}(\|p)));\5
+\\{flush\_node\_list}(\\{info}(\\{denominator}(\|p)));\5
+${}\\{free\_node}(\|p,\39\\{fraction\_noad\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\par
+\U202.\fi
+
+\N{1}{699}Subroutines for math mode.
+In order to convert mlists to hlists, i.e., noads to nodes, we need several
+subroutines that are conveniently dealt with now.
+
+Let us first introduce the macros that make it easy to get at the parameters and
+other font information. A size code, which is a multiple of 16, is added to a
+family number to get an index into the table of internal font numbers
+for each combination of family and size. (Be alert: Size codes get
+larger as the type gets smaller.)
+
+\Y\B\4\D$\\{text\_size}$ \5
+\T{0}\C{size code for the largest size in a family}\par
+\B\4\D$\\{script\_size}$ \5
+\T{16}\C{size code for the medium size in a family}\par
+\B\4\D$\\{script\_script\_size}$ \5
+\T{32}\C{size code for the smallest size in a family}\par
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_size}(\&{int} \|s)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|s\E\\{text\_size}){}$\1\5
+\\{print\_esc}(\X1438:\.{"textfont"}\X);\2\6
+\&{else} \&{if} ${}(\|s\E\\{script\_size}){}$\1\5
+\\{print\_esc}(\X1439:\.{"scriptfont"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1440:\.{"scriptscriptfont"}\X);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{700}Before an mlist is converted to an hlist, \TeX\ makes sure that
+the fonts in family~2 have enough parameters to be math-symbol
+fonts, and that the fonts in family~3 have enough parameters to be
+math-extension fonts. The math-symbol parameters are referred to by using the
+following macros, which take a size code as their parameter; for example,
+\\{num1}(\\{cur\_size}) gives the value of the \\{num1} parameter for the current size.
+
+\Y\B\4\D$\\{mathsy\_end}(\|X)$ \5
+$\\{fam\_fnt}(\T{2}+\|X)$ ] ] $.$ \\{sc}\par
+\B\4\D$\\{mathsy}(\|X)$ \5
+\\{font\_info} [ $\|X+\\{param\_base}$ [ \\{mathsy\_end}\par
+\B\4\D$\\{math\_x\_height}$ \5
+\\{mathsy}(\T{5})\C{height of `\.x'}\par
+\B\4\D$\\{math\_quad}$ \5
+\\{mathsy}(\T{6})\C{\.{18mu}}\par
+\B\4\D$\\{num1}$ \5
+\\{mathsy}(\T{8})\C{numerator shift-up in display styles}\par
+\B\4\D$\\{num2}$ \5
+\\{mathsy}(\T{9})\C{numerator shift-up in non-display, non-\.{\\atop}}\par
+\B\4\D$\\{num3}$ \5
+\\{mathsy}(\T{10})\C{numerator shift-up in non-display \.{\\atop}}\par
+\B\4\D$\\{denom1}$ \5
+\\{mathsy}(\T{11})\C{denominator shift-down in display styles}\par
+\B\4\D$\\{denom2}$ \5
+\\{mathsy}(\T{12})\C{denominator shift-down in non-display styles}\par
+\B\4\D$\\{sup1}$ \5
+\\{mathsy}(\T{13})\C{superscript shift-up in uncramped display style}\par
+\B\4\D$\\{sup2}$ \5
+\\{mathsy}(\T{14})\C{superscript shift-up in uncramped non-display}\par
+\B\4\D$\\{sup3}$ \5
+\\{mathsy}(\T{15})\C{superscript shift-up in cramped styles}\par
+\B\4\D$\\{sub1}$ \5
+\\{mathsy}(\T{16})\C{subscript shift-down if superscript is absent}\par
+\B\4\D$\\{sub2}$ \5
+\\{mathsy}(\T{17})\C{subscript shift-down if superscript is present}\par
+\B\4\D$\\{sup\_drop}$ \5
+\\{mathsy}(\T{18})\C{superscript baseline below top of large box}\par
+\B\4\D$\\{sub\_drop}$ \5
+\\{mathsy}(\T{19})\C{subscript baseline below bottom of large box}\par
+\B\4\D$\\{delim1}$ \5
+\\{mathsy}(\T{20})\C{size of \.{\\atopwithdelims} delimiters in display styles}\par
+\B\4\D$\\{delim2}$ \5
+\\{mathsy}(\T{21})\C{size of \.{\\atopwithdelims} delimiters in non-displays}\par
+\B\4\D$\\{axis\_height}$ \5
+\\{mathsy}(\T{22})\C{height of fraction lines above the baseline}\par
+\B\4\D$\\{total\_mathsy\_params}$ \5
+\T{22}\par
+\fi
+
+\M{701}The math-extension parameters have similar macros, but the size code is
+omitted (since it is always \\{cur\_size} when we refer to such parameters).
+
+\Y\B\4\D$\\{mathex}(\|X)$ \5
+$\\{font\_info}[\|X+\\{param\_base}[\\{fam\_fnt}(\T{3}+\\{cur\_size})]].{}$\\{sc}\par
+\B\4\D$\\{default\_rule\_thickness}$ \5
+\\{mathex}(\T{8})\C{thickness of \.{\\over} bars}\par
+\B\4\D$\\{big\_op\_spacing1}$ \5
+\\{mathex}(\T{9})\C{minimum clearance above a displayed op}\par
+\B\4\D$\\{big\_op\_spacing2}$ \5
+\\{mathex}(\T{10})\C{minimum clearance below a displayed op}\par
+\B\4\D$\\{big\_op\_spacing3}$ \5
+\\{mathex}(\T{11})\C{minimum baselineskip above displayed op}\par
+\B\4\D$\\{big\_op\_spacing4}$ \5
+\\{mathex}(\T{12})\C{minimum baselineskip below displayed op}\par
+\B\4\D$\\{big\_op\_spacing5}$ \5
+\\{mathex}(\T{13})\C{padding above and below displayed limits}\par
+\B\4\D$\\{total\_mathex\_params}$ \5
+\T{13}\par
+\fi
+
+\M{702}We also need to compute the change in style between mlists and their
+subsidiaries. The following macros define the subsidiary style for
+an overlined nucleus (\\{cramped\_style}), for a subscript or a superscript
+(\\{sub\_style} or \\{sup\_style}), or for a numerator or denominator (\\{num\_style}
+or \\{denom\_style}).
+
+\Y\B\4\D$\\{cramped\_style}(\|X)$ \5
+$\T{2}*(\|X/\T{2})+{}$\\{cramped}\C{cramp the style}\par
+\B\4\D$\\{sub\_style}(\|X)$ \5
+$\T{2}*(\|X/\T{4})+\\{script\_style}+{}$\\{cramped}\C{smaller and cramped}\par
+\B\4\D$\\{sup\_style}(\|X)$ \5
+$\T{2}*(\|X/\T{4})+\\{script\_style}+(\|X\MOD\T{2}{}$)\C{smaller}\par
+\B\4\D$\\{num\_style}(\|X)$ \5
+$\|X+\T{2}-\T{2}*(\|X/\T{6}{}$)\C{smaller unless already script-script}\par
+\B\4\D$\\{denom\_style}(\|X)$ \5
+$\T{2}*(\|X/\T{2})+\\{cramped}+\T{2}-\T{2}*(\|X/\T{6}{}$)\C{smaller, cramped}\par
+\fi
+
+\M{703}When the style changes, the following piece of program computes associated
+information:
+
+\Y\B\4\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_style}<\\{script\_style}){}$\1\5
+${}\\{cur\_size}\K\\{text\_size};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_size}\K\T{16}*((\\{cur\_style}-\\{text\_style})/\T{2});{}$\2\6
+${}\\{cur\_mu}\K\\{x\_over\_n}(\\{math\_quad}(\\{cur\_size}),\39\T{18});{}$\6
+\4${}\}{}$\2\par
+\Us720, 726, 730, 754, 760\ETs763.\fi
+
+\M{704}Here is a function that returns a pointer to a rule node having a given
+thickness \|t. The rule will extend horizontally to the boundary of the vlist
+that eventually contains it.
+
+\Y\B\&{pointer} \\{fraction\_rule}(\&{scaled} \|t)\C{construct the bar for a fraction}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{new\_rule}(\,);{}$\5
+${}\\{height}(\|p)\K\|t;{}$\5
+${}\\{depth}(\|p)\K\T{0};{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{705}The \\{overbar} function returns a pointer to a vlist box that consists of
+a given box \|b, above which has been placed a kern of height \|k under a
+fraction rule of thickness \|t under additional space of height \|t.
+
+\Y\B\&{pointer} \\{overbar}(\&{pointer} \|b${},\39{}$\&{scaled} \|k${},\39{}$\&{scaled} \|t)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\C{nodes being constructed}\7
+${}\|p\K\\{new\_kern}(\|k);{}$\5
+${}\\{link}(\|p)\K\|b;{}$\5
+${}\|q\K\\{fraction\_rule}(\|t);{}$\5
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\|p\K\\{new\_kern}(\|t);{}$\5
+${}\\{link}(\|p)\K\|q;{}$\5
+\&{return} \\{vpack}${}(\|p,\39\\{natural});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{706}The \\{var\_delimiter} function, which finds or constructs a sufficiently
+large delimiter, is the most interesting of the auxiliary functions that
+currently concern us. Given a pointer \|d to a delimiter field in some noad,
+together with a size code \|s and a vertical distance \|v, this function
+returns a pointer to a box that contains the smallest variant of \|d whose
+height plus depth is \|v or more. (And if no variant is large enough, it
+returns the largest available variant.) In particular, this routine will
+construct arbitrarily large delimiters from extensible components, if
+\|d leads to such characters.
+
+The value returned is a box whose \\{shift\_amount} has been set so that
+the box is vertically centered with respect to the axis in the given size.
+If a built-up symbol is returned, the height of the box before shifting
+will be the height of its topmost component.
+
+\Y\B\hbox{\4}\X709:Declare subprocedures for \\{var\_delimiter}\X\7
+\&{pointer} \\{var\_delimiter}(\&{pointer} \|d${},\39{}$\&{small\_number} \|s${},\39{}$\&{scaled} \|v)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|b;\C{the box that will be constructed}\6
+\&{internal\_font\_number} \|f${},{}$ \|g;\C{best-so-far and tentative font codes}\6
+\&{quarterword} \|c${},{}$ \|x${},{}$ \|y;\C{best-so-far and tentative character codes}\6
+\&{int} \|m${},{}$ \|n;\C{the number of extensible pieces}\6
+\&{scaled} \|u;\C{height-plus-depth of a tentative character}\6
+\&{scaled} \|w;\C{largest height-plus-depth so far}\6
+\&{four\_quarters} \|q;\C{character info}\6
+\&{eight\_bits} \\{hd};\C{height-depth byte}\6
+\&{four\_quarters} \|r;\C{extensible pieces}\6
+\&{small\_number} \|z;\C{runs through font family members}\6
+\&{bool} \\{large\_attempt};\C{are we trying the ``large'' variant?}\7
+${}\|f\K\\{null\_font};{}$\5
+${}\|w\K\T{0};{}$\5
+${}\\{large\_attempt}\K\\{false};{}$\5
+${}\|z\K\\{small\_fam}(\|d);{}$\5
+${}\|x\K\\{small\_char}(\|d);{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\X707:Look at the variants of $(\|z,\|x)$; set \|f and \|c whenever a better character is found; \&{goto} \\{found} as soon as a large enough variant is encountered\X;\6
+\&{if} (\\{large\_attempt})\1\5
+\&{goto} \\{found};\C{there were none large enough}\2\6
+${}\\{large\_attempt}\K\\{true};{}$\5
+${}\|z\K\\{large\_fam}(\|d);{}$\5
+${}\|x\K\\{large\_char}(\|d);{}$\6
+\4${}\}{}$\2\6
+\4\\{found}:\6
+\&{if} ${}(\|f\I\\{null\_font}){}$\1\5
+\X710:Make variable \|b point to a box for $(\|f,\|c)$\X;\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|b\K\\{new\_null\_box}(\,);{}$\5
+${}\\{width}(\|b)\K\\{null\_delimiter\_space}{}$;\C{use this width if no delimiter was found}\6
+\4${}\}{}$\2\6
+${}\\{shift\_amount}(\|b)\K\\{half}(\\{height}(\|b)-\\{depth}(\|b))-\\{axis\_height}(\|s);{}$\5
+\&{return} \|b;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{707}The search process is complicated slightly by the facts that some of the
+characters might not be present in some of the fonts, and they might not
+be probed in increasing order of height.
+
+\Y\B\4\X707:Look at the variants of $(\|z,\|x)$; set \|f and \|c whenever a better character is found; \&{goto} \\{found} as soon as a large enough variant is encountered\X${}\E{}$\6
+\&{if} ${}((\|z\I\T{0})\V(\|x\I\\{min\_quarterword})){}$\5
+${}\{{}$\5
+\1${}\|z\K\|z+\|s+\T{16}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|z\K\|z-\T{16};{}$\5
+${}\|g\K\\{fam\_fnt}(\|z);{}$\6
+\&{if} ${}(\|g\I\\{null\_font}){}$\1\5
+\X708:Look at the list of characters starting with \|x in font \|g; set \|f and \|c whenever a better character is found; \&{goto} \\{found} as soon as a large enough variant is encountered\X;\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|z<\T{16}));{}$\6
+\4${}\}{}$\2\par
+\U706.\fi
+
+\M{708}\B\X708:Look at the list of characters starting with \|x in font \|g; set \|f and \|c whenever a better character is found; \&{goto} \\{found} as soon as a large enough variant is encountered\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|y\K\|x;{}$\6
+\&{if} ${}((\\{qo}(\|y)\G\\{font\_bc}[\|g])\W(\\{qo}(\|y)\Z\\{font\_ec}[\|g])){}$\5
+${}\{{}$\5
+\1\\{resume}:\5
+${}\|q\K\\{char\_info}(\|g)(\|y);{}$\6
+\&{if} (\\{char\_exists}(\|q))\5
+${}\{{}$\5
+\1\&{if} ${}(\\{char\_tag}(\|q)\E\\{ext\_tag}){}$\5
+${}\{{}$\5
+\1${}\|f\K\|g;{}$\5
+${}\|c\K\|y;{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+${}\\{hd}\K\\{height\_depth}(\|q);{}$\5
+${}\|u\K\\{char\_height}(\|g)(\\{hd})+\\{char\_depth}(\|g)(\\{hd});{}$\6
+\&{if} ${}(\|u>\|w){}$\5
+${}\{{}$\5
+\1${}\|f\K\|g;{}$\5
+${}\|c\K\|y;{}$\5
+${}\|w\K\|u;{}$\6
+\&{if} ${}(\|u\G\|v){}$\1\5
+\&{goto} \\{found};\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{char\_tag}(\|q)\E\\{list\_tag}){}$\5
+${}\{{}$\5
+\1${}\|y\K\\{rem\_byte}(\|q);{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U707.\fi
+
+\M{709}Here is a subroutine that creates a new box, whose list contains a
+single character, and whose width includes the italic correction for
+that character. The height or depth of the box will be negative, if
+the height or depth of the character is negative; thus, this routine
+may deliver a slightly different result than \\{hpack} would produce.
+
+\Y\B\4\X709:Declare subprocedures for \\{var\_delimiter}\X${}\E{}$\6
+\&{pointer} \\{char\_box}(\&{internal\_font\_number} \|f${},\39{}$\&{quarterword} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{four\_quarters} \|q;\6
+\&{eight\_bits} \\{hd};\C{\\{height\_depth} byte}\6
+\&{pointer} \|b${},{}$ \|p;\C{the new box and its character node}\7
+${}\|q\K\\{char\_info}(\|f)(\|c);{}$\5
+${}\\{hd}\K\\{height\_depth}(\|q);{}$\5
+${}\|b\K\\{new\_null\_box}(\,);{}$\5
+${}\\{width}(\|b)\K\\{char\_width}(\|f)(\|q)+\\{char\_italic}(\|f)(\|q);{}$\5
+${}\\{height}(\|b)\K\\{char\_height}(\|f)(\\{hd});{}$\5
+${}\\{depth}(\|b)\K\\{char\_depth}(\|f)(\\{hd});{}$\5
+${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{character}(\|p)\K\|c;{}$\5
+${}\\{font}(\|p)\K\|f;{}$\5
+${}\\{list\_ptr}(\|b)\K\|p;{}$\5
+\&{return} \|b;\6
+\4${}\}{}$\2\par
+\As711\ET712.
+\U706.\fi
+
+\M{710}When the following code is executed, \\{char\_tag}(\|q) will be equal to
+\\{ext\_tag} if and only if a built-up symbol is supposed to be returned.
+
+\Y\B\4\X710:Make variable \|b point to a box for $(\|f,\|c)$\X${}\E{}$\6
+\&{if} ${}(\\{char\_tag}(\|q)\E\\{ext\_tag}){}$\1\5
+\X713:Construct an extensible character in a new box \|b, using recipe \\{rem\_byte}(\|q) and font \|f\X\2\6
+\&{else} $\|b\K\\{char\_box}(\|f,\39\|c{}$)\par
+\U706.\fi
+
+\M{711}When we build an extensible character, it's handy to have the
+following subroutine, which puts a given character on top
+of the characters already in box \|b:
+
+\Y\B\4\X709:Declare subprocedures for \\{var\_delimiter}\X${}\mathrel+\E{}$\6
+\&{void} \\{stack\_into\_box}(\&{pointer} \|b${},\39{}$\&{internal\_font\_number} \|f${},\39{}$\&{quarterword} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{new node placed into \|b}\7
+${}\|p\K\\{char\_box}(\|f,\39\|c);{}$\5
+${}\\{link}(\|p)\K\\{list\_ptr}(\|b);{}$\5
+${}\\{list\_ptr}(\|b)\K\|p;{}$\5
+${}\\{height}(\|b)\K\\{height}(\|p);{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{712}Another handy subroutine computes the height plus depth of
+a given character:
+
+\Y\B\4\X709:Declare subprocedures for \\{var\_delimiter}\X${}\mathrel+\E{}$\6
+\&{scaled} \\{height\_plus\_depth}(\&{internal\_font\_number} \|f${},\39{}$\&{quarterword} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{four\_quarters} \|q;\6
+\&{eight\_bits} \\{hd};\C{\\{height\_depth} byte}\7
+${}\|q\K\\{char\_info}(\|f)(\|c);{}$\5
+${}\\{hd}\K\\{height\_depth}(\|q);{}$\5
+\&{return} \\{char\_height}(\|f)(\\{hd})${}+\\{char\_depth}(\|f)(\\{hd});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{713}\B\X713:Construct an extensible character in a new box \|b, using recipe \\{rem\_byte}(\|q) and font \|f\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|b\K\\{new\_null\_box}(\,);{}$\5
+${}\\{type}(\|b)\K\\{vlist\_node};{}$\5
+${}\|r\K\\{font\_info}[\\{exten\_base}[\|f]+\\{rem\_byte}(\|q)].\\{qqqq}{}$;\6
+\X714:Compute the minimum suitable height, \|w, and the corresponding number of extension steps, \|n; also set \\{width}(\|b)\X;\6
+${}\|c\K\\{ext\_bot}(\|r);{}$\6
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\1\5
+${}\\{stack\_into\_box}(\|b,\39\|f,\39\|c);{}$\2\6
+${}\|c\K\\{ext\_rep}(\|r);{}$\6
+\&{for} ${}(\|m\K\T{1};{}$ ${}\|m\Z\|n;{}$ ${}\|m\PP){}$\1\5
+${}\\{stack\_into\_box}(\|b,\39\|f,\39\|c);{}$\2\6
+${}\|c\K\\{ext\_mid}(\|r);{}$\6
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\5
+${}\{{}$\5
+\1${}\\{stack\_into\_box}(\|b,\39\|f,\39\|c);{}$\5
+${}\|c\K\\{ext\_rep}(\|r);{}$\6
+\&{for} ${}(\|m\K\T{1};{}$ ${}\|m\Z\|n;{}$ ${}\|m\PP){}$\1\5
+${}\\{stack\_into\_box}(\|b,\39\|f,\39\|c);{}$\2\6
+\4${}\}{}$\2\6
+${}\|c\K\\{ext\_top}(\|r);{}$\6
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\1\5
+${}\\{stack\_into\_box}(\|b,\39\|f,\39\|c);{}$\2\6
+${}\\{depth}(\|b)\K\|w-\\{height}(\|b);{}$\6
+\4${}\}{}$\2\par
+\U710.\fi
+
+\M{714}The width of an extensible character is the width of the repeatable
+module. If this module does not have positive height plus depth,
+we don't use any copies of it, otherwise we use as few as possible
+(in groups of two if there is a middle part).
+
+\Y\B\4\X714:Compute the minimum suitable height, \|w, and the corresponding number of extension steps, \|n; also set \\{width}(\|b)\X${}\E{}$\6
+$\|c\K\\{ext\_rep}(\|r);{}$\5
+${}\|u\K\\{height\_plus\_depth}(\|f,\39\|c);{}$\5
+${}\|w\K\T{0};{}$\5
+${}\|q\K\\{char\_info}(\|f)(\|c);{}$\5
+${}\\{width}(\|b)\K\\{char\_width}(\|f)(\|q)+\\{char\_italic}(\|f)(\|q){}$;\6
+${}\|c\K\\{ext\_bot}(\|r){}$;\5
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\1\5
+${}\|w\K\|w+\\{height\_plus\_depth}(\|f,\39\|c);{}$\2\6
+${}\|c\K\\{ext\_mid}(\|r){}$;\5
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\1\5
+${}\|w\K\|w+\\{height\_plus\_depth}(\|f,\39\|c);{}$\2\6
+${}\|c\K\\{ext\_top}(\|r){}$;\5
+\&{if} ${}(\|c\I\\{min\_quarterword}){}$\1\5
+${}\|w\K\|w+\\{height\_plus\_depth}(\|f,\39\|c);{}$\2\6
+${}\|n\K\T{0};{}$\6
+\&{if} ${}(\|u>\T{0}){}$\1\6
+\&{while} ${}(\|w<\|v){}$\5
+${}\{{}$\5
+\1${}\|w\K\|w+\|u;{}$\5
+\\{incr}(\|n);\6
+\&{if} ${}(\\{ext\_mid}(\|r)\I\\{min\_quarterword}){}$\1\5
+${}\|w\K\|w+\|u;{}$\2\6
+\4${}\}{}$\2\2\par
+\U713.\fi
+
+\M{715}The next subroutine is much simpler; it is used for numerators and
+denominators of fractions as well as for displayed operators and
+their limits above and below. It takes a given box~\|b and
+changes it so that the new box is centered in a box of width~\|w.
+The centering is done by putting \.{\\hss} glue at the left and right
+of the list inside \|b, then packaging the new box; thus, the
+actual box might not really be centered, if it already contains
+infinite glue.
+
+The given box might contain a single character whose italic correction
+has been added to the width of the box; in this case a compensating
+kern is inserted.
+
+\Y\B\&{pointer} \\{rebox}(\&{pointer} \|b${},\39{}$\&{scaled} \|w)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{temporary register for list manipulation}\6
+\&{internal\_font\_number} \|f;\C{font in a one-character box}\6
+\&{scaled} \|v;\C{width of a character without italic correction}\7
+\&{if} ${}((\\{width}(\|b)\I\|w)\W(\\{list\_ptr}(\|b)\I\\{null})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|b)\E\\{vlist\_node}){}$\1\5
+${}\|b\K\\{hpack}(\|b,\39\\{natural});{}$\2\6
+${}\|p\K\\{list\_ptr}(\|b);{}$\6
+\&{if} ${}((\\{is\_char\_node}(\|p))\W(\\{link}(\|p)\E\\{null})){}$\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|p);{}$\5
+${}\|v\K\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|p)));{}$\6
+\&{if} ${}(\|v\I\\{width}(\|b)){}$\1\5
+${}\\{link}(\|p)\K\\{new\_kern}(\\{width}(\|b)-\|v);{}$\2\6
+\4${}\}{}$\2\6
+${}\\{free\_node}(\|b,\39\\{box\_node\_size});{}$\5
+${}\|b\K\\{new\_glue}(\\{ss\_glue});{}$\5
+${}\\{link}(\|b)\K\|p;{}$\6
+\&{while} ${}(\\{link}(\|p)\I\\{null}){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+${}\\{link}(\|p)\K\\{new\_glue}(\\{ss\_glue});{}$\5
+\&{return} \\{hpack}${}(\|b,\39\|w,\39\\{exactly});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{width}(\|b)\K\|w;{}$\5
+\&{return} \|b;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{716}Here is a subroutine that creates a new glue specification from another
+one that is expressed in `\.{mu}', given the value of the math unit.
+
+\Y\B\4\D$\\{mu\_mult}(\|X)$ \5
+$\\{nx\_plus\_y}(\|n,\39\|X,\39\\{xn\_over\_d}(\|X,\39\|f,\39\T{\~200000}){}$)\par
+\Y\B\&{pointer} \\{math\_glue}(\&{pointer} \|g${},\39{}$\&{scaled} \|m)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new glue specification}\6
+\&{int} \|n;\C{integer part of \|m}\6
+\&{scaled} \|f;\C{fraction part of \|m}\7
+${}\|n\K\\{x\_over\_n}(\|m,\39\T{\~200000});{}$\5
+${}\|f\K\\{rem}{}$;\6
+\&{if} ${}(\|f<\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|n);\5
+${}\|f\K\|f+\T{\~200000};{}$\6
+\4${}\}{}$\2\6
+${}\|p\K\\{get\_node}(\\{glue\_spec\_size});{}$\5
+${}\\{width}(\|p)\K\\{mu\_mult}(\\{width}(\|g)){}$;\C{convert \.{mu} to \.{pt}}\6
+${}\\{stretch\_order}(\|p)\K\\{stretch\_order}(\|g);{}$\6
+\&{if} ${}(\\{stretch\_order}(\|p)\E\\{normal}){}$\1\5
+${}\\{stretch}(\|p)\K\\{mu\_mult}(\\{stretch}(\|g));{}$\2\6
+\&{else}\1\5
+${}\\{stretch}(\|p)\K\\{stretch}(\|g);{}$\2\6
+${}\\{shrink\_order}(\|p)\K\\{shrink\_order}(\|g);{}$\6
+\&{if} ${}(\\{shrink\_order}(\|p)\E\\{normal}){}$\1\5
+${}\\{shrink}(\|p)\K\\{mu\_mult}(\\{shrink}(\|g));{}$\2\6
+\&{else}\1\5
+${}\\{shrink}(\|p)\K\\{shrink}(\|g);{}$\2\6
+\&{return} \|p;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{717}The \\{math\_kern} subroutine removes \\{mu\_glue} from a kern node, given
+the value of the math unit.
+
+\Y\B\&{void} \\{math\_kern}(\&{pointer} \|p${},\39{}$\&{scaled} \|m)\1\1 $\{{}$\5
+\&{int} \|n;\C{integer part of \|m}\6
+\&{scaled} \|f;\C{fraction part of \|m}\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{mu\_glue})$ $\{{}$\5
+$\|n\K\\{x\_over\_n}(\|m,\39\T{\~200000});{}$\5
+${}\|f\K\\{rem}{}$;\6
+\&{if} ${}(\|f<\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|n);\5
+${}\|f\K\|f+\T{\~200000};{}$\6
+\4${}\}{}$\2\6
+${}\\{width}(\|p)\K\\{mu\_mult}(\\{width}(\|p));$ \\{subtype}(\|p) $\K$ \&{explicit}; $\}$ $\}{}$\par
+\fi
+
+\M{718}Sometimes it is necessary to destroy an mlist. The following
+subroutine empties the current list, assuming that $\\{abs}(\\{mode})\E\\{mmode}$.
+
+\Y\B\&{void} \\{flush\_math}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\\{link}(\\{head}));\5
+\\{flush\_node\_list}(\\{incompleat\_noad});\5
+${}\\{link}(\\{head})\K\\{null};{}$\5
+${}\\{tail}\K\\{head};{}$\5
+${}\\{incompleat\_noad}\K\\{null};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{719}Typesetting math formulas.
+\TeX's most important routine for dealing with formulas is called
+\\{mlist\_to\_hlist}. After a formula has been scanned and represented as an
+mlist, this routine converts it to an hlist that can be placed into a box
+or incorporated into the text of a paragraph. There are three implicit
+parameters, passed in global variables: \\{cur\_mlist} points to the first
+node or noad in the given mlist (and it might be \\{null}); \\{cur\_style} is a
+style code; and \\{mlist\_penalties} is \\{true} if penalty nodes for potential
+line breaks are to be inserted into the resulting hlist. After
+\\{mlist\_to\_hlist} has acted, \\{link}(\\{temp\_head}) points to the translated hlist.
+
+Since mlists can be inside mlists, the procedure is recursive. And since this
+is not part of \TeX's inner loop, the program has been written in a manner
+that stresses compactness over efficiency.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{cur\_mlist};\C{beginning of mlist to be translated}\6
+\&{small\_number} \\{cur\_style};\C{style code at current place in the list}\6
+\&{small\_number} \\{cur\_size};\C{size code corresponding to \\{cur\_style}}\6
+\&{scaled} \\{cur\_mu};\C{the math unit width corresponding to \\{cur\_size}}\6
+\&{bool} \\{mlist\_penalties};\C{should \\{mlist\_to\_hlist} insert penalties?}\par
+\fi
+
+\M{720}The recursion in \\{mlist\_to\_hlist} is due primarily to a subroutine
+called \\{clean\_box} that puts a given noad field into a box using a given
+math style; \\{mlist\_to\_hlist} can call \\{clean\_box}, which can call
+\\{mlist\_to\_hlist}.
+
+The box returned by \\{clean\_box} is ``clean'' in the
+sense that its \\{shift\_amount} is zero.
+
+\Y\B\&{void} \\{mlist\_to\_hlist}(\&{void});\7
+\&{pointer} \\{clean\_box}(\&{pointer} \|p${},\39{}$\&{small\_number} \|s)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{beginning of a list to be boxed}\6
+\&{small\_number} \\{save\_style};\C{\\{cur\_style} to be restored}\6
+\&{pointer} \|x;\C{box to be returned}\6
+\&{pointer} \|r;\C{temporary pointer}\7
+\&{switch} (\\{math\_type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{math\_char}:\6
+${}\{{}$\5
+\1${}\\{cur\_mlist}\K\\{new\_noad}(\,);{}$\5
+${}\\{mem}[\\{nucleus}(\\{cur\_mlist})]\K\\{mem}[\|p];{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{sub\_box}:\6
+${}\{{}$\5
+\1${}\|q\K\\{info}(\|p);{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{sub\_mlist}:\5
+${}\\{cur\_mlist}\K\\{info}(\|p){}$;\5
+\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1${}\|q\K\\{new\_null\_box}(\,);{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{save\_style}\K\\{cur\_style};{}$\5
+${}\\{cur\_style}\K\|s;{}$\5
+${}\\{mlist\_penalties}\K\\{false}{}$;\6
+\\{mlist\_to\_hlist}(\,);\5
+${}\|q\K\\{link}(\\{temp\_head}){}$;\C{recursive call}\6
+${}\\{cur\_style}\K\\{save\_style}{}$;\C{restore the style}\6
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+\4\\{found}:\6
+\&{if} ${}(\\{is\_char\_node}(\|q)\V(\|q\E\\{null})){}$\1\5
+${}\|x\K\\{hpack}(\|q,\39\\{natural});{}$\2\6
+\&{else} \&{if} ${}((\\{link}(\|q)\E\\{null})\W(\\{type}(\|q)\Z\\{vlist\_node})\W(\\{shift\_amount}(\|q)\E\T{0})){}$\1\5
+${}\|x\K\|q{}$;\C{it's already clean}\2\6
+\&{else}\1\5
+${}\|x\K\\{hpack}(\|q,\39\\{natural});{}$\2\6
+\X721:Simplify a trivial box\X;\6
+\&{return} \|x;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{721}Here we save memory space in a common case.
+
+\Y\B\4\X721:Simplify a trivial box\X${}\E{}$\6
+$\|q\K\\{list\_ptr}(\|x);{}$\6
+\&{if} (\\{is\_char\_node}(\|q))\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\|q);{}$\6
+\&{if} ${}(\|r\I\\{null}){}$\1\6
+\&{if} ${}(\\{link}(\|r)\E\\{null}){}$\1\6
+\&{if} ${}(\R\\{is\_char\_node}(\|r)){}$\1\6
+\&{if} ${}(\\{type}(\|r)\E\\{kern\_node}{}$)\C{unneeded italic correction}\6
+${}\{{}$\5
+\1${}\\{free\_node}(\|r,\39\\{small\_node\_size});{}$\5
+${}\\{link}(\|q)\K\\{null};{}$\6
+\4${}\}{}$\2\2\2\2\6
+\4${}\}{}$\2\par
+\U720.\fi
+
+\M{722}It is convenient to have a procedure that converts a \\{math\_char}
+field to an ``unpacked'' form. The \\{fetch} routine sets \\{cur\_f}, \\{cur\_c},
+and \\{cur\_i} to the font code, character code, and character information bytes of
+a given noad field. It also takes care of issuing error messages for
+nonexistent characters; in such cases, \\{char\_exists}(\\{cur\_i}) will be \\{false}
+after \\{fetch} has acted, and the field will also have been reset to \\{empty}.
+
+\Y\B\&{void} \\{fetch}(\&{pointer} \|a)\C{unpack the \\{math\_char} field \|a}\6
+${}\{{}$\5
+\1${}\\{cur\_c}\K\\{character}(\|a);{}$\5
+${}\\{cur\_f}\K\\{fam\_fnt}(\\{fam}(\|a)+\\{cur\_size});{}$\6
+\&{if} ${}(\\{cur\_f}\E\\{null\_font}){}$\1\5
+\X723:Complain about an undefined family and set \\{cur\_i} null\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}((\\{qo}(\\{cur\_c})\G\\{font\_bc}[\\{cur\_f}])\W(\\{qo}(\\{cur\_c})\Z\\{font\_ec}[\\{cur\_f}])){}$\1\5
+${}\\{cur\_i}\K\\{char\_info}(\\{cur\_f})(\\{cur\_c});{}$\2\6
+\&{else}\1\5
+${}\\{cur\_i}\K\\{null\_character};{}$\2\6
+\&{if} ${}(\R(\\{char\_exists}(\\{cur\_i}))){}$\5
+${}\{{}$\5
+\1${}\\{char\_warning}(\\{cur\_f},\39\\{qo}(\\{cur\_c}));{}$\5
+${}\\{math\_type}(\|a)\K\\{empty};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{723}\B\X723:Complain about an undefined family and set \\{cur\_i} null\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{""});\5
+\\{print\_size}(\\{cur\_size});\5
+\\{print\_char}(\.{'\ '});\5
+\\{print\_int}(\\{fam}(\|a));\5
+\\{print\_str}(\.{"\ is\ undefined\ (char}\)\.{acter\ "});\5
+\\{print\_ASCII}(\\{qo}(\\{cur\_c}));\5
+\\{print\_char}(\.{')'});\5
+\\{help4}(\.{"Somewhere\ in\ the\ ma}\)\.{th\ formula\ just\ ende}\)\.{d,\ you\ used\ the"})\6
+(\.{"stated\ character\ fr}\)\.{om\ an\ undefined\ font}\)\.{\ family.\ For\ example}\)\.{,"})\6
+(\.{"plain\ TeX\ doesn't\ a}\)\.{llow\ \\\\it\ or\ \\\\sl\ in}\)\.{\ subscripts.\ Proceed}\)\.{,"})\6
+(\.{"and\ I'll\ try\ to\ for}\)\.{get\ that\ I\ needed\ th}\)\.{at\ character."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{cur\_i}\K\\{null\_character};{}$\5
+${}\\{math\_type}(\|a)\K\\{empty};{}$\6
+\4${}\}{}$\2\par
+\U722.\fi
+
+\M{724}The outputs of \\{fetch} are placed in global variables.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{internal\_font\_number} \\{cur\_f};\C{the \\{font} field of a \\{math\_char}}\6
+\&{quarterword} \\{cur\_c};\C{the \\{character} field of a \\{math\_char}}\6
+\&{four\_quarters} \\{cur\_i};\C{the \\{char\_info} of a \\{math\_char}, or a lig/kern instruction}\par
+\fi
+
+\M{725}We need to do a lot of different things, so \\{mlist\_to\_hlist} makes two
+passes over the given mlist.
+
+The first pass does most of the processing: It removes ``mu'' spacing from
+glue, it recursively evaluates all subsidiary mlists so that only the
+top-level mlist remains to be handled, it puts fractions and square roots
+and such things into boxes, it attaches subscripts and superscripts, and
+it computes the overall height and depth of the top-level mlist so that
+the size of delimiters for a \\{left\_noad} and a \\{right\_noad} will be known.
+The hlist resulting from each noad is recorded in that noad's \\{new\_hlist}
+field, an integer field that replaces the \\{nucleus} or \\{thickness}.
+
+The second pass eliminates all noads and inserts the correct glue and
+penalties between nodes.
+
+\Y\B\4\D$\\{new\_hlist}(\|X)$ \5
+$\\{mem}[\\{nucleus}(\|X)].{}$\|i\C{the translation of an mlist}\par
+\fi
+
+\M{726}Here is the overall plan of \\{mlist\_to\_hlist}, and the list of its
+local variables.
+
+\Y\B\hbox{\4}\X734:Declare math construction procedures\X\7
+\&{void} \\{mlist\_to\_hlist}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \\{mlist};\C{beginning of the given list}\6
+\&{bool} \\{penalties};\C{should penalty nodes be inserted?}\6
+\&{small\_number} \\{style};\C{the given style}\6
+\&{small\_number} \\{save\_style};\C{holds \\{cur\_style} during recursion}\6
+\&{pointer} \|q;\C{runs through the mlist}\6
+\&{pointer} \|r;\C{the most recent noad preceding \|q}\6
+\&{small\_number} \\{r\_type};\C{the \\{type} of noad \|r, or \\{op\_noad} if $\|r\E\\{null}$}\6
+\&{small\_number} \|t;\C{the effective \\{type} of noad \|q during the second pass}\6
+\&{pointer} \|p${},{}$ \|x${},{}$ \|y${},{}$ \|z;\C{temporary registers for list construction}\6
+\&{int} \\{pen};\C{a penalty to be inserted}\6
+\&{small\_number} \|s;\C{the size of a noad to be deleted}\6
+\&{scaled} \\{max\_h}${},{}$ \\{max\_d};\C{maximum height and depth of the list translated so far}\6
+\&{scaled} \\{delta};\C{offset between subscript and superscript}\7
+${}\\{mlist}\K\\{cur\_mlist};{}$\5
+${}\\{penalties}\K\\{mlist\_penalties};{}$\5
+${}\\{style}\K\\{cur\_style}{}$;\C{tuck global parameters away as local variables}\6
+${}\|q\K\\{mlist};{}$\5
+${}\|r\K\\{null};{}$\5
+${}\\{r\_type}\K\\{op\_noad};{}$\5
+${}\\{max\_h}\K\T{0};{}$\5
+${}\\{max\_d}\K\T{0};{}$\5
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+\&{while} ${}(\|q\I\\{null}){}$\1\5
+\X727:Process node-or-noad \|q as much as possible in preparation for the second pass of \\{mlist\_to\_hlist}, then move to the next item in the mlist\X;\2\6
+\X729:Convert \(a)a final \\{bin\_noad} to an \\{ord\_noad}\X;\6
+\X760:Make a second pass over the mlist, removing all noads and inserting the proper spacing and penalties\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{727}We use the fact that no character nodes appear in an mlist, hence
+the field \\{type}(\|q) is always present.
+
+\Y\B\4\X727:Process node-or-noad \|q as much as possible in preparation for the second pass of \\{mlist\_to\_hlist}, then move to the next item in the mlist\X${}\E{}$\6
+${}\{{}$\5
+\1\X728:Do first-pass processing based on \\{type}(\|q); \&{goto} \\{done\_with\_noad} if a noad has been fully processed, \&{goto} \\{check\_dimensions} if it has been translated into \\{new\_hlist}(\|q), or \&{goto} \\{done\_with\_node} if a node has
+been fully processed\X;\6
+\4\\{check\_dimensions}:\5
+${}\|z\K\\{hpack}(\\{new\_hlist}(\|q),\39\\{natural});{}$\6
+\&{if} ${}(\\{height}(\|z)>\\{max\_h}){}$\1\5
+${}\\{max\_h}\K\\{height}(\|z);{}$\2\6
+\&{if} ${}(\\{depth}(\|z)>\\{max\_d}){}$\1\5
+${}\\{max\_d}\K\\{depth}(\|z);{}$\2\6
+${}\\{free\_node}(\|z,\39\\{box\_node\_size});{}$\6
+\4\\{done\_with\_noad}:\5
+${}\|r\K\|q;{}$\5
+${}\\{r\_type}\K\\{type}(\|r);{}$\6
+\4\\{done\_with\_node}:\5
+${}\|q\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\par
+\U726.\fi
+
+\M{728}One of the things we must do on the first pass is change a \\{bin\_noad} to
+an \\{ord\_noad} if the \\{bin\_noad} is not in the context of a binary operator.
+The values of \|r and \\{r\_type} make this fairly easy.
+
+\Y\B\4\X728:Do first-pass processing based on \\{type}(\|q); \&{goto} \\{done\_with\_noad} if a noad has been fully processed, \&{goto} \\{check\_dimensions} if it has been translated into \\{new\_hlist}(\|q), or \&{goto} \\{done\_with\_node} if a node
+has been fully processed\X${}\E{}$\6
+\4\\{reswitch}:\5
+${}\\{delta}\K\T{0};{}$\6
+\&{switch} (\\{type}(\|q))\5
+${}\{{}$\1\6
+\4\&{case} \\{bin\_noad}:\6
+\&{switch} (\\{r\_type})\5
+${}\{{}$\1\6
+\4\&{case} \\{bin\_noad}:\5
+\&{case} \\{op\_noad}:\5
+\&{case} \\{rel\_noad}:\5
+\&{case} \\{open\_noad}:\5
+\&{case} \\{punct\_noad}:\5
+\&{case} \\{left\_noad}:\6
+${}\{{}$\5
+\1${}\\{type}(\|q)\K\\{ord\_noad};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4\&{default}:\5
+\\{do\_nothing};\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{rel\_noad}:\5
+\&{case} \\{close\_noad}:\5
+\&{case} \\{punct\_noad}:\5
+\&{case} \\{right\_noad}:\6
+${}\{{}$\5
+\1\hbox{}\6
+\X729:Convert \(a)a final \\{bin\_noad} to an \\{ord\_noad}\X;\6
+\&{if} ${}(\\{type}(\|q)\E\\{right\_noad}){}$\1\5
+\&{goto} \\{done\_with\_noad};\2\6
+\4${}\}{}$\5
+\2\&{break};\5
+\hbox{\4}\X733:Cases for noads that can follow a \\{bin\_noad}\X\6
+\hbox{\4}\X730:Cases for nodes that can appear in an mlist, after which we \&{goto} \\{done\_with\_node}\X\6
+\4\&{default}:\5
+\\{confusion}(\X1664:\.{"mlist1"}\X);\6
+\4${}\}{}$\2\6
+\X754:Convert \(n)\\{nucleus}(\|q) to an hlist and attach the sub/superscripts\X\par
+\U727.\fi
+
+\M{729}\B\X729:Convert \(a)a final \\{bin\_noad} to an \\{ord\_noad}\X${}\E{}$\6
+\&{if} ${}(\\{r\_type}\E\\{bin\_noad})$ $\\{type}(\|r)\K{}$\\{ord\_noad}\par
+\Us726\ET728.\fi
+
+\M{730}\B\X730:Cases for nodes that can appear in an mlist, after which we \&{goto} \\{done\_with\_node}\X${}\E{}$\6
+\4\&{case} \\{style\_node}:\6
+${}\{{}$\5
+\1${}\\{cur\_style}\K\\{subtype}(\|q);{}$\5
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+\&{goto} \\{done\_with\_node};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{choice\_node}:\5
+\X731:Change this node to a style node followed by the correct choice, then \&{goto} \\{done\_with\_node}\X\6
+\4\&{case} \\{ins\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{case} \\{adjust\_node}:\5
+\&{case} \\{whatsit\_node}:\5
+\&{case} \\{penalty\_node}:\5
+\&{case} \\{disc\_node}:\5
+\&{goto} \\{done\_with\_node};\6
+\4\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1\&{if} ${}(\\{height}(\|q)>\\{max\_h}){}$\1\5
+${}\\{max\_h}\K\\{height}(\|q);{}$\2\6
+\&{if} ${}(\\{depth}(\|q)>\\{max\_d}){}$\1\5
+${}\\{max\_d}\K\\{depth}(\|q);{}$\2\6
+\&{goto} \\{done\_with\_node};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{glue\_node}:\6
+${}\{{}$\5
+\1\X732:Convert \(m)math glue to ordinary glue\X;\6
+\&{goto} \\{done\_with\_node};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{kern\_node}:\6
+${}\{{}$\5
+\1${}\\{math\_kern}(\|q,\39\\{cur\_mu});{}$\5
+\&{goto} \\{done\_with\_node};\6
+\4${}\}{}$\2\par
+\U728.\fi
+
+\M{731}\B\D$\\{choose\_mlist}(\|X)$ \6
+${}\{{}$\5
+\1${}\|p\K\|X(\|q);{}$\5
+${}\|X(\|q)\K\\{null}{}$;\5
+${}\}{}$\2\par
+\Y\B\4\X731:Change this node to a style node followed by the correct choice, then \&{goto} \\{done\_with\_node}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{switch} ${}(\\{cur\_style}/\T{2}){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+\\{choose\_mlist}(\\{display\_mlist})\5
+\&{break};\C{$\\{display\_style}\E\T{0}$}\6
+\4\&{case} \T{1}:\5
+\\{choose\_mlist}(\\{text\_mlist})\5
+\&{break};\C{$\\{text\_style}\E\T{2}$}\6
+\4\&{case} \T{2}:\5
+\\{choose\_mlist}(\\{script\_mlist})\5
+\&{break};\C{$\\{script\_style}\E\T{4}$}\6
+\4\&{case} \T{3}:\5
+\\{choose\_mlist}(\\{script\_script\_mlist});\C{$\\{script\_script\_style}\E\T{6}$}\6
+\4${}\}{}$\C{there are no other cases}\2\6
+\\{flush\_node\_list}(\\{display\_mlist}(\|q));\5
+\\{flush\_node\_list}(\\{text\_mlist}(\|q));\5
+\\{flush\_node\_list}(\\{script\_mlist}(\|q));\5
+\\{flush\_node\_list}(\\{script\_script\_mlist}(\|q));\6
+${}\\{type}(\|q)\K\\{style\_node};{}$\5
+${}\\{subtype}(\|q)\K\\{cur\_style};{}$\5
+${}\\{width}(\|q)\K\T{0};{}$\5
+${}\\{depth}(\|q)\K\T{0};{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|z\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\|p;{}$\6
+\&{while} ${}(\\{link}(\|p)\I\\{null}){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+${}\\{link}(\|p)\K\|z;{}$\6
+\4${}\}{}$\2\6
+\&{goto} \\{done\_with\_node};\6
+\4${}\}{}$\2\par
+\U730.\fi
+
+\M{732}Conditional math glue (`\.{\\nonscript}') results in a \\{glue\_node}
+pointing to \\{zero\_glue}, with $\\{subtype}(\|q)\E\\{cond\_math\_glue}$; in such a case
+the node following will be eliminated if it is a glue or kern node and if the
+current size is different from \\{text\_size}. Unconditional math glue
+(`\.{\\muskip}') is converted to normal glue by multiplying the dimensions
+by \\{cur\_mu}.
+
+\Y\B\4\X732:Convert \(m)math glue to ordinary glue\X${}\E{}$\6
+\&{if} ${}(\\{subtype}(\|q)\E\\{mu\_glue}){}$\5
+${}\{{}$\5
+\1${}\|x\K\\{glue\_ptr}(\|q);{}$\5
+${}\|y\K\\{math\_glue}(\|x,\39\\{cur\_mu});{}$\5
+\\{delete\_glue\_ref}(\|x);\5
+${}\\{glue\_ptr}(\|q)\K\|y;{}$\5
+${}\\{subtype}(\|q)\K\\{normal};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\\{cur\_size}\I\\{text\_size})\W(\\{subtype}(\|q)\E\\{cond\_math\_glue})){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{link}(\|q);{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}((\\{type}(\|p)\E\\{glue\_node})\V(\\{type}(\|p)\E\\{kern\_node})){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{link}(\|p);{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+\\{flush\_node\_list}(\|p);\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\par
+\U730.\fi
+
+\M{733}\B\X733:Cases for noads that can follow a \\{bin\_noad}\X${}\E{}$\6
+\4\&{case} \\{left\_noad}:\5
+\&{goto} \\{done\_with\_noad};\6
+\4\&{case} \\{fraction\_noad}:\6
+${}\{{}$\5
+\1\\{make\_fraction}(\|q);\5
+\&{goto} \\{check\_dimensions};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{op\_noad}:\6
+${}\{{}$\5
+\1${}\\{delta}\K\\{make\_op}(\|q);{}$\6
+\&{if} ${}(\\{subtype}(\|q)\E\\{limits}){}$\1\5
+\&{goto} \\{check\_dimensions};\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{ord\_noad}:\5
+\\{make\_ord}(\|q);\5
+\&{break};\6
+\4\&{case} \\{open\_noad}:\5
+\&{case} \\{inner\_noad}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{radical\_noad}:\5
+\\{make\_radical}(\|q);\5
+\&{break};\6
+\4\&{case} \\{over\_noad}:\5
+\\{make\_over}(\|q);\5
+\&{break};\6
+\4\&{case} \\{under\_noad}:\5
+\\{make\_under}(\|q);\5
+\&{break};\6
+\4\&{case} \\{accent\_noad}:\5
+\\{make\_math\_accent}(\|q);\5
+\&{break};\6
+\4\&{case} \\{vcenter\_noad}:\5
+\\{make\_vcenter}(\|q);\5
+\&{break};\par
+\U728.\fi
+
+\M{734}Most of the actual construction work of \\{mlist\_to\_hlist} is done
+by procedures with names
+like \\{make\_fraction}, \\{make\_radical}, etc. To illustrate
+the general setup of such procedures, let's begin with a couple of
+simple ones.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\E{}$\6
+\&{void} \\{make\_over}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{info}(\\{nucleus}(\|q))\K\30\\{overbar}(\\{clean\_box}(\\{nucleus}(\|q),\39\\{cramped\_style}(\\{cur\_style})),\30\39\T{3}*\\{default\_rule\_thickness},\39\\{default\_rule\_thickness});{}$\5
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\6
+\4${}\}{}$\2\par
+\As735, 736, 737, 738, 743, 749, 752, 756\ETs762.
+\U726.\fi
+
+\M{735}\B\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_under}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|x${},{}$ \|y;\C{temporary registers for box construction}\6
+\&{scaled} \\{delta};\C{overall height plus depth}\7
+${}\|x\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cur\_style});{}$\5
+${}\|p\K\\{new\_kern}(\T{3}*\\{default\_rule\_thickness});{}$\5
+${}\\{link}(\|x)\K\|p;{}$\5
+${}\\{link}(\|p)\K\\{fraction\_rule}(\\{default\_rule\_thickness});{}$\5
+${}\|y\K\\{vpack}(\|x,\39\\{natural});{}$\5
+${}\\{delta}\K\\{height}(\|y)+\\{depth}(\|y)+\\{default\_rule\_thickness};{}$\5
+${}\\{height}(\|y)\K\\{height}(\|x);{}$\5
+${}\\{depth}(\|y)\K\\{delta}-\\{height}(\|y);{}$\5
+${}\\{info}(\\{nucleus}(\|q))\K\|y;{}$\5
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{736}\B\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_vcenter}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|v;\C{the box that should be centered vertically}\6
+\&{scaled} \\{delta};\C{its height plus depth}\7
+${}\|v\K\\{info}(\\{nucleus}(\|q));{}$\6
+\&{if} ${}(\\{type}(\|v)\I\\{vlist\_node}){}$\1\5
+\\{confusion}(\X1561:\.{"vcenter"}\X);\2\6
+${}\\{delta}\K\\{height}(\|v)+\\{depth}(\|v);{}$\5
+${}\\{height}(\|v)\K\\{axis\_height}(\\{cur\_size})+\\{half}(\\{delta});{}$\5
+${}\\{depth}(\|v)\K\\{delta}-\\{height}(\|v);{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{737}According to the rules in the \.{DVI} file specifications, we ensure alignment
+between a square root sign and the rule above its nucleus by assuming that the
+baseline of the square-root symbol is the same as the bottom of the rule. The
+height of the square-root symbol will be the thickness of the rule, and the
+depth of the square-root symbol should exceed or equal the height-plus-depth
+of the nucleus plus a certain minimum clearance~\\{clr}. The symbol will be
+placed so that the actual clearance is \\{clr} plus half the excess.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_radical}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|x${},{}$ \|y;\C{temporary registers for box construction}\6
+\&{scaled} \\{delta}${},{}$ \\{clr};\C{dimensions involved in the calculation}\7
+${}\|x\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cramped\_style}(\\{cur\_style}));{}$\6
+\&{if} ${}(\\{cur\_style}<\\{text\_style}{}$)\C{display style}\1\6
+${}\\{clr}\K\\{default\_rule\_thickness}+(\\{abs}(\\{math\_x\_height}(\\{cur\_size}))/\T{4});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{clr}\K\\{default\_rule\_thickness};{}$\5
+${}\\{clr}\K\\{clr}+(\\{abs}(\\{clr})/\T{4});{}$\6
+\4${}\}{}$\2\6
+${}\|y\K\\{var\_delimiter}(\\{left\_delimiter}(\|q),\39\\{cur\_size},\39\\{height}(\|x)+\\{depth}(\|x)+\\{clr}+\\{default\_rule\_thickness});{}$\5
+${}\\{delta}\K\\{depth}(\|y)-(\\{height}(\|x)+\\{depth}(\|x)+\\{clr});{}$\6
+\&{if} ${}(\\{delta}>\T{0}){}$\1\5
+${}\\{clr}\K\\{clr}+\\{half}(\\{delta}){}$;\C{increase the actual clearance}\2\6
+${}\\{shift\_amount}(\|y)\K{-}(\\{height}(\|x)+\\{clr});{}$\5
+${}\\{link}(\|y)\K\\{overbar}(\|x,\39\\{clr},\39\\{height}(\|y));{}$\5
+${}\\{info}(\\{nucleus}(\|q))\K\\{hpack}(\|y,\39\\{natural});{}$\5
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{738}Slants are not considered when placing accents in math mode. The accenter is
+centered over the accentee, and the accent width is treated as zero with
+respect to the size of the final box.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_math\_accent}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|x${},{}$ \|y;\C{temporary registers for box construction}\6
+\&{int} \|a;\C{address of lig/kern instruction}\6
+\&{quarterword} \|c;\C{accent character}\6
+\&{internal\_font\_number} \|f;\C{its font}\6
+\&{four\_quarters} \|i;\C{its \\{char\_info}}\6
+\&{scaled} \|s;\C{amount to skew the accent to the right}\6
+\&{scaled} \|h;\C{height of character being accented}\6
+\&{scaled} \\{delta};\C{space to remove between accent and accentee}\6
+\&{scaled} \|w;\C{width of the accentee, not including sub/superscripts}\7
+\\{fetch}(\\{accent\_chr}(\|q));\6
+\&{if} (\\{char\_exists}(\\{cur\_i}))\5
+${}\{{}$\5
+\1${}\|i\K\\{cur\_i};{}$\5
+${}\|c\K\\{cur\_c};{}$\5
+${}\|f\K\\{cur\_f}{}$;\6
+\X741:Compute the amount of skew\X;\6
+${}\|x\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cramped\_style}(\\{cur\_style}));{}$\5
+${}\|w\K\\{width}(\|x);{}$\5
+${}\|h\K\\{height}(\|x);{}$\5
+\X740:Switch to a larger accent if available and appropriate\X;\6
+\&{if} ${}(\|h<\\{x\_height}(\|f)){}$\1\5
+${}\\{delta}\K\|h{}$;\5
+\2\&{else}\1\5
+${}\\{delta}\K\\{x\_height}(\|f);{}$\2\6
+\&{if} ${}((\\{math\_type}(\\{supscr}(\|q))\I\\{empty})\V(\\{math\_type}(\\{subscr}(\|q))\I\\{empty})){}$\1\6
+\&{if} ${}(\\{math\_type}(\\{nucleus}(\|q))\E\\{math\_char}){}$\1\5
+\X742:Swap the subscript and superscript into box \|x\X;\2\2\6
+${}\|y\K\\{char\_box}(\|f,\39\|c);{}$\5
+${}\\{shift\_amount}(\|y)\K\|s+\\{half}(\|w-\\{width}(\|y));{}$\5
+${}\\{width}(\|y)\K\T{0};{}$\5
+${}\|p\K\\{new\_kern}({-}\\{delta});{}$\5
+${}\\{link}(\|p)\K\|x;{}$\5
+${}\\{link}(\|y)\K\|p;{}$\5
+${}\|y\K\\{vpack}(\|y,\39\\{natural});{}$\5
+${}\\{width}(\|y)\K\\{width}(\|x);{}$\6
+\&{if} ${}(\\{height}(\|y)<\|h){}$\1\5
+\X739:Make the height of box \|y equal to \|h\X;\2\6
+${}\\{info}(\\{nucleus}(\|q))\K\|y;{}$\5
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{739}\B\X739:Make the height of box \|y equal to \|h\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{new\_kern}(\|h-\\{height}(\|y));{}$\5
+${}\\{link}(\|p)\K\\{list\_ptr}(\|y);{}$\5
+${}\\{list\_ptr}(\|y)\K\|p;{}$\5
+${}\\{height}(\|y)\K\|h;{}$\6
+\4${}\}{}$\2\par
+\U738.\fi
+
+\M{740}\B\X740:Switch to a larger accent if available and appropriate\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{char\_tag}(\|i)\I\\{list\_tag}){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|y\K\\{rem\_byte}(\|i);{}$\5
+${}\|i\K\\{char\_info}(\|f)(\|y);{}$\6
+\&{if} ${}(\R\\{char\_exists}(\|i)){}$\1\5
+\&{goto} \\{done};\2\6
+\&{if} ${}(\\{char\_width}(\|f)(\|i)>\|w){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|c\K\|y;{}$\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U738.\fi
+
+\M{741}\B\X741:Compute the amount of skew\X${}\E{}$\6
+$\|s\K\T{0};{}$\6
+\&{if} ${}(\\{math\_type}(\\{nucleus}(\|q))\E\\{math\_char}){}$\5
+${}\{{}$\5
+\1\\{fetch}(\\{nucleus}(\|q));\6
+\&{if} ${}(\\{char\_tag}(\\{cur\_i})\E\\{lig\_tag}){}$\5
+${}\{{}$\5
+\1${}\|a\K\\{lig\_kern\_start}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})>\\{stop\_flag}){}$\5
+${}\{{}$\5
+\1${}\|a\K\\{lig\_kern\_restart}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{qo}(\\{next\_char}(\\{cur\_i}))\E\\{skew\_char}[\\{cur\_f}]){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{op\_byte}(\\{cur\_i})\G\\{kern\_flag}){}$\1\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})\Z\\{stop\_flag}){}$\1\5
+${}\|s\K\\{char\_kern}(\\{cur\_f})(\\{cur\_i});{}$\2\2\6
+\&{goto} \\{done1};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})\G\\{stop\_flag}){}$\1\5
+\&{goto} \\{done1};\2\6
+${}\|a\K\|a+\\{qo}(\\{skip\_byte}(\\{cur\_i}))+\T{1};{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\\{done1}:\par
+\U738.\fi
+
+\M{742}\B\X742:Swap the subscript and superscript into box \|x\X${}\E{}$\6
+${}\{{}$\5
+\1\\{flush\_node\_list}(\|x);\5
+${}\|x\K\\{new\_noad}(\,);{}$\5
+${}\\{mem}[\\{nucleus}(\|x)]\K\\{mem}[\\{nucleus}(\|q)];{}$\5
+${}\\{mem}[\\{supscr}(\|x)]\K\\{mem}[\\{supscr}(\|q)];{}$\5
+${}\\{mem}[\\{subscr}(\|x)]\K\\{mem}[\\{subscr}(\|q)]{}$;\6
+${}\\{mem}[\\{supscr}(\|q)].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{subscr}(\|q)].\\{hh}\K\\{empty\_field}{}$;\6
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_mlist};{}$\5
+${}\\{info}(\\{nucleus}(\|q))\K\|x;{}$\5
+${}\|x\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cur\_style});{}$\5
+${}\\{delta}\K\\{delta}+\\{height}(\|x)-\|h;{}$\5
+${}\|h\K\\{height}(\|x);{}$\6
+\4${}\}{}$\2\par
+\U738.\fi
+
+\M{743}The \\{make\_fraction} procedure is a bit different because it sets
+\\{new\_hlist}(\|q) directly rather than making a sub-box.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_fraction}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|v${},{}$ \|x${},{}$ \|y${},{}$ \|z;\C{temporary registers for box construction}\6
+\&{scaled} \\{delta}${},{}$ \\{delta1}${},{}$ \\{delta2}${},{}$ \\{shift\_up}${},{}$ \\{shift\_down}${},{}$ \\{clr};\C{dimensions for box calculations}\7
+\&{if} ${}(\\{thickness}(\|q)\E\\{default\_code}){}$\1\5
+${}\\{thickness}(\|q)\K\\{default\_rule\_thickness};{}$\2\6
+\X744:Create equal-width boxes \|x and \|z for the numerator and denominator, and compute the default amounts \\{shift\_up} and \\{shift\_down} by which they are displaced from the baseline\X;\6
+\&{if} ${}(\\{thickness}(\|q)\E\T{0}){}$\1\5
+\X745:Adjust \(s)\\{shift\_up} and \\{shift\_down} for the case of no fraction line\X\2\6
+\&{else}\1\5
+\X746:Adjust \(s)\\{shift\_up} and \\{shift\_down} for the case of a fraction line\X;\2\6
+\X747:Construct a vlist box for the fraction, according to \\{shift\_up} and \\{shift\_down}\X;\6
+\X748:Put the \(f)fraction into a box with its delimiters, and make \\{new\_hlist}(\|q) point to it\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{744}\B\X744:Create equal-width boxes \|x and \|z for the numerator and denominator, and compute the default amounts \\{shift\_up} and \\{shift\_down} by which they are displaced from the baseline\X${}\E{}$\6
+$\|x\K\\{clean\_box}(\\{numerator}(\|q),\39\\{num\_style}(\\{cur\_style}));{}$\5
+${}\|z\K\\{clean\_box}(\\{denominator}(\|q),\39\\{denom\_style}(\\{cur\_style}));{}$\6
+\&{if} ${}(\\{width}(\|x)<\\{width}(\|z)){}$\1\5
+${}\|x\K\\{rebox}(\|x,\39\\{width}(\|z));{}$\2\6
+\&{else}\1\5
+${}\|z\K\\{rebox}(\|z,\39\\{width}(\|x));{}$\2\6
+\&{if} ${}(\\{cur\_style}<\\{text\_style}{}$)\C{display style}\6
+${}\{{}$\5
+\1${}\\{shift\_up}\K\\{num1}(\\{cur\_size});{}$\5
+${}\\{shift\_down}\K\\{denom1}(\\{cur\_size});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{shift\_down}\K\\{denom2}(\\{cur\_size});{}$\6
+\&{if} ${}(\\{thickness}(\|q)\I\T{0}){}$\1\5
+${}\\{shift\_up}\K\\{num2}(\\{cur\_size});{}$\2\6
+\&{else}\1\5
+${}\\{shift\_up}\K\\{num3}(\\{cur\_size});{}$\2\6
+\4${}\}{}$\2\par
+\U743.\fi
+
+\M{745}The numerator and denominator must be separated by a certain minimum
+clearance, called \\{clr} in the following program. The difference between
+\\{clr} and the actual clearance is \T{2}\\{delta}.
+
+\Y\B\4\X745:Adjust \(s)\\{shift\_up} and \\{shift\_down} for the case of no fraction line\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_style}<\\{text\_style}){}$\1\5
+${}\\{clr}\K\T{7}*\\{default\_rule\_thickness};{}$\2\6
+\&{else}\1\5
+${}\\{clr}\K\T{3}*\\{default\_rule\_thickness};{}$\2\6
+${}\\{delta}\K\\{half}(\\{clr}-((\\{shift\_up}-\\{depth}(\|x))-(\\{height}(\|z)-\\{shift\_down})));{}$\6
+\&{if} ${}(\\{delta}>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{shift\_up}\K\\{shift\_up}+\\{delta};{}$\5
+${}\\{shift\_down}\K\\{shift\_down}+\\{delta};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U743.\fi
+
+\M{746}In the case of a fraction line, the minimum clearance depends on the actual
+thickness of the line.
+
+\Y\B\4\X746:Adjust \(s)\\{shift\_up} and \\{shift\_down} for the case of a fraction line\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_style}<\\{text\_style}){}$\1\5
+${}\\{clr}\K\T{3}*\\{thickness}(\|q);{}$\2\6
+\&{else}\1\5
+${}\\{clr}\K\\{thickness}(\|q);{}$\2\6
+${}\\{delta}\K\\{half}(\\{thickness}(\|q));{}$\5
+${}\\{delta1}\K\\{clr}-((\\{shift\_up}-\\{depth}(\|x))-(\\{axis\_height}(\\{cur\_size})+\\{delta}));{}$\5
+${}\\{delta2}\K\\{clr}-((\\{axis\_height}(\\{cur\_size})-\\{delta})-(\\{height}(\|z)-\\{shift\_down}));{}$\6
+\&{if} ${}(\\{delta1}>\T{0}){}$\1\5
+${}\\{shift\_up}\K\\{shift\_up}+\\{delta1};{}$\2\6
+\&{if} ${}(\\{delta2}>\T{0}){}$\1\5
+${}\\{shift\_down}\K\\{shift\_down}+\\{delta2};{}$\2\6
+\4${}\}{}$\2\par
+\U743.\fi
+
+\M{747}\B\X747:Construct a vlist box for the fraction, according to \\{shift\_up} and \\{shift\_down}\X${}\E{}$\6
+$\|v\K\\{new\_null\_box}(\,);{}$\5
+${}\\{type}(\|v)\K\\{vlist\_node};{}$\5
+${}\\{height}(\|v)\K\\{shift\_up}+\\{height}(\|x);{}$\5
+${}\\{depth}(\|v)\K\\{depth}(\|z)+\\{shift\_down};{}$\5
+${}\\{width}(\|v)\K\\{width}(\|x){}$;\C{this also equals \\{width}(\|z)}\6
+\&{if} ${}(\\{thickness}(\|q)\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_kern}((\\{shift\_up}-\\{depth}(\|x))-(\\{height}(\|z)-\\{shift\_down}));{}$\5
+${}\\{link}(\|p)\K\|z;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|y\K\\{fraction\_rule}(\\{thickness}(\|q)){}$;\6
+${}\|p\K\\{new\_kern}((\\{axis\_height}(\\{cur\_size})-\\{delta})-\30(\\{height}(\|z)-\\{shift\_down})){}$;\6
+${}\\{link}(\|y)\K\|p;{}$\5
+${}\\{link}(\|p)\K\|z{}$;\6
+${}\|p\K\\{new\_kern}((\\{shift\_up}-\\{depth}(\|x))-(\\{axis\_height}(\\{cur\_size})+\\{delta}));{}$\5
+${}\\{link}(\|p)\K\|y;{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\|x)\K\|p;$ $\\{list\_ptr}(\|v)\K{}$\|x\par
+\U743.\fi
+
+\M{748}\B\X748:Put the \(f)fraction into a box with its delimiters, and make \\{new\_hlist}(\|q) point to it\X${}\E{}$\6
+\&{if} ${}(\\{cur\_style}<\\{text\_style}){}$\1\5
+${}\\{delta}\K\\{delim1}(\\{cur\_size});{}$\2\6
+\&{else}\1\5
+${}\\{delta}\K\\{delim2}(\\{cur\_size});{}$\2\6
+${}\|x\K\\{var\_delimiter}(\\{left\_delimiter}(\|q),\39\\{cur\_size},\39\\{delta});{}$\5
+${}\\{link}(\|x)\K\|v{}$;\6
+${}\|z\K\\{var\_delimiter}(\\{right\_delimiter}(\|q),\39\\{cur\_size},\39\\{delta});{}$\5
+${}\\{link}(\|v)\K\|z{}$;\6
+$\\{new\_hlist}(\|q)\K\\{hpack}(\|x,\39\\{natural}{}$)\par
+\U743.\fi
+
+\M{749}If the nucleus of an \\{op\_noad} is a single character, it is to be
+centered vertically with respect to the axis, after first being enlarged
+(via a character list in the font) if we are in display style. The normal
+convention for placing displayed limits is to put them above and below the
+operator in display style.
+
+The italic correction is removed from the character if there is a subscript
+and the limits are not being displayed. The \\{make\_op}
+routine returns the value that should be used as an offset between
+subscript and superscript.
+
+After \\{make\_op} has acted, \\{subtype}(\|q) will be \\{limits} if and only if
+the limits have been set above and below the operator. In that case,
+\\{new\_hlist}(\|q) will already contain the desired final box.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{scaled} \\{make\_op}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{scaled} \\{delta};\C{offset between subscript and superscript}\6
+\&{pointer} \|p${},{}$ \|v${},{}$ \|x${},{}$ \|y${},{}$ \|z;\C{temporary registers for box construction}\6
+\&{quarterword} \|c;\5
+\&{four\_quarters} \|i;\C{registers for character examination}\6
+\&{scaled} \\{shift\_up}${},{}$ \\{shift\_down};\C{dimensions for box calculation}\7
+\&{if} ${}((\\{subtype}(\|q)\E\\{normal})\W(\\{cur\_style}<\\{text\_style})){}$\1\5
+${}\\{subtype}(\|q)\K\\{limits};{}$\2\6
+\&{if} ${}(\\{math\_type}(\\{nucleus}(\|q))\E\\{math\_char}){}$\5
+${}\{{}$\5
+\1\\{fetch}(\\{nucleus}(\|q));\6
+\&{if} ${}((\\{cur\_style}<\\{text\_style})\W(\\{char\_tag}(\\{cur\_i})\E\\{list\_tag}){}$)\C{make it larger}\6
+${}\{{}$\5
+\1${}\|c\K\\{rem\_byte}(\\{cur\_i});{}$\5
+${}\|i\K\\{char\_info}(\\{cur\_f})(\|c);{}$\6
+\&{if} (\\{char\_exists}(\|i))\5
+${}\{{}$\5
+\1${}\\{cur\_c}\K\|c;{}$\5
+${}\\{cur\_i}\K\|i;{}$\5
+${}\\{character}(\\{nucleus}(\|q))\K\|c;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{delta}\K\\{char\_italic}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\|x\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cur\_style});{}$\6
+\&{if} ${}((\\{math\_type}(\\{subscr}(\|q))\I\\{empty})\W(\\{subtype}(\|q)\I\\{limits})){}$\1\5
+${}\\{width}(\|x)\K\\{width}(\|x)-\\{delta}{}$;\C{remove italic correction}\2\6
+${}\\{shift\_amount}(\|x)\K\\{half}(\\{height}(\|x)-\\{depth}(\|x))-\\{axis\_height}(\\{cur\_size}){}$;\C{center vertically}\6
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\5
+${}\\{info}(\\{nucleus}(\|q))\K\|x;{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{delta}\K\T{0};{}$\2\6
+\&{if} ${}(\\{subtype}(\|q)\E\\{limits}){}$\1\5
+\X750:Construct a box with limits above and below it, skewed by \\{delta}\X;\2\6
+\&{return} \\{delta};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{750}The following program builds a vlist box \|v for displayed limits. The
+width of the box is not affected by the fact that the limits may be skewed.
+
+\Y\B\4\X750:Construct a box with limits above and below it, skewed by \\{delta}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\\{clean\_box}(\\{supscr}(\|q),\39\\{sup\_style}(\\{cur\_style}));{}$\5
+${}\|y\K\\{clean\_box}(\\{nucleus}(\|q),\39\\{cur\_style});{}$\5
+${}\|z\K\\{clean\_box}(\\{subscr}(\|q),\39\\{sub\_style}(\\{cur\_style}));{}$\5
+${}\|v\K\\{new\_null\_box}(\,);{}$\5
+${}\\{type}(\|v)\K\\{vlist\_node};{}$\5
+${}\\{width}(\|v)\K\\{width}(\|y);{}$\6
+\&{if} ${}(\\{width}(\|x)>\\{width}(\|v)){}$\1\5
+${}\\{width}(\|v)\K\\{width}(\|x);{}$\2\6
+\&{if} ${}(\\{width}(\|z)>\\{width}(\|v)){}$\1\5
+${}\\{width}(\|v)\K\\{width}(\|z);{}$\2\6
+${}\|x\K\\{rebox}(\|x,\39\\{width}(\|v));{}$\5
+${}\|y\K\\{rebox}(\|y,\39\\{width}(\|v));{}$\5
+${}\|z\K\\{rebox}(\|z,\39\\{width}(\|v)){}$;\6
+${}\\{shift\_amount}(\|x)\K\\{half}(\\{delta});{}$\5
+${}\\{shift\_amount}(\|z)\K{-}\\{shift\_amount}(\|x);{}$\5
+${}\\{height}(\|v)\K\\{height}(\|y);{}$\5
+${}\\{depth}(\|v)\K\\{depth}(\|y);{}$\5
+\X751:Attach the limits to \|y and adjust \\{height}(\|v), \\{depth}(\|v) to account for their presence\X;\6
+${}\\{new\_hlist}(\|q)\K\|v;{}$\6
+\4${}\}{}$\2\par
+\U749.\fi
+
+\M{751}We use \\{shift\_up} and \\{shift\_down} in the following program for the
+amount of glue between the displayed operator \|y and its limits \|x and
+\|z. The vlist inside box \|v will consist of \|x followed by \|y followed
+by \|z, with kern nodes for the spaces between and around them.
+
+\Y\B\4\X751:Attach the limits to \|y and adjust \\{height}(\|v), \\{depth}(\|v) to account for their presence\X${}\E{}$\6
+\&{if} ${}(\\{math\_type}(\\{supscr}(\|q))\E\\{empty}){}$\5
+${}\{{}$\5
+\1${}\\{free\_node}(\|x,\39\\{box\_node\_size});{}$\5
+${}\\{list\_ptr}(\|v)\K\|y;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{shift\_up}\K\\{big\_op\_spacing3}-\\{depth}(\|x);{}$\6
+\&{if} ${}(\\{shift\_up}<\\{big\_op\_spacing1}){}$\1\5
+${}\\{shift\_up}\K\\{big\_op\_spacing1};{}$\2\6
+${}\|p\K\\{new\_kern}(\\{shift\_up});{}$\5
+${}\\{link}(\|p)\K\|y;{}$\5
+${}\\{link}(\|x)\K\|p{}$;\6
+${}\|p\K\\{new\_kern}(\\{big\_op\_spacing5});{}$\5
+${}\\{link}(\|p)\K\|x;{}$\5
+${}\\{list\_ptr}(\|v)\K\|p;{}$\5
+${}\\{height}(\|v)\K\\{height}(\|v)+\\{big\_op\_spacing5}+\\{height}(\|x)+\\{depth}(\|x)+\\{shift\_up};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{math\_type}(\\{subscr}(\|q))\E\\{empty}){}$\1\5
+${}\\{free\_node}(\|z,\39\\{box\_node\_size});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{shift\_down}\K\\{big\_op\_spacing4}-\\{height}(\|z);{}$\6
+\&{if} ${}(\\{shift\_down}<\\{big\_op\_spacing2}){}$\1\5
+${}\\{shift\_down}\K\\{big\_op\_spacing2};{}$\2\6
+${}\|p\K\\{new\_kern}(\\{shift\_down});{}$\5
+${}\\{link}(\|y)\K\|p;{}$\5
+${}\\{link}(\|p)\K\|z{}$;\6
+${}\|p\K\\{new\_kern}(\\{big\_op\_spacing5});{}$\5
+${}\\{link}(\|z)\K\|p;{}$\5
+${}\\{depth}(\|v)\K\\{depth}(\|v)+\\{big\_op\_spacing5}+\\{height}(\|z)+\\{depth}(\|z)+\\{shift\_down};{}$\6
+\4${}\}{}$\2\par
+\U750.\fi
+
+\M{752}A ligature found in a math formula does not create a \\{ligature\_node}, because
+there is no question of hyphenation afterwards; the ligature will simply be
+stored in an ordinary \\{char\_node}, after residing in an \\{ord\_noad}.
+
+The \\{math\_type} is converted to \\{math\_text\_char} here if we would not want to
+apply an italic correction to the current character unless it belongs
+to a math font (i.e., a font with $\\{space}\E\T{0}$).
+
+No boundary characters enter into these ligatures.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_ord}(\&{pointer} \|q)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|a;\C{address of lig/kern instruction}\6
+\&{pointer} \|p${},{}$ \|r;\C{temporary registers for list manipulation}\7
+\4\\{restart}:\5
+\hbox{}\6
+\&{if} ${}(\\{math\_type}(\\{subscr}(\|q))\E\\{empty}){}$\1\6
+\&{if} ${}(\\{math\_type}(\\{supscr}(\|q))\E\\{empty}){}$\1\6
+\&{if} ${}(\\{math\_type}(\\{nucleus}(\|q))\E\\{math\_char}){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{link}(\|q);{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}((\\{type}(\|p)\G\\{ord\_noad})\W(\\{type}(\|p)\Z\\{punct\_noad})){}$\1\6
+\&{if} ${}(\\{math\_type}(\\{nucleus}(\|p))\E\\{math\_char}){}$\1\6
+\&{if} ${}(\\{fam}(\\{nucleus}(\|p))\E\\{fam}(\\{nucleus}(\|q))){}$\5
+${}\{{}$\5
+\1${}\\{math\_type}(\\{nucleus}(\|q))\K\\{math\_text\_char};{}$\5
+\\{fetch}(\\{nucleus}(\|q));\6
+\&{if} ${}(\\{char\_tag}(\\{cur\_i})\E\\{lig\_tag}){}$\5
+${}\{{}$\5
+\1${}\|a\K\\{lig\_kern\_start}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\\{cur\_c}\K\\{character}(\\{nucleus}(\|p));{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})>\\{stop\_flag}){}$\5
+${}\{{}$\5
+\1${}\|a\K\\{lig\_kern\_restart}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\X753:If instruction \\{cur\_i} is a kern with \\{cur\_c}, attach the kern after~\|q; or if it is a ligature with \\{cur\_c}, combine noads \|q and~\|p appropriately; then \&{return} if the cursor has moved past a noad, or \&{goto} \\{restart}\X;\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})\G\\{stop\_flag}){}$\1\5
+\&{return};\2\6
+${}\|a\K\|a+\\{qo}(\\{skip\_byte}(\\{cur\_i}))+\T{1};{}$\5
+${}\\{cur\_i}\K\\{font\_info}[\|a].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\2\2\6
+\4${}\}{}$\2\2\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{753}Note that a ligature between an \\{ord\_noad} and another kind of noad
+is replaced by an \\{ord\_noad}, when the two noads collapse into one.
+But we could make a parenthesis (say) change shape when it follows
+certain letters. Presumably a font designer will define such
+ligatures only when this convention makes sense.
+
+\chardef\?='174 % vertical line to indicate character retention
+
+\Y\B\4\X753:If instruction \\{cur\_i} is a kern with \\{cur\_c}, attach the kern after~\|q; or if it is a ligature with \\{cur\_c}, combine noads \|q and~\|p appropriately; then \&{return} if the cursor has moved past a noad, or \&{goto} \\{restart}\X${}%
+\E{}$\6
+\&{if} ${}(\\{next\_char}(\\{cur\_i})\E\\{cur\_c}){}$\1\6
+\&{if} ${}(\\{skip\_byte}(\\{cur\_i})\Z\\{stop\_flag}){}$\1\6
+\&{if} ${}(\\{op\_byte}(\\{cur\_i})\G\\{kern\_flag}){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_kern}(\\{char\_kern}(\\{cur\_f})(\\{cur\_i}));{}$\5
+${}\\{link}(\|p)\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\|p;{}$\5
+\&{return};\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{check\_interrupt};\C{allow a way out of infinite ligature loop}\6
+\&{switch} (\\{op\_byte}(\\{cur\_i}))\5
+${}\{{}$\1\6
+\4\\{qi}(\&{case} \T{1}):\5
+\\{qi}(\&{case} \T{5}):\5
+${}\\{character}(\\{nucleus}(\|q))\K\\{rem\_byte}(\\{cur\_i}){}$;\5
+\&{break};\C{\.{=:\?}, \.{=:\?>}}\6
+\4\\{qi}(\&{case} \T{2}):\5
+\\{qi}(\&{case} \T{6}):\5
+${}\\{character}(\\{nucleus}(\|p))\K\\{rem\_byte}(\\{cur\_i}){}$;\5
+\&{break};\C{\.{\?=:}, \.{\?=:>}}\6
+\4\\{qi}(\&{case} \T{3}):\5
+\\{qi}(\&{case} \T{7}):\5
+\\{qi}(\&{case} \T{11}):\6
+${}\{{}$\5
+\1${}\|r\K\\{new\_noad}(\,){}$;\C{\.{\?=:\?}, \.{\?=:\?>}, \.{\?=:\?>>}}\6
+${}\\{character}(\\{nucleus}(\|r))\K\\{rem\_byte}(\\{cur\_i});{}$\5
+${}\\{fam}(\\{nucleus}(\|r))\K\\{fam}(\\{nucleus}(\|q)){}$;\6
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{link}(\|r)\K\|p;{}$\6
+\&{if} ${}(\\{op\_byte}(\\{cur\_i})<\\{qi}(\T{11})){}$\1\5
+${}\\{math\_type}(\\{nucleus}(\|r))\K\\{math\_char};{}$\2\6
+\&{else}\1\5
+${}\\{math\_type}(\\{nucleus}(\|r))\K\\{math\_text\_char}{}$;\C{prevent combination}\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{link}(\|p);{}$\5
+${}\\{character}(\\{nucleus}(\|q))\K\\{rem\_byte}(\\{cur\_i}){}$;\C{\.{=:}}\6
+${}\\{mem}[\\{subscr}(\|q)]\K\\{mem}[\\{subscr}(\|p)];{}$\5
+${}\\{mem}[\\{supscr}(\|q)]\K\\{mem}[\\{supscr}(\|p)]{}$;\6
+${}\\{free\_node}(\|p,\39\\{noad\_size});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{op\_byte}(\\{cur\_i})>\\{qi}(\T{3})){}$\1\5
+\&{return};\2\6
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{math\_char};{}$\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\2\2\par
+\U752.\fi
+
+\M{754}When we get to the following part of the program, we have ``fallen through''
+from cases that did not lead to \\{check\_dimensions} or \\{done\_with\_noad} or
+\\{done\_with\_node}. Thus, \|q~points to a noad whose nucleus may need to be
+converted to an hlist, and whose subscripts and superscripts need to be
+appended if they are present.
+
+If \\{nucleus}(\|q) is not a \\{math\_char}, the variable \\{delta} is the amount
+by which a superscript should be moved right with respect to a subscript
+when both are present.
+
+\Y\B\4\X754:Convert \(n)\\{nucleus}(\|q) to an hlist and attach the sub/superscripts\X${}\E{}$\6
+\&{switch} (\\{math\_type}(\\{nucleus}(\|q)))\5
+${}\{{}$\1\6
+\4\&{case} \\{math\_char}:\5
+\&{case} \\{math\_text\_char}:\5
+\X755:Create a character node \|p for \\{nucleus}(\|q), possibly followed by a kern node for the italic correction, and set \\{delta} to the italic correction if a subscript is present\X\5
+\&{break};\6
+\4\&{case} \\{empty}:\5
+${}\|p\K\\{null}{}$;\5
+\&{break};\6
+\4\&{case} \\{sub\_box}:\5
+${}\|p\K\\{info}(\\{nucleus}(\|q)){}$;\5
+\&{break};\6
+\4\&{case} \\{sub\_mlist}:\6
+${}\{{}$\5
+\1${}\\{cur\_mlist}\K\\{info}(\\{nucleus}(\|q));{}$\5
+${}\\{save\_style}\K\\{cur\_style};{}$\5
+${}\\{mlist\_penalties}\K\\{false};{}$\5
+\\{mlist\_to\_hlist}(\,);\C{recursive call}\6
+${}\\{cur\_style}\K\\{save\_style};{}$\5
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+${}\|p\K\\{hpack}(\\{link}(\\{temp\_head}),\39\\{natural});{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1665:\.{"mlist2"}\X);\6
+\4${}\}{}$\2\6
+${}\\{new\_hlist}(\|q)\K\|p;{}$\6
+\&{if} ${}((\\{math\_type}(\\{subscr}(\|q))\E\\{empty})\W(\\{math\_type}(\\{supscr}(\|q))\E\\{empty})){}$\1\5
+\&{goto} \\{check\_dimensions};\2\6
+$\\{make\_scripts}(\|q,\39\\{delta}{}$)\par
+\U728.\fi
+
+\M{755}\B\X755:Create a character node \|p for \\{nucleus}(\|q), possibly followed by a kern node for the italic correction, and set \\{delta} to the italic correction if a subscript is present\X${}\E{}$\6
+${}\{{}$\5
+\1\\{fetch}(\\{nucleus}(\|q));\6
+\&{if} (\\{char\_exists}(\\{cur\_i}))\5
+${}\{{}$\5
+\1${}\\{delta}\K\\{char\_italic}(\\{cur\_f})(\\{cur\_i});{}$\5
+${}\|p\K\\{new\_character}(\\{cur\_f},\39\\{qo}(\\{cur\_c}));{}$\6
+\&{if} ${}((\\{math\_type}(\\{nucleus}(\|q))\E\\{math\_text\_char})\W(\\{space}(\\{cur\_f})\I\T{0})){}$\1\5
+${}\\{delta}\K\T{0}{}$;\C{no italic correction in mid-word of text font}\2\6
+\&{if} ${}((\\{math\_type}(\\{subscr}(\|q))\E\\{empty})\W(\\{delta}\I\T{0})){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\\{new\_kern}(\\{delta});{}$\5
+${}\\{delta}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\|p\K\\{null};{}$\2\6
+\4${}\}{}$\2\par
+\U754.\fi
+
+\M{756}The purpose of $\\{make\_scripts}(\|q,\\{delta})$ is to attach the subscript and/or
+superscript of noad \|q to the list that starts at \\{new\_hlist}(\|q),
+given that the subscript and superscript aren't both empty. The superscript
+will appear to the right of the subscript by a given distance \\{delta}.
+
+We set \\{shift\_down} and \\{shift\_up} to the minimum amounts to shift the
+baseline of subscripts and superscripts based on the given nucleus.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_scripts}(\&{pointer} \|q${},\39{}$\&{scaled} \\{delta})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|x${},{}$ \|y${},{}$ \|z;\C{temporary registers for box construction}\6
+\&{scaled} \\{shift\_up}${},{}$ \\{shift\_down}${},{}$ \\{clr};\C{dimensions in the calculation}\6
+\&{small\_number} \|t;\C{subsidiary size code}\7
+${}\|p\K\\{new\_hlist}(\|q);{}$\6
+\&{if} (\\{is\_char\_node}(\|p))\5
+${}\{{}$\5
+\1${}\\{shift\_up}\K\T{0};{}$\5
+${}\\{shift\_down}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|z\K\\{hpack}(\|p,\39\\{natural});{}$\6
+\&{if} ${}(\\{cur\_style}<\\{script\_style}){}$\1\5
+${}\|t\K\\{script\_size}{}$;\5
+\2\&{else}\1\5
+${}\|t\K\\{script\_script\_size};{}$\2\6
+${}\\{shift\_up}\K\\{height}(\|z)-\\{sup\_drop}(\|t);{}$\5
+${}\\{shift\_down}\K\\{depth}(\|z)+\\{sub\_drop}(\|t);{}$\5
+${}\\{free\_node}(\|z,\39\\{box\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{math\_type}(\\{supscr}(\|q))\E\\{empty}){}$\1\5
+\X757:Construct a subscript box \|x when there is no superscript\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\X758:Construct a superscript box \|x\X;\6
+\&{if} ${}(\\{math\_type}(\\{subscr}(\|q))\E\\{empty}){}$\1\5
+${}\\{shift\_amount}(\|x)\K{-}\\{shift\_up};{}$\2\6
+\&{else}\1\5
+\X759:Construct a sub/superscript combination box \|x, with the superscript offset by \\{delta}\X;\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{new\_hlist}(\|q)\E\\{null}){}$\1\5
+${}\\{new\_hlist}(\|q)\K\|x;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_hlist}(\|q);{}$\6
+\&{while} ${}(\\{link}(\|p)\I\\{null}){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+${}\\{link}(\|p)\K\|x;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{757}When there is a subscript without a superscript, the top of the subscript
+should not exceed the baseline plus four-fifths of the x-height.
+
+\Y\B\4\X757:Construct a subscript box \|x when there is no superscript\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\\{clean\_box}(\\{subscr}(\|q),\39\\{sub\_style}(\\{cur\_style}));{}$\5
+${}\\{width}(\|x)\K\\{width}(\|x)+\\{script\_space};{}$\6
+\&{if} ${}(\\{shift\_down}<\\{sub1}(\\{cur\_size})){}$\1\5
+${}\\{shift\_down}\K\\{sub1}(\\{cur\_size});{}$\2\6
+${}\\{clr}\K\\{height}(\|x)-(\\{abs}(\\{math\_x\_height}(\\{cur\_size})*\T{4})/\T{5});{}$\6
+\&{if} ${}(\\{shift\_down}<\\{clr}){}$\1\5
+${}\\{shift\_down}\K\\{clr};{}$\2\6
+${}\\{shift\_amount}(\|x)\K\\{shift\_down};{}$\6
+\4${}\}{}$\2\par
+\U756.\fi
+
+\M{758}The bottom of a superscript should never descend below the baseline plus
+one-fourth of the x-height.
+
+\Y\B\4\X758:Construct a superscript box \|x\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|x\K\\{clean\_box}(\\{supscr}(\|q),\39\\{sup\_style}(\\{cur\_style}));{}$\5
+${}\\{width}(\|x)\K\\{width}(\|x)+\\{script\_space};{}$\6
+\&{if} (\\{odd}(\\{cur\_style}))\1\5
+${}\\{clr}\K\\{sup3}(\\{cur\_size});{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_style}<\\{text\_style}){}$\1\5
+${}\\{clr}\K\\{sup1}(\\{cur\_size});{}$\2\6
+\&{else}\1\5
+${}\\{clr}\K\\{sup2}(\\{cur\_size});{}$\2\6
+\&{if} ${}(\\{shift\_up}<\\{clr}){}$\1\5
+${}\\{shift\_up}\K\\{clr};{}$\2\6
+${}\\{clr}\K\\{depth}(\|x)+(\\{abs}(\\{math\_x\_height}(\\{cur\_size}))/\T{4});{}$\6
+\&{if} ${}(\\{shift\_up}<\\{clr}){}$\1\5
+${}\\{shift\_up}\K\\{clr};{}$\2\6
+\4${}\}{}$\2\par
+\U756.\fi
+
+\M{759}When both subscript and superscript are present, the subscript must be
+separated from the superscript by at least four times \\{default\_rule\_thickness}.
+If this condition would be violated, the subscript moves down, after which
+both subscript and superscript move up so that the bottom of the superscript
+is at least as high as the baseline plus four-fifths of the x-height.
+
+\Y\B\4\X759:Construct a sub/superscript combination box \|x, with the superscript offset by \\{delta}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|y\K\\{clean\_box}(\\{subscr}(\|q),\39\\{sub\_style}(\\{cur\_style}));{}$\5
+${}\\{width}(\|y)\K\\{width}(\|y)+\\{script\_space};{}$\6
+\&{if} ${}(\\{shift\_down}<\\{sub2}(\\{cur\_size})){}$\1\5
+${}\\{shift\_down}\K\\{sub2}(\\{cur\_size});{}$\2\6
+${}\\{clr}\K\T{4}*\\{default\_rule\_thickness}-((\\{shift\_up}-\\{depth}(\|x))-(\\{height}(\|y)-\\{shift\_down}));{}$\6
+\&{if} ${}(\\{clr}>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{shift\_down}\K\\{shift\_down}+\\{clr};{}$\5
+${}\\{clr}\K(\\{abs}(\\{math\_x\_height}(\\{cur\_size})*\T{4})/\T{5})-(\\{shift\_up}-\\{depth}(\|x));{}$\6
+\&{if} ${}(\\{clr}>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{shift\_up}\K\\{shift\_up}+\\{clr};{}$\5
+${}\\{shift\_down}\K\\{shift\_down}-\\{clr};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{shift\_amount}(\|x)\K\\{delta}{}$;\C{superscript is \\{delta} to the right of the subscript}\6
+${}\|p\K\\{new\_kern}((\\{shift\_up}-\\{depth}(\|x))-(\\{height}(\|y)-\\{shift\_down}));{}$\5
+${}\\{link}(\|x)\K\|p;{}$\5
+${}\\{link}(\|p)\K\|y;{}$\5
+${}\|x\K\\{vpack}(\|x,\39\\{natural});{}$\5
+${}\\{shift\_amount}(\|x)\K\\{shift\_down};{}$\6
+\4${}\}{}$\2\par
+\U756.\fi
+
+\M{760}We have now tied up all the loose ends of the first pass of \\{mlist\_to\_hlist}.
+The second pass simply goes through and hooks everything together with the
+proper glue and penalties. It also handles the \\{left\_noad} and \\{right\_noad} that
+might be present, since \\{max\_h} and \\{max\_d} are now known. Variable \|p points
+to a node at the current end of the final hlist.
+
+\Y\B\4\X760:Make a second pass over the mlist, removing all noads and inserting the proper spacing and penalties\X${}\E{}$\6
+$\|p\K\\{temp\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+${}\|q\K\\{mlist};{}$\5
+${}\\{r\_type}\K\T{0};{}$\5
+${}\\{cur\_style}\K\\{style};{}$\5
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+\&{while} ${}(\|q\I\\{null}){}$\5
+${}\{{}$\5
+\1\X761:If node \|q is a style node, change the style and \&{goto} \\{delete\_q}; otherwise if it is not a noad, put it into the hlist, advance \|q, and \&{goto} \\{done}; otherwise set \|s to the size of noad \|q, set \|t to the associated type ($\\{ord%
+\_noad}\MRL{{.}{.}}\\{inner\_noad}$), and set \\{pen} to the associated penalty\X;\6
+\X766:Append inter-element spacing based on \\{r\_type} and \|t\X;\6
+\X767:Append any \\{new\_hlist} entries for \|q, and any appropriate penalties\X;\6
+${}\\{r\_type}\K\|t;{}$\6
+\4\\{delete\_q}:\5
+${}\|r\K\|q;{}$\5
+${}\|q\K\\{link}(\|q);{}$\5
+${}\\{free\_node}(\|r,\39\|s);{}$\6
+\4\\{done}:\5
+;\6
+\4${}\}{}$\2\par
+\U726.\fi
+
+\M{761}Just before doing the big \&{case} switch in the second pass, the program
+sets up default values so that most of the branches are short.
+
+\Y\B\4\X761:If node \|q is a style node, change the style and \&{goto} \\{delete\_q}; otherwise if it is not a noad, put it into the hlist, advance \|q, and \&{goto} \\{done}; otherwise set \|s to the size of noad \|q, set \|t to the associated type ($%
+\\{ord\_noad}\MRL{{.}{.}}\\{inner\_noad}$), and set \\{pen} to the associated penalty\X${}\E{}$\6
+$\|t\K\\{ord\_noad};{}$\5
+${}\|s\K\\{noad\_size};{}$\5
+${}\\{pen}\K\\{inf\_penalty};{}$\6
+\&{switch} (\\{type}(\|q))\5
+${}\{{}$\1\6
+\4\&{case} \\{op\_noad}:\5
+\&{case} \\{open\_noad}:\5
+\&{case} \\{close\_noad}:\5
+\&{case} \\{punct\_noad}:\5
+\&{case} \\{inner\_noad}:\5
+${}\|t\K\\{type}(\|q){}$;\5
+\&{break};\6
+\4\&{case} \\{bin\_noad}:\6
+${}\{{}$\5
+\1${}\|t\K\\{bin\_noad};{}$\5
+${}\\{pen}\K\\{bin\_op\_penalty};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{rel\_noad}:\6
+${}\{{}$\5
+\1${}\|t\K\\{rel\_noad};{}$\5
+${}\\{pen}\K\\{rel\_penalty};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{ord\_noad}:\5
+\&{case} \\{vcenter\_noad}:\5
+\&{case} \\{over\_noad}:\5
+\&{case} \\{under\_noad}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{radical\_noad}:\5
+${}\|s\K\\{radical\_noad\_size}{}$;\5
+\&{break};\6
+\4\&{case} \\{accent\_noad}:\5
+${}\|s\K\\{accent\_noad\_size}{}$;\5
+\&{break};\6
+\4\&{case} \\{fraction\_noad}:\6
+${}\{{}$\5
+\1${}\|t\K\\{inner\_noad};{}$\5
+${}\|s\K\\{fraction\_noad\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{left\_noad}:\5
+\&{case} \\{right\_noad}:\5
+${}\|t\K\\{make\_left\_right}(\|q,\39\\{style},\39\\{max\_d},\39\\{max\_h}){}$;\5
+\&{break};\6
+\4\&{case} \\{style\_node}:\5
+\X763:Change the current style and \&{goto} \\{delete\_q}\X\6
+\4\&{case} \\{whatsit\_node}:\5
+\&{case} \\{penalty\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{disc\_node}:\5
+\&{case} \\{adjust\_node}:\5
+\&{case} \\{ins\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{case} \\{glue\_node}:\5
+\&{case} \\{kern\_node}:\5
+\hbox{}\6
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\|q;{}$\5
+${}\|p\K\|q;{}$\5
+${}\|q\K\\{link}(\|q);{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{default}:\5
+\\{confusion}(\X1666:\.{"mlist3"}\X);\6
+\4${}\}{}$\2\par
+\U760.\fi
+
+\M{762}The \\{make\_left\_right} function constructs a left or right delimiter of
+the required size and returns the value \\{open\_noad} or \\{close\_noad}. The
+\\{right\_noad} and \\{left\_noad} will both be based on the original \\{style},
+so they will have consistent sizes.
+
+We use the fact that $\\{right\_noad}-\\{left\_noad}\E\\{close\_noad}-\\{open\_noad}$.
+
+\Y\B\4\X734:Declare math construction procedures\X${}\mathrel+\E{}$\6
+\&{small\_number} \\{make\_left\_right}(\&{pointer} \|q${},\39{}$\&{small\_number} \\{style}${},\39{}$\&{scaled} \\{max\_d}${},\39{}$\&{scaled} \\{max\_h})\1\1\2\2\6
+${}\{{}$\5
+\1\&{scaled} \\{delta}${},{}$ \\{delta1}${},{}$ \\{delta2};\C{dimensions used in the calculation}\7
+\&{if} ${}(\\{style}<\\{script\_style}){}$\1\5
+${}\\{cur\_size}\K\\{text\_size};{}$\2\6
+\&{else}\1\5
+${}\\{cur\_size}\K\T{16}*((\\{style}-\\{text\_style})/\T{2});{}$\2\6
+${}\\{delta2}\K\\{max\_d}+\\{axis\_height}(\\{cur\_size});{}$\5
+${}\\{delta1}\K\\{max\_h}+\\{max\_d}-\\{delta2};{}$\6
+\&{if} ${}(\\{delta2}>\\{delta1}){}$\1\5
+${}\\{delta1}\K\\{delta2}{}$;\C{\\{delta1} is max distance from axis}\2\6
+${}\\{delta}\K(\\{delta1}/\T{500})*\\{delimiter\_factor};{}$\5
+${}\\{delta2}\K\\{delta1}+\\{delta1}-\\{delimiter\_shortfall};{}$\6
+\&{if} ${}(\\{delta}<\\{delta2}){}$\1\5
+${}\\{delta}\K\\{delta2};{}$\2\6
+${}\\{new\_hlist}(\|q)\K\\{var\_delimiter}(\\{delimiter}(\|q),\39\\{cur\_size},\39\\{delta});{}$\5
+\&{return} \\{type}(\|q)${}-(\\{left\_noad}-\\{open\_noad}){}$;\C{\\{open\_noad} or \\{close\_noad}}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{763}\B\X763:Change the current style and \&{goto} \\{delete\_q}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_style}\K\\{subtype}(\|q);{}$\5
+${}\|s\K\\{style\_node\_size};{}$\5
+\X703:Set up the values of \\{cur\_size} and \\{cur\_mu}, based on \\{cur\_style}\X;\6
+\&{goto} \\{delete\_q};\6
+\4${}\}{}$\2\par
+\U761.\fi
+
+\M{764}The inter-element spacing in math formulas depends on a $8\times8$ table that
+\TeX\ preloads as a 64-digit string. The elements of this string have the
+following significance:
+$$\vbox{\halign{#\hfil\cr
+\.0 means no space;\cr
+\.1 means a conditional thin space (\.{\\nonscript\\mskip\\thinmuskip});\cr
+\.2 means a thin space (\.{\\mskip\\thinmuskip});\cr
+\.3 means a conditional medium space
+(\.{\\nonscript\\mskip\\medmuskip});\cr
+\.4 means a conditional thick space
+(\.{\\nonscript\\mskip\\thickmuskip});\cr
+\.* means an impossible case.\cr}}$$
+This is all pretty cryptic, but {\sl The \TeX book\/} explains what is
+supposed to happen, and the string makes it happen.
+
+A global variable \\{magic\_offset} is computed so that if \|a and \|b are
+in the range $\\{ord\_noad}\dotdot\\{inner\_noad}$, then $\\{str\_pool}[\|a*\T{8}+\|b+\\{magic\_offset}]$
+is the digit for spacing between noad types \|a and \|b.
+
+If \PASCAL\ had provided a good way to preload constant arrays, this part of
+the program would not have been so strange.
+
+\Y\B\4\D$\\{math\_spacing\_str}$ \6
+\hbox{\hskip-35pt}\.{"math\_spacing"}\hbox{$ \hskip-35pt$}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{magic\_offset};\C{used to find inter-element spacing}\par
+\fi
+
+\M{765}\B\X765:Compute the magic offset\X${}\E{}$\6
+$\\{magic\_offset}\K\\{str\_start}[\\{math\_spacing}]-\T{9}*{}$\\{ord\_noad}\par
+\U1337.\fi
+
+\M{766}\B\X766:Append inter-element spacing based on \\{r\_type} and \|t\X${}\E{}$\6
+\&{if} ${}(\\{r\_type}>\T{0}{}$)\C{not the first noad}\6
+${}\{{}$\5
+\1\&{switch} ${}(\\{so}(\\{str\_pool}[\\{r\_type}*\T{8}+\|t+\\{magic\_offset}])){}$\5
+${}\{{}$\1\6
+\4\&{case} \.{'0'}:\5
+${}\|x\K\T{0}{}$;\5
+\&{break};\6
+\4\&{case} \.{'1'}:\6
+\&{if} ${}(\\{cur\_style}<\\{script\_style}){}$\1\5
+${}\|x\K\\{thin\_mu\_skip\_code}{}$;\5
+\2\&{else}\1\5
+${}\|x\K\T{0}{}$;\5
+\2\&{break};\6
+\4\&{case} \.{'2'}:\5
+${}\|x\K\\{thin\_mu\_skip\_code}{}$;\5
+\&{break};\6
+\4\&{case} \.{'3'}:\6
+\&{if} ${}(\\{cur\_style}<\\{script\_style}){}$\1\5
+${}\|x\K\\{med\_mu\_skip\_code}{}$;\5
+\2\&{else}\1\5
+${}\|x\K\T{0}{}$;\5
+\2\&{break};\6
+\4\&{case} \.{'4'}:\6
+\&{if} ${}(\\{cur\_style}<\\{script\_style}){}$\1\5
+${}\|x\K\\{thick\_mu\_skip\_code}{}$;\5
+\2\&{else}\1\5
+${}\|x\K\T{0}{}$;\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1668:\.{"mlist4"}\X);\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|x\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\|y\K\\{math\_glue}(\\{glue\_par}(\|x),\39\\{cur\_mu});{}$\5
+${}\|z\K\\{new\_glue}(\|y);{}$\5
+${}\\{glue\_ref\_count}(\|y)\K\\{null};{}$\5
+${}\\{link}(\|p)\K\|z;{}$\5
+${}\|p\K\|z{}$;\6
+${}\\{subtype}(\|z)\K\|x+\T{1}{}$;\C{store a symbolic subtype}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U760.\fi
+
+\M{767}We insert a penalty node after the hlist entries of noad \|q if \\{pen}
+is not an ``infinite'' penalty, and if the node immediately following \|q
+is not a penalty node or a \\{rel\_noad} or absent entirely.
+
+\Y\B\4\X767:Append any \\{new\_hlist} entries for \|q, and any appropriate penalties\X${}\E{}$\6
+\&{if} ${}(\\{new\_hlist}(\|q)\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\\{new\_hlist}(\|q){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{link}(\|p)\E\\{null}));{}$\6
+\4${}\}{}$\2\6
+\&{if} (\\{penalties})\1\6
+\&{if} ${}(\\{link}(\|q)\I\\{null}){}$\1\6
+\&{if} ${}(\\{pen}<\\{inf\_penalty}){}$\5
+${}\{{}$\5
+\1${}\\{r\_type}\K\\{type}(\\{link}(\|q));{}$\6
+\&{if} ${}(\\{r\_type}\I\\{penalty\_node}){}$\1\6
+\&{if} ${}(\\{r\_type}\I\\{rel\_noad}){}$\5
+${}\{{}$\5
+\1${}\|z\K\\{new\_penalty}(\\{pen});{}$\5
+${}\\{link}(\|p)\K\|z;{}$\5
+${}\|p\K\|z;{}$\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\2\2\par
+\U760.\fi
+
+\N{1}{768}Alignment.
+It's sort of a miracle whenever \.{\\halign} and \.{\\valign} work, because
+they cut across so many of the control structures of \TeX.
+
+Therefore the
+present page is probably not the best place for a beginner to start reading
+this program; it is better to master everything else first.
+
+Let us focus our thoughts on an example of what the input might be, in order
+to get some idea about how the alignment miracle happens. The example doesn't
+do anything useful, but it is sufficiently general to indicate all of the
+special cases that must be dealt with; please do not be disturbed by its
+apparent complexity and meaninglessness.
+$$\vbox{\halign{\.{#}\hfil\cr
+{}\\tabskip 2pt plus 3pt\cr
+{}\\halign to 300pt\{u1\#v1\&\cr
+\hskip 50pt\\tabskip 1pt plus 1fil u2\#v2\&\cr
+\hskip 50pt u3\#v3\\cr\cr
+\hskip 25pt a1\&\\omit a2\&\\vrule\\cr\cr
+\hskip 25pt \\noalign\{\\vskip 3pt\}\cr
+\hskip 25pt b1\\span b2\\cr\cr
+\hskip 25pt \\omit\&c2\\span\\omit\\cr\}\cr}}$$
+Here's what happens:
+
+\yskip
+(0) When `\.{\\halign to 300pt\{}' is scanned, the \\{scan\_spec} routine
+places the 300pt dimension onto the \\{save\_stack}, and an \\{align\_group}
+code is placed above it. This will make it possible to complete the alignment
+when the matching `\.\}' is found.
+
+(1) The preamble is scanned next. Macros in the preamble are not expanded,
+except as part of a tabskip specification. For example, if \.{u2} had been
+a macro in the preamble above, it would have been expanded, since \TeX\
+must look for `\.{minus...}' as part of the tabskip glue. A ``preamble list''
+is constructed based on the user's preamble; in our case it contains the
+following seven items:
+$$\vbox{\halign{\.{#}\hfil\qquad&(#)\hfil\cr
+{}\\glue 2pt plus 3pt&the tabskip preceding column 1\cr
+{}\\alignrecord, width $-\infty$&preamble info for column 1\cr
+{}\\glue 2pt plus 3pt&the tabskip between columns 1 and 2\cr
+{}\\alignrecord, width $-\infty$&preamble info for column 2\cr
+{}\\glue 1pt plus 1fil&the tabskip between columns 2 and 3\cr
+{}\\alignrecord, width $-\infty$&preamble info for column 3\cr
+{}\\glue 1pt plus 1fil&the tabskip following column 3\cr}}$$
+These ``alignrecord'' entries have the same size as an \\{unset\_node},
+since they will later be converted into such nodes. However, at the
+moment they have no \\{type} or \\{subtype} fields; they have \\{info} fields
+instead, and these \\{info} fields are initially set to the value \\{end\_span},
+for reasons explained below. Furthermore, the alignrecord nodes have no
+\\{height} or \\{depth} fields; these are renamed \\{u\_part} and \\{v\_part},
+and they point to token lists for the templates of the alignment.
+For example, the \\{u\_part} field in the first alignrecord points to the
+token list `\.{u1}', i.e., the template preceding the `\.\#' for column~1.
+
+(2) \TeX\ now looks at what follows the \.{\\cr} that ended the preamble.
+It is not `\.{\\noalign}' or `\.{\\omit}', so this input is put back to
+be read again, and the template `\.{u1}' is fed to the scanner. Just
+before reading `\.{u1}', \TeX\ goes into restricted horizontal mode.
+Just after reading `\.{u1}', \TeX\ will see `\.{a1}', and then (when the
+{\.\&} is sensed) \TeX\ will see `\.{v1}'. Then \TeX\ scans an \\{endv}
+token, indicating the end of a column. At this point an \\{unset\_node} is
+created, containing the contents of the current hlist (i.e., `\.{u1a1v1}').
+The natural width of this unset node replaces the \\{width} field of the
+alignrecord for column~1; in general, the alignrecords will record the
+maximum natural width that has occurred so far in a given column.
+
+(3) Since `\.{\\omit}' follows the `\.\&', the templates for column~2
+are now bypassed. Again \TeX\ goes into restricted horizontal mode and
+makes an \\{unset\_node} from the resulting hlist; but this time the
+hlist contains simply `\.{a2}'. The natural width of the new unset box
+is remembered in the \\{width} field of the alignrecord for column~2.
+
+(4) A third \\{unset\_node} is created for column 3, using essentially the
+mechanism that worked for column~1; this unset box contains `\.{u3\\vrule
+v3}'. The vertical rule in this case has running dimensions that will later
+extend to the height and depth of the whole first row, since each \\{unset\_node}
+in a row will eventually inherit the height and depth of its enclosing box.
+
+(5) The first row has now ended; it is made into a single unset box
+comprising the following seven items:
+$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr
+{}\\glue 2pt plus 3pt\cr
+{}\\unsetbox for 1 column: u1a1v1\cr
+{}\\glue 2pt plus 3pt\cr
+{}\\unsetbox for 1 column: a2\cr
+{}\\glue 1pt plus 1fil\cr
+{}\\unsetbox for 1 column: u3\\vrule v3\cr
+{}\\glue 1pt plus 1fil\cr}}$$
+The width of this unset row is unimportant, but it has the correct height
+and depth, so the correct baselineskip glue will be computed as the row
+is inserted into a vertical list.
+
+(6) Since `\.{\\noalign}' follows the current \.{\\cr}, \TeX\ appends
+additional material (in this case \.{\\vskip 3pt}) to the vertical list.
+While processing this material, \TeX\ will be in internal vertical
+mode, and \\{no\_align\_group} will be on \\{save\_stack}.
+
+(7) The next row produces an unset box that looks like this:
+$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr
+{}\\glue 2pt plus 3pt\cr
+{}\\unsetbox for 2 columns: u1b1v1u2b2v2\cr
+{}\\glue 1pt plus 1fil\cr
+{}\\unsetbox for 1 column: {\rm(empty)}\cr
+{}\\glue 1pt plus 1fil\cr}}$$
+The natural width of the unset box that spans columns 1~and~2 is stored
+in a ``span node,'' which we will explain later; the \\{info} field of the
+alignrecord for column~1 now points to the new span node, and the \\{info}
+of the span node points to \\{end\_span}.
+
+(8) The final row produces the unset box
+$$\vbox{\halign{\hbox to 325pt{\qquad\.{#}\hfil}\cr
+{}\\glue 2pt plus 3pt\cr
+{}\\unsetbox for 1 column: {\rm(empty)}\cr
+{}\\glue 2pt plus 3pt\cr
+{}\\unsetbox for 2 columns: u2c2v2\cr
+{}\\glue 1pt plus 1fil\cr}}$$
+A new span node is attached to the alignrecord for column 2.
+
+(9) The last step is to compute the true column widths and to change all the
+unset boxes to hboxes, appending the whole works to the vertical list that
+encloses the \.{\\halign}. The rules for deciding on the final widths of
+each unset column box will be explained below.
+
+\yskip\noindent
+Note that as \.{\\halign} is being processed, we fearlessly give up control
+to the rest of \TeX. At critical junctures, an alignment routine is
+called upon to step in and do some little action, but most of the time
+these routines just lurk in the background. It's something like
+post-hypnotic suggestion.
+
+\fi
+
+\M{769}We have mentioned that alignrecords contain no \\{height} or \\{depth} fields.
+Their \\{glue\_sign} and \\{glue\_order} are pre-empted as well, since it
+is necessary to store information about what to do when a template ends.
+This information is called the \\{extra\_info} field.
+
+\Y\B\4\D$\\{u\_part}(\|X)$ \5
+$\\{mem}[\|X+\\{height\_offset}].{}$\|i\C{pointer to \<u_j> token list}\par
+\B\4\D$\\{v\_part}(\|X)$ \5
+$\\{mem}[\|X+\\{depth\_offset}].{}$\|i\C{pointer to \<v_j> token list}\par
+\B\4\D$\\{extra\_info}(\|X)$ \5
+$\\{info}(\|X+\\{list\_offset}{}$)\C{info to remember during template}\par
+\fi
+
+\M{770}Alignments can occur within alignments, so a small stack is used to access
+the alignrecord information. At each level we have a \\{preamble} pointer,
+indicating the beginning of the preamble list; a \\{cur\_align} pointer,
+indicating the current position in the preamble list; a \\{cur\_span} pointer,
+indicating the value of \\{cur\_align} at the beginning of a sequence of
+spanned columns; a \\{cur\_loop} pointer, indicating the tabskip glue before
+an alignrecord that should be copied next if the current list is extended;
+and the \\{align\_state} variable, which indicates the nesting of braces so
+that \.{\\cr} and \.{\\span} and tab marks are properly intercepted.
+There also are pointers \\{cur\_head} and \\{cur\_tail} to the head and tail
+of a list of adjustments being moved out from horizontal mode to
+vertical~mode.
+
+The current values of these seven quantities appear in global variables;
+when they have to be pushed down, they are stored in 5-word nodes, and
+\\{align\_ptr} points to the topmost such node.
+
+\Y\B\4\D$\\{preamble}$ \5
+\\{link}(\\{align\_head})\C{the current preamble list}\par
+\B\4\D$\\{align\_stack\_node\_size}$ \5
+\T{5}\C{number of \\{mem} words to save alignment states}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{cur\_align};\C{current position in preamble list}\6
+\&{pointer} \\{cur\_span};\C{start of currently spanned columns in preamble list}\6
+\&{pointer} \\{cur\_loop};\C{place to copy when extending a periodic preamble}\6
+\&{pointer} \\{align\_ptr};\C{most recently pushed-down alignment stack node}\6
+\&{pointer} \\{cur\_head}${},{}$ \\{cur\_tail};\C{adjustment list pointers}\par
+\fi
+
+\M{771}The \\{align\_state} and \\{preamble} variables are initialized elsewhere.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{align\_ptr}\K\\{null};{}$\5
+${}\\{cur\_align}\K\\{null};{}$\5
+${}\\{cur\_span}\K\\{null};{}$\5
+${}\\{cur\_loop}\K\\{null};{}$\5
+${}\\{cur\_head}\K\\{null};{}$\5
+${}\\{cur\_tail}\K\\{null}{}$;\par
+\fi
+
+\M{772}Alignment stack maintenance is handled by a pair of trivial routines
+called \\{push\_alignment} and \\{pop\_alignment}.
+
+\Y\B\&{void} \\{push\_alignment}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new alignment stack node}\7
+${}\|p\K\\{get\_node}(\\{align\_stack\_node\_size});{}$\5
+${}\\{link}(\|p)\K\\{align\_ptr};{}$\5
+${}\\{info}(\|p)\K\\{cur\_align};{}$\5
+${}\\{llink}(\|p)\K\\{preamble};{}$\5
+${}\\{rlink}(\|p)\K\\{cur\_span};{}$\5
+${}\\{mem}[\|p+\T{2}].\|i\K\\{cur\_loop};{}$\5
+${}\\{mem}[\|p+\T{3}].\|i\K\\{align\_state};{}$\5
+${}\\{info}(\|p+\T{4})\K\\{cur\_head};{}$\5
+${}\\{link}(\|p+\T{4})\K\\{cur\_tail};{}$\5
+${}\\{align\_ptr}\K\|p;{}$\5
+${}\\{cur\_head}\K\\{get\_avail}(\,);{}$\6
+\4${}\}{}$\2\7
+\&{void} \\{pop\_alignment}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the top alignment stack node}\7
+\\{free\_avail}(\\{cur\_head});\5
+${}\|p\K\\{align\_ptr};{}$\5
+${}\\{cur\_tail}\K\\{link}(\|p+\T{4});{}$\5
+${}\\{cur\_head}\K\\{info}(\|p+\T{4});{}$\5
+${}\\{align\_state}\K\\{mem}[\|p+\T{3}].\|i;{}$\5
+${}\\{cur\_loop}\K\\{mem}[\|p+\T{2}].\|i;{}$\5
+${}\\{cur\_span}\K\\{rlink}(\|p);{}$\5
+${}\\{preamble}\K\\{llink}(\|p);{}$\5
+${}\\{cur\_align}\K\\{info}(\|p);{}$\5
+${}\\{align\_ptr}\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\|p,\39\\{align\_stack\_node\_size});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{773}\TeX\ has eight procedures that govern alignments: \\{init\_align} and
+\\{fin\_align} are used at the very beginning and the very end; \\{init\_row} and
+\\{fin\_row} are used at the beginning and end of individual rows; \\{init\_span}
+is used at the beginning of a sequence of spanned columns (possibly involving
+only one column); \\{init\_col} and \\{fin\_col} are used at the beginning and
+end of individual columns; and \\{align\_peek} is used after \.{\\cr} to see
+whether the next item is \.{\\noalign}.
+
+We shall consider these routines in the order they are first used during
+the course of a complete \.{\\halign}, namely \\{init\_align}, \\{align\_peek},
+\\{init\_row}, \\{init\_span}, \\{init\_col}, \\{fin\_col}, \\{fin\_row}, \\{fin\_align}.
+
+\fi
+
+\M{774}When \.{\\halign} or \.{\\valign} has been scanned in an appropriate
+mode, \TeX\ calls \\{init\_align}, whose task is to get everything off to a
+good start. This mostly involves scanning the preamble and putting its
+information into the preamble list.
+
+\Y\B\hbox{\4}\X782:Declare the procedure called \\{get\_preamble\_token}\X\hbox{}\1\1\6
+\&{void} \\{align\_peek}(\&{void});\6
+\&{void} \\{normal\_paragraph}(\&{void});\6
+\&{void} \\{init\_align}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \\{save\_cs\_ptr};\C{\\{warning\_index} value for error messages}\6
+\&{pointer} \|p;\C{for short-term temporary use}\7
+${}\\{save\_cs\_ptr}\K\\{cur\_cs}{}$;\C{\.{\\halign} or \.{\\valign}, usually}\6
+\\{push\_alignment}(\,);\5
+${}\\{align\_state}\K{-}\T{1000000}{}$;\C{enter a new alignment level}\6
+\X776:Check for improper alignment in displayed math\X;\6
+\\{push\_nest}(\,);\C{enter a new semantic level}\6
+\X775:Change current mode to ${-}\\{vmode}$ for \.{\\halign}, ${-}\\{hmode}$ for \.{\\valign}\X;\6
+${}\\{scan\_spec}(\\{align\_group},\39\\{false}){}$;\6
+\X777:Scan the preamble and record it in the \\{preamble} list\X;\6
+\\{new\_save\_level}(\\{align\_group});\6
+\&{if} ${}(\\{every\_cr}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_cr},\39\\{every\_cr\_text});{}$\2\6
+\\{align\_peek}(\,);\C{look for \.{\\noalign} or \.{\\omit}}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{775}In vertical modes, \\{prev\_depth} already has the correct value. But
+if we are in \\{mmode} (displayed formula mode), we reach out to the
+enclosing vertical mode for the \\{prev\_depth} value that produces the
+correct baseline calculations.
+
+\Y\B\4\X775:Change current mode to ${-}\\{vmode}$ for \.{\\halign}, ${-}\\{hmode}$ for \.{\\valign}\X${}\E{}$\6
+\&{if} ${}(\\{mode}\E\\{mmode}){}$\5
+${}\{{}$\5
+\1${}\\{mode}\K{-}\\{vmode};{}$\5
+${}\\{prev\_depth}\K\\{nest}[\\{nest\_ptr}-\T{2}].\\{aux\_field}.\\{sc};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{mode}>\T{0})$ \\{negate}(\\{mode})\par
+\U774.\fi
+
+\M{776}When \.{\\halign} is used as a displayed formula, there should be
+no other pieces of mlists present.
+
+\Y\B\4\X776:Check for improper alignment in displayed math\X${}\E{}$\6
+\&{if} ${}((\\{mode}\E\\{mmode})\W((\\{tail}\I\\{head})\V(\\{incompleat\_noad}\I\\{null}))){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ "});\5
+\\{print\_esc}(\X1542:\.{"halign"}\X);\5
+\\{print\_str}(\.{"\ inside\ \$\$'s"});\5
+\\{help3}(\.{"Displays\ can\ use\ sp}\)\.{ecial\ alignments\ (li}\)\.{ke\ \\\\eqalignno)"})\6
+(\.{"only\ if\ nothing\ but}\)\.{\ the\ alignment\ itsel}\)\.{f\ is\ between\ \$\$'s."})\6
+(\.{"So\ I've\ deleted\ the}\)\.{\ formulas\ that\ prece}\)\.{ded\ this\ alignment."});\6
+\&{error} (\,)\1\5
+;\2\6
+\\{flush\_math}(\,);\6
+\4${}\}{}$\2\par
+\U774.\fi
+
+\M{777}\B\X777:Scan the preamble and record it in the \\{preamble} list\X${}\E{}$\6
+$\\{preamble}\K\\{null};{}$\5
+${}\\{cur\_align}\K\\{align\_head};{}$\5
+${}\\{cur\_loop}\K\\{null};{}$\5
+${}\\{scanner\_status}\K\\{aligning};{}$\5
+${}\\{warning\_index}\K\\{save\_cs\_ptr};{}$\5
+${}\\{align\_state}\K{-}\T{1000000}{}$;\C{at this point, $\\{cur\_cmd}\E\\{left\_brace}$}\6
+\&{loop}\5
+${}\{{}$\5
+\1\X778:Append the current tabskip glue to the preamble list\X;\6
+\&{if} ${}(\\{cur\_cmd}\E\\{car\_ret}){}$\1\5
+\&{goto} \\{done};\C{\.{\\cr} ends the preamble}\2\6
+\X779:Scan preamble text until \\{cur\_cmd} is \\{tab\_mark} or \\{car\_ret}, looking for changes in the tabskip glue; append an alignrecord to the preamble list\X;\6
+\4${}\}{}$\2\6
+\\{done}: $\\{scanner\_status}\K{}$\\{normal}\par
+\U774.\fi
+
+\M{778}\B\X778:Append the current tabskip glue to the preamble list\X${}\E{}$\6
+$\\{link}(\\{cur\_align})\K\\{new\_param\_glue}(\\{tab\_skip\_code});$ $\\{cur\_align}\K\\{link}{}$(\\{cur\_align})\par
+\U777.\fi
+
+\M{779}\B\X779:Scan preamble text until \\{cur\_cmd} is \\{tab\_mark} or \\{car\_ret}, looking for changes in the tabskip glue; append an alignrecord to the preamble list\X${}\E{}$\6
+\X783:Scan the template \<u_j>, putting the resulting token list in \\{hold\_head}\X;\6
+${}\\{link}(\\{cur\_align})\K\\{new\_null\_box}(\,);{}$\5
+${}\\{cur\_align}\K\\{link}(\\{cur\_align}){}$;\C{a new alignrecord}\6
+${}\\{info}(\\{cur\_align})\K\\{end\_span};{}$\5
+${}\\{width}(\\{cur\_align})\K\\{null\_flag};{}$\5
+${}\\{u\_part}(\\{cur\_align})\K\\{link}(\\{hold\_head});{}$\5
+\X784:Scan the template \<v_j>, putting the resulting token list in \\{hold\_head}\X;\6
+$\\{v\_part}(\\{cur\_align})\K\\{link}{}$(\\{hold\_head})\par
+\U777.\fi
+
+\M{780}We enter `\.{\\span}' into \\{eqtb} with \\{tab\_mark} as its command code,
+and with \\{span\_code} as the command modifier. This makes \TeX\ interpret it
+essentially the same as an alignment delimiter like `\.\&', yet it is
+recognizably different when we need to distinguish it from a normal delimiter.
+It also turns out to be useful to give a special \\{cr\_code} to `\.{\\cr}',
+and an even larger \\{cr\_cr\_code} to `\.{\\crcr}'.
+
+The end of a template is represented by two ``frozen'' control sequences
+called \.{\\endtemplate}. The first has the command code \\{end\_template}, which
+is $>$ \\{outer\_call}, so it will not easily disappear in the presence of errors.
+The \\{get\_x\_token} routine converts the first into the second, which has \\{endv}
+as its command code.
+
+\Y\B\4\D$\\{span\_code}$ \5
+\T{256}\C{distinct from any character}\par
+\B\4\D$\\{cr\_code}$ \5
+\T{257}\C{distinct from \\{span\_code} and from any character}\par
+\B\4\D$\\{cr\_cr\_code}$ \5
+$(\\{cr\_code}+\T{1}{}$)\C{this distinguishes \.{\\crcr} from \.{\\cr}}\par
+\B\4\D$\\{end\_template\_token}$ \5
+$\\{cs\_token\_flag}+{}$\\{frozen\_end\_template}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1669:\.{"span"}\X,\39\\{tab\_mark},\39\\{span\_code}){}$;\6
+${}\\{primitive}(\X1670:\.{"cr"}\X,\39\\{car\_ret},\39\\{cr\_code});{}$\5
+${}\\{text}(\\{frozen\_cr})\K\X1670:\.{"cr"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_cr}]\K\\{eqtb}[\\{cur\_val}]{}$;\6
+${}\\{primitive}(\X1671:\.{"crcr"}\X,\39\\{car\_ret},\39\\{cr\_cr\_code});{}$\5
+${}\\{text}(\\{frozen\_end\_template})\K\X1672:\.{"endtemplate"}\X;{}$\5
+${}\\{text}(\\{frozen\_endv})\K\X1672:\.{"endtemplate"}\X;{}$\5
+${}\\{eq\_type}(\\{frozen\_endv})\K\\{endv};{}$\5
+${}\\{equiv}(\\{frozen\_endv})\K\\{null\_list};{}$\5
+${}\\{eq\_level}(\\{frozen\_endv})\K\\{level\_one}{}$;\6
+${}\\{eqtb}[\\{frozen\_end\_template}]\K\\{eqtb}[\\{frozen\_endv}];{}$\5
+${}\\{eq\_type}(\\{frozen\_end\_template})\K\\{end\_template}{}$;\par
+\fi
+
+\M{781}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{tab\_mark}:\6
+\&{if} ${}(\\{chr\_code}\E\\{span\_code}){}$\1\5
+\\{print\_esc}(\X1669:\.{"span"}\X);\2\6
+\&{else}\1\5
+\\{chr\_cmd}(\.{"alignment\ tab\ chara}\)\.{cter\ "})\5
+\2\&{break};\6
+\4\&{case} \\{car\_ret}:\6
+\&{if} ${}(\\{chr\_code}\E\\{cr\_code}){}$\1\5
+\\{print\_esc}(\X1670:\.{"cr"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1671:\.{"crcr"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{782}The preamble is copied directly, except that \.{\\tabskip} causes a change
+to the tabskip glue, thereby possibly expanding macros that immediately
+follow it. An appearance of \.{\\span} also causes such an expansion.
+
+Note that if the preamble contains `\.{\\global\\tabskip}', the `\.{\\global}'
+token survives in the preamble and the `\.{\\tabskip}' defines new
+tabskip glue (locally).
+
+\Y\B\4\X782:Declare the procedure called \\{get\_preamble\_token}\X${}\E{}$\6
+\&{void} \\{get\_preamble\_token}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{restart}:\5
+\\{get\_token}(\,);\6
+\&{while} ${}((\\{cur\_chr}\E\\{span\_code})\W(\\{cur\_cmd}\E\\{tab\_mark})){}$\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\C{this token will be expanded once}\6
+\&{if} ${}(\\{cur\_cmd}>\\{max\_command}){}$\5
+${}\{{}$\5
+\1\\{expand}(\,);\5
+\\{get\_token}(\,);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{endv}){}$\1\5
+\\{fatal\_error}(\.{"(interwoven\ alignme}\)\.{nt\ preambles\ are\ not}\)\.{\ allowed)"});\2\6
+\&{if} ${}((\\{cur\_cmd}\E\\{assign\_glue})\W(\\{cur\_chr}\E\\{glue\_base}+\\{tab\_skip\_code})){}$\5
+${}\{{}$\5
+\1\\{scan\_optional\_equals}(\,);\5
+\\{scan\_glue}(\\{glue\_val});\6
+\&{if} ${}(\\{global\_defs}>\T{0}){}$\1\5
+${}\\{geq\_define}(\\{glue\_base}+\\{tab\_skip\_code},\39\\{glue\_ref},\39\\{cur\_val});{}$\2\6
+\&{else}\1\5
+${}\\{eq\_define}(\\{glue\_base}+\\{tab\_skip\_code},\39\\{glue\_ref},\39\\{cur\_val});{}$\2\6
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U774.\fi
+
+\M{783}Spaces are eliminated from the beginning of a template.
+
+\Y\B\4\X783:Scan the template \<u_j>, putting the resulting token list in \\{hold\_head}\X${}\E{}$\6
+$\|p\K\\{hold\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_preamble\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\E\\{mac\_param}){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}((\\{cur\_cmd}\Z\\{car\_ret})\W(\\{cur\_cmd}\G\\{tab\_mark})\W(\\{align\_state}\E{-}\T{1000000})){}$\1\6
+\&{if} ${}((\|p\E\\{hold\_head})\W(\\{cur\_loop}\E\\{null})\W(\\{cur\_cmd}\E\\{tab\_mark})){}$\1\5
+${}\\{cur\_loop}\K\\{cur\_align};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \#\ inserted\ }\)\.{in\ alignment\ preambl}\)\.{e"});\5
+\\{help3}(\.{"There\ should\ be\ exa}\)\.{ctly\ one\ \#\ between\ \&}\)\.{'s,\ when\ an"})\6
+(\.{"\\\\halign\ or\ \\\\valig}\)\.{n\ is\ being\ set\ up.\ I}\)\.{n\ this\ case\ you\ had"})\6
+(\.{"none,\ so\ I've\ put\ o}\)\.{ne\ in;\ maybe\ that\ wi}\)\.{ll\ work."});\5
+\\{back\_error}(\,);\5
+\&{goto} \\{done1};\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}((\\{cur\_cmd}\I\\{spacer})\V(\|p\I\\{hold\_head})){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\\{get\_avail}(\,);{}$\5
+${}\|p\K\\{link}(\|p);{}$\5
+${}\\{info}(\|p)\K\\{cur\_tok};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\\{done1}:\par
+\U779.\fi
+
+\M{784}\B\X784:Scan the template \<v_j>, putting the resulting token list in \\{hold\_head}\X${}\E{}$\6
+$\|p\K\\{hold\_head};{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{resume}:\5
+\\{get\_preamble\_token}(\,);\6
+\&{if} ${}((\\{cur\_cmd}\Z\\{car\_ret})\W(\\{cur\_cmd}\G\\{tab\_mark})\W(\\{align\_state}\E{-}\T{1000000})){}$\1\5
+\&{goto} \\{done2};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{mac\_param}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Only\ one\ \#\ is\ allow}\)\.{ed\ per\ tab"});\5
+\\{help3}(\.{"There\ should\ be\ exa}\)\.{ctly\ one\ \#\ between\ \&}\)\.{'s,\ when\ an"})\6
+(\.{"\\\\halign\ or\ \\\\valig}\)\.{n\ is\ being\ set\ up.\ I}\)\.{n\ this\ case\ you\ had"})\6
+(\.{"more\ than\ one,\ so\ I}\)\.{'m\ ignoring\ all\ but\ }\)\.{the\ first."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\6
+${}\\{link}(\|p)\K\\{get\_avail}(\,);{}$\5
+${}\|p\K\\{link}(\|p);{}$\5
+${}\\{info}(\|p)\K\\{cur\_tok};{}$\6
+\4${}\}{}$\2\6
+\4\\{done2}:\5
+${}\\{link}(\|p)\K\\{get\_avail}(\,);{}$\5
+${}\|p\K\\{link}(\|p);$ $\\{info}(\|p)\K{}$\\{end\_template\_token}\C{put \.{\\endtemplate} at the end}\par
+\U779.\fi
+
+\M{785}The tricky part about alignments is getting the templates into the
+scanner at the right time, and recovering control when a row or column
+is finished.
+
+We usually begin a row after each \.{\\cr} has been sensed, unless that
+\.{\\cr} is followed by \.{\\noalign} or by the right brace that terminates
+the alignment. The \\{align\_peek} routine is used to look ahead and do
+the right thing; it either gets a new row started, or gets a \.{\\noalign}
+started, or finishes off the alignment.
+
+\Y\B\4\X785:Declare the procedure called \\{align\_peek}\X${}\E{}$\6
+\&{void} \\{align\_peek}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{restart}:\5
+${}\\{align\_state}\K\T{1000000};{}$\5
+\X406:Get the next non-blank non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\E\\{no\_align}){}$\5
+${}\{{}$\5
+\1\\{scan\_left\_brace}(\,);\5
+\\{new\_save\_level}(\\{no\_align\_group});\6
+\&{if} ${}(\\{mode}\E{-}\\{vmode}){}$\1\5
+\\{normal\_paragraph}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{right\_brace}){}$\1\5
+\\{fin\_align}(\,);\2\6
+\&{else} \&{if} ${}((\\{cur\_cmd}\E\\{car\_ret})\W(\\{cur\_chr}\E\\{cr\_cr\_code})){}$\1\5
+\&{goto} \\{restart};\C{ignore \.{\\crcr}}\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{init\_row}(\,);\C{start a new row}\6
+\\{init\_col}(\,);\C{start a new column and replace what we peeked at}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U800.\fi
+
+\M{786}To start a row (i.e., a `row' that rhymes with `dough' but not with `bough'),
+we enter a new semantic level, copy the first tabskip glue, and change
+from internal vertical mode to restricted horizontal mode or vice versa.
+The \\{space\_factor} and \\{prev\_depth} are not used on this semantic level,
+but we clear them to zero just to be tidy.
+
+\Y\B\hbox{\4}\X787:Declare the procedure called \\{init\_span}\X\hbox{}\1\1\6
+\&{void} \\{init\_row}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{push\_nest}(\,);\5
+${}\\{mode}\K({-}\\{hmode}-\\{vmode})-\\{mode};{}$\6
+\&{if} ${}(\\{mode}\E{-}\\{hmode}){}$\1\5
+${}\\{space\_factor}\K\T{0}{}$;\5
+\2\&{else}\1\5
+${}\\{prev\_depth}\K\T{0};{}$\2\6
+\\{tail\_append}(\\{new\_glue}(\\{glue\_ptr}(\\{preamble})));\5
+${}\\{subtype}(\\{tail})\K\\{tab\_skip\_code}+\T{1}{}$;\6
+${}\\{cur\_align}\K\\{link}(\\{preamble});{}$\5
+${}\\{cur\_tail}\K\\{cur\_head};{}$\5
+\\{init\_span}(\\{cur\_align});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{787}The parameter to \\{init\_span} is a pointer to the alignrecord where the
+next column or group of columns will begin. A new semantic level is
+entered, so that the columns will generate a list for subsequent packaging.
+
+\Y\B\4\X787:Declare the procedure called \\{init\_span}\X${}\E{}$\6
+\&{void} \\{init\_span}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\\{push\_nest}(\,);\6
+\&{if} ${}(\\{mode}\E{-}\\{hmode}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{prev\_depth}\K\\{ignore\_depth};{}$\5
+\\{normal\_paragraph}(\,);\6
+\4${}\}{}$\2\6
+${}\\{cur\_span}\K\|p;{}$\6
+\4${}\}{}$\2\par
+\U786.\fi
+
+\M{788}When a column begins, we assume that \\{cur\_cmd} is either \\{omit} or else
+the current token should be put back into the input until the \<u_j>
+template has been scanned. (Note that \\{cur\_cmd} might be \\{tab\_mark} or
+\\{car\_ret}.) We also assume that \\{align\_state} is approximately 1000000 at
+this time. We remain in the same mode, and start the template if it is
+called for.
+
+\Y\B\&{void} \\{init\_col}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{extra\_info}(\\{cur\_align})\K\\{cur\_cmd};{}$\6
+\&{if} ${}(\\{cur\_cmd}\E\\{omit}){}$\1\5
+${}\\{align\_state}\K\T{0};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\\{begin\_token\_list}(\\{u\_part}(\\{cur\_align}),\39\\{u\_template});{}$\6
+\4${}\}{}$\C{now $\\{align\_state}\E\T{1000000}$}\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{789}The scanner sets \\{align\_state} to zero when the \<u_j> template ends. When
+a subsequent \.{\\cr} or \.{\\span} or tab mark occurs with $\\{align\_state}\E\T{0}$,
+the scanner activates the following code, which fires up the \<v_j> template.
+We need to remember the \\{cur\_chr}, which is either \\{cr\_cr\_code}, \\{cr\_code},
+\\{span\_code}, or a character code, depending on how the column text has ended.
+
+This part of the program had better not be activated when the preamble
+to another alignment is being scanned, or when no alignment preamble is active.
+
+\Y\B\4\X789:Insert the \(v)\<v_j> template and \&{goto} \\{restart}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\\{scanner\_status}\E\\{aligning})\V(\\{cur\_align}\E\\{null})){}$\1\5
+\\{fatal\_error}(\.{"(interwoven\ alignme}\)\.{nt\ preambles\ are\ not}\)\.{\ allowed)"});\2\6
+${}\\{cur\_cmd}\K\\{extra\_info}(\\{cur\_align});{}$\5
+${}\\{extra\_info}(\\{cur\_align})\K\\{cur\_chr};{}$\6
+\&{if} ${}(\\{cur\_cmd}\E\\{omit}){}$\1\5
+${}\\{begin\_token\_list}(\\{omit\_template},\39\\{v\_template});{}$\2\6
+\&{else}\1\5
+${}\\{begin\_token\_list}(\\{v\_part}(\\{cur\_align}),\39\\{v\_template});{}$\2\6
+${}\\{align\_state}\K\T{1000000};{}$\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\par
+\U342.\fi
+
+\M{790}The token list \\{omit\_template} just referred to is a constant token
+list that contains the special control sequence \.{\\endtemplate} only.
+
+\Y\B\4\X790:Initialize the special list heads and constant nodes\X${}\E{}$\6
+$\\{info}(\\{omit\_template})\K\\{end\_template\_token}{}$;\C{$\\{link}(\\{omit\_template})\E\\{null}$}\par
+\As797, 820, 981\ETs988.
+\U164.\fi
+
+\M{791}When the \\{endv} command at the end of a \<v_j> template comes through the
+scanner, things really start to happen; and it is the \\{fin\_col} routine
+that makes them happen. This routine returns \\{true} if a row as well as a
+column has been finished.
+
+\Y\B\&{bool} \\{fin\_col}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the alignrecord after the current one}\6
+\&{pointer} \|q${},{}$ \|r;\C{temporary pointers for list manipulation}\6
+\&{pointer} \|s;\C{a new span node}\6
+\&{pointer} \|u;\C{a new unset box}\6
+\&{scaled} \|w;\C{natural width}\6
+\&{glue\_ord} \|o;\C{order of infinity}\6
+\&{halfword} \|n;\C{span counter}\7
+\&{if} ${}(\\{cur\_align}\E\\{null}){}$\1\5
+\\{confusion}(\X1673:\.{"endv"}\X);\2\6
+${}\|q\K\\{link}(\\{cur\_align}){}$;\5
+\&{if} ${}(\|q\E\\{null}){}$\1\5
+\\{confusion}(\X1673:\.{"endv"}\X);\2\6
+\&{if} ${}(\\{align\_state}<\T{500000}){}$\1\5
+\\{fatal\_error}(\.{"(interwoven\ alignme}\)\.{nt\ preambles\ are\ not}\)\.{\ allowed)"});\2\6
+${}\|p\K\\{link}(\|q);{}$\5
+\X792:If the preamble list has been traversed, check that the row has ended\X;\6
+\&{if} ${}(\\{extra\_info}(\\{cur\_align})\I\\{span\_code}){}$\5
+${}\{{}$\5
+\1\\{unsave}(\,);\5
+\\{new\_save\_level}(\\{align\_group});\6
+\X796:Package an unset box for the current column and record its width\X;\6
+\X795:Copy the tabskip glue between columns\X;\6
+\&{if} ${}(\\{extra\_info}(\\{cur\_align})\G\\{cr\_code}){}$\5
+${}\{{}$\5
+\1\&{return} \\{true};\6
+\4${}\}{}$\2\6
+\\{init\_span}(\|p);\6
+\4${}\}{}$\2\6
+${}\\{align\_state}\K\T{1000000};{}$\5
+\X406:Get the next non-blank non-call token\X;\6
+${}\\{cur\_align}\K\|p;{}$\5
+\\{init\_col}(\,);\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{792}\B\X792:If the preamble list has been traversed, check that the row has ended\X${}\E{}$\6
+\&{if} ${}((\|p\E\\{null})\W(\\{extra\_info}(\\{cur\_align})<\\{cr\_code})){}$\1\6
+\&{if} ${}(\\{cur\_loop}\I\\{null}){}$\1\5
+\X793:Lengthen the preamble periodically\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Extra\ alignment\ tab}\)\.{\ has\ been\ changed\ to}\)\.{\ "});\5
+\\{print\_esc}(\X1670:\.{"cr"}\X);\5
+\\{help3}(\.{"You\ have\ given\ more}\)\.{\ \\\\span\ or\ \&\ marks\ t}\)\.{han\ there\ were"})\6
+(\.{"in\ the\ preamble\ to\ }\)\.{the\ \\\\halign\ or\ \\\\va}\)\.{lign\ now\ in\ progress}\)\.{."})\6
+(\.{"So\ I'll\ assume\ that}\)\.{\ you\ meant\ to\ type\ \\}\)\.{\\cr\ instead."});\5
+${}\\{extra\_info}(\\{cur\_align})\K\\{cr\_code};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\2\par
+\U791.\fi
+
+\M{793}\B\X793:Lengthen the preamble periodically\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{new\_null\_box}(\,);{}$\5
+${}\|p\K\\{link}(\|q){}$;\C{a new alignrecord}\6
+${}\\{info}(\|p)\K\\{end\_span};{}$\5
+${}\\{width}(\|p)\K\\{null\_flag};{}$\5
+${}\\{cur\_loop}\K\\{link}(\\{cur\_loop});{}$\5
+\X794:Copy the templates from node \\{cur\_loop} into node \|p\X;\6
+${}\\{cur\_loop}\K\\{link}(\\{cur\_loop});{}$\5
+${}\\{link}(\|p)\K\\{new\_glue}(\\{glue\_ptr}(\\{cur\_loop}));{}$\6
+\4${}\}{}$\2\par
+\U792.\fi
+
+\M{794}\B\X794:Copy the templates from node \\{cur\_loop} into node \|p\X${}\E{}$\6
+$\|q\K\\{hold\_head};{}$\5
+${}\|r\K\\{u\_part}(\\{cur\_loop});{}$\6
+\&{while} ${}(\|r\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{get\_avail}(\,);{}$\5
+${}\|q\K\\{link}(\|q);{}$\5
+${}\\{info}(\|q)\K\\{info}(\|r);{}$\5
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\\{u\_part}(\|p)\K\\{link}(\\{hold\_head});{}$\5
+${}\|q\K\\{hold\_head};{}$\5
+${}\|r\K\\{v\_part}(\\{cur\_loop});{}$\6
+\&{while} ${}(\|r\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{get\_avail}(\,);{}$\5
+${}\|q\K\\{link}(\|q);{}$\5
+${}\\{info}(\|q)\K\\{info}(\|r);{}$\5
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\|q)\K\\{null};$ $\\{v\_part}(\|p)\K\\{link}{}$(\\{hold\_head})\par
+\U793.\fi
+
+\M{795}\B\X795:Copy the tabskip glue between columns\X${}\E{}$\6
+\\{tail\_append}(\\{new\_glue}(\\{glue\_ptr}(\\{link}(\\{cur\_align})))); $\\{subtype}(\\{tail})\K\\{tab\_skip\_code}+{}$\T{1}\par
+\U791.\fi
+
+\M{796}\B\X796:Package an unset box for the current column and record its width\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{mode}\E{-}\\{hmode}){}$\5
+${}\{{}$\5
+\1${}\\{adjust\_tail}\K\\{cur\_tail};{}$\5
+${}\|u\K\\{hpack}(\\{link}(\\{head}),\39\\{natural});{}$\5
+${}\|w\K\\{width}(\|u);{}$\5
+${}\\{cur\_tail}\K\\{adjust\_tail};{}$\5
+${}\\{adjust\_tail}\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|u\K\\{vpackage}(\\{link}(\\{head}),\39\\{natural},\39\T{0});{}$\5
+${}\|w\K\\{height}(\|u);{}$\6
+\4${}\}{}$\2\6
+${}\|n\K\\{min\_quarterword}{}$;\C{this represents a span count of 1}\6
+\&{if} ${}(\\{cur\_span}\I\\{cur\_align}){}$\1\5
+\X798:Update width entry for spanned columns\X\2\6
+\&{else} \&{if} ${}(\|w>\\{width}(\\{cur\_align})){}$\1\5
+${}\\{width}(\\{cur\_align})\K\|w;{}$\2\6
+${}\\{type}(\|u)\K\\{unset\_node};{}$\5
+${}\\{span\_count}(\|u)\K\|n{}$;\6
+\X659:Determine the stretch order\X;\6
+${}\\{glue\_order}(\|u)\K\|o;{}$\5
+${}\\{glue\_stretch}(\|u)\K\\{total\_stretch}[\|o]{}$;\6
+\X665:Determine the shrink order\X;\6
+${}\\{glue\_sign}(\|u)\K\|o;{}$\5
+${}\\{glue\_shrink}(\|u)\K\\{total\_shrink}[\|o]{}$;\6
+\\{pop\_nest}(\,);\5
+${}\\{link}(\\{tail})\K\|u;{}$\5
+${}\\{tail}\K\|u;{}$\6
+\4${}\}{}$\2\par
+\U791.\fi
+
+\M{797}A span node is a 2-word record containing \\{width}, \\{info}, and \\{link}
+fields. The \\{link} field is not really a link, it indicates the number of
+spanned columns; the \\{info} field points to a span node for the same
+starting column, having a greater extent of spanning, or to \\{end\_span},
+which has the largest possible \\{link} field; the \\{width} field holds the
+largest natural width corresponding to a particular set of spanned columns.
+
+A list of the maximum widths so far, for spanned columns starting at a
+given column, begins with the \\{info} field of the alignrecord for that
+column.
+
+\Y\B\4\D$\\{span\_node\_size}$ \5
+\T{2}\C{number of \\{mem} words for a span node}\par
+\Y\B\4\X790:Initialize the special list heads and constant nodes\X${}\mathrel+\E{}$\6
+$\\{link}(\\{end\_span})\K\\{max\_quarterword}+\T{1};{}$\5
+${}\\{info}(\\{end\_span})\K\\{null}{}$;\par
+\fi
+
+\M{798}\B\X798:Update width entry for spanned columns\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{cur\_span}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\\{incr}(\|n);\5
+${}\|q\K\\{link}(\\{link}(\|q));{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{cur\_align}));{}$\6
+\&{if} ${}(\|n>\\{max\_quarterword}){}$\1\5
+\\{confusion}(\X1674:\.{"256\ spans"}\X);\C{this can happen, but won't}\2\6
+${}\|q\K\\{cur\_span};{}$\6
+\&{while} ${}(\\{link}(\\{info}(\|q))<\|n){}$\1\5
+${}\|q\K\\{info}(\|q);{}$\2\6
+\&{if} ${}(\\{link}(\\{info}(\|q))>\|n){}$\5
+${}\{{}$\5
+\1${}\|s\K\\{get\_node}(\\{span\_node\_size});{}$\5
+${}\\{info}(\|s)\K\\{info}(\|q);{}$\5
+${}\\{link}(\|s)\K\|n;{}$\5
+${}\\{info}(\|q)\K\|s;{}$\5
+${}\\{width}(\|s)\K\|w;{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{width}(\\{info}(\|q))<\|w){}$\1\5
+${}\\{width}(\\{info}(\|q))\K\|w;{}$\2\6
+\4${}\}{}$\2\par
+\U796.\fi
+
+\M{799}At the end of a row, we append an unset box to the current vlist (for
+\.{\\halign}) or the current hlist (for \.{\\valign}). This unset box
+contains the unset boxes for the columns, separated by the tabskip glue.
+Everything will be set later.
+
+\Y\B\&{void} \\{fin\_row}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new unset box}\7
+\&{if} ${}(\\{mode}\E{-}\\{hmode}){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{hpack}(\\{link}(\\{head}),\39\\{natural});{}$\5
+\\{pop\_nest}(\,);\5
+\\{append\_to\_vlist}(\|p);\6
+\&{if} ${}(\\{cur\_head}\I\\{cur\_tail}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\\{link}(\\{cur\_head});{}$\5
+${}\\{tail}\K\\{cur\_tail};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{vpack}(\\{link}(\\{head}),\39\\{natural});{}$\5
+\\{pop\_nest}(\,);\5
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\6
+\4${}\}{}$\2\6
+${}\\{type}(\|p)\K\\{unset\_node};{}$\5
+${}\\{glue\_stretch}(\|p)\K\T{0};{}$\6
+\&{if} ${}(\\{every\_cr}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_cr},\39\\{every\_cr\_text});{}$\2\6
+\\{align\_peek}(\,);\6
+\4${}\}{}$\C{note that $\\{glue\_shrink}(\|p)\E\T{0}$ since $\\{glue\_shrink}\MRL{{\E}{\E}}\\{shift\_amount}$}\2\par
+\fi
+
+\M{800}Finally, we will reach the end of the alignment, and we can breathe a
+sigh of relief that memory hasn't overflowed. All the unset boxes will now be
+set so that the columns line up, taking due account of spanned columns.
+
+\Y\B\&{void} \\{do\_assignments}(\&{void});\6
+\&{void} \\{resume\_after\_display}(\&{void});\6
+\&{void} \\{build\_page}(\&{void});\7
+\&{void} \\{fin\_align}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q${},{}$ \|r${},{}$ \|s${},{}$ \|u${},{}$ \|v;\C{registers for the list operations}\6
+\&{scaled} \|t${},{}$ \|w;\C{width of column}\6
+\&{scaled} \|o;\C{shift offset for unset boxes}\6
+\&{halfword} \|n;\C{matching span amount}\6
+\&{scaled} \\{rule\_save};\C{temporary storage for \\{overfull\_rule}}\6
+\&{memory\_word} \\{aux\_save};\C{temporary storage for \\{aux}}\7
+\&{if} ${}(\\{cur\_group}\I\\{align\_group}){}$\1\5
+\\{confusion}(\X1675:\.{"align1"}\X);\2\6
+\\{unsave}(\,);\C{that \\{align\_group} was for individual entries}\6
+\&{if} ${}(\\{cur\_group}\I\\{align\_group}){}$\1\5
+\\{confusion}(\X1676:\.{"align0"}\X);\2\6
+\\{unsave}(\,);\C{that \\{align\_group} was for the whole alignment}\6
+\&{if} ${}(\\{nest}[\\{nest\_ptr}-\T{1}].\\{mode\_field}\E\\{mmode}){}$\1\5
+${}\|o\K\\{display\_indent};{}$\2\6
+\&{else}\1\5
+${}\|o\K\T{0};{}$\2\6
+\X801:Go through the preamble list, determining the column widths and changing the alignrecords to dummy unset boxes\X;\6
+\X804:Package the preamble list, to determine the actual tabskip glue amounts, and let \|p point to this prototype box\X;\6
+\X805:Set the glue in all the unset boxes of the current list\X;\6
+\\{flush\_node\_list}(\|p);\5
+\\{pop\_alignment}(\,);\5
+\X812:Insert the \(c)current list into its environment\X;\6
+\4${}\}{}$\2\7
+\hbox{\4}\X785:Declare the procedure called \\{align\_peek}\X\par
+\fi
+
+\M{801}It's time now to dismantle the preamble list and to compute the column
+widths. Let $w_{ij}$ be the maximum of the natural widths of all entries
+that span columns $i$ through $j$, inclusive. The alignrecord for column~$i$
+contains $w_{ii}$ in its \\{width} field, and there is also a linked list of
+the nonzero $w_{ij}$ for increasing $j$, accessible via the \\{info} field;
+these span nodes contain the value $j-i+\\{min\_quarterword}$ in their
+\\{link} fields. The values of $w_{ii}$ were initialized to \\{null\_flag}, which
+we regard as $-\infty$.
+
+The final column widths are defined by the formula
+$$w_j=\max_{1\L i\L j}\biggl( w_{ij}-\sum_{i\L k<j}(t_k+w_k)\biggr),$$
+where $t_k$ is the natural width of the tabskip glue between columns
+$k$ and~$k+1$. However, if $w_{ij}=-\infty$ for all \|i in the range
+$\T{1}\Z\|i\Z\|j$ (i.e., if every entry that involved column~\|j also involved
+column~$\|j+\T{1}$), we let $w_j=0$, and we zero out the tabskip glue after
+column~\|j.
+
+\TeX\ computes these values by using the following scheme: First $w_1=w_{11}$.
+Then replace $w_{2j}$ by $\max(w_{2j},w_{1j}-t_1-w_1)$, for all $j>1$.
+Then $w_2=w_{22}$. Then replace $w_{3j}$ by $\max(w_{3j},w_{2j}-t_2-w_2)$
+for all $j>2$; and so on. If any $w_j$ turns out to be $-\infty$, its
+value is changed to zero and so is the next tabskip.
+
+\Y\B\4\X801:Go through the preamble list, determining the column widths and changing the alignrecords to dummy unset boxes\X${}\E{}$\6
+$\|q\K\\{link}(\\{preamble}){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\\{flush\_list}(\\{u\_part}(\|q));\5
+\\{flush\_list}(\\{v\_part}(\|q));\5
+${}\|p\K\\{link}(\\{link}(\|q));{}$\6
+\&{if} ${}(\\{width}(\|q)\E\\{null\_flag}){}$\1\5
+\X802:Nullify \\{width}(\|q) and the tabskip glue following this column\X;\2\6
+\&{if} ${}(\\{info}(\|q)\I\\{end\_span}){}$\1\5
+\X803:Merge the widths in the span nodes of \|q with those of \|p, destroying the span nodes of \|q\X;\2\6
+${}\\{type}(\|q)\K\\{unset\_node};{}$\5
+${}\\{span\_count}(\|q)\K\\{min\_quarterword};{}$\5
+${}\\{height}(\|q)\K\T{0};{}$\5
+${}\\{depth}(\|q)\K\T{0};{}$\5
+${}\\{glue\_order}(\|q)\K\\{normal};{}$\5
+${}\\{glue\_sign}(\|q)\K\\{normal};{}$\5
+${}\\{glue\_stretch}(\|q)\K\T{0};{}$\5
+${}\\{glue\_shrink}(\|q)\K\T{0};{}$\5
+${}\|q\K\|p;{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|q\E\\{null}){}$)\par
+\U800.\fi
+
+\M{802}\B\X802:Nullify \\{width}(\|q) and the tabskip glue following this column\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{width}(\|q)\K\T{0};{}$\5
+${}\|r\K\\{link}(\|q);{}$\5
+${}\|s\K\\{glue\_ptr}(\|r);{}$\6
+\&{if} ${}(\|s\I\\{zero\_glue}){}$\5
+${}\{{}$\5
+\1\\{add\_glue\_ref}(\\{zero\_glue});\5
+\\{delete\_glue\_ref}(\|s);\5
+${}\\{glue\_ptr}(\|r)\K\\{zero\_glue};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U801.\fi
+
+\M{803}Merging of two span-node lists is a typical exercise in the manipulation of
+linearly linked data structures. The essential invariant in the following
+ \&{do} $\{$ loop is that we want to dispense with node \|r, in \|q's list,
+and \|u is its successor; all nodes of \|p's list up to and including \|s
+have been processed, and the successor of \|s matches \|r or precedes \|r
+or follows \|r, according as $\\{link}(\|r)\E\|n$ or $\\{link}(\|r)>\|n$ or $\\{link}(\|r)<\|n$.
+
+\Y\B\4\X803:Merge the widths in the span nodes of \|q with those of \|p, destroying the span nodes of \|q\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|t\K\\{width}(\|q)+\\{width}(\\{glue\_ptr}(\\{link}(\|q)));{}$\5
+${}\|r\K\\{info}(\|q);{}$\5
+${}\|s\K\\{end\_span};{}$\5
+${}\\{info}(\|s)\K\|p;{}$\5
+${}\|n\K\\{min\_quarterword}+\T{1}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{width}(\|r)\K\\{width}(\|r)-\|t;{}$\5
+${}\|u\K\\{info}(\|r);{}$\6
+\&{while} ${}(\\{link}(\|r)>\|n){}$\5
+${}\{{}$\5
+\1${}\|s\K\\{info}(\|s);{}$\5
+${}\|n\K\\{link}(\\{info}(\|s))+\T{1};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{link}(\|r)<\|n){}$\5
+${}\{{}$\5
+\1${}\\{info}(\|r)\K\\{info}(\|s);{}$\5
+${}\\{info}(\|s)\K\|r;{}$\5
+\\{decr}(\\{link}(\|r));\5
+${}\|s\K\|r;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{width}(\|r)>\\{width}(\\{info}(\|s))){}$\1\5
+${}\\{width}(\\{info}(\|s))\K\\{width}(\|r);{}$\2\6
+${}\\{free\_node}(\|r,\39\\{span\_node\_size});{}$\6
+\4${}\}{}$\2\6
+${}\|r\K\|u;{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r\E\\{end\_span}));{}$\6
+\4${}\}{}$\2\par
+\U801.\fi
+
+\M{804}Now the preamble list has been converted to a list of alternating unset
+boxes and tabskip glue, where the box widths are equal to the final
+column sizes. In case of \.{\\valign}, we change the widths to heights,
+so that a correct error message will be produced if the alignment is
+overfull or underfull.
+
+\Y\B\4\X804:Package the preamble list, to determine the actual tabskip glue amounts, and let \|p point to this prototype box\X${}\E{}$\6
+$\\{save\_ptr}\K\\{save\_ptr}-\T{2};{}$\5
+${}\\{pack\_begin\_line}\K{-}\\{mode\_line};{}$\6
+\&{if} ${}(\\{mode}\E{-}\\{vmode}){}$\5
+${}\{{}$\5
+\1${}\\{rule\_save}\K\\{overfull\_rule};{}$\5
+${}\\{overfull\_rule}\K\T{0}{}$;\C{prevent rule from being packaged}\6
+${}\|p\K\\{hpack}(\\{preamble},\39\\{saved}(\T{1}),\39\\{saved}(\T{0}));{}$\5
+${}\\{overfull\_rule}\K\\{rule\_save};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{link}(\\{preamble}){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{height}(\|q)\K\\{width}(\|q);{}$\5
+${}\\{width}(\|q)\K\T{0};{}$\5
+${}\|q\K\\{link}(\\{link}(\|q));{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{null}));{}$\5
+${}\|p\K\\{vpack}(\\{preamble},\39\\{saved}(\T{1}),\39\\{saved}(\T{0}));{}$\5
+${}\|q\K\\{link}(\\{preamble}){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{width}(\|q)\K\\{height}(\|q);{}$\5
+${}\\{height}(\|q)\K\T{0};{}$\5
+${}\|q\K\\{link}(\\{link}(\|q));{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{null}));{}$\6
+\4${}\}{}$\2\6
+$\\{pack\_begin\_line}\K{}$\T{0}\par
+\U800.\fi
+
+\M{805}\B\X805:Set the glue in all the unset boxes of the current list\X${}\E{}$\6
+$\|q\K\\{link}(\\{head});{}$\5
+${}\|s\K\\{head};{}$\6
+\&{while} ${}(\|q\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{is\_char\_node}(\|q)){}$\1\6
+\&{if} ${}(\\{type}(\|q)\E\\{unset\_node}){}$\1\5
+\X807:Set the unset box \|q and the unset boxes in it\X\2\6
+\&{else} \&{if} ${}(\\{type}(\|q)\E\\{rule\_node}){}$\1\5
+\X806:Make the running dimensions in rule \|q extend to the boundaries of the alignment\X;\2\2\6
+${}\|s\K\|q;{}$\5
+${}\|q\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\par
+\U800.\fi
+
+\M{806}\B\X806:Make the running dimensions in rule \|q extend to the boundaries of the alignment\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{is\_running}(\\{width}(\|q)))\1\5
+${}\\{width}(\|q)\K\\{width}(\|p);{}$\2\6
+\&{if} (\\{is\_running}(\\{height}(\|q)))\1\5
+${}\\{height}(\|q)\K\\{height}(\|p);{}$\2\6
+\&{if} (\\{is\_running}(\\{depth}(\|q)))\1\5
+${}\\{depth}(\|q)\K\\{depth}(\|p);{}$\2\6
+\&{if} ${}(\|o\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\|q\K\\{hpack}(\|q,\39\\{natural});{}$\5
+${}\\{shift\_amount}(\|q)\K\|o;{}$\5
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{link}(\|s)\K\|q;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U805.\fi
+
+\M{807}The unset box \|q represents a row that contains one or more unset boxes,
+depending on how soon \.{\\cr} occurred in that row.
+
+\Y\B\4\X807:Set the unset box \|q and the unset boxes in it\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{mode}\E{-}\\{vmode}){}$\5
+${}\{{}$\5
+\1${}\\{type}(\|q)\K\\{hlist\_node};{}$\5
+${}\\{width}(\|q)\K\\{width}(\|p);{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{type}(\|q)\K\\{vlist\_node};{}$\5
+${}\\{height}(\|q)\K\\{height}(\|p);{}$\6
+\4${}\}{}$\2\6
+${}\\{glue\_order}(\|q)\K\\{glue\_order}(\|p);{}$\5
+${}\\{glue\_sign}(\|q)\K\\{glue\_sign}(\|p);{}$\5
+${}\\{glue\_set}(\|q)\K\\{glue\_set}(\|p);{}$\5
+${}\\{shift\_amount}(\|q)\K\|o;{}$\5
+${}\|r\K\\{link}(\\{list\_ptr}(\|q));{}$\5
+${}\|s\K\\{link}(\\{list\_ptr}(\|p)){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\X808:Set the glue in node \|r and change it from an unset node\X;\6
+${}\|r\K\\{link}(\\{link}(\|r));{}$\5
+${}\|s\K\\{link}(\\{link}(\|s));{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r\E\\{null}));{}$\6
+\4${}\}{}$\2\par
+\U805.\fi
+
+\M{808}A box made from spanned columns will be followed by tabskip glue nodes and
+by empty boxes as if there were no spanning. This permits perfect alignment
+of subsequent entries, and it prevents values that depend on floating point
+arithmetic from entering into the dimensions of any boxes.
+
+\Y\B\4\X808:Set the glue in node \|r and change it from an unset node\X${}\E{}$\6
+$\|n\K\\{span\_count}(\|r);{}$\5
+${}\|t\K\\{width}(\|s);{}$\5
+${}\|w\K\|t;{}$\5
+${}\|u\K\\{hold\_head};{}$\6
+\&{while} ${}(\|n>\\{min\_quarterword}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|n);\5
+\X809:Append tabskip glue and an empty box to list \|u, and update \|s and \|t as the prototype nodes are passed\X;\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{mode}\E{-}\\{vmode}){}$\1\5
+\X810:Make the unset node \|r into an \\{hlist\_node} of width \|w, setting the glue as if the width were \|t\X\2\6
+\&{else}\1\5
+\X811:Make the unset node \|r into a \\{vlist\_node} of height \|w, setting the glue as if the height were \|t\X;\2\6
+${}\\{shift\_amount}(\|r)\K\T{0};{}$\6
+\&{if} ${}(\|u\I\\{hold\_head}{}$)\C{append blank boxes to account for spanned nodes}\6
+${}\{{}$\5
+\1${}\\{link}(\|u)\K\\{link}(\|r);{}$\5
+${}\\{link}(\|r)\K\\{link}(\\{hold\_head});{}$\5
+${}\|r\K\|u;{}$\6
+\4${}\}{}$\2\par
+\U807.\fi
+
+\M{809}\B\X809:Append tabskip glue and an empty box to list \|u, and update \|s and \|t as the prototype nodes are passed\X${}\E{}$\6
+$\|s\K\\{link}(\|s);{}$\5
+${}\|v\K\\{glue\_ptr}(\|s);{}$\5
+${}\\{link}(\|u)\K\\{new\_glue}(\|v);{}$\5
+${}\|u\K\\{link}(\|u);{}$\5
+${}\\{subtype}(\|u)\K\\{tab\_skip\_code}+\T{1};{}$\5
+${}\|t\K\|t+\\{width}(\|v);{}$\6
+\&{if} ${}(\\{glue\_sign}(\|p)\E\\{stretching}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{stretch\_order}(\|v)\E\\{glue\_order}(\|p)){}$\1\5
+${}\|t\K\|t+\\{round}(\&{float}(\\{glue\_set}(\|p))*\\{stretch}(\|v));{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{glue\_sign}(\|p)\E\\{shrinking}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{shrink\_order}(\|v)\E\\{glue\_order}(\|p)){}$\1\5
+${}\|t\K\|t-\\{round}(\&{float}(\\{glue\_set}(\|p))*\\{shrink}(\|v));{}$\2\6
+\4${}\}{}$\2\6
+${}\|s\K\\{link}(\|s);{}$\5
+${}\\{link}(\|u)\K\\{new\_null\_box}(\,);{}$\5
+${}\|u\K\\{link}(\|u);{}$\5
+${}\|t\K\|t+\\{width}(\|s);{}$\6
+\&{if} ${}(\\{mode}\E{-}\\{vmode}){}$\1\5
+${}\\{width}(\|u)\K\\{width}(\|s){}$;\5
+\2\&{else}\5
+${}\{{}$\5
+\1${}\\{type}(\|u)\K\\{vlist\_node};{}$\5
+${}\\{height}(\|u)\K\\{width}(\|s);{}$\6
+\4${}\}{}$\2\par
+\U808.\fi
+
+\M{810}\B\X810:Make the unset node \|r into an \\{hlist\_node} of width \|w, setting the glue as if the width were \|t\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{height}(\|r)\K\\{height}(\|q);{}$\5
+${}\\{depth}(\|r)\K\\{depth}(\|q);{}$\6
+\&{if} ${}(\|t\E\\{width}(\|r)){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+${}\\{glue\_order}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|t>\\{width}(\|r)){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{stretching};{}$\6
+\&{if} ${}(\\{glue\_stretch}(\|r)\E\T{0}){}$\1\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\2\6
+\&{else}\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}((\|t-\\{width}(\|r))/{}$(\&{double}) \\{glue\_stretch}(\|r));\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_order}(\|r)\K\\{glue\_sign}(\|r);{}$\5
+${}\\{glue\_sign}(\|r)\K\\{shrinking};{}$\6
+\&{if} ${}(\\{glue\_shrink}(\|r)\E\T{0}){}$\1\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\2\6
+\&{else} \&{if} ${}((\\{glue\_order}(\|r)\E\\{normal})\W(\\{width}(\|r)-\|t>\\{glue\_shrink}(\|r))){}$\1\5
+\\{set\_glue\_ratio\_one}(\\{glue\_set}(\|r));\2\6
+\&{else}\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}((\\{width}(\|r)-\|t)/{}$(\&{double}) \\{glue\_shrink}(\|r));\2\6
+\4${}\}{}$\2\6
+${}\\{width}(\|r)\K\|w;{}$\5
+${}\\{type}(\|r)\K\\{hlist\_node};{}$\6
+\4${}\}{}$\2\par
+\U808.\fi
+
+\M{811}\B\X811:Make the unset node \|r into a \\{vlist\_node} of height \|w, setting the glue as if the height were \|t\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{width}(\|r)\K\\{width}(\|q);{}$\6
+\&{if} ${}(\|t\E\\{height}(\|r)){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{normal};{}$\5
+${}\\{glue\_order}(\|r)\K\\{normal};{}$\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|t>\\{height}(\|r)){}$\5
+${}\{{}$\5
+\1${}\\{glue\_sign}(\|r)\K\\{stretching};{}$\6
+\&{if} ${}(\\{glue\_stretch}(\|r)\E\T{0}){}$\1\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\2\6
+\&{else}\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}((\|t-\\{height}(\|r))/{}$(\&{double}) \\{glue\_stretch}(\|r));\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{glue\_order}(\|r)\K\\{glue\_sign}(\|r);{}$\5
+${}\\{glue\_sign}(\|r)\K\\{shrinking};{}$\6
+\&{if} ${}(\\{glue\_shrink}(\|r)\E\T{0}){}$\1\5
+\\{set\_glue\_ratio\_zero}(\\{glue\_set}(\|r));\2\6
+\&{else} \&{if} ${}((\\{glue\_order}(\|r)\E\\{normal})\W(\\{height}(\|r)-\|t>\\{glue\_shrink}(\|r))){}$\1\5
+\\{set\_glue\_ratio\_one}(\\{glue\_set}(\|r));\2\6
+\&{else}\1\5
+${}\\{glue\_set}(\|r)\K\\{unfloat}((\\{height}(\|r)-\|t)/{}$(\&{double}) \\{glue\_shrink}(\|r));\2\6
+\4${}\}{}$\2\6
+${}\\{height}(\|r)\K\|w;{}$\5
+${}\\{type}(\|r)\K\\{vlist\_node};{}$\6
+\4${}\}{}$\2\par
+\U808.\fi
+
+\M{812}We now have a completed alignment, in the list that starts at \\{head}
+and ends at \\{tail}. This list will be merged with the one that encloses
+it. (In case the enclosing mode is \\{mmode}, for displayed formulas,
+we will need to insert glue before and after the display; that part of the
+program will be deferred until we're more familiar with such operations.)
+
+In restricted horizontal mode, the \\{clang} part of \\{aux} is undefined;
+an over-cautious \PASCAL\ runtime system may complain about this.
+
+\Y\B\4\X812:Insert the \(c)current list into its environment\X${}\E{}$\6
+$\\{aux\_save}\K\\{aux};{}$\5
+${}\|p\K\\{link}(\\{head});{}$\5
+${}\|q\K\\{tail};{}$\5
+\\{pop\_nest}(\,);\6
+\&{if} ${}(\\{mode}\E\\{mmode}){}$\1\5
+\X1206:Finish an alignment in a display\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{aux}\K\\{aux\_save};{}$\5
+${}\\{link}(\\{tail})\K\|p;{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\5
+${}\\{tail}\K\|q;{}$\2\6
+\&{if} ${}(\\{mode}\E\\{vmode}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\2\par
+\U800.\fi
+
+\N{1}{813}Breaking paragraphs into lines.
+We come now to what is probably the most interesting algorithm of \TeX:
+the mechanism for choosing the ``best possible'' breakpoints that yield
+the individual lines of a paragraph. \TeX's line-breaking algorithm takes
+a given horizontal list and converts it to a sequence of boxes that are
+appended to the current vertical list. In the course of doing this, it
+creates a special data structure containing three kinds of records that are
+not used elsewhere in \TeX. Such nodes are created while a paragraph is
+being processed, and they are destroyed afterwards; thus, the other parts
+of \TeX\ do not need to know anything about how line-breaking is done.
+
+The method used here is based on an approach devised by Michael F. Plass and
+the author in 1977, subsequently generalized and improved by the same two
+people in 1980. A detailed discussion appears in {\sl SOFTWARE---Practice
+\AM\ Experience \bf11} (1981), 1119--1184, where it is shown that the
+line-breaking problem can be regarded as a special case of the problem of
+computing the shortest path in an acyclic network. The cited paper includes
+numerous examples and describes the history of line breaking as it has been
+practiced by printers through the ages. The present implementation adds two
+new ideas to the algorithm of 1980: Memory space requirements are considerably
+reduced by using smaller records for inactive nodes than for active ones,
+and arithmetic overflow is avoided by using ``delta distances'' instead of
+keeping track of the total distance from the beginning of the paragraph to the
+current point.
+
+\fi
+
+\M{814}The \\{line\_break} procedure should be invoked only in horizontal mode; it
+leaves that mode and places its output into the current vlist of the
+enclosing vertical mode (or internal vertical mode).
+There is one explicit parameter: \\{final\_widow\_penalty} is the amount of
+additional penalty to be inserted before the final line of the paragraph.
+
+There are also a number of implicit parameters: The hlist to be broken
+starts at \\{link}(\\{head}), and it is nonempty. The value of \\{prev\_graf} in the
+enclosing semantic level tells where the paragraph should begin in the
+sequence of line numbers, in case hanging indentation or \.{\\parshape}
+is in use; \\{prev\_graf} is zero unless this paragraph is being continued
+after a displayed formula. Other implicit parameters, such as the
+\\{par\_shape\_ptr} and various penalties to use for hyphenation, etc., appear
+in \\{eqtb}.
+
+After \\{line\_break} has acted, it will have updated the current vlist and the
+value of \\{prev\_graf}. Furthermore, the global variable \\{just\_box} will
+point to the final box created by \\{line\_break}, so that the width of this
+line can be ascertained when it is necessary to decide whether to use
+\\{above\_display\_skip} or \\{above\_display\_short\_skip} before a displayed formula.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{just\_box};\C{the \\{hlist\_node} for the last line of the new paragraph}\par
+\fi
+
+\M{815}Since \\{line\_break} is a rather lengthy procedure---sort of a small world unto
+itself---we must build it up little by little, somewhat more cautiously
+than we have done with the simpler procedures of \TeX. Here is the
+general outline.
+
+\Y\B\hbox{\4}\X826:Declare subprocedures for \\{line\_break}\X\7
+\&{void} \\{line\_break}(\&{int} \\{final\_widow\_penalty})\1\1\2\2\6
+${}\{{}$\5
+\1\X862:Local variables for line breaking\X\6
+${}\\{pack\_begin\_line}\K\\{mode\_line}{}$;\C{this is for over/underfull box messages}\6
+\X816:Get ready to start line breaking\X;\6
+\X863:Find optimal breakpoints\X;\6
+\X876:Break the paragraph at the chosen breakpoints, justify the resulting lines to the correct widths, and append them to the current vertical list\X;\6
+\X865:Clean up the memory by removing the break nodes\X;\6
+${}\\{pack\_begin\_line}\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{816}The first task is to move the list from \\{head} to \\{temp\_head} and go
+into the enclosing semantic level. We also append the \.{\\parfillskip}
+glue to the end of the paragraph, removing a space (or other glue node) if
+it was there, since spaces usually precede blank lines and instances of
+`\.{\$\$}'. The \\{par\_fill\_skip} is preceded by an infinite penalty, so
+it will never be considered as a potential breakpoint.
+
+This code assumes that a \\{glue\_node} and a \\{penalty\_node} occupy the
+same number of \\{mem}~words.
+
+\Y\B\4\X816:Get ready to start line breaking\X${}\E{}$\6
+$\\{link}(\\{temp\_head})\K\\{link}(\\{head});{}$\6
+\&{if} (\\{is\_char\_node}(\\{tail}))\1\5
+\\{tail\_append}(\\{new\_penalty}(\\{inf\_penalty}))\2\6
+\&{else} \&{if} ${}(\\{type}(\\{tail})\I\\{glue\_node}){}$\1\5
+\\{tail\_append}(\\{new\_penalty}(\\{inf\_penalty}))\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{type}(\\{tail})\K\\{penalty\_node};{}$\5
+\\{delete\_glue\_ref}(\\{glue\_ptr}(\\{tail}));\5
+\\{flush\_node\_list}(\\{leader\_ptr}(\\{tail}));\5
+${}\\{penalty}(\\{tail})\K\\{inf\_penalty};{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\\{new\_param\_glue}(\\{par\_fill\_skip\_code});{}$\5
+${}\\{init\_cur\_lang}\K\\{prev\_graf}\MOD\T{\~200000};{}$\5
+${}\\{init\_l\_hyf}\K\\{prev\_graf}/\T{\~20000000};{}$\5
+${}\\{init\_r\_hyf}\K(\\{prev\_graf}/\T{\~200000})\MOD\T{\~100};{}$\5
+\\{pop\_nest}(\,);\par
+\As827, 834\ETs848.
+\U815.\fi
+
+\M{817}When looking for optimal line breaks, \TeX\ creates a ``break node'' for
+each break that is {\sl feasible}, in the sense that there is a way to end
+a line at the given place without requiring any line to stretch more than
+a given tolerance. A break node is characterized by three things: the position
+of the break (which is a pointer to a \\{glue\_node}, \\{math\_node}, \\{penalty\_node},
+or \\{disc\_node}); the ordinal number of the line that will follow this
+breakpoint; and the fitness classification of the line that has just
+ended, i.e., \\{tight\_fit}, \\{decent\_fit}, \\{loose\_fit}, or \\{very\_loose\_fit}.
+
+\Y\B\4\D$\\{tight\_fit}$ \5
+\T{3}\C{fitness classification for lines shrinking 0.5 to 1.0 of their shrinkability}\par
+\B\4\D$\\{loose\_fit}$ \5
+\T{1}\C{fitness classification for lines stretching 0.5 to 1.0 of their stretchability}\par
+\B\4\D$\\{very\_loose\_fit}$ \5
+\T{0}\C{fitness classification for lines stretching more than their stretchability}\par
+\B\4\D$\\{decent\_fit}$ \5
+\T{2}\C{fitness classification for all other lines}\par
+\fi
+
+\M{818}The algorithm essentially determines the best possible way to achieve
+each feasible combination of position, line, and fitness. Thus, it answers
+questions like, ``What is the best way to break the opening part of the
+paragraph so that the fourth line is a tight line ending at such-and-such
+a place?'' However, the fact that all lines are to be the same length
+after a certain point makes it possible to regard all sufficiently large
+line numbers as equivalent, when the looseness parameter is zero, and this
+makes it possible for the algorithm to save space and time.
+
+An ``active node'' and a ``passive node'' are created in \\{mem} for each
+feasible breakpoint that needs to be considered. Active nodes are three
+words long and passive nodes are two words long. We need active nodes only
+for breakpoints near the place in the paragraph that is currently being
+examined, so they are recycled within a comparatively short time after
+they are created.
+
+\fi
+
+\M{819}An active node for a given breakpoint contains six fields:
+
+\yskip\hang\\{link} points to the next node in the list of active nodes; the
+last active node has $\\{link}\E\\{last\_active}$.
+
+\yskip\hang\\{break\_node} points to the passive node associated with this
+breakpoint.
+
+\yskip\hang\\{line\_number} is the number of the line that follows this
+breakpoint.
+
+\yskip\hang\\{fitness} is the fitness classification of the line ending at this
+breakpoint.
+
+\yskip\hang\\{type} is either \\{hyphenated} or \\{unhyphenated}, depending on
+whether this breakpoint is a \\{disc\_node}.
+
+\yskip\hang\\{total\_demerits} is the minimum possible sum of demerits over all
+lines leading from the beginning of the paragraph to this breakpoint.
+
+\yskip\noindent
+The value of \\{link}(\\{active}) points to the first active node on a linked list
+of all currently active nodes. This list is in order by \\{line\_number},
+except that nodes with $\\{line\_number}>\\{easy\_line}$ may be in any order relative
+to each other.
+
+\Y\B\4\D$\\{active\_node\_size}$ \5
+\T{3}\C{number of words in active nodes}\par
+\B\4\D$\\{fitness}$ \5
+\\{subtype}\C{$\\{very\_loose\_fit}\dotdot\\{tight\_fit}$ on final line for this break}\par
+\B\4\D$\\{break\_node}$ \5
+\\{rlink}\C{pointer to the corresponding passive node}\par
+\B\4\D$\\{line\_number}$ \5
+\\{llink}\C{line that begins at this breakpoint}\par
+\B\4\D$\\{total\_demerits}(\|X)$ \5
+$\\{mem}[\|X+\T{2}].{}$\|i\C{the quantity that \TeX\ minimizes}\par
+\B\4\D$\\{unhyphenated}$ \5
+\T{0}\C{the \\{type} of a normal active break node}\par
+\B\4\D$\\{hyphenated}$ \5
+\T{1}\C{the \\{type} of an active node that breaks at a \\{disc\_node}}\par
+\B\4\D$\\{last\_active}$ \5
+\\{active}\C{the active list ends where it begins}\par
+\fi
+
+\M{820}\B\X790:Initialize the special list heads and constant nodes\X${}\mathrel+\E{}$\6
+$\\{type}(\\{last\_active})\K\\{hyphenated};{}$\5
+${}\\{line\_number}(\\{last\_active})\K\\{max\_halfword};{}$\5
+${}\\{subtype}(\\{last\_active})\K\T{0}{}$;\C{the \\{subtype} is never examined by the algorithm}\par
+\fi
+
+\M{821}The passive node for a given breakpoint contains only four fields:
+
+\yskip\hang\\{link} points to the passive node created just before this one,
+if any, otherwise it is \\{null}.
+
+\yskip\hang\\{cur\_break} points to the position of this breakpoint in the
+horizontal list for the paragraph being broken.
+
+\yskip\hang\\{prev\_break} points to the passive node that should precede this
+one in an optimal path to this breakpoint.
+
+\yskip\hang\\{serial} is equal to \|n if this passive node is the \|nth
+one created during the current pass. (This field is used only when
+printing out detailed statistics about the line-breaking calculations.)
+
+\yskip\noindent
+There is a global variable called \\{passive} that points to the most
+recently created passive node. Another global variable, \\{printed\_node},
+is used to help print out the paragraph when detailed information about
+the line-breaking computation is being displayed.
+
+\Y\B\4\D$\\{passive\_node\_size}$ \5
+\T{2}\C{number of words in passive nodes}\par
+\B\4\D$\\{cur\_break}$ \5
+\\{rlink}\C{in passive node, points to position of this breakpoint}\par
+\B\4\D$\\{prev\_break}$ \5
+\\{llink}\C{points to passive node that should precede this one}\par
+\B\4\D$\\{serial}$ \5
+\\{info}\C{serial number for symbolic identification}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{passive};\C{most recent node on passive list}\6
+\&{pointer} \\{printed\_node};\C{most recent node that has been printed}\6
+\&{halfword} \\{pass\_number};\C{the number of passive nodes allocated on this pass}\par
+\fi
+
+\M{822}The active list also contains ``delta'' nodes that help the algorithm
+compute the badness of individual lines. Such nodes appear only between two
+active nodes, and they have $\\{type}\E\\{delta\_node}$. If \|p and \|r are active nodes
+and if \|q is a delta node between them, so that $\\{link}(\|p)\E\|q$ and $\\{link}(\|q)\E\|r$,
+then \|q tells the space difference between lines in the horizontal list that
+start after breakpoint \|p and lines that start after breakpoint \|r. In
+other words, if we know the length of the line that starts after \|p and
+ends at our current position, then the corresponding length of the line that
+starts after \|r is obtained by adding the amounts in node~\|q. A delta node
+contains six scaled numbers, since it must record the net change in glue
+stretchability with respect to all orders of infinity. The natural width
+difference appears in $\\{mem}[\|q+\T{1}].\\{sc}$; the stretch differences in units of
+pt, fil, fill, and filll appear in $\\{mem}[\|q+\T{2}\dotdot\|q+\T{5}].\\{sc}$; and the shrink difference
+appears in $\\{mem}[\|q+\T{6}].\\{sc}$. The \\{subtype} field of a delta node is not used.
+
+\Y\B\4\D$\\{delta\_node\_size}$ \5
+\T{7}\C{number of words in a delta node}\par
+\B\4\D$\\{delta\_node}$ \5
+\T{2}\C{\\{type} field in a delta node}\par
+\fi
+
+\M{823}As the algorithm runs, it maintains a set of six delta-like registers
+for the length of the line following the first active breakpoint to the
+current position in the given hlist. When it makes a pass through the
+active list, it also maintains a similar set of six registers for the
+length following the active breakpoint of current interest. A third set
+holds the length of an empty line (namely, the sum of \.{\\leftskip} and
+\.{\\rightskip}); and a fourth set is used to create new delta nodes.
+
+When we pass a delta node we want to do operations like
+$$\hbox{\ignorespaces\&{for} \|k $\K$ \T{1} \&{to} \T{6} \&{do} $\\{cur\_active\_width}[\|k]\K\\{cur\_active\_width}[\|k]+\\{mem}[\|q+\|k].\\{sc}$};$$ and we
+want to do this without the overhead of \&{for} loops. The \\{do\_all\_six}
+macro makes such six-tuples convenient.
+
+\Y\B\4\D$\\{do\_all\_six}(\|X)$ \5
+\|X(\T{1});\5
+\|X(\T{2});\5
+\|X(\T{3});\5
+\|X(\T{4});\5
+\|X(\T{5}); \|X(\T{6})\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} \\{active\_width0}[\T{6}]${},{}$ ${}{*\&{const}\ }\\{active\_width}\K\\{active\_width0}-\T{1}{}$;\C{distance from first active node to~\\{cur\_p}}\6
+\&{scaled} \\{cur\_active\_width0}[\T{6}]${},{}$ ${}{*\&{const}\ }\\{cur\_active\_width}\K\\{cur\_active\_width0}-\T{1}{}$;\C{distance from current active node}\6
+\&{scaled} \\{background0}[\T{6}]${},{}$ ${}{*\&{const}\ }\\{background}\K\\{background0}-\T{1}{}$;\C{length of an ``empty'' line}\6
+\&{scaled} \\{break\_width0}[\T{6}]${},{}$ ${}{*\&{const}\ }\\{break\_width}\K\\{break\_width0}-\T{1}{}$;\C{length being computed after current break}\par
+\fi
+
+\M{824}Let's state the principles of the delta nodes more precisely and concisely,
+so that the following programs will be less obscure. For each legal
+breakpoint~\|p in the paragraph, we define two quantities $\alpha(p)$ and
+$\beta(p)$ such that the length of material in a line from breakpoint~\|p
+to breakpoint~\|q is $\gamma+\beta(q)-\alpha(p)$, for some fixed $\gamma$.
+Intuitively, $\alpha(p)$ and $\beta(q)$ are the total length of material from
+the beginning of the paragraph to a point ``after'' a break at \|p and to a
+point ``before'' a break at \|q; and $\gamma$ is the width of an empty line,
+namely the length contributed by \.{\\leftskip} and \.{\\rightskip}.
+
+Suppose, for example, that the paragraph consists entirely of alternating
+boxes and glue skips; let the boxes have widths $x_1\ldots x_n$ and
+let the skips have widths $y_1\ldots y_n$, so that the paragraph can be
+represented by $x_1y_1\ldots x_ny_n$. Let $p_i$ be the legal breakpoint
+at $y_i$; then $\alpha(p_i)=x_1+y_1+\cdots+x_i+y_i$, and $\beta(p_i)=
+x_1+y_1+\cdots+x_i$. To check this, note that the length of material from
+$p_2$ to $p_5$, say, is $\gamma+x_3+y_3+x_4+y_4+x_5=\gamma+\beta(p_5)
+-\alpha(p_2)$.
+
+The quantities $\alpha$, $\beta$, $\gamma$ involve glue stretchability and
+shrinkability as well as a natural width. If we were to compute $\alpha(p)$
+and $\beta(p)$ for each \|p, we would need multiple precision arithmetic, and
+the multiprecise numbers would have to be kept in the active nodes.
+\TeX\ avoids this problem by working entirely with relative differences
+or ``deltas.'' Suppose, for example, that the active list contains
+$a_1\,\delta_1\,a_2\,\delta_2\,a_3$, where the \|a's are active breakpoints
+and the $\delta$'s are delta nodes. Then $\delta_1=\alpha(a_1)-\alpha(a_2)$
+and $\delta_2=\alpha(a_2)-\alpha(a_3)$. If the line breaking algorithm is
+currently positioned at some other breakpoint \|p, the \\{active\_width} array
+contains the value $\gamma+\beta(p)-\alpha(a_1)$. If we are scanning through
+the list of active nodes and considering a tentative line that runs from
+$a_2$ to~\|p, say, the \\{cur\_active\_width} array will contain the value
+$\gamma+\beta(p)-\alpha(a_2)$. Thus, when we move from $a_2$ to $a_3$,
+we want to add $\alpha(a_2)-\alpha(a_3)$ to \\{cur\_active\_width}; and this
+is just $\delta_2$, which appears in the active list between $a_2$ and
+$a_3$. The \\{background} array contains $\gamma$. The \\{break\_width} array
+will be used to calculate values of new delta nodes when the active
+list is being updated.
+
+\fi
+
+\M{825}Glue nodes in a horizontal list that is being paragraphed are not supposed to
+include ``infinite'' shrinkability; that is why the algorithm maintains
+four registers for stretching but only one for shrinking. If the user tries to
+introduce infinite shrinkability, the shrinkability will be reset to finite
+and an error message will be issued. A boolean variable \\{no\_shrink\_error\_yet}
+prevents this error message from appearing more than once per paragraph.
+
+\Y\B\4\D$\\{check\_shrinkage}(\|X)$ \6
+\&{if} ${}((\\{shrink\_order}(\|X)\I\\{normal})\W(\\{shrink}(\|X)\I\T{0})){}$\5
+${}\{{}$\5
+\1${}\|X\K\\{finite\_shrink}(\|X);{}$\6
+\4${}\}{}$\2\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{no\_shrink\_error\_yet};\C{have we complained about infinite shrinkage?}\par
+\fi
+
+\M{826}\B\X826:Declare subprocedures for \\{line\_break}\X${}\E{}$\6
+\&{pointer} \\{finite\_shrink}(\&{pointer} \|p)\C{recovers from infinite shrinkage}\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{new glue specification}\7
+\&{if} (\\{no\_shrink\_error\_yet})\5
+${}\{{}$\5
+\1${}\\{no\_shrink\_error\_yet}\K\\{false};{}$\5
+\\{print\_err}(\.{"Infinite\ glue\ shrin}\)\.{kage\ found\ in\ a\ para}\)\.{graph"});\5
+\\{help5}(\.{"The\ paragraph\ just\ }\)\.{ended\ includes\ some\ }\)\.{glue\ that\ has"})\6
+(\.{"infinite\ shrinkabil}\)\.{ity,\ e.g.,\ `\\\\hskip\ }\)\.{0pt\ minus\ 1fil'."})\6
+(\.{"Such\ glue\ doesn't\ b}\)\.{elong\ there---it\ all}\)\.{ows\ a\ paragraph"})\6
+(\.{"of\ any\ length\ to\ fi}\)\.{t\ on\ one\ line.\ But\ i}\)\.{t's\ safe\ to\ proceed,}\)\.{"})\6
+(\.{"since\ the\ offensive}\)\.{\ shrinkability\ has\ b}\)\.{een\ made\ finite."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+${}\|q\K\\{new\_spec}(\|p);{}$\5
+${}\\{shrink\_order}(\|q)\K\\{normal};{}$\5
+\\{delete\_glue\_ref}(\|p);\5
+\&{return} \|q;\6
+\4${}\}{}$\2\par
+\As829, 877, 895\ETs942.
+\U815.\fi
+
+\M{827}\B\X816:Get ready to start line breaking\X${}\mathrel+\E{}$\6
+$\\{no\_shrink\_error\_yet}\K\\{true}{}$;\6
+\\{check\_shrinkage}(\\{left\_skip});\5
+\\{check\_shrinkage}(\\{right\_skip});\6
+${}\|q\K\\{left\_skip};{}$\5
+${}\|r\K\\{right\_skip};{}$\5
+${}\\{background}[\T{1}]\K\\{width}(\|q)+\\{width}(\|r){}$;\6
+${}\\{background}[\T{2}]\K\T{0};{}$\5
+${}\\{background}[\T{3}]\K\T{0};{}$\5
+${}\\{background}[\T{4}]\K\T{0};{}$\5
+${}\\{background}[\T{5}]\K\T{0}{}$;\6
+${}\\{background}[\T{2}+\\{stretch\_order}(\|q)]\K\\{stretch}(\|q){}$;\6
+${}\\{background}[\T{2}+\\{stretch\_order}(\|r)]\K\30\\{background}[\T{2}+\\{stretch\_order}(\|r)]+\\{stretch}(\|r){}$;\6
+${}\\{background}[\T{6}]\K\\{shrink}(\|q)+\\{shrink}(\|r){}$;\par
+\fi
+
+\M{828}A pointer variable \\{cur\_p} runs through the given horizontal list as we look
+for breakpoints. This variable is global, since it is used both by \\{line\_break}
+and by its subprocedure \\{try\_break}.
+
+Another global variable called \\{threshold} is used to determine the feasibility
+of individual lines: Breakpoints are feasible if there is a way to reach
+them without creating lines whose badness exceeds \\{threshold}. (The
+badness is compared to \\{threshold} before penalties are added, so that
+penalty values do not affect the feasibility of breakpoints, except that
+no break is allowed when the penalty is 10000 or more.) If \\{threshold}
+is 10000 or more, all legal breaks are considered feasible, since the
+\\{badness} function specified above never returns a value greater than~10000.
+
+Up to three passes might be made through the paragraph in an attempt to find at
+least one set of feasible breakpoints. On the first pass, we have
+$\\{threshold}\E\\{pretolerance}$ and $\\{second\_pass}\E\\{final\_pass}\E\\{false}$.
+If this pass fails to find a
+feasible solution, \\{threshold} is set to \\{tolerance}, \\{second\_pass} is set
+\\{true}, and an attempt is made to hyphenate as many words as possible.
+If that fails too, we add \\{emergency\_stretch} to the background
+stretchability and set $\\{final\_pass}\E\\{true}$.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{cur\_p};\C{the current breakpoint under consideration}\6
+\&{bool} \\{second\_pass};\C{is this our second attempt to break this paragraph?}\6
+\&{bool} \\{final\_pass};\C{is this our final attempt to break this paragraph?}\6
+\&{int} \\{threshold};\C{maximum badness on feasible lines}\par
+\fi
+
+\M{829}The heart of the line-breaking procedure is `\\{try\_break}', a subroutine
+that tests if the current breakpoint \\{cur\_p} is feasible, by running
+through the active list to see what lines of text can be made from active
+nodes to~\\{cur\_p}. If feasible breaks are possible, new break nodes are
+created. If \\{cur\_p} is too far from an active node, that node is
+deactivated.
+
+The parameter \\{pi} to \\{try\_break} is the penalty associated
+with a break at \\{cur\_p}; we have $\\{pi}\E\\{eject\_penalty}$ if the break is forced,
+and $\\{pi}\E\\{inf\_penalty}$ if the break is illegal.
+
+The other parameter, \\{break\_type}, is set to \\{hyphenated} or \\{unhyphenated},
+depending on whether or not the current break is at a \\{disc\_node}. The
+end of a paragraph is also regarded as `\\{hyphenated}'; this case is
+distinguishable by the condition $\\{cur\_p}\E\\{null}$.
+
+\Y\B\4\D$\\{copy\_to\_cur\_active}(\|X)$ \5
+$\\{cur\_active\_width}[\|X]\K\\{active\_width}{}$[\|X]\par
+\Y\B\4\X826:Declare subprocedures for \\{line\_break}\X${}\mathrel+\E{}$\6
+\&{void} \\{try\_break}(\&{int} \\{pi}${},\39{}$\&{small\_number} \\{break\_type})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|r;\C{runs through the active list}\6
+\&{pointer} \\{prev\_r};\C{stays a step behind \|r}\6
+\&{halfword} \\{old\_l};\C{maximum line number in current equivalence class of lines}\6
+\&{bool} \\{no\_break\_yet};\C{have we found a feasible break at \\{cur\_p}?}\7
+\X830:Other local variables for \\{try\_break}\X\6
+\X831:Make sure that \\{pi} is in the proper range\X;\6
+${}\\{no\_break\_yet}\K\\{true};{}$\5
+${}\\{prev\_r}\K\\{active};{}$\5
+${}\\{old\_l}\K\T{0};{}$\5
+\\{do\_all\_six}(\\{copy\_to\_cur\_active});\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{resume}:\5
+${}\|r\K\\{link}(\\{prev\_r});{}$\5
+\X832:If node \|r is of type \\{delta\_node}, update \\{cur\_active\_width}, set \\{prev\_r} and \\{prev\_prev\_r}, then \&{goto} \&{continue}\X;\6
+\X835:If a line number class has ended, create new active nodes for the best feasible breaks in that class; then \&{return} if $\|r\K\\{last\_active}$, otherwise compute the new \\{line\_width}\X;\6
+\X851:Consider the demerits for a line from \|r to \\{cur\_p}; deactivate node \|r if it should no longer be active; then \&{goto} \&{continue} if a line from \|r to \\{cur\_p} is infeasible, otherwise record a new feasible break\X;\6
+\4${}\}{}$\2\6
+\4\\{end}:\5
+;\6
+\8\#\&{ifdef} \.{STAT}\6
+\X858:Update the value of \\{printed\_node} for symbolic displays\X;\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{830}\B\X830:Other local variables for \\{try\_break}\X${}\E{}$\6
+\&{pointer} \\{prev\_prev\_r};\C{a step behind \\{prev\_r}, if $\\{type}(\\{prev\_r})\E\\{delta\_node}$}\6
+\&{pointer} \|s;\C{runs through nodes ahead of \\{cur\_p}}\6
+\&{pointer} \|q;\C{points to a new node being created}\6
+\&{pointer} \|v;\C{points to a glue specification or a node ahead of \\{cur\_p}}\6
+\&{int} \|t;\C{node count, if \\{cur\_p} is a discretionary node}\6
+\&{internal\_font\_number} \|f;\C{used in character width calculation}\6
+\&{halfword} \|l;\C{line number of current active node}\6
+\&{bool} \\{node\_r\_stays\_active};\C{should node \|r remain in the active list?}\6
+\&{scaled} \\{line\_width};\C{the current line will be justified to this width}\6
+\&{uint8\_t} \\{fit\_class};\C{possible fitness class of test line}\6
+\&{halfword} \|b;\C{badness of test line}\6
+\&{int} \|d;\C{demerits of test line}\6
+\&{bool} \\{artificial\_demerits};\C{has \|d been forced to zero?}\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{pointer} \\{save\_link};\C{temporarily holds value of \\{link}(\\{cur\_p})}\6
+\8\#\&{endif}\6
+\&{scaled} \\{shortfall};\C{used in badness calculations}\par
+\U829.\fi
+
+\M{831}\B\X831:Make sure that \\{pi} is in the proper range\X${}\E{}$\6
+\&{if} ${}(\\{abs}(\\{pi})\G\\{inf\_penalty})$ \6
+\&{if} ${}(\\{pi}>\T{0}){}$\1\5
+\&{goto} \\{end};\C{this breakpoint is inhibited by infinite penalty}\2\6
+\&{else} $\\{pi}\K{}$\\{eject\_penalty}\C{this breakpoint will be forced}\par
+\U829.\fi
+
+\M{832}The following code uses the fact that $\\{type}(\\{last\_active})\I\\{delta\_node}$.
+
+\Y\B\4\D$\\{update\_width}(\|X)$ \5
+$\\{cur\_active\_width}[\|X]\K\\{cur\_active\_width}[\|X]+\\{mem}[\|r+\|X].{}$\\{sc}\par
+\Y\B\4\X832:If node \|r is of type \\{delta\_node}, update \\{cur\_active\_width}, set \\{prev\_r} and \\{prev\_prev\_r}, then \&{goto} \&{continue}\X${}\E{}$\6
+\&{if} ${}(\\{type}(\|r)\E\\{delta\_node}){}$\5
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{update\_width});\5
+${}\\{prev\_prev\_r}\K\\{prev\_r};{}$\5
+${}\\{prev\_r}\K\|r;{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U829.\fi
+
+\M{833}As we consider various ways to end a line at \\{cur\_p}, in a given line number
+class, we keep track of the best total demerits known, in an array with
+one entry for each of the fitness classifications. For example,
+\\{minimal\_demerits}[\\{tight\_fit}] contains the fewest total demerits of feasible
+line breaks ending at \\{cur\_p} with a \\{tight\_fit} line; \\{best\_place}[\\{tight\_fit}]
+points to the passive node for the break before~\\{cur\_p} that achieves such
+an optimum; and \\{best\_pl\_line}[\\{tight\_fit}] is the \\{line\_number} field in the
+active node corresponding to \\{best\_place}[\\{tight\_fit}]. When no feasible break
+sequence is known, the \\{minimal\_demerits} entries will be equal to
+\\{awful\_bad}, which is $2^{30}-1$. Another variable, \\{minimum\_demerits},
+keeps track of the smallest value in the \\{minimal\_demerits} array.
+
+\Y\B\4\D$\\{awful\_bad}$ \5
+\T{\~7777777777}\C{more than a billion demerits}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} ${}\\{minimal\_demerits0}[\\{tight\_fit}-\\{very\_loose\_fit}+\T{1}],{}$ ${}{*\&{const}\ }\\{minimal\_demerits}\K\\{minimal\_demerits0}-\\{very\_loose\_fit}{}$;\C{best total demerits known for current line class and position, given the fitness}%
+\6
+\&{int} \\{minimum\_demerits};\C{best total demerits known for current line class and position}\6
+\&{pointer} ${}\\{best\_place0}[\\{tight\_fit}-\\{very\_loose\_fit}+\T{1}],{}$ ${}{*\&{const}\ }\\{best\_place}\K\\{best\_place0}-\\{very\_loose\_fit}{}$;\C{how to achieve \\{minimal\_demerits}}\6
+\&{halfword} ${}\\{best\_pl\_line0}[\\{tight\_fit}-\\{very\_loose\_fit}+\T{1}],{}$ ${}{*\&{const}\ }\\{best\_pl\_line}\K\\{best\_pl\_line0}-\\{very\_loose\_fit}{}$;\C{corresponding line number}\par
+\fi
+
+\M{834}\B\X816:Get ready to start line breaking\X${}\mathrel+\E{}$\6
+$\\{minimum\_demerits}\K\\{awful\_bad};{}$\5
+${}\\{minimal\_demerits}[\\{tight\_fit}]\K\\{awful\_bad};{}$\5
+${}\\{minimal\_demerits}[\\{decent\_fit}]\K\\{awful\_bad};{}$\5
+${}\\{minimal\_demerits}[\\{loose\_fit}]\K\\{awful\_bad};{}$\5
+${}\\{minimal\_demerits}[\\{very\_loose\_fit}]\K\\{awful\_bad}{}$;\par
+\fi
+
+\M{835}The first part of the following code is part of \TeX's inner loop, so
+we don't want to waste any time. The current active node, namely node \|r,
+contains the line number that will be considered next. At the end of the
+list we have arranged the data structure so that $\|r\E\\{last\_active}$ and
+$\\{line\_number}(\\{last\_active})>\\{old\_l}$.
+
+\Y\B\4\X835:If a line number class has ended, create new active nodes for the best feasible breaks in that class; then \&{return} if $\|r\K\\{last\_active}$, otherwise compute the new \\{line\_width}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|l\K\\{line\_number}(\|r);{}$\6
+\&{if} ${}(\|l>\\{old\_l}){}$\5
+${}\{{}$\5
+\C{now we are no longer in the inner loop}\1\6
+\&{if} ${}((\\{minimum\_demerits}<\\{awful\_bad})\W\30((\\{old\_l}\I\\{easy\_line})\V(\|r\E\\{last\_active}))){}$\1\5
+\X836:Create new active nodes for the best feasible breaks just found\X;\2\6
+\&{if} ${}(\|r\E\\{last\_active}){}$\1\5
+\&{goto} \\{end};\2\6
+\X850:Compute the new line width\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U829.\fi
+
+\M{836}It is not necessary to create new active nodes having \\{minimal\_demerits}
+greater than
+$\\{minimum\_demerits}+\\{abs}(\\{adj\_demerits})$, since such active nodes will never
+be chosen in the final paragraph breaks. This observation allows us to
+omit a substantial number of feasible breakpoints from further consideration.
+
+\Y\B\4\X836:Create new active nodes for the best feasible breaks just found\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} (\\{no\_break\_yet})\1\5
+\X837:Compute the values of \\{break\_width}\X;\2\6
+\X843:Insert a delta node to prepare for breaks at \\{cur\_p}\X;\6
+\&{if} ${}(\\{abs}(\\{adj\_demerits})\G\\{awful\_bad}-\\{minimum\_demerits}){}$\1\5
+${}\\{minimum\_demerits}\K\\{awful\_bad}-\T{1};{}$\2\6
+\&{else}\1\5
+${}\\{minimum\_demerits}\K\\{minimum\_demerits}+\\{abs}(\\{adj\_demerits});{}$\2\6
+\&{for} ${}(\\{fit\_class}\K\\{very\_loose\_fit};{}$ ${}\\{fit\_class}\Z\\{tight\_fit};{}$ ${}\\{fit\_class}\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{minimal\_demerits}[\\{fit\_class}]\Z\\{minimum\_demerits}){}$\1\5
+\X845:Insert a new active node from \\{best\_place}[\\{fit\_class}] to \\{cur\_p}\X;\2\6
+${}\\{minimal\_demerits}[\\{fit\_class}]\K\\{awful\_bad};{}$\6
+\4${}\}{}$\2\6
+${}\\{minimum\_demerits}\K\\{awful\_bad};{}$\5
+\X844:Insert a delta node to prepare for the next active node\X;\6
+\4${}\}{}$\2\par
+\U835.\fi
+
+\M{837}When we insert a new active node for a break at \\{cur\_p}, suppose this
+new node is to be placed just before active node \|a; then we essentially
+want to insert `$\delta\,\\{cur\_p}\,\delta^\prime$' before \|a, where
+$\delta=\alpha(a)-\alpha(\\{cur\_p})$ and $\delta^\prime=\alpha(\\{cur\_p})-\alpha(a)$
+in the notation explained above. The \\{cur\_active\_width} array now holds
+$\gamma+\beta(\\{cur\_p})-\alpha(a)$; so $\delta$ can be obtained by
+subtracting \\{cur\_active\_width} from the quantity $\gamma+\beta(\\{cur\_p})-
+\alpha(\\{cur\_p})$. The latter quantity can be regarded as the length of a
+line ``from \\{cur\_p} to \\{cur\_p}''; we call it the \\{break\_width} at \\{cur\_p}.
+
+The \\{break\_width} is usually negative, since it consists of the background
+(which is normally zero) minus the width of nodes following~\\{cur\_p} that are
+eliminated after a break. If, for example, node \\{cur\_p} is a glue node, the
+width of this glue is subtracted from the background; and we also look
+ahead to eliminate all subsequent glue and penalty and kern and math
+nodes, subtracting their widths as well.
+
+Kern nodes do not disappear at a line break unless they are \&{explicit}.
+
+\Y\B\4\D$\\{set\_break\_width\_to\_background}(\|X)$ \5
+$\\{break\_width}[\|X]\K\\{background}{}$[\|X]\par
+\Y\B\4\X837:Compute the values of \\{break\_width}\X${}\E{}$\6
+$\{{}$\5
+$\\{no\_break\_yet}\K\\{false};{}$\5
+\\{do\_all\_six}(\\{set\_break\_width\_to\_background});\5
+${}\|s\K\\{cur\_p};{}$\6
+\&{if} ${}(\\{break\_type}>\\{unhyphenated}){}$\1\6
+\&{if} ${}(\\{cur\_p}\I\\{null}){}$\1\5
+\X840:Compute the discretionary \\{break\_width} values\X;\2\2\6
+\&{while} ${}(\|s\I\\{null})$ $\{{}$\5
+\&{if} (\\{is\_char\_node}(\|s))\1\5
+\&{goto} \\{done};\2\6
+\&{switch} (\\{type}(\|s)) $\{$ \6
+\4\&{case} \\{glue\_node}:\5
+\X838:Subtract glue from \\{break\_width}\X\5
+\&{break};\6
+\4\&{case} \\{penalty\_node}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{math\_node}:\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]-\\{width}(\|s){}$;\5
+\&{break}; \&{case} \\{kern\_node}: \&{if} ( \\{subtype}(\|s) $\I$ \&{explicit} ) \&{goto} \\{done};\6
+\&{else}\1\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]-\\{width}(\|s){}$;\5
+\2\&{break};\6
+\4\&{default}:\5
+\&{goto} \\{done}; $\}{}$\6
+$\|s\K\\{link}(\|s);$ $\}$ \6
+\4\\{done}:\5
+; $\}{}$\par
+\U836.\fi
+
+\M{838}\B\X838:Subtract glue from \\{break\_width}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|v\K\\{glue\_ptr}(\|s);{}$\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]-\\{width}(\|v);{}$\5
+${}\\{break\_width}[\T{2}+\\{stretch\_order}(\|v)]\K\\{break\_width}[\T{2}+\\{stretch\_order}(\|v)]-\\{stretch}(\|v);{}$\5
+${}\\{break\_width}[\T{6}]\K\\{break\_width}[\T{6}]-\\{shrink}(\|v);{}$\6
+\4${}\}{}$\2\par
+\U837.\fi
+
+\M{839}When \\{cur\_p} is a discretionary break, the length of a line ``from \\{cur\_p} to
+\\{cur\_p}'' has to be defined properly so that the other calculations work out.
+Suppose that the pre-break text at \\{cur\_p} has length $l_0$, the post-break
+text has length $l_1$, and the replacement text has length \|l. Suppose
+also that \|q is the node following the replacement text. Then length of a
+line from \\{cur\_p} to \|q will be computed as $\gamma+\beta(q)-\alpha(\\{cur\_p})$,
+where $\beta(q)=\beta(\\{cur\_p})-l_0+l$. The actual length will be the background
+plus $l_1$, so the length from \\{cur\_p} to \\{cur\_p} should be $\gamma+l_0+l_1-l$.
+If the post-break text of the discretionary is empty, a break may also
+discard~\|q; in that unusual case we subtract the length of~\|q and any
+other nodes that will be discarded after the discretionary break.
+
+The value of $l_0$ need not be computed, since \\{line\_break} will put
+it into the global variable \\{disc\_width} before calling \\{try\_break}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} \\{disc\_width};\C{the length of discretionary material preceding a break}\par
+\fi
+
+\M{840}\B\X840:Compute the discretionary \\{break\_width} values\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|t\K\\{replace\_count}(\\{cur\_p});{}$\5
+${}\|v\K\\{cur\_p};{}$\5
+${}\|s\K\\{post\_break}(\\{cur\_p});{}$\6
+\&{while} ${}(\|t>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|t);\5
+${}\|v\K\\{link}(\|v);{}$\5
+\X841:Subtract the width of node \|v from \\{break\_width}\X;\6
+\4${}\}{}$\2\6
+\&{while} ${}(\|s\I\\{null}){}$\5
+${}\{{}$\5
+\1\X842:Add the width of node \|s to \\{break\_width}\X;\6
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\2\6
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]+\\{disc\_width};{}$\6
+\&{if} ${}(\\{post\_break}(\\{cur\_p})\E\\{null}){}$\1\5
+${}\|s\K\\{link}(\|v){}$;\C{nodes may be discardable after the break}\2\6
+\4${}\}{}$\2\par
+\U837.\fi
+
+\M{841}Replacement texts and discretionary texts are supposed to contain
+only character nodes, kern nodes, ligature nodes, and box or rule nodes.
+
+\Y\B\4\X841:Subtract the width of node \|v from \\{break\_width}\X${}\E{}$\6
+\&{if} (\\{is\_char\_node}(\|v))\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|v);{}$\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]-\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|v)));{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|v))\5
+${}\{{}$\1\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\\{lig\_char}(\|v)){}$;\6
+${}\\{break\_width}[\T{1}]\K\30\\{break\_width}[\T{1}]-\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{lig\_char}(\|v))));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{kern\_node}:\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]-\\{width}(\|v){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1677:\.{"disc1"}\X);\6
+\4${}\}{}$\2\2\par
+\U840.\fi
+
+\M{842}\B\X842:Add the width of node \|s to \\{break\_width}\X${}\E{}$\6
+\&{if} (\\{is\_char\_node}(\|s))\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|s);{}$\5
+${}\\{break\_width}[\T{1}]\K\30\\{break\_width}[\T{1}]+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|s)));{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|s))\5
+${}\{{}$\1\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\\{lig\_char}(\|s));{}$\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{lig\_char}(\|s))));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{kern\_node}:\5
+${}\\{break\_width}[\T{1}]\K\\{break\_width}[\T{1}]+\\{width}(\|s){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1678:\.{"disc2"}\X);\6
+\4${}\}{}$\2\2\par
+\U840.\fi
+
+\M{843}We use the fact that $\\{type}(\\{active})\I\\{delta\_node}$.
+
+\Y\B\4\D$\\{convert\_to\_break\_width}(\|X)$ \5
+$\\{mem}[\\{prev\_r}+\|X].\\{sc}\K\30\hbox{\hskip10pt}\\{mem}[\\{prev\_r}+\|X].\\{sc}-\\{cur\_active\_width}[\|X]+\\{break\_width}{}$[\|X]\par
+\B\4\D$\\{store\_break\_width}(\|X)$ \5
+$\\{active\_width}[\|X]\K\\{break\_width}{}$[\|X]\par
+\B\4\D$\\{new\_delta\_to\_break\_width}(\|X)$ \5
+$\\{mem}[\|q+\|X].\\{sc}\K\\{break\_width}[\|X]-\\{cur\_active\_width}{}$[\|X]\par
+\Y\B\4\X843:Insert a delta node to prepare for breaks at \\{cur\_p}\X${}\E{}$\6
+\&{if} ${}(\\{type}(\\{prev\_r})\E\\{delta\_node}{}$)\C{modify an existing delta node}\6
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{convert\_to\_break\_width});\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{prev\_r}\E\\{active}{}$)\C{no delta node needed at the beginning}\6
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{store\_break\_width});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{get\_node}(\\{delta\_node\_size});{}$\5
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{type}(\|q)\K\\{delta\_node}{}$;\6
+${}\\{subtype}(\|q)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+\\{do\_all\_six}(\\{new\_delta\_to\_break\_width});\5
+${}\\{link}(\\{prev\_r})\K\|q;{}$\5
+${}\\{prev\_prev\_r}\K\\{prev\_r};{}$\5
+${}\\{prev\_r}\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U836.\fi
+
+\M{844}When the following code is performed, we will have just inserted at
+least one active node before \|r, so $\\{type}(\\{prev\_r})\I\\{delta\_node}$.
+
+\Y\B\4\D$\\{new\_delta\_from\_break\_width}(\|X)$ \5
+$\\{mem}[\|q+\|X].\\{sc}\K\\{cur\_active\_width}[\|X]-\\{break\_width}{}$[\|X]\par
+\Y\B\4\X844:Insert a delta node to prepare for the next active node\X${}\E{}$\6
+\&{if} ${}(\|r\I\\{last\_active}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{get\_node}(\\{delta\_node\_size});{}$\5
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{type}(\|q)\K\\{delta\_node}{}$;\6
+${}\\{subtype}(\|q)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+\\{do\_all\_six}(\\{new\_delta\_from\_break\_width});\5
+${}\\{link}(\\{prev\_r})\K\|q;{}$\5
+${}\\{prev\_prev\_r}\K\\{prev\_r};{}$\5
+${}\\{prev\_r}\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U836.\fi
+
+\M{845}When we create an active node, we also create the corresponding
+passive node.
+
+\Y\B\4\X845:Insert a new active node from \\{best\_place}[\\{fit\_class}] to \\{cur\_p}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{get\_node}(\\{passive\_node\_size});{}$\5
+${}\\{link}(\|q)\K\\{passive};{}$\5
+${}\\{passive}\K\|q;{}$\5
+${}\\{cur\_break}(\|q)\K\\{cur\_p};{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\\{incr}(\\{pass\_number});\5
+${}\\{serial}(\|q)\K\\{pass\_number};{}$\6
+\8\#\&{endif}\6
+${}\\{prev\_break}(\|q)\K\\{best\_place}[\\{fit\_class}]{}$;\6
+${}\|q\K\\{get\_node}(\\{active\_node\_size});{}$\5
+${}\\{break\_node}(\|q)\K\\{passive};{}$\5
+${}\\{line\_number}(\|q)\K\\{best\_pl\_line}[\\{fit\_class}]+\T{1};{}$\5
+${}\\{fitness}(\|q)\K\\{fit\_class};{}$\5
+${}\\{type}(\|q)\K\\{break\_type};{}$\5
+${}\\{total\_demerits}(\|q)\K\\{minimal\_demerits}[\\{fit\_class}];{}$\5
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{link}(\\{prev\_r})\K\|q;{}$\5
+${}\\{prev\_r}\K\|q;{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\1\5
+\X846:Print a symbolic description of the new break node\X;\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\par
+\U836.\fi
+
+\M{846}\B\X846:Print a symbolic description of the new break node\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{"@@"});\5
+\\{print\_int}(\\{serial}(\\{passive}));\5
+\\{print\_str}(\.{":\ line\ "});\5
+${}\\{print\_int}(\\{line\_number}(\|q)-\T{1});{}$\5
+\\{print\_char}(\.{'.'});\5
+\\{print\_int}(\\{fit\_class});\6
+\&{if} ${}(\\{break\_type}\E\\{hyphenated}){}$\1\5
+\\{print\_char}(\.{'-'});\2\6
+\\{print\_str}(\.{"\ t="});\5
+\\{print\_int}(\\{total\_demerits}(\|q));\5
+\\{print\_str}(\.{"\ ->\ @@"});\6
+\&{if} ${}(\\{prev\_break}(\\{passive})\E\\{null}){}$\1\5
+\\{print\_char}(\.{'0'});\2\6
+\&{else}\1\5
+\\{print\_int}(\\{serial}(\\{prev\_break}(\\{passive})));\2\6
+\4${}\}{}$\2\par
+\U845.\fi
+
+\M{847}The length of lines depends on whether the user has specified
+\.{\\parshape} or \.{\\hangindent}. If \\{par\_shape\_ptr} is not null, it
+points to a $(2n+1)$-word record in \\{mem}, where the \\{info} in the first
+word contains the value of \|n, and the other $2n$ words contain the left
+margins and line lengths for the first \|n lines of the paragraph; the
+specifications for line \|n apply to all subsequent lines. If
+$\\{par\_shape\_ptr}\E\\{null}$, the shape of the paragraph depends on the value of
+$\|n\E\\{hang\_after}$; if $\|n\G\T{0}$, hanging indentation takes place on lines $\|n+\T{1}$,
+$\|n+\T{2}$, \dots, otherwise it takes place on lines 1, \dots, $\vert
+n\vert$. When hanging indentation is active, the left margin is
+\\{hang\_indent}, if $\\{hang\_indent}\G\T{0}$, else it is 0; the line length is
+$\\{hsize}-\vert\\{hang\_indent}\vert$. The normal setting is
+$\\{par\_shape\_ptr}\E\\{null}$, $\\{hang\_after}\E\T{1}$, and $\\{hang\_indent}\E\T{0}$.
+Note that if $\\{hang\_indent}\E\T{0}$, the value of \\{hang\_after} is irrelevant.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{halfword} \\{easy\_line};\C{line numbers $>$ \\{easy\_line} are equivalent in break nodes}\6
+\&{halfword} \\{last\_special\_line};\C{line numbers $>$ \\{last\_special\_line} all have the same width}\6
+\&{scaled} \\{first\_width};\C{the width of all lines $\Z$ \\{last\_special\_line}, if no \.{\\parshape} has been specified}\6
+\&{scaled} \\{second\_width};\C{the width of all lines $>$ \\{last\_special\_line}}\6
+\&{scaled} \\{first\_indent};\C{left margin to go with \\{first\_width}}\6
+\&{scaled} \\{second\_indent};\C{left margin to go with \\{second\_width}}\par
+\fi
+
+\M{848}We compute the values of \\{easy\_line} and the other local variables relating
+to line length when the \\{line\_break} procedure is initializing itself.
+
+\Y\B\4\X816:Get ready to start line breaking\X${}\mathrel+\E{}$\6
+\&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\1\6
+\&{if} ${}(\\{hang\_indent}\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{last\_special\_line}\K\T{0};{}$\5
+${}\\{second\_width}\K\\{hsize};{}$\5
+${}\\{second\_indent}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\X849:Set line length parameters in preparation for hanging indentation\X\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{last\_special\_line}\K\\{info}(\\{par\_shape\_ptr})-\T{1};{}$\5
+${}\\{second\_width}\K\\{mem}[\\{par\_shape\_ptr}+\T{2}*(\\{last\_special\_line}+\T{1})].\\{sc};{}$\5
+${}\\{second\_indent}\K\\{mem}[\\{par\_shape\_ptr}+\T{2}*\\{last\_special\_line}+\T{1}].\\{sc};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{looseness}\E\T{0}){}$\1\5
+${}\\{easy\_line}\K\\{last\_special\_line};{}$\2\6
+\&{else} $\\{easy\_line}\K{}$\\{max\_halfword}\par
+\fi
+
+\M{849}\B\X849:Set line length parameters in preparation for hanging indentation\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{last\_special\_line}\K\\{abs}(\\{hang\_after});{}$\6
+\&{if} ${}(\\{hang\_after}<\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{first\_width}\K\\{hsize}-\\{abs}(\\{hang\_indent});{}$\6
+\&{if} ${}(\\{hang\_indent}\G\T{0}){}$\1\5
+${}\\{first\_indent}\K\\{hang\_indent};{}$\2\6
+\&{else}\1\5
+${}\\{first\_indent}\K\T{0};{}$\2\6
+${}\\{second\_width}\K\\{hsize};{}$\5
+${}\\{second\_indent}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{first\_width}\K\\{hsize};{}$\5
+${}\\{first\_indent}\K\T{0};{}$\5
+${}\\{second\_width}\K\\{hsize}-\\{abs}(\\{hang\_indent});{}$\6
+\&{if} ${}(\\{hang\_indent}\G\T{0}){}$\1\5
+${}\\{second\_indent}\K\\{hang\_indent};{}$\2\6
+\&{else}\1\5
+${}\\{second\_indent}\K\T{0};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U848.\fi
+
+\M{850}When we come to the following code, we have just encountered the first
+active node~\|r whose \\{line\_number} field contains \|l. Thus we want to
+compute the length of the $l\mskip1mu$th line of the current paragraph. Furthermore,
+we want to set \\{old\_l} to the last number in the class of line numbers
+equivalent to~\|l.
+
+\Y\B\4\X850:Compute the new line width\X${}\E{}$\6
+\&{if} ${}(\|l>\\{easy\_line}){}$\5
+${}\{{}$\5
+\1${}\\{line\_width}\K\\{second\_width};{}$\5
+${}\\{old\_l}\K\\{max\_halfword}-\T{1};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{old\_l}\K\|l;{}$\6
+\&{if} ${}(\|l>\\{last\_special\_line}){}$\1\5
+${}\\{line\_width}\K\\{second\_width};{}$\2\6
+\&{else} \&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\1\5
+${}\\{line\_width}\K\\{first\_width};{}$\2\6
+\&{else}\1\5
+${}\\{line\_width}\K\\{mem}[\\{par\_shape\_ptr}+\T{2}*\|l\,].\\{sc};{}$\2\6
+\4${}\}{}$\2\par
+\U835.\fi
+
+\M{851}The remaining part of \\{try\_break} deals with the calculation of
+demerits for a break from \|r to \\{cur\_p}.
+
+The first thing to do is calculate the badness, \|b. This value will always
+be between zero and $\\{inf\_bad}+\T{1}$; the latter value occurs only in the
+case of lines from \|r to \\{cur\_p} that cannot shrink enough to fit the necessary
+width. In such cases, node \|r will be deactivated.
+We also deactivate node~\|r when a break at~\\{cur\_p} is forced, since future
+breaks must go through a forced break.
+
+\Y\B\4\X851:Consider the demerits for a line from \|r to \\{cur\_p}; deactivate node \|r if it should no longer be active; then \&{goto} \&{continue} if a line from \|r to \\{cur\_p} is infeasible, otherwise record a new feasible break\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{artificial\_demerits}\K\\{false}{}$;\6
+${}\\{shortfall}\K\\{line\_width}-\\{cur\_active\_width}[\T{1}]{}$;\C{we're this much too short}\6
+\&{if} ${}(\\{shortfall}>\T{0}){}$\1\5
+\X852:Set the value of \|b to the badness for stretching the line, and compute the corresponding \\{fit\_class}\X\2\6
+\&{else}\1\5
+\X853:Set the value of \|b to the badness for shrinking the line, and compute the corresponding \\{fit\_class}\X;\2\6
+\&{if} ${}((\|b>\\{inf\_bad})\V(\\{pi}\E\\{eject\_penalty})){}$\1\5
+\X854:Prepare to deactivate node~\|r, and \&{goto} \\{deactivate} unless there is a reason to consider lines of text from \|r to \\{cur\_p}\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{prev\_r}\K\|r;{}$\6
+\&{if} ${}(\|b>\\{threshold}){}$\1\5
+\&{goto} \\{resume};\2\6
+${}\\{node\_r\_stays\_active}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\X855:Record a new feasible break\X;\6
+\&{if} (\\{node\_r\_stays\_active})\1\5
+\&{goto} \\{resume};\C{\\{prev\_r} has been set to \|r}\2\6
+\4\\{deactivate}:\5
+\X860:Deactivate node \|r\X;\6
+\4${}\}{}$\2\par
+\U829.\fi
+
+\M{852}When a line must stretch, the available stretchability can be found in the
+subarray $\\{cur\_active\_width}[\T{2}\dotdot\T{5}]$, in units of points, fil, fill, and filll.
+
+The present section is part of \TeX's inner loop, and it is most often performed
+when the badness is infinite; therefore it is worth while to make a quick
+test for large width excess and small stretchability, before calling the
+\\{badness} subroutine.
+
+\Y\B\4\X852:Set the value of \|b to the badness for stretching the line, and compute the corresponding \\{fit\_class}\X${}\E{}$\6
+\&{if} ${}((\\{cur\_active\_width}[\T{3}]\I\T{0})\V(\\{cur\_active\_width}[\T{4}]\I\T{0})\V\30(\\{cur\_active\_width}[\T{5}]\I\T{0})){}$\5
+${}\{{}$\5
+\1${}\|b\K\T{0};{}$\5
+${}\\{fit\_class}\K\\{decent\_fit}{}$;\C{infinite stretch}\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{shortfall}>\T{7230584}){}$\1\6
+\&{if} ${}(\\{cur\_active\_width}[\T{2}]<\T{1663497}){}$\5
+${}\{{}$\5
+\1${}\|b\K\\{inf\_bad};{}$\5
+${}\\{fit\_class}\K\\{very\_loose\_fit};{}$\5
+\&{goto} \\{done1};\6
+\4${}\}{}$\2\2\6
+${}\|b\K\\{badness}(\\{shortfall},\39\\{cur\_active\_width}[\T{2}]);{}$\6
+\&{if} ${}(\|b>\T{12}){}$\1\6
+\&{if} ${}(\|b>\T{99}){}$\1\5
+${}\\{fit\_class}\K\\{very\_loose\_fit};{}$\2\6
+\&{else}\1\5
+${}\\{fit\_class}\K\\{loose\_fit};{}$\2\2\6
+\&{else}\1\5
+${}\\{fit\_class}\K\\{decent\_fit};{}$\2\6
+\4\\{done1}:\5
+;\6
+\4${}\}{}$\2\par
+\U851.\fi
+
+\M{853}Shrinkability is never infinite in a paragraph;
+we can shrink the line from \|r to \\{cur\_p} by at most \\{cur\_active\_width}[\T{6}].
+
+\Y\B\4\X853:Set the value of \|b to the badness for shrinking the line, and compute the corresponding \\{fit\_class}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}({-}\\{shortfall}>\\{cur\_active\_width}[\T{6}]){}$\1\5
+${}\|b\K\\{inf\_bad}+\T{1};{}$\2\6
+\&{else}\1\5
+${}\|b\K\\{badness}({-}\\{shortfall},\39\\{cur\_active\_width}[\T{6}]);{}$\2\6
+\&{if} ${}(\|b>\T{12}){}$\1\5
+${}\\{fit\_class}\K\\{tight\_fit}{}$;\5
+\2\&{else}\1\5
+${}\\{fit\_class}\K\\{decent\_fit};{}$\2\6
+\4${}\}{}$\2\par
+\U851.\fi
+
+\M{854}During the final pass, we dare not lose all active nodes, lest we lose
+touch with the line breaks already found. The code shown here makes sure
+that such a catastrophe does not happen, by permitting overfull boxes as
+a last resort. This particular part of \TeX\ was a source of several subtle
+bugs before the correct program logic was finally discovered; readers
+who seek to ``improve'' \TeX\ should therefore think thrice before daring
+to make any changes here.
+
+\Y\B\4\X854:Prepare to deactivate node~\|r, and \&{goto} \\{deactivate} unless there is a reason to consider lines of text from \|r to \\{cur\_p}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{final\_pass}\W(\\{minimum\_demerits}\E\\{awful\_bad})\W\30(\\{link}(\|r)\E\\{last\_active})\W(\\{prev\_r}\E\\{active})){}$\1\5
+${}\\{artificial\_demerits}\K\\{true}{}$;\C{set demerits zero, this break is forced}\2\6
+\&{else} \&{if} ${}(\|b>\\{threshold}){}$\1\5
+\&{goto} \\{deactivate};\2\6
+${}\\{node\_r\_stays\_active}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\U851.\fi
+
+\M{855}When we get to this part of the code, the line from \|r to \\{cur\_p} is
+feasible, its badness is~\|b, and its fitness classification is \\{fit\_class}.
+We don't want to make an active node for this break yet, but we will
+compute the total demerits and record them in the \\{minimal\_demerits} array,
+if such a break is the current champion among all ways to get to \\{cur\_p}
+in a given line-number class and fitness class.
+
+\Y\B\4\X855:Record a new feasible break\X${}\E{}$\6
+\&{if} (\\{artificial\_demerits})\1\5
+${}\|d\K\T{0};{}$\2\6
+\&{else}\1\5
+\X859:Compute the demerits, \|d, from \|r to \\{cur\_p}\X;\2\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\1\5
+\X856:Print a symbolic description of this feasible break\X;\2\6
+\8\#\&{endif}\6
+${}\|d\K\|d+\\{total\_demerits}(\|r){}$;\C{this is the minimum total demerits from the beginning to \\{cur\_p} via \|r}\6
+\&{if} ${}(\|d\Z\\{minimal\_demerits}[\\{fit\_class}]){}$\5
+${}\{{}$\5
+\1${}\\{minimal\_demerits}[\\{fit\_class}]\K\|d;{}$\5
+${}\\{best\_place}[\\{fit\_class}]\K\\{break\_node}(\|r);{}$\5
+${}\\{best\_pl\_line}[\\{fit\_class}]\K\|l;{}$\6
+\&{if} ${}(\|d<\\{minimum\_demerits}){}$\1\5
+${}\\{minimum\_demerits}\K\|d;{}$\2\6
+\4${}\}{}$\2\par
+\U851.\fi
+
+\M{856}\B\X856:Print a symbolic description of this feasible break\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{printed\_node}\I\\{cur\_p}){}$\1\5
+\X857:Print the list between \\{printed\_node} and \\{cur\_p}, then set \\{printed\_node}: $\K$ \\{cur\_p}\X;\2\6
+\\{print\_nl}(\.{"@"});\6
+\&{if} ${}(\\{cur\_p}\E\\{null}){}$\1\5
+\\{print\_esc}(\X1569:\.{"par"}\X);\2\6
+\&{else} \&{if} ${}(\\{type}(\\{cur\_p})\I\\{glue\_node}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\\{cur\_p})\E\\{penalty\_node}){}$\1\5
+\\{print\_esc}(\X1553:\.{"penalty"}\X);\2\6
+\&{else} \&{if} ${}(\\{type}(\\{cur\_p})\E\\{disc\_node}){}$\1\5
+\\{print\_esc}(\X1400:\.{"discretionary"}\X);\2\6
+\&{else} \&{if} ${}(\\{type}(\\{cur\_p})\E\\{kern\_node}){}$\1\5
+\\{print\_esc}(\X1396:\.{"kern"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1398:\.{"math"}\X);\2\6
+\4${}\}{}$\2\6
+\\{print\_str}(\.{"\ via\ @@"});\6
+\&{if} ${}(\\{break\_node}(\|r)\E\\{null}){}$\1\5
+\\{print\_char}(\.{'0'});\2\6
+\&{else}\1\5
+\\{print\_int}(\\{serial}(\\{break\_node}(\|r)));\2\6
+\\{print\_str}(\.{"\ b="});\6
+\&{if} ${}(\|b>\\{inf\_bad}){}$\1\5
+\\{print\_char}(\.{'*'});\5
+\2\&{else}\1\5
+\\{print\_int}(\|b);\2\6
+\\{print\_str}(\.{"\ p="});\5
+\\{print\_int}(\\{pi});\5
+\\{print\_str}(\.{"\ d="});\6
+\&{if} (\\{artificial\_demerits})\1\5
+\\{print\_char}(\.{'*'});\5
+\2\&{else}\1\5
+\\{print\_int}(\|d);\2\6
+\4${}\}{}$\2\par
+\U855.\fi
+
+\M{857}\B\X857:Print the list between \\{printed\_node} and \\{cur\_p}, then set \\{printed\_node}: $\K$ \\{cur\_p}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_nl}(\.{""});\6
+\&{if} ${}(\\{cur\_p}\E\\{null}){}$\1\5
+\\{short\_display}(\\{link}(\\{printed\_node}));\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{save\_link}\K\\{link}(\\{cur\_p});{}$\5
+${}\\{link}(\\{cur\_p})\K\\{null};{}$\5
+\\{print\_nl}(\.{""});\5
+\\{short\_display}(\\{link}(\\{printed\_node}));\5
+${}\\{link}(\\{cur\_p})\K\\{save\_link};{}$\6
+\4${}\}{}$\2\6
+${}\\{printed\_node}\K\\{cur\_p};{}$\6
+\4${}\}{}$\2\par
+\U856.\fi
+
+\M{858}When the data for a discretionary break is being displayed, we will have
+printed the \\{pre\_break} and \\{post\_break} lists; we want to skip over the
+third list, so that the discretionary data will not appear twice. The
+following code is performed at the very end of \\{try\_break}.
+
+\Y\B\4\X858:Update the value of \\{printed\_node} for symbolic displays\X${}\E{}$\6
+\&{if} ${}(\\{cur\_p}\E\\{printed\_node}){}$\1\6
+\&{if} ${}(\\{cur\_p}\I\\{null}){}$\1\6
+\&{if} ${}(\\{type}(\\{cur\_p})\E\\{disc\_node}){}$\5
+${}\{{}$\5
+\1${}\|t\K\\{replace\_count}(\\{cur\_p});{}$\6
+\&{while} ${}(\|t>\T{0}){}$\5
+${}\{{}$\5
+\1\\{decr}(\|t);\5
+${}\\{printed\_node}\K\\{link}(\\{printed\_node});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\2\par
+\U829.\fi
+
+\M{859}\B\X859:Compute the demerits, \|d, from \|r to \\{cur\_p}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|d\K\\{line\_penalty}+\|b;{}$\6
+\&{if} ${}(\\{abs}(\|d)\G\T{10000}){}$\1\5
+${}\|d\K\T{100000000}{}$;\5
+\2\&{else}\1\5
+${}\|d\K\|d*\|d;{}$\2\6
+\&{if} ${}(\\{pi}\I\T{0}){}$\1\6
+\&{if} ${}(\\{pi}>\T{0}){}$\1\5
+${}\|d\K\|d+\\{pi}*\\{pi};{}$\2\6
+\&{else} \&{if} ${}(\\{pi}>\\{eject\_penalty}){}$\1\5
+${}\|d\K\|d-\\{pi}*\\{pi};{}$\2\2\6
+\&{if} ${}((\\{break\_type}\E\\{hyphenated})\W(\\{type}(\|r)\E\\{hyphenated})){}$\1\6
+\&{if} ${}(\\{cur\_p}\I\\{null}){}$\1\5
+${}\|d\K\|d+\\{double\_hyphen\_demerits};{}$\2\6
+\&{else}\1\5
+${}\|d\K\|d+\\{final\_hyphen\_demerits};{}$\2\2\6
+\&{if} ${}(\\{abs}(\\{fit\_class}-\\{fitness}(\|r))>\T{1}){}$\1\5
+${}\|d\K\|d+\\{adj\_demerits};{}$\2\6
+\4${}\}{}$\2\par
+\U855.\fi
+
+\M{860}When an active node disappears, we must delete an adjacent delta node if the
+active node was at the beginning or the end of the active list, or if it
+was surrounded by delta nodes. We also must preserve the property that
+\\{cur\_active\_width} represents the length of material from \\{link}(\\{prev\_r})
+to~\\{cur\_p}.
+
+\Y\B\4\D$\\{combine\_two\_deltas}(\|X)$ \5
+$\\{mem}[\\{prev\_r}+\|X].\\{sc}\K\\{mem}[\\{prev\_r}+\|X].\\{sc}+\\{mem}[\|r+\|X].{}$\\{sc}\par
+\B\4\D$\\{downdate\_width}(\|X)$ \5
+$\\{cur\_active\_width}[\|X]\K\\{cur\_active\_width}[\|X]-\\{mem}[\\{prev\_r}+\|X].{}$\\{sc}\par
+\Y\B\4\X860:Deactivate node \|r\X${}\E{}$\6
+$\\{link}(\\{prev\_r})\K\\{link}(\|r);{}$\5
+${}\\{free\_node}(\|r,\39\\{active\_node\_size});{}$\6
+\&{if} ${}(\\{prev\_r}\E\\{active}){}$\1\5
+\X861:Update the active widths, since the first active node has been deleted\X\2\6
+\&{else} \&{if} ${}(\\{type}(\\{prev\_r})\E\\{delta\_node}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{prev\_r});{}$\6
+\&{if} ${}(\|r\E\\{last\_active}){}$\5
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{downdate\_width});\5
+${}\\{link}(\\{prev\_prev\_r})\K\\{last\_active};{}$\5
+${}\\{free\_node}(\\{prev\_r},\39\\{delta\_node\_size});{}$\5
+${}\\{prev\_r}\K\\{prev\_prev\_r};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|r)\E\\{delta\_node}){}$\5
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{update\_width});\5
+\\{do\_all\_six}(\\{combine\_two\_deltas});\5
+${}\\{link}(\\{prev\_r})\K\\{link}(\|r);{}$\5
+${}\\{free\_node}(\|r,\39\\{delta\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U851.\fi
+
+\M{861}The following code uses the fact that $\\{type}(\\{last\_active})\I\\{delta\_node}$. If the
+active list has just become empty, we do not need to update the
+\\{active\_width} array, since it will be initialized when an active
+node is next inserted.
+
+\Y\B\4\D$\\{update\_active}(\|X)$ \5
+$\\{active\_width}[\|X]\K\\{active\_width}[\|X]+\\{mem}[\|r+\|X].{}$\\{sc}\par
+\Y\B\4\X861:Update the active widths, since the first active node has been deleted\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{active});{}$\6
+\&{if} ${}(\\{type}(\|r)\E\\{delta\_node}){}$\5
+${}\{{}$\5
+\1\\{do\_all\_six}(\\{update\_active});\5
+\\{do\_all\_six}(\\{copy\_to\_cur\_active});\5
+${}\\{link}(\\{active})\K\\{link}(\|r);{}$\5
+${}\\{free\_node}(\|r,\39\\{delta\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U860.\fi
+
+\N{1}{862}Breaking paragraphs into lines, continued.
+So far we have gotten a little way into the \\{line\_break} routine, having
+covered its important \\{try\_break} subroutine. Now let's consider the
+rest of the process.
+
+The main loop of \\{line\_break} traverses the given hlist,
+starting at \\{link}(\\{temp\_head}), and calls \\{try\_break} at each legal
+breakpoint. A variable called \\{auto\_breaking} is set to true except
+within math formulas, since glue nodes are not legal breakpoints when
+they appear in formulas.
+
+The current node of interest in the hlist is pointed to by \\{cur\_p}. Another
+variable, \\{prev\_p}, is usually one step behind \\{cur\_p}, but the real
+meaning of \\{prev\_p} is this: If $\\{type}(\\{cur\_p})\E\\{glue\_node}$ then \\{cur\_p} is a legal
+breakpoint if and only if \\{auto\_breaking} is true and \\{prev\_p} does not
+point to a glue node, penalty node, explicit kern node, or math node.
+
+The following declarations provide for a few other local variables that are
+used in special calculations.
+
+\Y\B\4\X862:Local variables for line breaking\X${}\E{}$\6
+\&{bool} \\{auto\_breaking};\C{is node \\{cur\_p} outside a formula?}\6
+\&{pointer} \\{prev\_p};\C{helps to determine when glue nodes are breakpoints}\6
+\&{pointer} \|q${},{}$ \|r${},{}$ \|s${},{}$ \\{prev\_s};\C{miscellaneous nodes of temporary interest}\6
+\&{internal\_font\_number} \|f;\C{used when calculating character widths}\par
+\A893.
+\U815.\fi
+
+\M{863}The `\ignorespaces\&{loop}\unskip' in the following code is performed at most
+thrice per call of \\{line\_break}, since it is actually a pass over the
+entire paragraph.
+
+\Y\B\4\X863:Find optimal breakpoints\X${}\E{}$\6
+$\\{threshold}\K\\{pretolerance};{}$\6
+\&{if} ${}(\\{threshold}\G\T{0}){}$\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{STAT}\1\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"@firstpass"});\5
+${}\}{}$\2\6
+\8\#\&{endif}\6
+${}\\{second\_pass}\K\\{false};{}$\5
+${}\\{final\_pass}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{threshold}\K\\{tolerance};{}$\5
+${}\\{second\_pass}\K\\{true};{}$\5
+${}\\{final\_pass}\K(\\{emergency\_stretch}\Z\T{0});{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\1\5
+\\{begin\_diagnostic}(\,);\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{threshold}>\\{inf\_bad}){}$\1\5
+${}\\{threshold}\K\\{inf\_bad};{}$\2\6
+\&{if} (\\{second\_pass})\1\5
+\X891:Initialize for hyphenating a paragraph\X;\2\6
+\X864:Create an active breakpoint representing the beginning of the paragraph\X;\6
+${}\\{cur\_p}\K\\{link}(\\{temp\_head});{}$\5
+${}\\{auto\_breaking}\K\\{true}{}$;\6
+${}\\{prev\_p}\K\\{cur\_p}{}$;\C{glue at beginning is not a legal breakpoint}\6
+\&{while} ${}((\\{cur\_p}\I\\{null})\W(\\{link}(\\{active})\I\\{last\_active})){}$\1\5
+\X866:Call \\{try\_break} if \\{cur\_p} is a legal breakpoint; on the second pass, also try to hyphenate the next word, if \\{cur\_p} is a glue node; then advance \\{cur\_p} to the next node of the paragraph that could possibly be a legal breakpoint\X;\2%
+\6
+\&{if} ${}(\\{cur\_p}\E\\{null}){}$\1\5
+\X873:Try the final line break at the end of the paragraph, and \&{goto} \\{done} if the desired breakpoints have been found\X;\2\6
+\X865:Clean up the memory by removing the break nodes\X;\6
+\&{if} ${}(\R\\{second\_pass}){}$\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{STAT}\1\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\1\5
+\\{print\_nl}(\.{"@secondpass"});\2\6
+\8\#\&{endif}\6
+${}\\{threshold}\K\\{tolerance};{}$\5
+${}\\{second\_pass}\K\\{true};{}$\5
+${}\\{final\_pass}\K(\\{emergency\_stretch}\Z\T{0});{}$\6
+\4${}\}{}$\C{if at first you don't succeed, \dots}\2\6
+\&{else}\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{STAT}\1\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\1\5
+\\{print\_nl}(\.{"@emergencypass"});\2\6
+\8\#\&{endif}\6
+${}\\{background}[\T{2}]\K\\{background}[\T{2}]+\\{emergency\_stretch};{}$\5
+${}\\{final\_pass}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4\\{done}:\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_paragraphs}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{end\_diagnostic}(\\{true});\5
+\\{normalize\_selector}(\,);\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\U815.\fi
+
+\M{864}The active node that represents the starting point does not need a
+corresponding passive node.
+
+\Y\B\4\D$\\{store\_background}(\|X)$ \5
+$\\{active\_width}[\|X]\K\\{background}{}$[\|X]\par
+\Y\B\4\X864:Create an active breakpoint representing the beginning of the paragraph\X${}\E{}$\6
+$\|q\K\\{get\_node}(\\{active\_node\_size});{}$\5
+${}\\{type}(\|q)\K\\{unhyphenated};{}$\5
+${}\\{fitness}(\|q)\K\\{decent\_fit};{}$\5
+${}\\{link}(\|q)\K\\{last\_active};{}$\5
+${}\\{break\_node}(\|q)\K\\{null};{}$\5
+${}\\{line\_number}(\|q)\K\\{prev\_graf}+\T{1};{}$\5
+${}\\{total\_demerits}(\|q)\K\T{0};{}$\5
+${}\\{link}(\\{active})\K\|q;{}$\5
+\\{do\_all\_six}(\\{store\_background});\6
+${}\\{passive}\K\\{null};{}$\5
+${}\\{printed\_node}\K\\{temp\_head};{}$\5
+${}\\{pass\_number}\K\T{0};$ $\\{font\_in\_short\_display}\K{}$\\{null\_font}\par
+\U863.\fi
+
+\M{865}\B\X865:Clean up the memory by removing the break nodes\X${}\E{}$\6
+$\|q\K\\{link}(\\{active});{}$\6
+\&{while} ${}(\|q\I\\{last\_active}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_p}\K\\{link}(\|q);{}$\6
+\&{if} ${}(\\{type}(\|q)\E\\{delta\_node}){}$\1\5
+${}\\{free\_node}(\|q,\39\\{delta\_node\_size});{}$\2\6
+\&{else}\1\5
+${}\\{free\_node}(\|q,\39\\{active\_node\_size});{}$\2\6
+${}\|q\K\\{cur\_p};{}$\6
+\4${}\}{}$\2\6
+${}\|q\K\\{passive};{}$\6
+\&{while} ${}(\|q\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_p}\K\\{link}(\|q);{}$\5
+${}\\{free\_node}(\|q,\39\\{passive\_node\_size});{}$\5
+${}\|q\K\\{cur\_p};{}$\6
+\4${}\}{}$\2\par
+\Us815\ET863.\fi
+
+\M{866}Here is the main switch in the \\{line\_break} routine, where legal breaks
+are determined. As we move through the hlist, we need to keep the \\{active\_width}
+array up to date, so that the badness of individual lines is readily calculated
+by \\{try\_break}. It is convenient to use the short name \\{act\_width} for
+the component of active width that represents real width as opposed to glue.
+
+\Y\B\4\D$\\{act\_width}$ \5
+\\{active\_width}[\T{1}]\C{length from first active node to current node}\par
+\B\4\D$\\{kern\_break}$ \6
+${}\{{}$\5
+\1\&{if} ${}(\R\\{is\_char\_node}(\\{link}(\\{cur\_p}))\W\\{auto\_breaking}){}$\1\6
+\&{if} ${}(\\{type}(\\{link}(\\{cur\_p}))\E\\{glue\_node}){}$\1\5
+${}\\{try\_break}(\T{0},\39\\{unhyphenated});{}$\2\2\6
+${}\\{act\_width}\K\\{act\_width}+\\{width}(\\{cur\_p});{}$\6
+\4${}\}{}$\2\par
+\Y\B\4\X866:Call \\{try\_break} if \\{cur\_p} is a legal breakpoint; on the second pass, also try to hyphenate the next word, if \\{cur\_p} is a glue node; then advance \\{cur\_p} to the next node of the paragraph that could possibly be a legal
+breakpoint\X${}\E{}$\6
+$\{{}$\5
+\&{if} (\\{is\_char\_node}(\\{cur\_p}))\1\5
+\X867:Advance \(c)\\{cur\_p} to the node following the present string of characters\X;\2\6
+\&{switch} (\\{type}(\\{cur\_p})) $\{$ \6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+${}\\{act\_width}\K\\{act\_width}+\\{width}(\\{cur\_p}){}$;\5
+\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1362:Advance \(p)past a whatsit node in the \(l)\\{line\_break} loop\X\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\6
+${}\{{}$\5
+\1\X868:If node \\{cur\_p} is a legal breakpoint, call \\{try\_break}; then update the active widths by including the glue in \\{glue\_ptr}(\\{cur\_p})\X;\6
+\&{if} ${}(\\{second\_pass}\W\\{auto\_breaking}){}$\1\5
+\X894:Try to hyphenate the following word\X;\2\6
+\4${}\}{}$\5
+\2\&{break}; \&{case} \\{kern\_node}: \&{if} ( \\{subtype}(\\{cur\_p}) $\E$ \&{explicit} ) \\{kern\_break}\6
+\&{else}\1\5
+${}\\{act\_width}\K\\{act\_width}+\\{width}(\\{cur\_p}){}$;\5
+\2\&{break};\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\\{lig\_char}(\\{cur\_p}));{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{lig\_char}(\\{cur\_p}))));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{disc\_node}:\5
+\X869:Try to break after a discretionary fragment, then \&{goto} \\{done5}\X\6
+\4\&{case} \\{math\_node}:\6
+${}\{{}$\5
+\1${}\\{auto\_breaking}\K(\\{subtype}(\\{cur\_p})\E\\{after});{}$\5
+\\{kern\_break};\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{penalty\_node}:\5
+${}\\{try\_break}(\\{penalty}(\\{cur\_p}),\39\\{unhyphenated}){}$;\5
+\&{break};\6
+\4\&{case} \\{mark\_node}:\5
+\&{case} \\{ins\_node}:\5
+\&{case} \\{adjust\_node}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1679:\.{"paragraph"}\X); $\}{}$\6
+$\\{prev\_p}\K\\{cur\_p};{}$\5
+${}\\{cur\_p}\K\\{link}(\\{cur\_p});{}$\6
+\4\\{done5}:\5
+; $\}{}$\par
+\U863.\fi
+
+\M{867}The code that passes over the characters of words in a paragraph is
+part of \TeX's inner loop, so it has been streamlined for speed. We use
+the fact that `\.{\\parfillskip}' glue appears at the end of each paragraph;
+it is therefore unnecessary to check if $\\{link}(\\{cur\_p})\E\\{null}$ when \\{cur\_p} is a
+character node.
+
+\Y\B\4\X867:Advance \(c)\\{cur\_p} to the node following the present string of characters\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{prev\_p}\K\\{cur\_p}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|f\K\\{font}(\\{cur\_p});{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{cur\_p})));{}$\5
+${}\\{cur\_p}\K\\{link}(\\{cur\_p});{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\R\\{is\_char\_node}(\\{cur\_p})));{}$\6
+\4${}\}{}$\2\par
+\U866.\fi
+
+\M{868}When node \\{cur\_p} is a glue node, we look at \\{prev\_p} to see whether or not
+a breakpoint is legal at \\{cur\_p}, as explained above.
+
+\Y\B\4\X868:If node \\{cur\_p} is a legal breakpoint, call \\{try\_break}; then update the active widths by including the glue in \\{glue\_ptr}(\\{cur\_p})\X${}\E{}$\6
+\&{if} (\\{auto\_breaking}) $\{{}$\5
+\&{if} (\\{is\_char\_node}(\\{prev\_p}))\1\5
+${}\\{try\_break}(\T{0},\39\\{unhyphenated});{}$\2\6
+\&{else} \&{if} (\\{precedes\_break}(\\{prev\_p}))\1\5
+${}\\{try\_break}(\T{0},\39\\{unhyphenated});{}$\2\6
+\&{else} \&{if} ( $(\\{type}(\\{prev\_p})\E\\{kern\_node})$ $\W$ ( \\{subtype}(\\{prev\_p}) $\I$ \&{explicit} ) ) $\\{try\_break}(\T{0},\39\\{unhyphenated});$ $\}$ \\{check\_shrinkage}(\\{glue\_ptr}(\\{cur\_p}));\5
+${}\|q\K\\{glue\_ptr}(\\{cur\_p});{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{width}(\|q);\30{}$\5
+${}\\{active\_width}[\T{2}+\\{stretch\_order}(\|q)]\K\30\\{active\_width}[\T{2}+\\{stretch\_order}(\|q)]+\\{stretch}(\|q){}$;\6
+$\\{active\_width}[\T{6}]\K\\{active\_width}[\T{6}]+\\{shrink}{}$(\|q)\par
+\U866.\fi
+
+\M{869}The following code knows that discretionary texts contain
+only character nodes, kern nodes, box nodes, rule nodes, and ligature nodes.
+
+\Y\B\4\X869:Try to break after a discretionary fragment, then \&{goto} \\{done5}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|s\K\\{pre\_break}(\\{cur\_p});{}$\5
+${}\\{disc\_width}\K\T{0};{}$\6
+\&{if} ${}(\|s\E\\{null}){}$\1\5
+${}\\{try\_break}(\\{ex\_hyphen\_penalty},\39\\{hyphenated});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+\X870:Add the width of node \|s to \\{disc\_width}\X;\6
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|s\E\\{null}));{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{disc\_width};{}$\5
+${}\\{try\_break}(\\{hyphen\_penalty},\39\\{hyphenated});{}$\5
+${}\\{act\_width}\K\\{act\_width}-\\{disc\_width};{}$\6
+\4${}\}{}$\2\6
+${}\|r\K\\{replace\_count}(\\{cur\_p});{}$\5
+${}\|s\K\\{link}(\\{cur\_p});{}$\6
+\&{while} ${}(\|r>\T{0}){}$\5
+${}\{{}$\5
+\1\X871:Add the width of node \|s to \\{act\_width}\X;\6
+\\{decr}(\|r);\5
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\2\6
+${}\\{prev\_p}\K\\{cur\_p};{}$\5
+${}\\{cur\_p}\K\|s;{}$\5
+\&{goto} \\{done5};\6
+\4${}\}{}$\2\par
+\U866.\fi
+
+\M{870}\B\X870:Add the width of node \|s to \\{disc\_width}\X${}\E{}$\6
+\&{if} (\\{is\_char\_node}(\|s))\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|s);{}$\5
+${}\\{disc\_width}\K\\{disc\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|s)));{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|s))\5
+${}\{{}$\1\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\\{lig\_char}(\|s));{}$\5
+${}\\{disc\_width}\K\\{disc\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{lig\_char}(\|s))));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{kern\_node}:\5
+${}\\{disc\_width}\K\\{disc\_width}+\\{width}(\|s){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1680:\.{"disc3"}\X);\6
+\4${}\}{}$\2\2\par
+\U869.\fi
+
+\M{871}\B\X871:Add the width of node \|s to \\{act\_width}\X${}\E{}$\6
+\&{if} (\\{is\_char\_node}(\|s))\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|s);{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|s)));{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\6
+\&{switch} (\\{type}(\|s))\5
+${}\{{}$\1\6
+\4\&{case} \\{ligature\_node}:\6
+${}\{{}$\5
+\1${}\|f\K\\{font}(\\{lig\_char}(\|s));{}$\5
+${}\\{act\_width}\K\\{act\_width}+\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\\{lig\_char}(\|s))));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\&{case} \\{kern\_node}:\5
+${}\\{act\_width}\K\\{act\_width}+\\{width}(\|s){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1681:\.{"disc4"}\X);\6
+\4${}\}{}$\2\2\par
+\U869.\fi
+
+\M{872}The forced line break at the paragraph's end will reduce the list of
+breakpoints so that all active nodes represent breaks at $\\{cur\_p}\E\\{null}$.
+On the first pass, we insist on finding an active node that has the
+correct ``looseness.'' On the final pass, there will be at least one active
+node, and we will match the desired looseness as well as we can.
+
+The global variable \\{best\_bet} will be set to the active node for the best
+way to break the paragraph, and a few other variables are used to
+help determine what is best.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{best\_bet};\C{use this passive node and its predecessors}\6
+\&{int} \\{fewest\_demerits};\C{the demerits associated with \\{best\_bet}}\6
+\&{halfword} \\{best\_line};\C{line number following the last line of the new paragraph}\6
+\&{int} \\{actual\_looseness};\C{the difference between \\{line\_number}(\\{best\_bet}) and the optimum \\{best\_line}}\6
+\&{int} \\{line\_diff};\C{the difference between the current line number and the optimum \\{best\_line}}\par
+\fi
+
+\M{873}\B\X873:Try the final line break at the end of the paragraph, and \&{goto} \\{done} if the desired breakpoints have been found\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{try\_break}(\\{eject\_penalty},\39\\{hyphenated});{}$\6
+\&{if} ${}(\\{link}(\\{active})\I\\{last\_active}){}$\5
+${}\{{}$\5
+\1\X874:Find an active node with fewest demerits\X;\6
+\&{if} ${}(\\{looseness}\E\T{0}){}$\1\5
+\&{goto} \\{done};\2\6
+\X875:Find the best active node for the desired looseness\X;\6
+\&{if} ${}((\\{actual\_looseness}\E\\{looseness})\V\\{final\_pass}){}$\1\5
+\&{goto} \\{done};\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U863.\fi
+
+\M{874}\B\X874:Find an active node with fewest demerits\X${}\E{}$\6
+$\|r\K\\{link}(\\{active});{}$\5
+${}\\{fewest\_demerits}\K\\{awful\_bad}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{type}(\|r)\I\\{delta\_node}){}$\1\6
+\&{if} ${}(\\{total\_demerits}(\|r)<\\{fewest\_demerits}){}$\5
+${}\{{}$\5
+\1${}\\{fewest\_demerits}\K\\{total\_demerits}(\|r);{}$\5
+${}\\{best\_bet}\K\|r;{}$\6
+\4${}\}{}$\2\2\6
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r\E\\{last\_active}));$ $\\{best\_line}\K\\{line\_number}{}$(\\{best\_bet})\par
+\U873.\fi
+
+\M{875}The adjustment for a desired looseness is a slightly more complicated
+version of the loop just considered. Note that if a paragraph is broken
+into segments by displayed equations, each segment will be subject to the
+looseness calculation, independently of the other segments.
+
+\Y\B\4\X875:Find the best active node for the desired looseness\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{active});{}$\5
+${}\\{actual\_looseness}\K\T{0}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{type}(\|r)\I\\{delta\_node}){}$\5
+${}\{{}$\5
+\1${}\\{line\_diff}\K\\{line\_number}(\|r)-\\{best\_line};{}$\6
+\&{if} ${}(((\\{line\_diff}<\\{actual\_looseness})\W(\\{looseness}\Z\\{line\_diff}))\V\30((\\{line\_diff}>\\{actual\_looseness})\W(\\{looseness}\G\\{line\_diff}))){}$\5
+${}\{{}$\5
+\1${}\\{best\_bet}\K\|r;{}$\5
+${}\\{actual\_looseness}\K\\{line\_diff};{}$\5
+${}\\{fewest\_demerits}\K\\{total\_demerits}(\|r);{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\\{line\_diff}\E\\{actual\_looseness})\W\30(\\{total\_demerits}(\|r)<\\{fewest\_demerits})){}$\5
+${}\{{}$\5
+\1${}\\{best\_bet}\K\|r;{}$\5
+${}\\{fewest\_demerits}\K\\{total\_demerits}(\|r);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r\E\\{last\_active}));{}$\5
+${}\\{best\_line}\K\\{line\_number}(\\{best\_bet});{}$\6
+\4${}\}{}$\2\par
+\U873.\fi
+
+\M{876}Once the best sequence of breakpoints has been found (hurray), we call on the
+procedure \\{post\_line\_break} to finish the remainder of the work.
+(By introducing this subprocedure, we are able to keep \\{line\_break}
+from getting extremely long.)
+
+\Y\B\4\X876:Break the paragraph at the chosen breakpoints, justify the resulting lines to the correct widths, and append them to the current vertical list\X${}\E{}$\6
+\\{post\_line\_break}(\\{final\_widow\_penalty})\par
+\U815.\fi
+
+\M{877}The total number of lines that will be set by \\{post\_line\_break}
+is $\\{best\_line}-\\{prev\_graf}-\T{1}$. The last breakpoint is specified by
+\\{break\_node}(\\{best\_bet}), and this passive node points to the other breakpoints
+via the \\{prev\_break} links. The finishing-up phase starts by linking the
+relevant passive nodes in forward order, changing \\{prev\_break} to
+\\{next\_break}. (The \\{next\_break} fields actually reside in the same memory
+space as the \\{prev\_break} fields did, but we give them a new name because
+of their new significance.) Then the lines are justified, one by one.
+
+\Y\B\4\D$\\{next\_break}$ \5
+\\{prev\_break}\C{new name for \\{prev\_break} after links are reversed}\par
+\Y\B\4\X826:Declare subprocedures for \\{line\_break}\X${}\mathrel+\E{}$\6
+\&{void} \\{post\_line\_break}(\&{int} \\{final\_widow\_penalty})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|q${},{}$ \|r${},{}$ \|s;\C{temporary registers for list manipulation}\6
+\&{bool} \\{disc\_break};\C{was the current break at a discretionary node?}\6
+\&{bool} \\{post\_disc\_break};\C{and did it have a nonempty post-break part?}\6
+\&{scaled} \\{cur\_width};\C{width of line number \\{cur\_line}}\6
+\&{scaled} \\{cur\_indent};\C{left margin of line number \\{cur\_line}}\6
+\&{quarterword} \|t;\C{used for replacement counts in discretionary nodes}\6
+\&{int} \\{pen};\C{use when calculating penalties between lines}\6
+\&{halfword} \\{cur\_line};\C{the current line number being justified}\7
+\X878:Reverse the links of the relevant passive nodes, setting \\{cur\_p} to the first breakpoint\X;\6
+${}\\{cur\_line}\K\\{prev\_graf}+\T{1}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\X880:Justify the line ending at breakpoint \\{cur\_p}, and append it to the current vertical list, together with associated penalties and other insertions\X;\6
+\\{incr}(\\{cur\_line});\5
+${}\\{cur\_p}\K\\{next\_break}(\\{cur\_p});{}$\6
+\&{if} ${}(\\{cur\_p}\I\\{null}){}$\1\6
+\&{if} ${}(\R\\{post\_disc\_break}){}$\1\5
+\X879:Prune unwanted nodes at the beginning of the next line\X;\2\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_p}\E\\{null}));{}$\6
+\&{if} ${}((\\{cur\_line}\I\\{best\_line})\V(\\{link}(\\{temp\_head})\I\\{null})){}$\1\5
+\\{confusion}(\X1682:\.{"line\ breaking"}\X);\2\6
+${}\\{prev\_graf}\K\\{best\_line}-\T{1};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{878}The job of reversing links in a list is conveniently regarded as the job
+of taking items off one stack and putting them on another. In this case we
+take them off a stack pointed to by \|q and having \\{prev\_break} fields;
+we put them on a stack pointed to by \\{cur\_p} and having \\{next\_break} fields.
+Node \|r is the passive node being moved from stack to stack.
+
+\Y\B\4\X878:Reverse the links of the relevant passive nodes, setting \\{cur\_p} to the first breakpoint\X${}\E{}$\6
+$\|q\K\\{break\_node}(\\{best\_bet});{}$\5
+${}\\{cur\_p}\K\\{null}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|r\K\|q;{}$\5
+${}\|q\K\\{prev\_break}(\|q);{}$\5
+${}\\{next\_break}(\|r)\K\\{cur\_p};{}$\5
+${}\\{cur\_p}\K\|r;{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|q\E\\{null}){}$)\par
+\U877.\fi
+
+\M{879}Glue and penalty and kern and math nodes are deleted at the beginning of
+a line, except in the anomalous case that the node to be deleted is actually
+one of the chosen breakpoints. Otherwise
+the pruning done here is designed to match
+the lookahead computation in \\{try\_break}, where the \\{break\_width} values
+are computed for non-discretionary breakpoints.
+
+\Y\B\4\X879:Prune unwanted nodes at the beginning of the next line\X${}\E{}$\6
+$\{{}$\5
+$\|r\K\\{temp\_head};$ \&{loop}\5
+$\{{}$\5
+$\|q\K\\{link}(\|r);{}$\6
+\&{if} ${}(\|q\E\\{cur\_break}(\\{cur\_p})){}$\1\5
+\&{goto} \\{done1};\C{\\{cur\_break}(\\{cur\_p}) is the next breakpoint}\C{now \|q cannot be \\{null}}\2\6
+\&{if} (\\{is\_char\_node}(\|q))\1\5
+\&{goto} \\{done1};\2\6
+\&{if} (\\{non\_discardable}(\|q))\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}(\\{type}(\|q)\E\\{kern\_node})$ \&{if} ( \\{subtype}(\|q) $\I$ \&{explicit} ) \&{goto} \\{done1};\5
+${}\|r\K\|q{}$;\C{now $\\{type}(\|q)\E\\{glue\_node}$, \\{kern\_node}, \\{math\_node} or \\{penalty\_node}}\6
+$\}$ \6
+\4\\{done1}:\6
+\&{if} ${}(\|r\I\\{temp\_head}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|r)\K\\{null};{}$\5
+\\{flush\_node\_list}(\\{link}(\\{temp\_head}));\5
+${}\\{link}(\\{temp\_head})\K\|q;{}$\6
+\4${}\}{}$\2\6
+$\}{}$\par
+\U877.\fi
+
+\M{880}The current line to be justified appears in a horizontal list starting
+at \\{link}(\\{temp\_head}) and ending at \\{cur\_break}(\\{cur\_p}). If \\{cur\_break}(\\{cur\_p}) is
+a glue node, we reset the glue to equal the \\{right\_skip} glue; otherwise
+we append the \\{right\_skip} glue at the right. If \\{cur\_break}(\\{cur\_p}) is a
+discretionary node, we modify the list so that the discretionary break
+is compulsory, and we set \\{disc\_break} to \\{true}. We also append
+the \\{left\_skip} glue at the left of the line, unless it is zero.
+
+\Y\B\4\X880:Justify the line ending at breakpoint \\{cur\_p}, and append it to the current vertical list, together with associated penalties and other insertions\X${}\E{}$\6
+\X881:Modify the end of the line to reflect the nature of the break and to include \.{\\rightskip}; also set the proper value of \\{disc\_break}\X;\6
+\X887:Put the \(l)\.{\\leftskip} glue at the left and detach this line\X;\6
+\X889:Call the packaging subroutine, setting \\{just\_box} to the justified box\X;\6
+\X888:Append the new box to the current vertical list, followed by the list of special nodes taken out of the box by the packager\X;\6
+\X890:Append a penalty node, if a nonzero penalty is appropriate\X\par
+\U877.\fi
+
+\M{881}At the end of the following code, \|q will point to the final node on the
+list about to be justified.
+
+\Y\B\4\X881:Modify the end of the line to reflect the nature of the break and to include \.{\\rightskip}; also set the proper value of \\{disc\_break}\X${}\E{}$\6
+$\|q\K\\{cur\_break}(\\{cur\_p});{}$\5
+${}\\{disc\_break}\K\\{false};{}$\5
+${}\\{post\_disc\_break}\K\\{false};{}$\6
+\&{if} ${}(\|q\I\\{null}{}$)\C{\|q cannot be a \\{char\_node}}\1\6
+\&{if} ${}(\\{type}(\|q)\E\\{glue\_node}){}$\5
+${}\{{}$\5
+\1\\{delete\_glue\_ref}(\\{glue\_ptr}(\|q));\5
+${}\\{glue\_ptr}(\|q)\K\\{right\_skip};{}$\5
+${}\\{subtype}(\|q)\K\\{right\_skip\_code}+\T{1};{}$\5
+\\{add\_glue\_ref}(\\{right\_skip});\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|q)\E\\{disc\_node}){}$\1\5
+\X882:Change discretionary to compulsory and set \\{disc\_break}: $\K$ \\{true}\X\2\6
+\&{else} \&{if} ${}((\\{type}(\|q)\E\\{math\_node})\V(\\{type}(\|q)\E\\{kern\_node})){}$\1\5
+${}\\{width}(\|q)\K\T{0};{}$\2\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{temp\_head};{}$\6
+\&{while} ${}(\\{link}(\|q)\I\\{null}){}$\1\5
+${}\|q\K\\{link}(\|q);{}$\2\6
+\4${}\}{}$\2\6
+\X886:Put the \(r)\.{\\rightskip} glue after node \|q\X;\6
+\\{done}:\par
+\U880.\fi
+
+\M{882}\B\X882:Change discretionary to compulsory and set \\{disc\_break}: $\K$ \\{true}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|t\K\\{replace\_count}(\|q);{}$\5
+\X883:Destroy the \|t nodes following \|q, and make \|r point to the following node\X;\6
+\&{if} ${}(\\{post\_break}(\|q)\I\\{null}){}$\1\5
+\X884:Transplant the post-break list\X;\2\6
+\&{if} ${}(\\{pre\_break}(\|q)\I\\{null}){}$\1\5
+\X885:Transplant the pre-break list\X;\2\6
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{disc\_break}\K\\{true};{}$\6
+\4${}\}{}$\2\par
+\U881.\fi
+
+\M{883}\B\X883:Destroy the \|t nodes following \|q, and make \|r point to the following node\X${}\E{}$\6
+\&{if} ${}(\|t\E\T{0}){}$\1\5
+${}\|r\K\\{link}(\|q);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|r\K\|q;{}$\6
+\&{while} ${}(\|t>\T{1}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{link}(\|r);{}$\5
+\\{decr}(\|t);\6
+\4${}\}{}$\2\6
+${}\|s\K\\{link}(\|r);{}$\5
+${}\|r\K\\{link}(\|s);{}$\5
+${}\\{link}(\|s)\K\\{null};{}$\5
+\\{flush\_node\_list}(\\{link}(\|q));\5
+${}\\{replace\_count}(\|q)\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\U882.\fi
+
+\M{884}We move the post-break list from inside node \|q to the main list by
+re\-attaching it just before the present node \|r, then resetting \|r.
+
+\Y\B\4\X884:Transplant the post-break list\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|s\K\\{post\_break}(\|q);{}$\6
+\&{while} ${}(\\{link}(\|s)\I\\{null}){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+${}\\{link}(\|s)\K\|r;{}$\5
+${}\|r\K\\{post\_break}(\|q);{}$\5
+${}\\{post\_break}(\|q)\K\\{null};{}$\5
+${}\\{post\_disc\_break}\K\\{true};{}$\6
+\4${}\}{}$\2\par
+\U882.\fi
+
+\M{885}We move the pre-break list from inside node \|q to the main list by
+re\-attaching it just after the present node \|q, then resetting \|q.
+
+\Y\B\4\X885:Transplant the pre-break list\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|s\K\\{pre\_break}(\|q);{}$\5
+${}\\{link}(\|q)\K\|s;{}$\6
+\&{while} ${}(\\{link}(\|s)\I\\{null}){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+${}\\{pre\_break}(\|q)\K\\{null};{}$\5
+${}\|q\K\|s;{}$\6
+\4${}\}{}$\2\par
+\U882.\fi
+
+\M{886}\B\X886:Put the \(r)\.{\\rightskip} glue after node \|q\X${}\E{}$\6
+$\|r\K\\{new\_param\_glue}(\\{right\_skip\_code});{}$\5
+${}\\{link}(\|r)\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\|r;$ $\|q\K{}$\|r\par
+\U881.\fi
+
+\M{887}The following code begins with \|q at the end of the list to be
+justified. It ends with \|q at the beginning of that list, and with
+\\{link}(\\{temp\_head}) pointing to the remainder of the paragraph, if any.
+
+\Y\B\4\X887:Put the \(l)\.{\\leftskip} glue at the left and detach this line\X${}\E{}$\6
+$\|r\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\|q\K\\{link}(\\{temp\_head});{}$\5
+${}\\{link}(\\{temp\_head})\K\|r;{}$\6
+\&{if} ${}(\\{left\_skip}\I\\{zero\_glue}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{new\_param\_glue}(\\{left\_skip\_code});{}$\5
+${}\\{link}(\|r)\K\|q;{}$\5
+${}\|q\K\|r;{}$\6
+\4${}\}{}$\2\par
+\U880.\fi
+
+\M{888}\B\X888:Append the new box to the current vertical list, followed by the list of special nodes taken out of the box by the packager\X${}\E{}$\6
+\\{append\_to\_vlist}(\\{just\_box});\6
+\&{if} ${}(\\{adjust\_head}\I\\{adjust\_tail}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\\{link}(\\{adjust\_head});{}$\5
+${}\\{tail}\K\\{adjust\_tail};{}$\6
+\4${}\}{}$\2\6
+$\\{adjust\_tail}\K{}$\\{null}\par
+\U880.\fi
+
+\M{889}Now \|q points to the hlist that represents the current line of the
+paragraph. We need to compute the appropriate line width, pack the
+line into a box of this size, and shift the box by the appropriate
+amount of indentation.
+
+\Y\B\4\X889:Call the packaging subroutine, setting \\{just\_box} to the justified box\X${}\E{}$\6
+\&{if} ${}(\\{cur\_line}>\\{last\_special\_line}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_width}\K\\{second\_width};{}$\5
+${}\\{cur\_indent}\K\\{second\_indent};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_width}\K\\{first\_width};{}$\5
+${}\\{cur\_indent}\K\\{first\_indent};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_width}\K\\{mem}[\\{par\_shape\_ptr}+\T{2}*\\{cur\_line}].\\{sc};{}$\5
+${}\\{cur\_indent}\K\\{mem}[\\{par\_shape\_ptr}+\T{2}*\\{cur\_line}-\T{1}].\\{sc};{}$\6
+\4${}\}{}$\2\6
+${}\\{adjust\_tail}\K\\{adjust\_head};{}$\5
+${}\\{just\_box}\K\\{hpack}(\|q,\39\\{cur\_width},\39\\{exactly});$ $\\{shift\_amount}(\\{just\_box})\K{}$\\{cur\_indent}\par
+\U880.\fi
+
+\M{890}Penalties between the lines of a paragraph come from club and widow lines,
+from the \\{inter\_line\_penalty} parameter, and from lines that end at
+discretionary breaks. Breaking between lines of a two-line paragraph gets
+both club-line and widow-line penalties. The local variable \\{pen} will
+be set to the sum of all relevant penalties for the current line, except
+that the final line is never penalized.
+
+\Y\B\4\X890:Append a penalty node, if a nonzero penalty is appropriate\X${}\E{}$\6
+\&{if} ${}(\\{cur\_line}+\T{1}\I\\{best\_line}){}$\5
+${}\{{}$\5
+\1${}\\{pen}\K\\{inter\_line\_penalty};{}$\6
+\&{if} ${}(\\{cur\_line}\E\\{prev\_graf}+\T{1}){}$\1\5
+${}\\{pen}\K\\{pen}+\\{club\_penalty};{}$\2\6
+\&{if} ${}(\\{cur\_line}+\T{2}\E\\{best\_line}){}$\1\5
+${}\\{pen}\K\\{pen}+\\{final\_widow\_penalty};{}$\2\6
+\&{if} (\\{disc\_break})\1\5
+${}\\{pen}\K\\{pen}+\\{broken\_penalty};{}$\2\6
+\&{if} ${}(\\{pen}\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{new\_penalty}(\\{pen});{}$\5
+${}\\{link}(\\{tail})\K\|r;{}$\5
+${}\\{tail}\K\|r;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U880.\fi
+
+\N{1}{891}Pre-hyphenation.
+When the line-breaking routine is unable to find a feasible sequence of
+breakpoints, it makes a second pass over the paragraph, attempting to
+hyphenate the hyphenatable words. The goal of hyphenation is to insert
+discretionary material into the paragraph so that there are more
+potential places to break.
+
+The general rules for hyphenation are somewhat complex and technical,
+because we want to be able to hyphenate words that are preceded or
+followed by punctuation marks, and because we want the rules to work
+for languages other than English. We also must contend with the fact
+that hyphens might radically alter the ligature and kerning structure
+of a word.
+
+A sequence of characters will be considered for hyphenation only if it
+belongs to a ``potentially hyphenatable part'' of the current paragraph.
+This is a sequence of nodes $p_0p_1\ldots p_m$ where $p_0$ is a glue node,
+$p_1\ldots p_{m-1}$ are either character or ligature or whatsit or
+implicit kern nodes, and $p_m$ is a glue or penalty or insertion or adjust
+or mark or whatsit or explicit kern node. (Therefore hyphenation is
+disabled by boxes, math formulas, and discretionary nodes already inserted
+by the user.) The ligature nodes among $p_1\ldots p_{m-1}$ are effectively
+expanded into the original non-ligature characters; the kern nodes and
+whatsits are ignored. Each character \|c is now classified as either a
+nonletter (if $\\{lc\_code}(\|c)\E\T{0}$), a lowercase letter (if
+$\\{lc\_code}(\|c)\E\|c$), or an uppercase letter (otherwise); an uppercase letter
+is treated as if it were \\{lc\_code}(\|c) for purposes of hyphenation. The
+characters generated by $p_1\ldots p_{m-1}$ may begin with nonletters; let
+$c_1$ be the first letter that is not in the middle of a ligature. Whatsit
+nodes preceding $c_1$ are ignored; a whatsit found after $c_1$ will be the
+terminating node $p_m$. All characters that do not have the same font as
+$c_1$ will be treated as nonletters. The \\{hyphen\_char} for that font
+must be between 0 and 255, otherwise hyphenation will not be attempted.
+\TeX\ looks ahead for as many consecutive letters $c_1\ldots c_n$ as
+possible; however, \|n must be less than 64, so a character that would
+otherwise be $c_{64}$ is effectively not a letter. Furthermore $c_n$ must
+not be in the middle of a ligature. In this way we obtain a string of
+letters $c_1\ldots c_n$ that are generated by nodes $p_a\ldots p_b$, where
+$\T{1}\Z\|a\Z\|b+\T{1}\Z\|m$. If $\|n\G\\{l\_hyf}+\\{r\_hyf}$, this string qualifies for hyphenation;
+however, \\{uc\_hyph} must be positive, if $c_1$ is uppercase.
+
+The hyphenation process takes place in three stages. First, the candidate
+sequence $c_1\ldots c_n$ is found; then potential positions for hyphens
+are determined by referring to hyphenation tables; and finally, the nodes
+$p_a\ldots p_b$ are replaced by a new sequence of nodes that includes the
+discretionary breaks found.
+
+Fortunately, we do not have to do all this calculation very often, because
+of the way it has been taken out of \TeX's inner loop. For example, when
+the second edition of the author's 700-page book {\sl Seminumerical
+Algorithms} was typeset by \TeX, only about 1.2 hyphenations needed to be
+tried per paragraph, since the line breaking algorithm needed to use two
+passes on only about 5 per cent of the paragraphs.
+
+\Y\B\4\X891:Initialize for hyphenating a paragraph\X${}\E{}$\6
+${}\{{}$\6
+\8\#\&{ifdef} \.{INIT}\1\6
+\&{if} (\\{trie\_not\_ready})\1\5
+\\{init\_trie}(\,);\2\6
+\8\#\&{endif}\6
+${}\\{cur\_lang}\K\\{init\_cur\_lang};{}$\5
+${}\\{l\_hyf}\K\\{init\_l\_hyf};{}$\5
+${}\\{r\_hyf}\K\\{init\_r\_hyf};{}$\6
+\4${}\}{}$\2\par
+\U863.\fi
+
+\M{892}The letters $c_1\ldots c_n$ that are candidates for hyphenation are placed
+into an array called \\{hc}; the number \|n is placed into \\{hn}; pointers to
+nodes $p_{a-1}$ and~$p_b$ in the description above are placed into variables
+\\{ha} and \\{hb}; and the font number is placed into \\{hf}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint16\_t} \\{hc}[\T{66}];\C{word to be hyphenated}\6
+\&{small\_number} \\{hn};\C{the number of positions occupied in \\{hc}}\6
+\&{pointer} \\{ha}${},{}$ \\{hb};\C{nodes $\\{ha}\dotdot\\{hb}$ should be replaced by the hyphenated result}\6
+\&{internal\_font\_number} \\{hf};\C{font number of the letters in \\{hc}}\6
+\&{uint16\_t} \\{hu}[\T{64}];\C{like \\{hc}, before conversion to lowercase}\6
+\&{int} \\{hyf\_char};\C{hyphen character of the relevant font}\6
+\&{ASCII\_code} \\{cur\_lang}${},{}$ \\{init\_cur\_lang};\C{current hyphenation table of interest}\6
+\&{int} \\{l\_hyf}${},{}$ \\{r\_hyf}${},{}$ \\{init\_l\_hyf}${},{}$ \\{init\_r\_hyf};\C{limits on fragment sizes}\6
+\&{halfword} \\{hyf\_bchar};\C{boundary character after $c_n$}\par
+\fi
+
+\M{893}Hyphenation routines need a few more local variables.
+
+\Y\B\4\X862:Local variables for line breaking\X${}\mathrel+\E{}$\6
+\&{small\_number} \|j;\C{an index into \\{hc} or \\{hu}}\6
+\&{uint8\_t} \|c;\C{character being considered for hyphenation}\par
+\fi
+
+\M{894}When the following code is activated, the \\{line\_break} procedure is in its
+second pass, and \\{cur\_p} points to a glue node.
+
+\Y\B\4\X894:Try to hyphenate the following word\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{prev\_s}\K\\{cur\_p};{}$\5
+${}\|s\K\\{link}(\\{prev\_s});{}$\6
+\&{if} ${}(\|s\I\\{null}){}$\5
+${}\{{}$\5
+\1\X896:Skip to node \\{ha}, or \&{goto} \\{done1} if no hyphenation should be attempted\X;\6
+\&{if} ${}(\\{l\_hyf}+\\{r\_hyf}>\T{63}){}$\1\5
+\&{goto} \\{done1};\2\6
+\X897:Skip to node \\{hb}, putting letters into \\{hu} and \\{hc}\X;\6
+\X899:Check that the nodes following \\{hb} permit hyphenation and that at least $\\{l\_hyf}+\\{r\_hyf}$ letters have been found, otherwise \&{goto} \\{done1}\X;\6
+\\{hyphenate}(\,);\6
+\4${}\}{}$\2\6
+\4\\{done1}:\5
+;\6
+\4${}\}{}$\2\par
+\U866.\fi
+
+\M{895}\B\X826:Declare subprocedures for \\{line\_break}\X${}\mathrel+\E{}$\6
+\hbox{\4}\X906:Declare the function called \\{reconstitute}\X\7
+\&{void} \\{hyphenate}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\X901:Local variables for hyphenation\X\6
+\X923:Find hyphen locations for the word in \\{hc}, or \&{return}\X;\6
+\X902:If no hyphens were found, \&{return}\X;\6
+\X903:Replace nodes $\\{ha}\MRL{{.}{.}}\\{hb}$ by a sequence of nodes that includes the discretionary hyphens\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{896}The first thing we need to do is find the node \\{ha} just before the
+first letter.
+
+\Y\B\4\X896:Skip to node \\{ha}, or \&{goto} \\{done1} if no hyphenation should be attempted\X${}\E{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} (\\{is\_char\_node}(\|s))\5
+${}\{{}$\5
+\1${}\|c\K\\{qo}(\\{character}(\|s));{}$\5
+${}\\{hf}\K\\{font}(\|s);{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|s)\E\\{ligature\_node}){}$\1\6
+\&{if} ${}(\\{lig\_ptr}(\|s)\E\\{null}){}$\1\5
+\&{goto} \\{resume};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{lig\_ptr}(\|s);{}$\5
+${}\|c\K\\{qo}(\\{character}(\|q));{}$\5
+${}\\{hf}\K\\{font}(\|q);{}$\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}((\\{type}(\|s)\E\\{kern\_node})\W(\\{subtype}(\|s)\E\\{normal})){}$\1\5
+\&{goto} \\{resume};\2\6
+\&{else} \&{if} ${}(\\{type}(\|s)\E\\{whatsit\_node}){}$\5
+${}\{{}$\5
+\1\X1363:Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop\X;\6
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}(\\{lc\_code}(\|c)\I\T{0}){}$\1\6
+\&{if} ${}((\\{lc\_code}(\|c)\E\|c)\V(\\{uc\_hyph}>\T{0})){}$\1\5
+\&{goto} \\{done2};\2\6
+\&{else}\1\5
+\&{goto} \\{done1};\2\2\6
+\4\\{resume}:\5
+${}\\{prev\_s}\K\|s;{}$\5
+${}\|s\K\\{link}(\\{prev\_s});{}$\6
+\4${}\}{}$\2\6
+\4\\{done2}:\5
+${}\\{hyf\_char}\K\\{hyphen\_char}[\\{hf}];{}$\6
+\&{if} ${}(\\{hyf\_char}<\T{0}){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{if} ${}(\\{hyf\_char}>\T{255}){}$\1\5
+\&{goto} \\{done1};\2\6
+$\\{ha}\K{}$\\{prev\_s}\par
+\U894.\fi
+
+\M{897}The word to be hyphenated is now moved to the \\{hu} and \\{hc} arrays.
+
+\Y\B\4\X897:Skip to node \\{hb}, putting letters into \\{hu} and \\{hc}\X${}\E{}$\6
+$\\{hn}\K\T{0};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} (\\{is\_char\_node}(\|s))\5
+${}\{{}$\5
+\1\&{if} ${}(\\{font}(\|s)\I\\{hf}){}$\1\5
+\&{goto} \\{done3};\2\6
+${}\\{hyf\_bchar}\K\\{character}(\|s);{}$\5
+${}\|c\K\\{qo}(\\{hyf\_bchar});{}$\6
+\&{if} ${}(\\{lc\_code}(\|c)\E\T{0}){}$\1\5
+\&{goto} \\{done3};\2\6
+\&{if} ${}(\\{hn}\E\T{63}){}$\1\5
+\&{goto} \\{done3};\2\6
+${}\\{hb}\K\|s;{}$\5
+\\{incr}(\\{hn});\5
+${}\\{hu}[\\{hn}]\K\|c;{}$\5
+${}\\{hc}[\\{hn}]\K\\{lc\_code}(\|c);{}$\5
+${}\\{hyf\_bchar}\K\\{non\_char};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|s)\E\\{ligature\_node}){}$\1\5
+\X898:Move the characters of a ligature node to \\{hu} and \\{hc}; but \&{goto} \\{done3} if they are not all letters\X\2\6
+\&{else} \&{if} ${}((\\{type}(\|s)\E\\{kern\_node})\W(\\{subtype}(\|s)\E\\{normal})){}$\5
+${}\{{}$\5
+\1${}\\{hb}\K\|s;{}$\5
+${}\\{hyf\_bchar}\K\\{font\_bchar}[\\{hf}];{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\&{goto} \\{done3};\2\6
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\2\6
+\\{done3}:\par
+\U894.\fi
+
+\M{898}We let \|j be the index of the character being stored when a ligature node
+is being expanded, since we do not want to advance \\{hn} until we are sure
+that the entire ligature consists of letters. Note that it is possible
+to get to \\{done3} with $\\{hn}\E\T{0}$ and \\{hb} not set to any value.
+
+\Y\B\4\X898:Move the characters of a ligature node to \\{hu} and \\{hc}; but \&{goto} \\{done3} if they are not all letters\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{font}(\\{lig\_char}(\|s))\I\\{hf}){}$\1\5
+\&{goto} \\{done3};\2\6
+${}\|j\K\\{hn};{}$\5
+${}\|q\K\\{lig\_ptr}(\|s){}$;\5
+\&{if} ${}(\|q>\\{null}){}$\1\5
+${}\\{hyf\_bchar}\K\\{character}(\|q);{}$\2\6
+\&{while} ${}(\|q>\\{null}){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{qo}(\\{character}(\|q));{}$\6
+\&{if} ${}(\\{lc\_code}(\|c)\E\T{0}){}$\1\5
+\&{goto} \\{done3};\2\6
+\&{if} ${}(\|j\E\T{63}){}$\1\5
+\&{goto} \\{done3};\2\6
+\\{incr}(\|j);\5
+${}\\{hu}[\|j]\K\|c;{}$\5
+${}\\{hc}[\|j]\K\\{lc\_code}(\|c){}$;\6
+${}\|q\K\\{link}(\|q);{}$\6
+\4${}\}{}$\2\6
+${}\\{hb}\K\|s;{}$\5
+${}\\{hn}\K\|j;{}$\6
+\&{if} (\\{odd}(\\{subtype}(\|s)))\1\5
+${}\\{hyf\_bchar}\K\\{font\_bchar}[\\{hf}]{}$;\5
+\2\&{else}\1\5
+${}\\{hyf\_bchar}\K\\{non\_char};{}$\2\6
+\4${}\}{}$\2\par
+\U897.\fi
+
+\M{899}\B\X899:Check that the nodes following \\{hb} permit hyphenation and that at least $\\{l\_hyf}+\\{r\_hyf}$ letters have been found, otherwise \&{goto} \\{done1}\X${}\E{}$\6
+\&{if} ${}(\\{hn}<\\{l\_hyf}+\\{r\_hyf}){}$\1\5
+\&{goto} \\{done1};\C{\\{l\_hyf} and \\{r\_hyf} are $\G$ \T{1}}\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\R(\\{is\_char\_node}(\|s))){}$\1\6
+\&{switch} (\\{type}(\|s))\5
+${}\{{}$\1\6
+\4\&{case} \\{ligature\_node}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{case} \\{kern\_node}:\6
+\&{if} ${}(\\{subtype}(\|s)\I\\{normal}){}$\1\5
+\&{goto} \\{done4};\5
+\2\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\&{case} \\{glue\_node}:\5
+\&{case} \\{penalty\_node}:\5
+\&{case} \\{ins\_node}:\5
+\&{case} \\{adjust\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{goto} \\{done4};\6
+\4\&{default}:\5
+\&{goto} \\{done1};\6
+\4${}\}{}$\2\2\6
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\2\6
+\\{done4}:\par
+\U894.\fi
+
+\N{1}{900}Post-hyphenation.
+If a hyphen may be inserted between \\{hc}[\|j] and $\\{hc}[\|j+\T{1}]$, the hyphenation
+procedure will set \\{hyf}[\|j] to some small odd number. But before we look
+at \TeX's hyphenation procedure, which is independent of the rest of the
+line-breaking algorithm, let us consider what we will do with the hyphens
+it finds, since it is better to work on this part of the program before
+forgetting what \\{ha} and \\{hb}, etc., are all about.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{uint8\_t} \\{hyf}[\T{65}];\C{odd values indicate discretionary hyphens}\6
+\&{pointer} \\{init\_list};\C{list of punctuation characters preceding the word}\6
+\&{bool} \\{init\_lig};\C{does \\{init\_list} represent a ligature?}\6
+\&{bool} \\{init\_lft};\C{if so, did the ligature involve a left boundary?}\par
+\fi
+
+\M{901}\B\X901:Local variables for hyphenation\X${}\E{}$\6
+\&{int} \|i${},{}$ \|j${},{}$ \|l;\C{indices into \\{hc} or \\{hu}}\6
+\&{pointer} \|q${},{}$ \|r${},{}$ \|s;\C{temporary registers for list manipulation}\6
+\&{halfword} \\{bchar};\C{right boundary character of hyphenated word, or \\{non\_char}}\par
+\As912, 922\ETs929.
+\U895.\fi
+
+\M{902}\TeX\ will never insert a hyphen that has fewer than
+\.{\\lefthyphenmin} letters before it or fewer than
+\.{\\righthyphenmin} after it; hence, a short word has
+comparatively little chance of being hyphenated. If no hyphens have
+been found, we can save time by not having to make any changes to the
+paragraph.
+
+\Y\B\4\X902:If no hyphens were found, \&{return}\X${}\E{}$\6
+\&{for} ${}(\|j\K\\{l\_hyf};{}$ ${}\|j\Z\\{hn}-\\{r\_hyf};{}$ ${}\|j\PP){}$\1\6
+\&{if} (\\{odd}(\\{hyf}[\|j]))\1\5
+\&{goto} \\{found1};\2\2\6
+\&{return}; \\{found1}:\par
+\U895.\fi
+
+\M{903}If hyphens are in fact going to be inserted, \TeX\ first deletes the
+subsequence of nodes between \\{ha} and~\\{hb}. An attempt is made to
+preserve the effect that implicit boundary characters and punctuation marks
+had on ligatures inside the hyphenated word, by storing a left boundary or
+preceding character in \\{hu}[\T{0}] and by storing a possible right boundary
+in \\{bchar}. We set $\|j\K\T{0}$ if \\{hu}[\T{0}] is to be part of the reconstruction;
+otherwise $\|j\K\T{1}$.
+The variable \|s will point to the tail of the current hlist, and
+\|q will point to the node following \\{hb}, so that
+things can be hooked up after we reconstitute the hyphenated word.
+
+\Y\B\4\X903:Replace nodes $\\{ha}\MRL{{.}{.}}\\{hb}$ by a sequence of nodes that includes the discretionary hyphens\X${}\E{}$\6
+$\|q\K\\{link}(\\{hb});{}$\5
+${}\\{link}(\\{hb})\K\\{null};{}$\5
+${}\|r\K\\{link}(\\{ha});{}$\5
+${}\\{link}(\\{ha})\K\\{null};{}$\5
+${}\\{bchar}\K\\{hyf\_bchar};{}$\6
+\&{if} (\\{is\_char\_node}(\\{ha}))\1\6
+\&{if} ${}(\\{font}(\\{ha})\I\\{hf}){}$\1\5
+\&{goto} \\{found2};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{init\_list}\K\\{ha};{}$\5
+${}\\{init\_lig}\K\\{false};{}$\5
+${}\\{hu}[\T{0}]\K\\{qo}(\\{character}(\\{ha}));{}$\6
+\4${}\}{}$\2\2\6
+\&{else} \&{if} ${}(\\{type}(\\{ha})\E\\{ligature\_node}){}$\1\6
+\&{if} ${}(\\{font}(\\{lig\_char}(\\{ha}))\I\\{hf}){}$\1\5
+\&{goto} \\{found2};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{init\_list}\K\\{lig\_ptr}(\\{ha});{}$\5
+${}\\{init\_lig}\K\\{true};{}$\5
+${}\\{init\_lft}\K(\\{subtype}(\\{ha})>\T{1});{}$\5
+${}\\{hu}[\T{0}]\K\\{qo}(\\{character}(\\{lig\_char}(\\{ha})));{}$\6
+\&{if} ${}(\\{init\_list}\E\\{null}){}$\1\6
+\&{if} (\\{init\_lft})\5
+${}\{{}$\5
+\1${}\\{hu}[\T{0}]\K\T{256};{}$\5
+${}\\{init\_lig}\K\\{false};{}$\6
+\4${}\}{}$\C{in this case a ligature will be reconstructed from scratch}\2\2\6
+${}\\{free\_node}(\\{ha},\39\\{small\_node\_size});{}$\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\C{no punctuation found; look for left boundary}\1\6
+\&{if} ${}(\R\\{is\_char\_node}(\|r)){}$\1\6
+\&{if} ${}(\\{type}(\|r)\E\\{ligature\_node}){}$\1\6
+\&{if} ${}(\\{subtype}(\|r)>\T{1}){}$\1\5
+\&{goto} \\{found2};\2\2\2\6
+${}\|j\K\T{1};{}$\5
+${}\|s\K\\{ha};{}$\5
+${}\\{init\_list}\K\\{null};{}$\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\6
+${}\|s\K\\{cur\_p}{}$;\C{we have $\\{cur\_p}\I\\{ha}$ because $\\{type}(\\{cur\_p})\E\\{glue\_node}$}\6
+\&{while} ${}(\\{link}(\|s)\I\\{ha}){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+${}\|j\K\T{0};{}$\5
+\&{goto} \\{common\_ending};\6
+\4\\{found2}:\5
+${}\|s\K\\{ha};{}$\5
+${}\|j\K\T{0};{}$\5
+${}\\{hu}[\T{0}]\K\T{256};{}$\5
+${}\\{init\_lig}\K\\{false};{}$\5
+${}\\{init\_list}\K\\{null};{}$\6
+\4\\{common\_ending}:\5
+\\{flush\_node\_list}(\|r);\5
+\X913:Reconstitute nodes for the hyphenated word, inserting discretionary hyphens\X;\6
+\\{flush\_list}(\\{init\_list})\par
+\U895.\fi
+
+\M{904}We must now face the fact that the battle is not over, even though the
+{\def\!{\kern-1pt}%
+hyphens have been found: The process of reconstituting a word can be nontrivial
+because ligatures might change when a hyphen is present. {\sl The \TeX book\/}
+discusses the difficulties of the word ``difficult'', and
+the discretionary material surrounding a
+hyphen can be considerably more complex than that. Suppose
+\.{abcdef} is a word in a font for which the only ligatures are \.{b\!c},
+\.{c\!d}, \.{d\!e}, and \.{e\!f}. If this word permits hyphenation
+between \.b and \.c, the two patterns with and without hyphenation are
+$\.a\,\.b\,\.-\,\.{c\!d}\,\.{e\!f}$ and $\.a\,\.{b\!c}\,\.{d\!e}\,\.f$.
+Thus the insertion of a hyphen might cause effects to ripple arbitrarily
+far into the rest of the word. A further complication arises if additional
+hyphens appear together with such rippling, e.g., if the word in the
+example just given could also be hyphenated between \.c and \.d; \TeX\
+avoids this by simply ignoring the additional hyphens in such weird cases.}
+
+Still further complications arise in the presence of ligatures that do not
+delete the original characters. When punctuation precedes the word being
+hyphenated, \TeX's method is not perfect under all possible scenarios,
+because punctuation marks and letters can propagate information back and forth.
+For example, suppose the original pre-hyphenation pair
+\.{*a} changes to \.{*y} via a \.{\?=:} ligature, which changes to \.{xy}
+via a \.{=:\?} ligature; if $p_{a-1}=\.x$ and $p_a=\.y$, the reconstitution
+procedure isn't smart enough to obtain \.{xy} again. In such cases the
+font designer should include a ligature that goes from \.{xa} to \.{xy}.
+
+\fi
+
+\M{905}The processing is facilitated by a subroutine called \\{reconstitute}. Given
+a string of characters $x_j\ldots x_n$, there is a smallest index $m\ge j$
+such that the ``translation'' of $x_j\ldots x_n$ by ligatures and kerning
+has the form $y_1\ldots y_t$ followed by the translation of $x_{m+1}\ldots x_n$,
+where $y_1\ldots y_t$ is some nonempty sequence of character, ligature, and
+kern nodes. We call $x_j\ldots x_m$ a ``cut prefix'' of $x_j\ldots x_n$.
+For example, if $x_1x_2x_3=\.{fly}$, and if the font contains `fl' as a
+ligature and a kern between `fl' and `y', then $m=2$, $t=2$, and $y_1$ will
+be a ligature node for `fl' followed by an appropriate kern node~$y_2$.
+In the most common case, $x_j$~forms no ligature with $x_{j+1}$ and we
+simply have $m=j$, $y_1=x_j$. If $m<n$ we can repeat the procedure on
+$x_{m+1}\ldots x_n$ until the entire translation has been found.
+
+The \\{reconstitute} function returns the integer $m$ and puts the nodes
+$y_1\ldots y_t$ into a linked list starting at \\{link}(\\{hold\_head}),
+getting the input $x_j\ldots x_n$ from the \\{hu} array. If $x_j=256$,
+we consider $x_j$ to be an implicit left boundary character; in this
+case \|j must be strictly less than~\|n. There is a
+parameter \\{bchar}, which is either 256 or an implicit right boundary character
+assumed to be present just following~$x_n$. (The value $\\{hu}[\|n+\T{1}]$ is never
+explicitly examined, but the algorithm imagines that \\{bchar} is there.)
+
+If there exists an index \|k in the range $j\le k\le m$ such that \\{hyf}[\|k]
+is odd and such that the result of \\{reconstitute} would have been different
+if $x_{k+1}$ had been \\{hchar}, then \\{reconstitute} sets \\{hyphen\_passed}
+to the smallest such~\|k. Otherwise it sets \\{hyphen\_passed} to zero.
+
+A special convention is used in the case $\|j\E\T{0}$: Then we assume that the
+translation of \\{hu}[\T{0}] appears in a special list of charnodes starting at
+\\{init\_list}; moreover, if \\{init\_lig} is \\{true}, then \\{hu}[\T{0}] will be
+a ligature character, involving a left boundary if \\{init\_lft} is \\{true}.
+This facility is provided for cases when a hyphenated
+word is preceded by punctuation (like single or double quotes) that might
+affect the translation of the beginning of the word.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{small\_number} \\{hyphen\_passed};\C{first hyphen in a ligature, if any}\par
+\fi
+
+\M{906}\B\X906:Declare the function called \\{reconstitute}\X${}\E{}$\6
+\&{small\_number} \\{reconstitute}(\&{small\_number} \|j${},\39{}$\&{small\_number} \|n${},\39{}$\&{halfword} \\{bchar}${},\39{}$\&{halfword} \\{hchar})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{temporary register for list manipulation}\6
+\&{pointer} \|t;\C{a node being appended to}\6
+\&{four\_quarters} \|q;\C{character information or a lig/kern instruction}\6
+\&{halfword} \\{cur\_rh};\C{hyphen character for ligature testing}\6
+\&{halfword} \\{test\_char};\C{hyphen or other character for ligature testing}\6
+\&{scaled} \|w;\C{amount of kerning}\6
+\&{font\_index} \|k;\C{position of current lig/kern instruction}\7
+${}\\{hyphen\_passed}\K\T{0};{}$\5
+${}\|t\K\\{hold\_head};{}$\5
+${}\|w\K\T{0};{}$\5
+${}\\{link}(\\{hold\_head})\K\\{null}{}$;\C{at this point $\\{ligature\_present}\E\\{lft\_hit}\E\\{rt\_hit}\E\\{false}$}\6
+\X908:Set up data structures with the cursor following position \|j\X;\6
+\4\\{resume}:\5
+\X909:If there's a ligature or kern at the cursor position, update the data structures, possibly advancing~\|j; continue until the cursor moves\X;\6
+\X910:Append a ligature and/or kern to the translation; \&{goto} \&{continue} if the stack of inserted ligatures is nonempty\X;\6
+\&{return} \|j;\6
+\4${}\}{}$\2\par
+\U895.\fi
+
+\M{907}The reconstitution procedure shares many of the global data structures
+by which \TeX\ has processed the words before they were hyphenated.
+There is an implied ``cursor'' between characters \\{cur\_l} and \\{cur\_r};
+these characters will be tested for possible ligature activity. If
+\\{ligature\_present} then \\{cur\_l} is a ligature character formed from the
+original characters following \\{cur\_q} in the current translation list.
+There is a ``ligature stack'' between the cursor and character $\|j+\T{1}$,
+consisting of pseudo-ligature nodes linked together by their \\{link} fields.
+This stack is normally empty unless a ligature command has created a new
+character that will need to be processed later. A pseudo-ligature is
+a special node having a \\{character} field that represents a potential
+ligature and a \\{lig\_ptr} field that points to a \\{char\_node} or is \\{null}.
+We have
+$$\\{cur\_r}=\cases{\\{character}(\\{lig\_stack}),&if $\\{lig\_stack}>\\{null}$;\cr
+\hbox{$\\{qi}(\\{hu}[\|j+\T{1}])$},&if $\\{lig\_stack}\E\\{null}$ and $\|j<\|n$;\cr
+bchar,&if $\\{lig\_stack}\E\\{null}$ and $\|j\E\|n$.\cr}$$
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{halfword} \\{cur\_l}${},{}$ \\{cur\_r};\C{characters before and after the cursor}\6
+\&{pointer} \\{cur\_q};\C{where a ligature should be detached}\6
+\&{pointer} \\{lig\_stack};\C{unfinished business to the right of the cursor}\6
+\&{bool} \\{ligature\_present};\C{should a ligature node be made for \\{cur\_l}?}\6
+\&{bool} \\{lft\_hit}${},{}$ \\{rt\_hit};\C{did we hit a ligature with a boundary character?}\par
+\fi
+
+\M{908}\B\D$\\{append\_charnode\_to\_t}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{link}(\|t)\K\\{get\_avail}(\,);{}$\5
+${}\|t\K\\{link}(\|t);{}$\5
+${}\\{font}(\|t)\K\\{hf};{}$\5
+${}\\{character}(\|t)\K\|X;{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{set\_cur\_r}$ \6
+${}\{{}$\5
+\1\&{if} ${}(\|j<\|n){}$\1\5
+${}\\{cur\_r}\K\\{qi}(\\{hu}[\|j+\T{1}]){}$;\5
+\2\&{else}\1\5
+${}\\{cur\_r}\K\\{bchar};{}$\2\6
+\&{if} (\\{odd}(\\{hyf}[\|j]))\1\5
+${}\\{cur\_rh}\K\\{hchar}{}$;\5
+\2\&{else}\1\5
+${}\\{cur\_rh}\K\\{non\_char};{}$\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X908:Set up data structures with the cursor following position \|j\X${}\E{}$\6
+$\\{cur\_l}\K\\{qi}(\\{hu}[\|j]);{}$\5
+${}\\{cur\_q}\K\|t;{}$\6
+\&{if} ${}(\|j\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{ligature\_present}\K\\{init\_lig};{}$\5
+${}\|p\K\\{init\_list};{}$\6
+\&{if} (\\{ligature\_present})\1\5
+${}\\{lft\_hit}\K\\{init\_lft};{}$\2\6
+\&{while} ${}(\|p>\\{null}){}$\5
+${}\{{}$\5
+\1\\{append\_charnode\_to\_t}(\\{character}(\|p));\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_l}<\\{non\_char}){}$\1\5
+\\{append\_charnode\_to\_t}(\\{cur\_l});\2\6
+${}\\{lig\_stack}\K\\{null};$ \\{set\_cur\_r}\par
+\U906.\fi
+
+\M{909}We may want to look at the lig/kern program twice, once for a hyphen
+and once for a normal letter. (The hyphen might appear after the letter
+in the program, so we'd better not try to look for both at once.)
+
+\Y\B\4\X909:If there's a ligature or kern at the cursor position, update the data structures, possibly advancing~\|j; continue until the cursor moves\X${}\E{}$\6
+\&{if} ${}(\\{cur\_l}\E\\{non\_char}){}$\5
+${}\{{}$\5
+\1${}\|k\K\\{bchar\_label}[\\{hf}];{}$\6
+\&{if} ${}(\|k\E\\{non\_address}){}$\1\5
+\&{goto} \\{done};\5
+\2\&{else}\1\5
+${}\|q\K\\{font\_info}[\|k].\\{qqqq};{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{char\_info}(\\{hf})(\\{cur\_l});{}$\6
+\&{if} ${}(\\{char\_tag}(\|q)\I\\{lig\_tag}){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|k\K\\{lig\_kern\_start}(\\{hf})(\|q);{}$\5
+${}\|q\K\\{font\_info}[\|k].\\{qqqq};{}$\6
+\&{if} ${}(\\{skip\_byte}(\|q)>\\{stop\_flag}){}$\5
+${}\{{}$\5
+\1${}\|k\K\\{lig\_kern\_restart}(\\{hf})(\|q);{}$\5
+${}\|q\K\\{font\_info}[\|k].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{now \|k is the starting address of the lig/kern program}\2\6
+\&{if} ${}(\\{cur\_rh}<\\{non\_char}){}$\1\5
+${}\\{test\_char}\K\\{cur\_rh}{}$;\5
+\2\&{else}\1\5
+${}\\{test\_char}\K\\{cur\_r};{}$\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{next\_char}(\|q)\E\\{test\_char}){}$\1\6
+\&{if} ${}(\\{skip\_byte}(\|q)\Z\\{stop\_flag}){}$\1\6
+\&{if} ${}(\\{cur\_rh}<\\{non\_char}){}$\5
+${}\{{}$\5
+\1${}\\{hyphen\_passed}\K\|j;{}$\5
+${}\\{hchar}\K\\{non\_char};{}$\5
+${}\\{cur\_rh}\K\\{non\_char};{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{hchar}<\\{non\_char}){}$\1\6
+\&{if} (\\{odd}(\\{hyf}[\|j]))\5
+${}\{{}$\5
+\1${}\\{hyphen\_passed}\K\|j;{}$\5
+${}\\{hchar}\K\\{non\_char};{}$\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\\{op\_byte}(\|q)<\\{kern\_flag}){}$\1\5
+\X911:Carry out a ligature replacement, updating the cursor structure and possibly advancing~\|j; \&{goto} \&{continue} if the cursor doesn't advance, otherwise \&{goto} \\{done}\X;\2\6
+${}\|w\K\\{char\_kern}(\\{hf})(\|q);{}$\5
+\&{goto} \\{done};\C{this kern will be inserted below}\6
+\4${}\}{}$\2\2\2\6
+\&{if} ${}(\\{skip\_byte}(\|q)\G\\{stop\_flag}){}$\1\6
+\&{if} ${}(\\{cur\_rh}\E\\{non\_char}){}$\1\5
+\&{goto} \\{done};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_rh}\K\\{non\_char};{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\2\6
+${}\|k\K\|k+\\{qo}(\\{skip\_byte}(\|q))+\T{1};{}$\5
+${}\|q\K\\{font\_info}[\|k].\\{qqqq};{}$\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U906.\fi
+
+\M{910}\B\D$\\{wrap\_lig}(\|X)$ \6
+\&{if} (\\{ligature\_present})\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_ligature}(\\{hf},\39\\{cur\_l},\39\\{link}(\\{cur\_q}));{}$\6
+\&{if} (\\{lft\_hit})\5
+${}\{{}$\5
+\1${}\\{subtype}(\|p)\K\T{2};{}$\5
+${}\\{lft\_hit}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\&{if} (\|X)\1\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\5
+${}\{{}$\5
+\1\\{incr}(\\{subtype}(\|p));\5
+${}\\{rt\_hit}\K\\{false};{}$\6
+\4${}\}{}$\2\2\6
+${}\\{link}(\\{cur\_q})\K\|p;{}$\5
+${}\|t\K\|p;{}$\5
+${}\\{ligature\_present}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{pop\_lig\_stack}$ \6
+${}\{{}$\5
+\1\&{if} ${}(\\{lig\_ptr}(\\{lig\_stack})>\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|t)\K\\{lig\_ptr}(\\{lig\_stack}){}$;\C{this is a charnode for $\\{hu}[\|j+\T{1}]$}\6
+${}\|t\K\\{link}(\|t);{}$\5
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+${}\|p\K\\{lig\_stack};{}$\5
+${}\\{lig\_stack}\K\\{link}(\|p);{}$\5
+${}\\{free\_node}(\|p,\39\\{small\_node\_size});{}$\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\5
+\\{set\_cur\_r}\5
+\2\&{else}\1\5
+${}\\{cur\_r}\K\\{character}(\\{lig\_stack});{}$\2\6
+\4${}\}{}$\C{if \\{lig\_stack} isn't \\{null} we have $\\{cur\_rh}\E\\{non\_char}$}\2\par
+\Y\B\4\X910:Append a ligature and/or kern to the translation; \&{goto} \&{continue} if the stack of inserted ligatures is nonempty\X${}\E{}$\6
+\\{wrap\_lig}(\\{rt\_hit});\6
+\&{if} ${}(\|w\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|t)\K\\{new\_kern}(\|w);{}$\5
+${}\|t\K\\{link}(\|t);{}$\5
+${}\|w\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{lig\_stack}>\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_q}\K\|t;{}$\5
+${}\\{cur\_l}\K\\{character}(\\{lig\_stack});{}$\5
+${}\\{ligature\_present}\K\\{true};{}$\5
+\\{pop\_lig\_stack};\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U906.\fi
+
+\M{911}\B\X911:Carry out a ligature replacement, updating the cursor structure and possibly advancing~\|j; \&{goto} \&{continue} if the cursor doesn't advance, otherwise \&{goto} \\{done}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_l}\E\\{non\_char}){}$\1\5
+${}\\{lft\_hit}\K\\{true};{}$\2\6
+\&{if} ${}(\|j\E\|n){}$\1\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\5
+${}\\{rt\_hit}\K\\{true};{}$\2\2\6
+\\{check\_interrupt};\C{allow a way out in case there's an infinite ligature loop}\6
+\&{switch} (\\{op\_byte}(\|q))\5
+${}\{{}$\1\6
+\4\\{qi}(\&{case} \T{1}):\5
+\\{qi}(\&{case} \T{5}):\6
+${}\{{}$\5
+\1${}\\{cur\_l}\K\\{rem\_byte}(\|q){}$;\C{\.{=:\?}, \.{=:\?>}}\6
+${}\\{ligature\_present}\K\\{true};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{2}):\5
+\\{qi}(\&{case} \T{6}):\6
+${}\{{}$\5
+\1${}\\{cur\_r}\K\\{rem\_byte}(\|q){}$;\C{\.{\?=:}, \.{\?=:>}}\6
+\&{if} ${}(\\{lig\_stack}>\\{null}){}$\1\5
+${}\\{character}(\\{lig\_stack})\K\\{cur\_r};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{lig\_stack}\K\\{new\_lig\_item}(\\{cur\_r});{}$\6
+\&{if} ${}(\|j\E\|n){}$\1\5
+${}\\{bchar}\K\\{non\_char};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{lig\_ptr}(\\{lig\_stack})\K\|p;{}$\5
+${}\\{character}(\|p)\K\\{qi}(\\{hu}[\|j+\T{1}]);{}$\5
+${}\\{font}(\|p)\K\\{hf};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{3}):\6
+${}\{{}$\5
+\1${}\\{cur\_r}\K\\{rem\_byte}(\|q){}$;\C{\.{\?=:\?}}\6
+${}\|p\K\\{lig\_stack};{}$\5
+${}\\{lig\_stack}\K\\{new\_lig\_item}(\\{cur\_r});{}$\5
+${}\\{link}(\\{lig\_stack})\K\|p;{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{7}):\5
+\\{qi}(\&{case} \T{11}):\6
+${}\{{}$\5
+\1\\{wrap\_lig}(\\{false});\C{\.{\?=:\?>}, \.{\?=:\?>>}}\6
+${}\\{cur\_q}\K\|t;{}$\5
+${}\\{cur\_l}\K\\{rem\_byte}(\|q);{}$\5
+${}\\{ligature\_present}\K\\{true};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1${}\\{cur\_l}\K\\{rem\_byte}(\|q);{}$\5
+${}\\{ligature\_present}\K\\{true}{}$;\C{\.{=:}}\6
+\&{if} ${}(\\{lig\_stack}>\\{null}){}$\1\5
+\\{pop\_lig\_stack}\2\6
+\&{else} \&{if} ${}(\|j\E\|n){}$\1\5
+\&{goto} \\{done};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{append\_charnode\_to\_t}(\\{cur\_r});\5
+\\{incr}(\|j);\5
+\\{set\_cur\_r};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{op\_byte}(\|q)>\\{qi}(\T{4})){}$\1\6
+\&{if} ${}(\\{op\_byte}(\|q)\I\\{qi}(\T{7})){}$\1\5
+\&{goto} \\{done};\2\2\6
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U909.\fi
+
+\M{912}Okay, we're ready to insert the potential hyphenations that were found.
+When the following program is executed, we want to append the word
+$\\{hu}[\T{1}\dotdot\\{hn}]$ after node \\{ha}, and node \|q should be appended to the result.
+During this process, the variable \|i will be a temporary
+index into \\{hu}; the variable \|j will be an index to our current position
+in \\{hu}; the variable \|l will be the counterpart of \|j, in a discretionary
+branch; the variable \|r will point to new nodes being created; and
+we need a few new local variables:
+
+\Y\B\4\X901:Local variables for hyphenation\X${}\mathrel+\E{}$\6
+\&{pointer} \\{major\_tail}${},{}$ \\{minor\_tail};\C{the end of lists in the main and discretionary branches being reconstructed}\6
+\&{ASCII\_code} \|c;\C{character temporarily replaced by a hyphen}\6
+\&{uint8\_t} \\{c\_loc};\C{where that character came from}\6
+\&{int} \\{r\_count};\C{replacement count for discretionary}\6
+\&{pointer} \\{hyf\_node};\C{the hyphen, if it exists}\par
+\fi
+
+\M{913}When the following code is performed, \\{hyf}[\T{0}] and \\{hyf}[\\{hn}] will be zero.
+
+\Y\B\4\X913:Reconstitute nodes for the hyphenated word, inserting discretionary hyphens\X${}\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|l\K\|j;{}$\5
+${}\|j\K\\{reconstitute}(\|j,\39\\{hn},\39\\{bchar},\39\\{qi}(\\{hyf\_char}))+\T{1};{}$\6
+\&{if} ${}(\\{hyphen\_passed}\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|s)\K\\{link}(\\{hold\_head});{}$\6
+\&{while} ${}(\\{link}(\|s)>\\{null}){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+\&{if} ${}(\\{odd}(\\{hyf}[\|j-\T{1}])){}$\5
+${}\{{}$\5
+\1${}\|l\K\|j;{}$\5
+${}\\{hyphen\_passed}\K\|j-\T{1};{}$\5
+${}\\{link}(\\{hold\_head})\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{hyphen\_passed}>\T{0}){}$\1\5
+\X914:Create and append a discretionary node as an alternative to the unhyphenated word, and continue to develop both branches until they become equivalent\X;\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|j>\\{hn}));$ $\\{link}(\|s)\K{}$\|q\par
+\U903.\fi
+
+\M{914}In this repeat loop we will insert another discretionary if $\\{hyf}[\|j-\T{1}]$ is
+odd, when both branches of the previous discretionary end at position $\|j-\T{1}$.
+Strictly speaking, we aren't justified in doing this, because we don't know
+that a hyphen after $\|j-\T{1}$ is truly independent of those branches. But in almost
+all applications we would rather not lose a potentially valuable hyphenation
+point. (Consider the word `difficult', where the letter `c' is in position \|j.)
+
+\Y\B\4\D$\\{advance\_major\_tail}$ \6
+${}\{{}$\5
+\1${}\\{major\_tail}\K\\{link}(\\{major\_tail});{}$\5
+\\{incr}(\\{r\_count});\6
+\4${}\}{}$\2\par
+\Y\B\4\X914:Create and append a discretionary node as an alternative to the unhyphenated word, and continue to develop both branches until they become equivalent\X${}\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{link}(\|r)\K\\{link}(\\{hold\_head});{}$\5
+${}\\{type}(\|r)\K\\{disc\_node};{}$\5
+${}\\{major\_tail}\K\|r;{}$\5
+${}\\{r\_count}\K\T{0};{}$\6
+\&{while} ${}(\\{link}(\\{major\_tail})>\\{null}){}$\1\5
+\\{advance\_major\_tail};\2\6
+${}\|i\K\\{hyphen\_passed};{}$\5
+${}\\{hyf}[\|i]\K\T{0};{}$\5
+\X915:Put the \(c)characters $\\{hu}[\|l\MRL{{.}{.}}\|i]$ and a hyphen into \\{pre\_break}(\|r)\X;\6
+\X916:Put the \(c)characters $\\{hu}[\|i+\T{1..}]$ into \\{post\_break}(\|r), appending to this list and to \\{major\_tail} until synchronization has been achieved\X;\6
+\X918:Move pointer \|s to the end of the current list, and set \\{replace\_count}(\|r) appropriately\X;\6
+${}\\{hyphen\_passed}\K\|j-\T{1};{}$\5
+${}\\{link}(\\{hold\_head})\K\\{null};{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\R\\{odd}(\\{hyf}[\|j-\T{1}])){}$)\par
+\U913.\fi
+
+\M{915}The new hyphen might combine with the previous character via ligature
+or kern. At this point we have $\|l-\T{1}\Z\|i<\|j$ and $\|i<\\{hn}$.
+
+\Y\B\4\X915:Put the \(c)characters $\\{hu}[\|l\MRL{{.}{.}}\|i]$ and a hyphen into \\{pre\_break}(\|r)\X${}\E{}$\6
+$\\{minor\_tail}\K\\{null};{}$\5
+${}\\{pre\_break}(\|r)\K\\{null};{}$\5
+${}\\{hyf\_node}\K\\{new\_character}(\\{hf},\39\\{hyf\_char});{}$\6
+\&{if} ${}(\\{hyf\_node}\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{incr}(\|i);\5
+${}\|c\K\\{hu}[\|i];{}$\5
+${}\\{hu}[\|i]\K\\{hyf\_char};{}$\5
+\\{free\_avail}(\\{hyf\_node});\6
+\4${}\}{}$\2\6
+\&{while} ${}(\|l\Z\|i){}$\5
+${}\{{}$\5
+\1${}\|l\K\\{reconstitute}(\|l,\39\|i,\39\\{font\_bchar}[\\{hf}],\39\\{non\_char})+\T{1};{}$\6
+\&{if} ${}(\\{link}(\\{hold\_head})>\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{minor\_tail}\E\\{null}){}$\1\5
+${}\\{pre\_break}(\|r)\K\\{link}(\\{hold\_head});{}$\2\6
+\&{else}\1\5
+${}\\{link}(\\{minor\_tail})\K\\{link}(\\{hold\_head});{}$\2\6
+${}\\{minor\_tail}\K\\{link}(\\{hold\_head});{}$\6
+\&{while} ${}(\\{link}(\\{minor\_tail})>\\{null}){}$\1\5
+${}\\{minor\_tail}\K\\{link}(\\{minor\_tail});{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{hyf\_node}\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{hu}[\|i]\K\|c{}$;\C{restore the character in the hyphen position}\6
+${}\|l\K\|i;{}$\5
+\\{decr}(\|i);\6
+\4${}\}{}$\2\par
+\U914.\fi
+
+\M{916}The synchronization algorithm begins with $\|l\E\|i+\T{1}\Z\|j$.
+
+\Y\B\4\X916:Put the \(c)characters $\\{hu}[\|i+\T{1..}]$ into \\{post\_break}(\|r), appending to this list and to \\{major\_tail} until synchronization has been achieved\X${}\E{}$\6
+$\\{minor\_tail}\K\\{null};{}$\5
+${}\\{post\_break}(\|r)\K\\{null};{}$\5
+${}\\{c\_loc}\K\T{0};{}$\6
+\&{if} ${}(\\{bchar\_label}[\\{hf}]\I\\{non\_address}{}$)\C{put left boundary at beginning of new line}\6
+${}\{{}$\5
+\1\\{decr}(\|l);\5
+${}\|c\K\\{hu}[\|l];{}$\5
+${}\\{c\_loc}\K\|l;{}$\5
+${}\\{hu}[\|l]\K\T{256};{}$\6
+\4${}\}{}$\2\6
+\&{while} ${}(\|l<\|j){}$\5
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+${}\|l\K\\{reconstitute}(\|l,\39\\{hn},\39\\{bchar},\39\\{non\_char})+\T{1};{}$\6
+\&{if} ${}(\\{c\_loc}>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{hu}[\\{c\_loc}]\K\|c;{}$\5
+${}\\{c\_loc}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{link}(\\{hold\_head})>\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{minor\_tail}\E\\{null}){}$\1\5
+${}\\{post\_break}(\|r)\K\\{link}(\\{hold\_head});{}$\2\6
+\&{else}\1\5
+${}\\{link}(\\{minor\_tail})\K\\{link}(\\{hold\_head});{}$\2\6
+${}\\{minor\_tail}\K\\{link}(\\{hold\_head});{}$\6
+\&{while} ${}(\\{link}(\\{minor\_tail})>\\{null}){}$\1\5
+${}\\{minor\_tail}\K\\{link}(\\{minor\_tail});{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|l\G\|j));{}$\6
+\&{while} ${}(\|l>\|j){}$\1\5
+\X917:Append characters of \\{hu} [ \|j $\MRL{{.}{.}}$ ] to \\{major\_tail}, advancing~\|j\X;\2\6
+\4${}\}{}$\2\par
+\U914.\fi
+
+\M{917}\B\X917:Append characters of \\{hu} [ \|j $\MRL{{.}{.}}$ ] to \\{major\_tail}, advancing~\|j\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|j\K\\{reconstitute}(\|j,\39\\{hn},\39\\{bchar},\39\\{non\_char})+\T{1};{}$\5
+${}\\{link}(\\{major\_tail})\K\\{link}(\\{hold\_head});{}$\6
+\&{while} ${}(\\{link}(\\{major\_tail})>\\{null}){}$\1\5
+\\{advance\_major\_tail};\2\6
+\4${}\}{}$\2\par
+\U916.\fi
+
+\M{918}Ligature insertion can cause a word to grow exponentially in size. Therefore
+we must test the size of \\{r\_count} here, even though the hyphenated text
+was at most 63 characters long.
+
+\Y\B\4\X918:Move pointer \|s to the end of the current list, and set \\{replace\_count}(\|r) appropriately\X${}\E{}$\6
+\&{if} ${}(\\{r\_count}>\T{127}{}$)\C{we have to forget the discretionary hyphen}\6
+${}\{{}$\5
+\1${}\\{link}(\|s)\K\\{link}(\|r);{}$\5
+${}\\{link}(\|r)\K\\{null};{}$\5
+\\{flush\_node\_list}(\|r);\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\|s)\K\|r;{}$\5
+${}\\{replace\_count}(\|r)\K\\{r\_count};{}$\6
+\4${}\}{}$\2\6
+$\|s\K{}$\\{major\_tail}\par
+\U914.\fi
+
+\N{1}{919}Hyphenation.
+When a word $\\{hc}[\T{1}\dotdot\\{hn}]$ has been set up to contain a candidate for hyphenation,
+\TeX\ first looks to see if it is in the user's exception dictionary. If not,
+hyphens are inserted based on patterns that appear within the given word,
+using an algorithm due to Frank~M. Liang.
+
+Let's consider Liang's method first, since it is much more interesting than the
+exception-lookup routine. The algorithm begins by setting \\{hyf}[\|j] to zero
+for all \|j, and invalid characters are inserted into \\{hc}[\T{0}]
+and $\\{hc}[\\{hn}+\T{1}]$ to serve as delimiters. Then a reasonably fast method is
+used to see which of a given set of patterns occurs in the word
+$\\{hc}[\T{0}\dotdot(\\{hn}+\T{1})]$. Each pattern $p_1\ldots p_k$ of length \|k has an associated
+sequence of $\|k+\T{1}$ numbers $n_0\ldots n_k$; and if the pattern occurs in
+$\\{hc}[(\|j+\T{1})\dotdot(\|j+\|k)]$, \TeX\ will set $\\{hyf}[\|j+\|i]\K\hbox{max}(\\{hyf}[\|j+\|i],\,\hbox{$n_i$})$ for
+$\T{0}\Z\|i\Z\|k$. After this has been done for each pattern that occurs, a
+discretionary hyphen will be inserted between \\{hc}[\|j] and $\\{hc}[\|j+\T{1}]$ when
+\\{hyf}[\|j] is odd, as we have already seen.
+
+The set of patterns $p_1\ldots p_k$ and associated numbers $n_0\ldots n_k$
+depends, of course, on the language whose words are being hyphenated, and
+on the degree of hyphenation that is desired. A method for finding
+appropriate \|p's and \|n's, from a given dictionary of words and acceptable
+hyphenations, is discussed in Liang's Ph.D. thesis (Stanford University,
+1983); \TeX\ simply starts with the patterns and works from there.
+
+\fi
+
+\M{920}The patterns are stored in a compact table that is also efficient for
+retrieval, using a variant of ``trie memory'' [cf.\ {\sl The Art of
+Computer Programming \bf3} (1973), 481--505]. We can find each pattern
+$p_1\ldots p_k$ by letting $z_0$ be one greater than the relevant language
+index and then, for $\T{1}\Z\|i\Z\|k$,
+setting $\hbox{$z_i$}\K$ \\{trie\_link}\hbox{$(z_{i-1})+p_i$}; the pattern will be
+identified by the number $z_k$. Since all the pattern information is
+packed together into a single \\{trie\_link} array, it is necessary to
+prevent confusion between the data from inequivalent patterns, so another
+table is provided such that \\{trie\_char}\hbox{$(z_i)=p_i$} for all \|i. There
+is also a table \\{trie\_op}$(z_k)$ to identify the numbers $n_0\ldots n_k$
+associated with $p_1\ldots p_k$.
+
+Comparatively few different number sequences $n_0\ldots n_k$ actually occur,
+since most of the \|n's are generally zero. Therefore the number sequences
+are encoded in such a way that \\{trie\_op}$(z_k)$ is only one byte long.
+If $\\{trie\_op}(\,\hbox{$z_k$})\I\\{min\_quarterword}$, when $p_1\ldots p_k$ has matched
+the letters in $\\{hc}[(\|l-\|k+\T{1})\dotdot\|l\,]$ of language \|t,
+we perform all of the required operations
+for this pattern by carrying out the following little program: Set
+$\|v\K\\{trie\_op}(\,\hbox{$z_k$})$. Then set $\|v\K\|v+\\{op\_start}[\|t]$,
+$\\{hyf}[\|l-\\{hyf\_distance}[\|v]]\K\hbox{max}(\\{hyf}[\|l-\\{hyf\_distance}[\|v]],\\{hyf\_num}[\|v])$,
+and $\|v\K\\{hyf\_next}[\|v]$; repeat, if necessary, until $\|v\E\\{min\_quarterword}$.
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint16\_t} \&{trie\_pointer};\C{an index into \\{trie}}\par
+\fi
+
+\M{921}\B\D$\\{trie\_link}(\|X)$ \5
+$\\{trie}[\|X].{}$\\{rh}\C{``downward'' link in a trie}\par
+\B\4\D$\\{trie\_char}(\|X)$ \5
+$\\{trie}[\|X].{}$\\{b1}\C{character matched at this trie location}\par
+\B\4\D$\\{trie\_op}(\|X)$ \5
+$\\{trie}[\|X].{}$\\{b0}\C{program for hyphenation at this trie location}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{two\_halves} ${}\\{trie}[\\{trie\_size}+\T{1}]{}$;\C{\\{trie\_link}, \\{trie\_char}, \\{trie\_op}}\6
+\&{small\_number} \\{hyf\_distance0}[\\{trie\_op\_size}]${},{}$ ${}{*\&{const}\ }\\{hyf\_distance}\K\\{hyf\_distance0}-\T{1}{}$;\C{position $\|k-\|j$ of $n_j$}\6
+\&{small\_number} \\{hyf\_num0}[\\{trie\_op\_size}]${},{}$ ${}{*\&{const}\ }\\{hyf\_num}\K\\{hyf\_num0}-\T{1}{}$;\C{value of $n_j$}\6
+\&{quarterword} \\{hyf\_next0}[\\{trie\_op\_size}]${},{}$ ${}{*\&{const}\ }\\{hyf\_next}\K\\{hyf\_next0}-\T{1}{}$;\C{continuation code}\6
+\&{uint16\_t} \\{op\_start}[\T{256}];\C{offset for current language}\par
+\fi
+
+\M{922}\B\X901:Local variables for hyphenation\X${}\mathrel+\E{}$\6
+\&{trie\_pointer} \|z;\C{an index into \\{trie}}\6
+\&{int} \|v;\C{an index into \\{hyf\_distance}, etc.}\par
+\fi
+
+\M{923}Assuming that these auxiliary tables have been set up properly, the
+hyphenation algorithm is quite short. In the following code we set $\\{hc}[\\{hn}+\T{2}]$
+to the impossible value 256, in order to guarantee that $\\{hc}[\\{hn}+\T{3}]$ will
+never be fetched.
+
+\Y\B\4\X923:Find hyphen locations for the word in \\{hc}, or \&{return}\X${}\E{}$\6
+\&{for} ${}(\|j\K\T{0};{}$ ${}\|j\Z\\{hn};{}$ ${}\|j\PP){}$\1\5
+${}\\{hyf}[\|j]\K\T{0};{}$\2\6
+\X930:Look for the word \\{hc}[\T{1..}\\{hn}] in the exception table, and \&{goto} \\{found} (with \\{hyf} containing the hyphens) if an entry is found\X;\6
+\&{if} ${}(\\{trie\_char}(\\{cur\_lang}+\T{1})\I\\{qi}(\\{cur\_lang})){}$\1\5
+\&{return};\C{no patterns for \\{cur\_lang}}\2\6
+${}\\{hc}[\T{0}]\K\T{0};{}$\5
+${}\\{hc}[\\{hn}+\T{1}]\K\T{0};{}$\5
+${}\\{hc}[\\{hn}+\T{2}]\K\T{256}{}$;\C{insert delimiters}\6
+\&{for} ${}(\|j\K\T{0};{}$ ${}\|j\Z\\{hn}-\\{r\_hyf}+\T{1};{}$ ${}\|j\PP){}$\5
+${}\{{}$\5
+\1${}\|z\K\\{trie\_link}(\\{cur\_lang}+\T{1})+\\{hc}[\|j];{}$\5
+${}\|l\K\|j;{}$\6
+\&{while} ${}(\\{hc}[\|l]\E\\{qo}(\\{trie\_char}(\|z))){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{trie\_op}(\|z)\I\\{min\_quarterword}){}$\1\5
+\X924:Store \(m)maximum values in the \\{hyf} table\X;\2\6
+\\{incr}(\|l);\5
+${}\|z\K\\{trie\_link}(\|z)+\\{hc}[\|l];{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4\\{found}:\6
+\&{for} ${}(\|j\K\T{0};{}$ ${}\|j\Z\\{l\_hyf}-\T{1};{}$ ${}\|j\PP){}$\1\5
+${}\\{hyf}[\|j]\K\T{0};{}$\2\6
+\&{for} ${}(\|j\K\T{0};{}$ ${}\|j\Z\\{r\_hyf}-\T{1};{}$ ${}\|j\PP)$ $\\{hyf}[\\{hn}-\|j]\K{}$\T{0}\par
+\U895.\fi
+
+\M{924}\B\X924:Store \(m)maximum values in the \\{hyf} table\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|v\K\\{trie\_op}(\|z){}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|v\K\|v+\\{op\_start}[\\{cur\_lang}];{}$\5
+${}\|i\K\|l-\\{hyf\_distance}[\|v];{}$\6
+\&{if} ${}(\\{hyf\_num}[\|v]>\\{hyf}[\|i]){}$\1\5
+${}\\{hyf}[\|i]\K\\{hyf\_num}[\|v];{}$\2\6
+${}\|v\K\\{hyf\_next}[\|v];{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|v\E\\{min\_quarterword}));{}$\6
+\4${}\}{}$\2\par
+\U923.\fi
+
+\M{925}The exception table that is built by \TeX's \.{\\hyphenation} primitive is
+organized as an ordered hash table [cf.\ Amble and Knuth, {\sl The Computer
+Journal\/ \bf17} (1974), 135--142] using linear probing. If $\alpha$ and
+$\beta$ are words, we will say that $\alpha<\beta$ if $\vert\alpha\vert<
+\vert\beta\vert$ or if $\vert\alpha\vert=\vert\beta\vert$ and
+$\alpha$ is lexicographically smaller than $\beta$. (The notation $\vert
+\alpha\vert$ stands for the length of $\alpha$.) The idea of ordered hashing
+is to arrange the table so that a given word $\alpha$ can be sought by computing
+a hash address $h=h(\alpha)$ and then looking in table positions \|h, $\|h-\T{1}$,
+\dots, until encountering the first word $\L\alpha$. If this word is
+different from $\alpha$, we can conclude that $\alpha$ is not in the table.
+
+The words in the table point to lists in \\{mem} that specify hyphen positions
+in their \\{info} fields. The list for $c_1\ldots c_n$ contains the number \|k if
+the word $c_1\ldots c_n$ has a discretionary hyphen between $c_k$ and
+$c_{k+1}$.
+
+\Y\B\4\X18:Types in the outer block\X${}\mathrel+\E{}$\6
+\&{typedef} \&{uint16\_t} \&{hyph\_pointer};\C{an index into the ordered hash table}\par
+\fi
+
+\M{926}\B\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{str\_number} ${}\\{hyph\_word}[\\{hyph\_size}+\T{1}]{}$;\C{exception words}\6
+\&{pointer} ${}\\{hyph\_list}[\\{hyph\_size}+\T{1}]{}$;\C{lists of hyphen positions}\6
+\&{hyph\_pointer} \\{hyph\_count};\C{the number of words in the exception dictionary}\par
+\fi
+
+\M{927}\B\X19:Local variables for initialization\X${}\mathrel+\E{}$\6
+\&{hyph\_pointer} \|z;\C{runs through the exception dictionary}\par
+\fi
+
+\M{928}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|z\K\T{0};{}$ ${}\|z\Z\\{hyph\_size};{}$ ${}\|z\PP){}$\5
+${}\{{}$\5
+\1${}\\{hyph\_word}[\|z]\K\T{0};{}$\5
+${}\\{hyph\_list}[\|z]\K\\{null};{}$\6
+\4${}\}{}$\2\6
+${}\\{hyph\_count}\K\T{0}{}$;\par
+\fi
+
+\M{929}The algorithm for exception lookup is quite simple, as soon as we have
+a few more local variables to work with.
+
+\Y\B\4\X901:Local variables for hyphenation\X${}\mathrel+\E{}$\6
+\&{hyph\_pointer} \|h;\C{an index into \\{hyph\_word} and \\{hyph\_list}}\6
+\&{str\_number} \|k;\C{an index into \\{str\_start}}\6
+\&{pool\_pointer} \|u;\C{an index into \\{str\_pool}}\par
+\fi
+
+\M{930}First we compute the hash code \|h, then we search until we either
+find the word or we don't. Words from different languages are kept
+separate by appending the language code to the string.
+
+\Y\B\4\X930:Look for the word \\{hc}[\T{1..}\\{hn}] in the exception table, and \&{goto} \\{found} (with \\{hyf} containing the hyphens) if an entry is found\X${}\E{}$\6
+$\|h\K\\{hc}[\T{1}];{}$\5
+\\{incr}(\\{hn});\5
+${}\\{hc}[\\{hn}]\K\\{cur\_lang};{}$\6
+\&{for} ${}(\|j\K\T{2};{}$ ${}\|j\Z\\{hn};{}$ ${}\|j\PP){}$\1\5
+${}\|h\K(\|h+\|h+\\{hc}[\|j])\MOD\\{hyph\_size};{}$\2\6
+\&{loop}\5
+${}\{{}$\5
+\1\X931:If the string \\{hyph\_word}[\|h] is less than \(hc)\\{hc}[\T{1..}\\{hn}], \&{goto} \\{not\_found}; but if the two strings are equal, set \\{hyf} to the hyphen positions and \&{goto} \\{found}\X;\6
+\&{if} ${}(\|h>\T{0}){}$\1\5
+\\{decr}(\|h);\5
+\2\&{else}\1\5
+${}\|h\K\\{hyph\_size};{}$\2\6
+\4${}\}{}$\2\6
+\\{not\_found}: \\{decr}(\\{hn})\par
+\U923.\fi
+
+\M{931}\B\X931:If the string \\{hyph\_word}[\|h] is less than \(hc)\\{hc}[\T{1..}\\{hn}], \&{goto} \\{not\_found}; but if the two strings are equal, set \\{hyf} to the hyphen positions and \&{goto} \\{found}\X${}\E{}$\6
+$\|k\K\\{hyph\_word}[\|h];{}$\6
+\&{if} ${}(\|k\E\T{0}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\&{if} ${}(\\{length}(\|k)<\\{hn}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\&{if} ${}(\\{length}(\|k)\E\\{hn}){}$\5
+${}\{{}$\5
+\1${}\|j\K\T{1};{}$\5
+${}\|u\K\\{str\_start}[\|k]{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{so}(\\{str\_pool}[\|u])<\\{hc}[\|j]){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\&{if} ${}(\\{so}(\\{str\_pool}[\|u])>\\{hc}[\|j]){}$\1\5
+\&{goto} \\{done};\2\6
+\\{incr}(\|j);\5
+\\{incr}(\|u);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|j>\\{hn}));{}$\5
+\X932:Insert hyphens as specified in \\{hyph\_list}[\|h]\X;\6
+\\{decr}(\\{hn});\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U930.\fi
+
+\M{932}\B\X932:Insert hyphens as specified in \\{hyph\_list}[\|h]\X${}\E{}$\6
+$\|s\K\\{hyph\_list}[\|h];{}$\6
+\&{while} ${}(\|s\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{hyf}[\\{info}(\|s)]\K\T{1};{}$\5
+${}\|s\K\\{link}(\|s);{}$\6
+\4${}\}{}$\2\par
+\U931.\fi
+
+\M{933}\B\X933:Search \\{hyph\_list} for pointers to \|p\X${}\E{}$\6
+\&{for} ${}(\|q\K\T{0};{}$ ${}\|q\Z\\{hyph\_size};{}$ ${}\|q\PP){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{hyph\_list}[\|q]\E\|p){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"HYPH("});\5
+\\{print\_int}(\|q);\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U172.\fi
+
+\M{934}We have now completed the hyphenation routine, so the \\{line\_break} procedure
+is finished at last. Since the hyphenation exception table is fresh in our
+minds, it's a good time to deal with the routine that adds new entries to it.
+
+When \TeX\ has scanned `\.{\\hyphenation}', it calls on a procedure named
+\\{new\_hyph\_exceptions} to do the right thing.
+
+\Y\B\4\D$\\{set\_cur\_lang}$ \6
+\&{if} ${}(\\{language}\Z\T{0}){}$\1\5
+${}\\{cur\_lang}\K\T{0};{}$\2\6
+\&{else} \&{if} ${}(\\{language}>\T{255}){}$\1\5
+${}\\{cur\_lang}\K\T{0};{}$\2\6
+\&{else} $\\{cur\_lang}\K{}$\\{language}\par
+\Y\B\&{void} \\{new\_hyph\_exceptions}(\&{void})\C{enters new exceptions}\6
+${}\{{}$\5
+\1\&{uint8\_t} \|n;\C{length of current word; not always a \&{small\_number}}\6
+\&{int} \|j;\C{an index into \\{hc}}\6
+\&{hyph\_pointer} \|h;\C{an index into \\{hyph\_word} and \\{hyph\_list}}\6
+\&{str\_number} \|k;\C{an index into \\{str\_start}}\6
+\&{pointer} \|p;\C{head of a list of hyphen positions}\6
+\&{pointer} \|q;\C{used when creating a new node for list \|p}\6
+\&{str\_number} \|s${},{}$ \|t;\C{strings being compared or stored}\6
+\&{pool\_pointer} \|u${},{}$ \|v;\C{indices into \\{str\_pool}}\7
+\\{scan\_left\_brace}(\,);\C{a left brace must follow \.{\\hyphenation}}\6
+\\{set\_cur\_lang};\5
+\X935:Enter as many hyphenation exceptions as are listed, until coming to a right brace; then \&{return}\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{935}\B\X935:Enter as many hyphenation exceptions as are listed, until coming to a right brace; then \&{return}\X${}\E{}$\6
+$\|n\K\T{0};{}$\5
+${}\|p\K\\{null};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\4\\{reswitch}:\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{letter}:\5
+\&{case} \\{other\_char}:\5
+\&{case} \\{char\_given}:\5
+\X937:Append a new letter or hyphen\X\5
+\&{break};\6
+\4\&{case} \\{char\_num}:\6
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\\{cur\_chr}\K\\{cur\_val};{}$\5
+${}\\{cur\_cmd}\K\\{char\_given};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{spacer}:\5
+\&{case} \\{right\_brace}:\6
+${}\{{}$\5
+\1\&{if} ${}(\|n>\T{1}){}$\1\5
+\X939:Enter a hyphenation exception\X;\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{right\_brace}){}$\1\5
+\&{return};\2\6
+${}\|n\K\T{0};{}$\5
+${}\|p\K\\{null};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\X936:Give improper \.{\\hyphenation} error\X\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U934.\fi
+
+\M{936}\B\X936:Give improper \.{\\hyphenation} error\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ "});\5
+\\{print\_esc}(\X1683:\.{"hyphenation"}\X);\5
+\\{print\_str}(\.{"\ will\ be\ flushed"});\5
+\\{help2}(\.{"Hyphenation\ excepti}\)\.{ons\ must\ contain\ onl}\)\.{y\ letters"})\6
+(\.{"and\ hyphens.\ But\ co}\)\.{ntinue;\ I'll\ forgive}\)\.{\ and\ forget."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U935.\fi
+
+\M{937}\B\X937:Append a new letter or hyphen\X${}\E{}$\6
+\&{if} ${}(\\{cur\_chr}\E\.{'-'}){}$\1\5
+\X938:Append the value \|n to list \|p\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{lc\_code}(\\{cur\_chr})\E\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Not\ a\ letter"});\5
+\\{help2}(\.{"Letters\ in\ \\\\hyphen}\)\.{ation\ words\ must\ hav}\)\.{e\ \\\\lccode>0."})\6
+(\.{"Proceed;\ I'll\ ignor}\)\.{e\ the\ character\ I\ ju}\)\.{st\ read."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|n<\T{63}){}$\5
+${}\{{}$\5
+\1\\{incr}(\|n);\5
+${}\\{hc}[\|n]\K\\{lc\_code}(\\{cur\_chr});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U935.\fi
+
+\M{938}\B\X938:Append the value \|n to list \|p\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|n<\T{63}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\\{info}(\|q)\K\|n;{}$\5
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U937.\fi
+
+\M{939}\B\X939:Enter a hyphenation exception\X${}\E{}$\6
+${}\{{}$\5
+\1\\{incr}(\|n);\5
+${}\\{hc}[\|n]\K\\{cur\_lang};{}$\5
+\\{str\_room}(\|n);\5
+${}\|h\K\T{0};{}$\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\|n;{}$ ${}\|j\PP){}$\5
+${}\{{}$\5
+\1${}\|h\K(\|h+\|h+\\{hc}[\|j])\MOD\\{hyph\_size};{}$\5
+\\{append\_char}(\\{hc}[\|j]);\6
+\4${}\}{}$\2\6
+${}\|s\K\\{make\_string}(\,);{}$\5
+\X940:Insert the \(p)pair $(\|s,\|p)$ into the exception table\X;\6
+\4${}\}{}$\2\par
+\U935.\fi
+
+\M{940}\B\X940:Insert the \(p)pair $(\|s,\|p)$ into the exception table\X${}\E{}$\6
+\&{if} ${}(\\{hyph\_count}\E\\{hyph\_size}){}$\1\5
+${}\\{overflow}(\.{"exception\ dictionar}\)\.{y"},\39\\{hyph\_size});{}$\2\6
+\\{incr}(\\{hyph\_count});\6
+\&{while} ${}(\\{hyph\_word}[\|h]\I\T{0}){}$\5
+${}\{{}$\5
+\1\X941:If the string \\{hyph\_word}[\|h] is less than \(or)or equal to \|s, interchange $(\\{hyph\_word}[\|h],\\{hyph\_list}[\|h])$ with $(\|s,\|p)$\X;\6
+\&{if} ${}(\|h>\T{0}){}$\1\5
+\\{decr}(\|h);\5
+\2\&{else}\1\5
+${}\|h\K\\{hyph\_size};{}$\2\6
+\4${}\}{}$\2\6
+${}\\{hyph\_word}[\|h]\K\|s;$ $\\{hyph\_list}[\|h]\K{}$\|p\par
+\U939.\fi
+
+\M{941}\B\X941:If the string \\{hyph\_word}[\|h] is less than \(or)or equal to \|s, interchange $(\\{hyph\_word}[\|h],\\{hyph\_list}[\|h])$ with $(\|s,\|p)$\X${}\E{}$\6
+$\|k\K\\{hyph\_word}[\|h];{}$\6
+\&{if} ${}(\\{length}(\|k)<\\{length}(\|s)){}$\1\5
+\&{goto} \\{found};\2\6
+\&{if} ${}(\\{length}(\|k)>\\{length}(\|s)){}$\1\5
+\&{goto} \\{not\_found};\2\6
+${}\|u\K\\{str\_start}[\|k];{}$\5
+${}\|v\K\\{str\_start}[\|s]{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{if} ${}(\\{str\_pool}[\|u]<\\{str\_pool}[\|v]){}$\1\5
+\&{goto} \\{found};\2\6
+\&{if} ${}(\\{str\_pool}[\|u]>\\{str\_pool}[\|v]){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\\{incr}(\|u);\5
+\\{incr}(\|v);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|u\E\\{str\_start}[\|k+\T{1}]));{}$\6
+\4\\{found}:\5
+${}\|q\K\\{hyph\_list}[\|h];{}$\5
+${}\\{hyph\_list}[\|h]\K\|p;{}$\5
+${}\|p\K\|q{}$;\6
+${}\|t\K\\{hyph\_word}[\|h];{}$\5
+${}\\{hyph\_word}[\|h]\K\|s;{}$\5
+${}\|s\K\|t;$ \\{not\_found}:\par
+\U940.\fi
+
+\N{1}{942}Initializing the hyphenation tables.
+The trie for \TeX's hyphenation algorithm is built from a sequence of
+patterns following a \.{\\patterns} specification. Such a specification
+is allowed only in \.{INITEX}, since the extra memory for auxiliary tables
+and for the initialization program itself would only clutter up the
+production version of \TeX\ with a lot of deadwood.
+
+The first step is to build a trie that is linked, instead of packed
+into sequential storage, so that insertions are readily made.
+After all patterns have been processed, \.{INITEX}
+compresses the linked trie by identifying common subtries. Finally the
+trie is packed into the efficient sequential form that the hyphenation
+algorithm actually uses.
+
+\Y\B\4\X826:Declare subprocedures for \\{line\_break}\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\X944:Declare procedures for preprocessing hyphenation patterns\X\6
+\8\#\&{endif}\par
+\fi
+
+\M{943}Before we discuss trie building in detail, let's consider the simpler
+problem of creating the \\{hyf\_distance}, \\{hyf\_num}, and \\{hyf\_next} arrays.
+
+Suppose, for example, that \TeX\ reads the pattern `\.{ab2cde1}'. This is
+a pattern of length 5, with $n_0\ldots n_5=0\,0\,2\,0\,0\,1$ in the
+notation above. We want the corresponding \\{trie\_op} code \|v to have
+$\\{hyf\_distance}[\|v]\E\T{3}$, $\\{hyf\_num}[\|v]\E\T{2}$, and \\{hyf\_next}[\|v] $\E\hbox{$v^\prime$}$,
+where the auxiliary \\{trie\_op} code $v^\prime$ has
+$\\{hyf\_distance}[\,\hbox{$v^\prime$}]\E\T{0}$, $\\{hyf\_num}[\,\hbox{$v^\prime$}]\E\T{1}$, and
+$\\{hyf\_next}[\,\hbox{$v^\prime$}]\E\\{min\_quarterword}$.
+
+\TeX\ computes an appropriate value \|v with the \\{new\_trie\_op} subroutine
+below, by setting
+$$\hbox{$\hbox{$v^\prime$}\K$ $\\{new\_trie\_op}(\T{0},\T{1},\\{min\_quarterword})$,\qquad
+$\|v\K\\{new\_trie\_op}(\T{3},\T{2},\,\hbox{$v^\prime$})$.}$$
+This subroutine looks up its three
+parameters in a special hash table, assigning a new value only if these
+three have not appeared before for the current language.
+
+The hash table is called \\{trie\_op\_hash}, and the number of entries it contains
+is \\{trie\_op\_ptr}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{uint16\_t} ${}\\{trie\_op\_hash0}[\\{trie\_op\_size}+\\{trie\_op\_size}+\T{1}],{}$ ${}{*\&{const}\ }\\{trie\_op\_hash}\K\\{trie\_op\_hash0}+\\{trie\_op\_size}{}$;\C{trie op codes for quadruples}\6
+\&{quarterword} \\{trie\_used}[\T{256}];\C{largest opcode used so far for this language}\6
+\&{ASCII\_code} \\{trie\_op\_lang0}[\\{trie\_op\_size}]${},{}$ ${}{*\&{const}\ }\\{trie\_op\_lang}\K\\{trie\_op\_lang0}-\T{1}{}$;\C{language part of a hashed quadruple}\6
+\&{quarterword} \\{trie\_op\_val0}[\\{trie\_op\_size}]${},{}$ ${}{*\&{const}\ }\\{trie\_op\_val}\K\\{trie\_op\_val0}-\T{1}{}$;\C{opcode corresponding to a hashed quadruple}\6
+\&{uint16\_t} \\{trie\_op\_ptr};\C{number of stored ops so far}\6
+\8\#\&{endif}\par
+\fi
+
+\M{944}It's tempting to remove the \\{overflow} stops in the following procedure;
+\\{new\_trie\_op} could return \\{min\_quarterword} (thereby simply ignoring
+part of a hyphenation pattern) instead of aborting the job. However, that would
+lead to different hyphenation results on different installations of \TeX\
+using the same patterns. The \\{overflow} stops are necessary for portability
+of patterns.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\E{}$\6
+\&{quarterword} \\{new\_trie\_op}(\&{small\_number} \|d${},\39{}$\&{small\_number} \|n${},\39{}$\&{quarterword} \|v)\1\1\2\2\6
+${}\{{}$\5
+\1\\{int16\_t}\|h;\C{trial hash location}\7
+\&{quarterword} \|u;\C{trial op code}\6
+\&{uint16\_t} \|l;\C{pointer to stored data}\7
+${}\|h\K\\{abs}(\|n+\T{313}*\|d+\T{361}*\|v+\T{1009}*\\{cur\_lang})\MOD(\\{trie\_op\_size}+\\{trie\_op\_size})-\\{trie\_op\_size};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1${}\|l\K\\{trie\_op\_hash}[\|h];{}$\6
+\&{if} ${}(\|l\E\T{0}{}$)\C{empty position found for a new op}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{trie\_op\_ptr}\E\\{trie\_op\_size}){}$\1\5
+${}\\{overflow}(\.{"pattern\ memory\ ops"},\39\\{trie\_op\_size});{}$\2\6
+${}\|u\K\\{trie\_used}[\\{cur\_lang}];{}$\6
+\&{if} ${}(\|u\E\\{max\_quarterword}){}$\1\5
+${}\\{overflow}(\.{"pattern\ memory\ ops\ }\)\.{per\ language"},\39\\{max\_quarterword}-\\{min\_quarterword});{}$\2\6
+\\{incr}(\\{trie\_op\_ptr});\5
+\\{incr}(\|u);\5
+${}\\{trie\_used}[\\{cur\_lang}]\K\|u;{}$\5
+${}\\{hyf\_distance}[\\{trie\_op\_ptr}]\K\|d;{}$\5
+${}\\{hyf\_num}[\\{trie\_op\_ptr}]\K\|n;{}$\5
+${}\\{hyf\_next}[\\{trie\_op\_ptr}]\K\|v;{}$\5
+${}\\{trie\_op\_lang}[\\{trie\_op\_ptr}]\K\\{cur\_lang};{}$\5
+${}\\{trie\_op\_hash}[\|h]\K\\{trie\_op\_ptr};{}$\5
+${}\\{trie\_op\_val}[\\{trie\_op\_ptr}]\K\|u;{}$\5
+\&{return} \|u;\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{hyf\_distance}[\|l]\E\|d)\W(\\{hyf\_num}[\|l]\E\|n)\W(\\{hyf\_next}[\|l]\E\|v)\W(\\{trie\_op\_lang}[\|l]\E\\{cur\_lang})){}$\5
+${}\{{}$\5
+\1\&{return} \\{trie\_op\_val}[\|l];\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|h>{-}\\{trie\_op\_size}){}$\1\5
+\\{decr}(\|h);\5
+\2\&{else}\1\5
+${}\|h\K\\{trie\_op\_size};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\As948, 949, 953, 957, 959, 960\ETs966.
+\U942.\fi
+
+\M{945}After \\{new\_trie\_op} has compressed the necessary opcode information,
+plenty of information is available to unscramble the data into the
+final form needed by our hyphenation algorithm.
+
+\Y\B\4\X945:Sort \(t)the hyphenation op tables into proper order\X${}\E{}$\6
+$\\{op\_start}[\T{0}]\K{-}\\{min\_quarterword};{}$\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\T{255};{}$ ${}\|j\PP){}$\1\5
+${}\\{op\_start}[\|j]\K\\{op\_start}[\|j-\T{1}]+\\{qo}(\\{trie\_used}[\|j-\T{1}]);{}$\2\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{trie\_op\_ptr};{}$ ${}\|j\PP){}$\1\5
+${}\\{trie\_op\_hash}[\|j]\K\\{op\_start}[\\{trie\_op\_lang}[\|j]]+\\{trie\_op\_val}[\|j]{}$;\C{destination}\2\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{trie\_op\_ptr};{}$ ${}\|j\PP){}$\1\6
+\&{while} ${}(\\{trie\_op\_hash}[\|j]>\|j){}$\5
+${}\{{}$\5
+\1${}\|k\K\\{trie\_op\_hash}[\|j]{}$;\6
+${}\|t\K\\{hyf\_distance}[\|k];{}$\5
+${}\\{hyf\_distance}[\|k]\K\\{hyf\_distance}[\|j];{}$\5
+${}\\{hyf\_distance}[\|j]\K\|t{}$;\6
+${}\|t\K\\{hyf\_num}[\|k];{}$\5
+${}\\{hyf\_num}[\|k]\K\\{hyf\_num}[\|j];{}$\5
+${}\\{hyf\_num}[\|j]\K\|t{}$;\6
+${}\|t\K\\{hyf\_next}[\|k];{}$\5
+${}\\{hyf\_next}[\|k]\K\\{hyf\_next}[\|j];{}$\5
+${}\\{hyf\_next}[\|j]\K\|t{}$;\6
+${}\\{trie\_op\_hash}[\|j]\K\\{trie\_op\_hash}[\|k];{}$\5
+${}\\{trie\_op\_hash}[\|k]\K\|k;{}$\6
+\4${}\}{}$\2\2\par
+\U952.\fi
+
+\M{946}Before we forget how to initialize the data structures that have been
+mentioned so far, let's write down the code that gets them started.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K{-}\\{trie\_op\_size};{}$ ${}\|k\Z\\{trie\_op\_size};{}$ ${}\|k\PP){}$\1\5
+${}\\{trie\_op\_hash}[\|k]\K\T{0};{}$\2\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{255};{}$ ${}\|k\PP){}$\1\5
+${}\\{trie\_used}[\|k]\K\\{min\_quarterword};{}$\2\6
+${}\\{trie\_op\_ptr}\K\T{0}{}$;\par
+\fi
+
+\M{947}The linked trie that is used to preprocess hyphenation patterns appears
+in several global arrays. Each node represents an instruction of the form
+``if you see character \|c, then perform operation \|o, move to the
+next character, and go to node \|l; otherwise go to node \|r.''
+The four quantities \|c, \|o, \|l, and \|r are stored in four arrays
+\\{trie\_c}, \\{trie\_o}, \\{trie\_l}, and \\{trie\_r}. The root of the trie
+is \\{trie\_l}[\T{0}], and the number of nodes is \\{trie\_ptr}. Null trie
+pointers are represented by zero. To initialize the trie, we simply
+set \\{trie\_l}[\T{0}] and \\{trie\_ptr} to zero. We also set \\{trie\_c}[\T{0}] to some
+arbitrary value, since the algorithm may access it.
+
+The algorithms maintain the condition
+$$\hbox{$\\{trie\_c}[\\{trie\_r}[\|z]]>\\{trie\_c}[\|z]$\qquad
+whenever $\|z\I\T{0}$ and $\\{trie\_r}[\|z]\I\T{0}$};$$ in other words, sibling nodes are
+ordered by their \|c fields.
+
+\Y\B\4\D$\\{trie\_root}$ \5
+\\{trie\_l}[\T{0}]\C{root of the linked trie}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{packed\_ASCII\_code} ${}\\{trie\_c}[\\{trie\_size}+\T{1}]{}$;\C{characters to match}\6
+\hbox{\hskip10pt}\&{quarterword} ${}\\{trie\_o}[\\{trie\_size}+\T{1}]{}$;\C{operations to perform}\6
+\hbox{\hskip10pt}\&{trie\_pointer} ${}\\{trie\_l}[\\{trie\_size}+\T{1}]{}$;\C{left subtrie links}\6
+\hbox{\hskip10pt}\&{trie\_pointer} ${}\\{trie\_r}[\\{trie\_size}+\T{1}]{}$;\C{right subtrie links}\6
+\hbox{\hskip10pt}\&{trie\_pointer} \\{trie\_ptr};\C{the number of nodes in the trie}\6
+\hbox{\hskip10pt}\&{trie\_pointer} ${}\\{trie\_hash}[\\{trie\_size}+\T{1}]{}$;\C{used to identify equivalent subtries}\6
+\8\#\&{endif}\par
+\fi
+
+\M{948}Let us suppose that a linked trie has already been constructed.
+Experience shows that we can often reduce its size by recognizing common
+subtries; therefore another hash table is introduced for this purpose,
+somewhat similar to \\{trie\_op\_hash}. The new hash table will be
+initialized to zero.
+
+The function \\{trie\_node}(\|p) returns \|p if \|p is distinct from other nodes
+that it has seen, otherwise it returns the number of the first equivalent
+node that it has seen.
+
+Notice that we might make subtries equivalent even if they correspond to
+patterns for different languages, in which the trie ops might mean quite
+different things. That's perfectly all right.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{trie\_pointer} \\{trie\_node}(\&{trie\_pointer} \|p)\C{converts to a canonical form}\6
+${}\{{}$\5
+\1\&{trie\_pointer} \|h;\C{trial hash location}\6
+\&{trie\_pointer} \|q;\C{trial trie node}\7
+${}\|h\K\\{abs}(\\{trie\_c}[\|p]+\T{1009}*\\{trie\_o}[\|p]+\30\T{2718}*\\{trie\_l}[\|p]+\T{3142}*\\{trie\_r}[\|p])\MOD\\{trie\_size};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1${}\|q\K\\{trie\_hash}[\|h];{}$\6
+\&{if} ${}(\|q\E\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{trie\_hash}[\|h]\K\|p;{}$\5
+\&{return} \|p;\6
+\4${}\}{}$\2\6
+\&{if} ${}((\\{trie\_c}[\|q]\E\\{trie\_c}[\|p])\W(\\{trie\_o}[\|q]\E\\{trie\_o}[\|p])\W\30(\\{trie\_l}[\|q]\E\\{trie\_l}[\|p])\W(\\{trie\_r}[\|q]\E\\{trie\_r}[\|p])){}$\5
+${}\{{}$\5
+\1\&{return} \|q;\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|h>\T{0}){}$\1\5
+\\{decr}(\|h);\5
+\2\&{else}\1\5
+${}\|h\K\\{trie\_size};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{949}A neat recursive procedure is now able to compress a trie by
+traversing it and applying \\{trie\_node} to its nodes in ``bottom up''
+fashion. We will compress the entire trie by clearing \\{trie\_hash} to
+zero and then saying `$\\{trie\_root}\K\\{compress\_trie}(\\{trie\_root})$'.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{trie\_pointer} \\{compress\_trie}(\&{trie\_pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|p\E\T{0}){}$\1\5
+\&{return} \T{0};\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{trie\_l}[\|p]\K\\{compress\_trie}(\\{trie\_l}[\|p]);{}$\5
+${}\\{trie\_r}[\|p]\K\\{compress\_trie}(\\{trie\_r}[\|p]);{}$\5
+\&{return} \\{trie\_node}(\|p);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{950}The compressed trie will be packed into the \\{trie} array using a
+``top-down first-fit'' procedure. This is a little tricky, so the reader
+should pay close attention: The \\{trie\_hash} array is cleared to zero
+again and renamed \\{trie\_ref} for this phase of the operation; later on,
+\\{trie\_ref}[\|p] will be nonzero only if the linked trie node \|p is the
+smallest character
+in a family and if the characters \|c of that family have been allocated to
+locations $\\{trie\_ref}[\|p]+\|c$ in the \\{trie} array. Locations of \\{trie} that
+are in use will have $\\{trie\_link}\E\T{0}$, while the unused holes in \\{trie}
+will be doubly linked with \\{trie\_link} pointing to the next larger vacant
+location and \\{trie\_back} pointing to the next smaller one. This double
+linking will have been carried out only as far as \\{trie\_max}, where
+\\{trie\_max} is the largest index of \\{trie} that will be needed.
+To save time at the low end of the trie, we maintain array entries
+\\{trie\_min}[\|c] pointing to the smallest hole that is greater than~\|c.
+Another array \\{trie\_taken} tells whether or not a given location is
+equal to \\{trie\_ref}[\|p] for some \|p; this array is used to ensure that
+distinct nodes in the compressed trie will have distinct \\{trie\_ref}
+entries.
+
+\Y\B\4\D$\\{trie\_ref}$ \5
+\\{trie\_hash}\C{where linked trie families go into \\{trie}}\par
+\B\4\D$\\{trie\_back}(\|X)$ \5
+$\\{trie}[\|X].{}$\\{lh}\C{backward links in \\{trie} holes}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{bool} \\{trie\_taken0}[\\{trie\_size}]${},{}$ ${}{*\&{const}\ }\\{trie\_taken}\K\\{trie\_taken0}-\T{1}{}$;\C{does a family start here?}\6
+\hbox{\hskip10pt}\&{trie\_pointer} \\{trie\_min}[\T{256}];\C{the first possible slot for each character}\6
+\hbox{\hskip10pt}\&{trie\_pointer} \\{trie\_max};\C{largest location used in \\{trie}}\6
+\hbox{\hskip10pt}\&{bool} \\{trie\_not\_ready};\C{is the trie still in linked form?}\6
+\8\#\&{endif}\par
+\fi
+
+\M{951}Each time \.{\\patterns} appears, it contributes further patterns to
+the future trie, which will be built only when hyphenation is attempted or
+when a format file is dumped. The boolean variable \\{trie\_not\_ready}
+will change to \\{false} when the trie is compressed; this will disable
+further patterns.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{trie\_not\_ready}\K\\{true};{}$\5
+${}\\{trie\_root}\K\T{0};{}$\5
+${}\\{trie\_c}[\T{0}]\K\\{si}(\T{0});{}$\5
+${}\\{trie\_ptr}\K\T{0}{}$;\par
+\fi
+
+\M{952}Here is how the trie-compression data structures are initialized.
+If storage is tight, it would be possible to overlap \\{trie\_op\_hash},
+\\{trie\_op\_lang}, and \\{trie\_op\_val} with \\{trie}, \\{trie\_hash}, and \\{trie\_taken},
+because we finish with the former just before we need the latter.
+
+\Y\B\4\X952:Get ready to compress the trie\X${}\E{}$\6
+\X945:Sort \(t)the hyphenation op tables into proper order\X;\6
+\&{for} ${}(\|p\K\T{0};{}$ ${}\|p\Z\\{trie\_size};{}$ ${}\|p\PP){}$\1\5
+${}\\{trie\_hash}[\|p]\K\T{0};{}$\2\6
+${}\\{trie\_root}\K\\{compress\_trie}(\\{trie\_root}){}$;\C{identify equivalent subtries}\6
+\&{for} ${}(\|p\K\T{0};{}$ ${}\|p\Z\\{trie\_ptr};{}$ ${}\|p\PP){}$\1\5
+${}\\{trie\_ref}[\|p]\K\T{0};{}$\2\6
+\&{for} ${}(\|p\K\T{0};{}$ ${}\|p\Z\T{255};{}$ ${}\|p\PP){}$\1\5
+${}\\{trie\_min}[\|p]\K\|p+\T{1};{}$\2\6
+${}\\{trie\_link}(\T{0})\K\T{1};$ $\\{trie\_max}\K{}$\T{0}\par
+\U966.\fi
+
+\M{953}The \\{first\_fit} procedure finds the smallest hole \|z in \\{trie} such that
+a trie family starting at a given node \|p will fit into vacant positions
+starting at \|z. If $\|c\E\\{trie\_c}[\|p]$, this means that location $\|z-\|c$ must
+not already be taken by some other family, and that $\|z-\|c$ $+\hbox{$c^\prime$}$
+must be vacant for all characters $c^\prime$ in the family. The procedure
+sets \\{trie\_ref}[\|p] to $\|z-\|c$ when the first fit has been found.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{void} \\{first\_fit}(\&{trie\_pointer} \|p)\C{packs a family into \\{trie}}\6
+${}\{{}$\5
+\1\&{trie\_pointer} \|h;\C{candidate for \\{trie\_ref}[\|p]}\6
+\&{trie\_pointer} \|z;\C{runs through holes}\6
+\&{trie\_pointer} \|q;\C{runs through the family starting at \|p}\6
+\&{ASCII\_code} \|c;\C{smallest character in the family}\6
+\&{trie\_pointer} \|l${},{}$ \|r;\C{left and right neighbors}\6
+\&{uint16\_t} \\{ll};\C{upper limit of \\{trie\_min} updating}\7
+${}\|c\K\\{so}(\\{trie\_c}[\|p]);{}$\5
+${}\|z\K\\{trie\_min}[\|c]{}$;\C{get the first conceivably good hole}\6
+\&{loop}\5
+${}\{{}$\5
+\1${}\|h\K\|z-\|c{}$;\6
+\X954:Ensure that $\\{trie\_max}\G\|h+\T{256}$\X;\6
+\&{if} (\\{trie\_taken}[\|h])\1\5
+\&{goto} \\{not\_found};\2\6
+\X955:If all characters of the family fit relative to \|h, then \&{goto} \\{found},\30\ otherwise \&{goto} \\{not\_found}\X;\6
+\4\\{not\_found}:\5
+${}\|z\K\\{trie\_link}(\|z){}$;\C{move to the next hole}\6
+\4${}\}{}$\2\6
+\4\\{found}:\5
+\X956:Pack the family into \\{trie} relative to \|h\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{954}By making sure that \\{trie\_max} is at least $\|h+\T{256}$, we can be sure that
+$\\{trie\_max}>\|z$, since $\|h\E\|z-\|c$. It follows that location \\{trie\_max} will
+never be occupied in \\{trie}, and we will have $\\{trie\_max}\G\\{trie\_link}(\|z)$.
+
+\Y\B\4\X954:Ensure that $\\{trie\_max}\G\|h+\T{256}$\X${}\E{}$\6
+\&{if} ${}(\\{trie\_max}<\|h+\T{256}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{trie\_size}\Z\|h+\T{256}){}$\1\5
+${}\\{overflow}(\.{"pattern\ memory"},\39\\{trie\_size}){}$;\2\6
+\&{do}\5
+${}\{{}$\1\6
+\\{incr}(\\{trie\_max});\5
+${}\\{trie\_taken}[\\{trie\_max}]\K\\{false};{}$\5
+${}\\{trie\_link}(\\{trie\_max})\K\\{trie\_max}+\T{1};{}$\5
+${}\\{trie\_back}(\\{trie\_max})\K\\{trie\_max}-\T{1};{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{trie\_max}\E\|h+\T{256}));{}$\6
+\4${}\}{}$\2\par
+\U953.\fi
+
+\M{955}\B\X955:If all characters of the family fit relative to \|h, then \&{goto} \\{found},\30\ otherwise \&{goto} \\{not\_found}\X${}\E{}$\6
+$\|q\K\\{trie\_r}[\|p];{}$\6
+\&{while} ${}(\|q>\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{trie\_link}(\|h+\\{so}(\\{trie\_c}[\|q]))\E\T{0}){}$\1\5
+\&{goto} \\{not\_found};\2\6
+${}\|q\K\\{trie\_r}[\|q];{}$\6
+\4${}\}{}$\2\6
+\&{goto} \\{found}\par
+\U953.\fi
+
+\M{956}\B\X956:Pack the family into \\{trie} relative to \|h\X${}\E{}$\6
+$\\{trie\_taken}[\|h]\K\\{true};{}$\5
+${}\\{trie\_ref}[\|p]\K\|h;{}$\5
+${}\|q\K\|p{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|z\K\|h+\\{so}(\\{trie\_c}[\|q]);{}$\5
+${}\|l\K\\{trie\_back}(\|z);{}$\5
+${}\|r\K\\{trie\_link}(\|z);{}$\5
+${}\\{trie\_back}(\|r)\K\|l;{}$\5
+${}\\{trie\_link}(\|l)\K\|r;{}$\5
+${}\\{trie\_link}(\|z)\K\T{0};{}$\6
+\&{if} ${}(\|l<\T{256}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|z<\T{256}){}$\1\5
+${}\\{ll}\K\|z{}$;\5
+\2\&{else}\1\5
+${}\\{ll}\K\T{256}{}$;\2\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{trie\_min}[\|l]\K\|r;{}$\5
+\\{incr}(\|l);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|l\E\\{ll}));{}$\6
+\4${}\}{}$\2\6
+${}\|q\K\\{trie\_r}[\|q];{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|q\E\T{0}){}$)\par
+\U953.\fi
+
+\M{957}To pack the entire linked trie, we use the following recursive procedure.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{void} \\{trie\_pack}(\&{trie\_pointer} \|p)\C{pack subtries of a family}\6
+${}\{{}$\5
+\1\&{trie\_pointer} \|q;\C{a local variable that need not be saved on recursive calls}\7
+\&{do}\5
+${}\{{}$\1\6
+${}\|q\K\\{trie\_l}[\|p];{}$\6
+\&{if} ${}((\|q>\T{0})\W(\\{trie\_ref}[\|q]\E\T{0})){}$\5
+${}\{{}$\5
+\1\\{first\_fit}(\|q);\5
+\\{trie\_pack}(\|q);\6
+\4${}\}{}$\2\6
+${}\|p\K\\{trie\_r}[\|p];{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|p\E\T{0}));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{958}When the whole trie has been allocated into the sequential table, we
+must go through it once again so that \\{trie} contains the correct
+information. Null pointers in the linked trie will be represented by the
+value~0, which properly implements an ``empty'' family.
+
+\Y\B\4\X958:Move the data into \\{trie}\X${}\E{}$\6
+$\|h.\\{rh}\K\T{0};{}$\5
+${}\|h.\\{b0}\K\\{min\_quarterword};{}$\5
+${}\|h.\\{b1}\K\\{min\_quarterword}{}$;\C{$\\{trie\_link}\K\T{0}$, $\\{trie\_op}\K\\{min\_quarterword}$, $\\{trie\_char}\K\\{qi}(\T{0})$}\6
+\&{if} ${}(\\{trie\_root}\E\T{0}{}$)\C{no patterns were given}\6
+${}\{{}$\5
+\1\&{for} ${}(\|r\K\T{0};{}$ ${}\|r\Z\T{256};{}$ ${}\|r\PP){}$\1\5
+${}\\{trie}[\|r]\K\|h;{}$\2\6
+${}\\{trie\_max}\K\T{256};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{trie\_fix}(\\{trie\_root});\C{this fixes the non-holes in \\{trie}}\6
+${}\|r\K\T{0}{}$;\C{now we will zero out all the holes}\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|s\K\\{trie\_link}(\|r);{}$\5
+${}\\{trie}[\|r]\K\|h;{}$\5
+${}\|r\K\|s;{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|r>\\{trie\_max}));{}$\6
+\4${}\}{}$\2\6
+${}\\{trie\_char}(\T{0})\K\\{qi}(\.{'?'}){}$;\C{make $\\{trie\_char}(\|c)\I\|c$ for all \|c}\par
+\U966.\fi
+
+\M{959}The fixing-up procedure is, of course, recursive. Since the linked trie
+usually has overlapping subtries, the same data may be moved several
+times; but that causes no harm, and at most as much work is done as it
+took to build the uncompressed trie.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{void} \\{trie\_fix}(\&{trie\_pointer} \|p)\C{moves \|p and its siblings into \\{trie}}\6
+${}\{{}$\5
+\1\&{trie\_pointer} \|q;\C{a local variable that need not be saved on recursive calls}\6
+\&{ASCII\_code} \|c;\C{another one that need not be saved}\6
+\&{trie\_pointer} \|z;\C{\\{trie} reference; this local variable must be saved}\7
+${}\|z\K\\{trie\_ref}[\|p]{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|q\K\\{trie\_l}[\|p];{}$\5
+${}\|c\K\\{so}(\\{trie\_c}[\|p]);{}$\5
+${}\\{trie\_link}(\|z+\|c)\K\\{trie\_ref}[\|q];{}$\5
+${}\\{trie\_char}(\|z+\|c)\K\\{qi}(\|c);{}$\5
+${}\\{trie\_op}(\|z+\|c)\K\\{trie\_o}[\|p];{}$\6
+\&{if} ${}(\|q>\T{0}){}$\1\5
+\\{trie\_fix}(\|q);\2\6
+${}\|p\K\\{trie\_r}[\|p];{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|p\E\T{0}));{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{960}Now let's go back to the easier problem, of building the linked
+trie. When \.{INITEX} has scanned the `\.{\\patterns}' control
+sequence, it calls on \\{new\_patterns} to do the right thing.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{void} \\{new\_patterns}(\&{void})\C{initializes the hyphenation pattern data}\6
+${}\{{}$\5
+\1\&{uint8\_t} \|k${},{}$ \|l;\C{indices into \\{hc} and \\{hyf}; not always in \&{small\_number} range}\6
+\&{bool} \\{digit\_sensed};\C{should the next digit be treated as a letter?}\6
+\&{quarterword} \|v;\C{trie op code}\6
+\&{trie\_pointer} \|p${},{}$ \|q;\C{nodes of trie traversed during insertion}\6
+\&{bool} \\{first\_child};\C{is $\|p\E\\{trie\_l}[\|q]$?}\6
+\&{ASCII\_code} \|c;\C{character being inserted}\7
+\&{if} (\\{trie\_not\_ready})\5
+${}\{{}$\5
+\1\\{set\_cur\_lang};\5
+\\{scan\_left\_brace}(\,);\C{a left brace must follow \.{\\patterns}}\6
+\X961:Enter all of the patterns into a linked trie, until coming to a right brace\X;\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Too\ late\ for\ "});\5
+\\{print\_esc}(\X1684:\.{"patterns"}\X);\5
+\\{help1}(\.{"All\ patterns\ must\ b}\)\.{e\ given\ before\ types}\)\.{etting\ begins."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{link}(\\{garbage})\K\\{scan\_toks}(\\{false},\39\\{false});{}$\5
+\\{flush\_list}(\\{def\_ref});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{961}Novices are not supposed to be using \.{\\patterns}, so the error
+messages are terse. (Note that all error messages appear in \TeX's string
+pool, even if they are used only by \.{INITEX}.)
+
+\Y\B\4\X961:Enter all of the patterns into a linked trie, until coming to a right brace\X${}\E{}$\6
+$\|k\K\T{0};{}$\5
+${}\\{hyf}[\T{0}]\K\T{0};{}$\5
+${}\\{digit\_sensed}\K\\{false};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{letter}:\5
+\&{case} \\{other\_char}:\5
+\X962:Append a new letter or a hyphen level\X\5
+\&{break};\6
+\4\&{case} \\{spacer}:\5
+\&{case} \\{right\_brace}:\6
+${}\{{}$\5
+\1\&{if} ${}(\|k>\T{0}){}$\1\5
+\X963:Insert a new pattern into the linked trie\X;\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{right\_brace}){}$\1\5
+\&{goto} \\{done};\2\6
+${}\|k\K\T{0};{}$\5
+${}\\{hyf}[\T{0}]\K\T{0};{}$\5
+${}\\{digit\_sensed}\K\\{false};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ "});\5
+\\{print\_esc}(\X1684:\.{"patterns"}\X);\5
+\\{help1}(\.{"(See\ Appendix\ H.)"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U960.\fi
+
+\M{962}\B\X962:Append a new letter or a hyphen level\X${}\E{}$\6
+\&{if} ${}(\\{digit\_sensed}\V(\\{cur\_chr}<\.{'0'})\V(\\{cur\_chr}>\.{'9'})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_chr}\E\.{'.'}){}$\1\5
+${}\\{cur\_chr}\K\T{0}{}$;\C{edge-of-word delimiter}\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_chr}\K\\{lc\_code}(\\{cur\_chr});{}$\6
+\&{if} ${}(\\{cur\_chr}\E\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Nonletter"});\5
+\\{help1}(\.{"(See\ Appendix\ H.)"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|k<\T{63}){}$\5
+${}\{{}$\5
+\1\\{incr}(\|k);\5
+${}\\{hc}[\|k]\K\\{cur\_chr};{}$\5
+${}\\{hyf}[\|k]\K\T{0};{}$\5
+${}\\{digit\_sensed}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\|k<\T{63}){}$\5
+${}\{{}$\5
+\1${}\\{hyf}[\|k]\K\\{cur\_chr}-\.{'0'};{}$\5
+${}\\{digit\_sensed}\K\\{true};{}$\6
+\4${}\}{}$\2\par
+\U961.\fi
+
+\M{963}When the following code comes into play, the pattern $p_1\ldots p_k$
+appears in $\\{hc}[\T{1}\dotdot\|k]$, and the corresponding sequence of numbers $n_0\ldots
+n_k$ appears in $\\{hyf}[\T{0}\dotdot\|k]$.
+
+\Y\B\4\X963:Insert a new pattern into the linked trie\X${}\E{}$\6
+${}\{{}$\5
+\1\X965:Compute the trie op code, \|v, and set \|l: $\K$ \T{0}\X;\6
+${}\|q\K\T{0};{}$\5
+${}\\{hc}[\T{0}]\K\\{cur\_lang};{}$\6
+\&{while} ${}(\|l\Z\|k){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{hc}[\|l];{}$\5
+\\{incr}(\|l);\5
+${}\|p\K\\{trie\_l}[\|q];{}$\5
+${}\\{first\_child}\K\\{true};{}$\6
+\&{while} ${}((\|p>\T{0})\W(\|c>\\{so}(\\{trie\_c}[\|p]))){}$\5
+${}\{{}$\5
+\1${}\|q\K\|p;{}$\5
+${}\|p\K\\{trie\_r}[\|q];{}$\5
+${}\\{first\_child}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}((\|p\E\T{0})\V(\|c<\\{so}(\\{trie\_c}[\|p]))){}$\1\5
+\X964:Insert a new trie node between \|q and \|p, and make \|p point to it\X;\2\6
+${}\|q\K\|p{}$;\C{now node \|q represents $p_1\ldots p_{l-1}$}\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{trie\_o}[\|q]\I\\{min\_quarterword}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Duplicate\ pattern"});\5
+\\{help1}(\.{"(See\ Appendix\ H.)"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+${}\\{trie\_o}[\|q]\K\|v;{}$\6
+\4${}\}{}$\2\par
+\U961.\fi
+
+\M{964}\B\X964:Insert a new trie node between \|q and \|p, and make \|p point to it\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{trie\_ptr}\E\\{trie\_size}){}$\1\5
+${}\\{overflow}(\.{"pattern\ memory"},\39\\{trie\_size});{}$\2\6
+\\{incr}(\\{trie\_ptr});\5
+${}\\{trie\_r}[\\{trie\_ptr}]\K\|p;{}$\5
+${}\|p\K\\{trie\_ptr};{}$\5
+${}\\{trie\_l}[\|p]\K\T{0};{}$\6
+\&{if} (\\{first\_child})\1\5
+${}\\{trie\_l}[\|q]\K\|p{}$;\5
+\2\&{else}\1\5
+${}\\{trie\_r}[\|q]\K\|p;{}$\2\6
+${}\\{trie\_c}[\|p]\K\\{si}(\|c);{}$\5
+${}\\{trie\_o}[\|p]\K\\{min\_quarterword};{}$\6
+\4${}\}{}$\2\par
+\U963.\fi
+
+\M{965}\B\X965:Compute the trie op code, \|v, and set \|l: $\K$ \T{0}\X${}\E{}$\6
+\&{if} ${}(\\{hc}[\T{1}]\E\T{0}){}$\1\5
+${}\\{hyf}[\T{0}]\K\T{0};{}$\2\6
+\&{if} ${}(\\{hc}[\|k]\E\T{0}){}$\1\5
+${}\\{hyf}[\|k]\K\T{0};{}$\2\6
+${}\|l\K\|k;{}$\5
+${}\|v\K\\{min\_quarterword};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{hyf}[\|l]\I\T{0}){}$\1\5
+${}\|v\K\\{new\_trie\_op}(\|k-\|l,\39\\{hyf}[\|l],\39\|v);{}$\2\6
+\&{if} ${}(\|l>\T{0}){}$\1\5
+\\{decr}(\|l);\5
+\2\&{else}\1\5
+\&{goto} \\{done1};\2\6
+\4${}\}{}$\2\6
+\\{done1}:\par
+\U963.\fi
+
+\M{966}Finally we put everything together: Here is how the trie gets to its
+final, efficient form.
+The following packing routine is rigged so that the root of the linked
+tree gets mapped into location 1 of \\{trie}, as required by the hyphenation
+algorithm. This happens because the first call of \\{first\_fit} will
+``take'' location~1.
+
+\Y\B\4\X944:Declare procedures for preprocessing hyphenation patterns\X${}\mathrel+\E{}$\6
+\&{void} \\{init\_trie}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{trie\_pointer} \|p;\C{pointer for initialization}\6
+\&{int} \|j${},{}$ \|k${},{}$ \|t;\C{all-purpose registers for initialization}\6
+\&{trie\_pointer} \|r${},{}$ \|s;\C{used to clean up the packed \\{trie}}\6
+\&{two\_halves} \|h;\C{template used to zero out \\{trie}'s holes}\7
+\X952:Get ready to compress the trie\X;\6
+\&{if} ${}(\\{trie\_root}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{first\_fit}(\\{trie\_root});\5
+\\{trie\_pack}(\\{trie\_root});\6
+\4${}\}{}$\2\6
+\X958:Move the data into \\{trie}\X;\6
+${}\\{trie\_not\_ready}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{967}Breaking vertical lists into pages.
+The \\{vsplit} procedure, which implements \TeX's \.{\\vsplit} operation,
+is considerably simpler than \\{line\_break} because it doesn't have to
+worry about hyphenation, and because its mission is to discover a single
+break instead of an optimum sequence of breakpoints. But before we get
+into the details of \\{vsplit}, we need to consider a few more basic things.
+
+\fi
+
+\M{968}A subroutine called \\{prune\_page\_top} takes a pointer to a vlist and
+returns a pointer to a modified vlist in which all glue, kern, and penalty nodes
+have been deleted before the first box or rule node. However, the first
+box or rule is actually preceded by a newly created glue node designed so that
+the topmost baseline will be at distance \\{split\_top\_skip} from the top,
+whenever this is possible without backspacing.
+
+In this routine and those that follow, we make use of the fact that a
+vertical list contains no character nodes, hence the \\{type} field exists
+for each node in the list.
+
+\Y\B\&{pointer} \\{prune\_page\_top}(\&{pointer} \|p)\C{adjust top after page break}\6
+${}\{{}$\5
+\1\&{pointer} \\{prev\_p};\C{lags one step behind \|p}\6
+\&{pointer} \|q;\C{temporary variable for list manipulation}\7
+${}\\{prev\_p}\K\\{temp\_head};{}$\5
+${}\\{link}(\\{temp\_head})\K\|p;{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\1\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\5
+\X969:Insert glue for \\{split\_top\_skip} and set~\|p: $\K$ \\{null}\X\5
+\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\&{case} \\{mark\_node}:\5
+\&{case} \\{ins\_node}:\6
+${}\{{}$\5
+\1${}\\{prev\_p}\K\|p;{}$\5
+${}\|p\K\\{link}(\\{prev\_p});{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\&{case} \\{kern\_node}:\5
+\&{case} \\{penalty\_node}:\6
+${}\{{}$\5
+\1${}\|q\K\|p;{}$\5
+${}\|p\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\\{link}(\\{prev\_p})\K\|p;{}$\5
+\\{flush\_node\_list}(\|q);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1685:\.{"pruning"}\X);\6
+\4${}\}{}$\2\2\6
+\&{return} \\{link}(\\{temp\_head});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{969}\B\X969:Insert glue for \\{split\_top\_skip} and set~\|p: $\K$ \\{null}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{new\_skip\_param}(\\{split\_top\_skip\_code});{}$\5
+${}\\{link}(\\{prev\_p})\K\|q;{}$\5
+${}\\{link}(\|q)\K\|p{}$;\C{now $\\{temp\_ptr}\E\\{glue\_ptr}(\|q)$}\6
+\&{if} ${}(\\{width}(\\{temp\_ptr})>\\{height}(\|p)){}$\1\5
+${}\\{width}(\\{temp\_ptr})\K\\{width}(\\{temp\_ptr})-\\{height}(\|p);{}$\2\6
+\&{else}\1\5
+${}\\{width}(\\{temp\_ptr})\K\T{0};{}$\2\6
+${}\|p\K\\{null};{}$\6
+\4${}\}{}$\2\par
+\U968.\fi
+
+\M{970}The next subroutine finds the best place to break a given vertical list
+so as to obtain a box of height~\|h, with maximum depth~\|d.
+A pointer to the beginning of the vertical list is given,
+and a pointer to the optimum breakpoint is returned. The list is effectively
+followed by a forced break, i.e., a penalty node with the \\{eject\_penalty};
+if the best break occurs at this artificial node, the value \\{null} is returned.
+
+An array of six \&{scaled} distances is used to keep track of the height
+from the beginning of the list to the current place, just as in \\{line\_break}.
+In fact, we use one of the same arrays, only changing its name to reflect
+its new significance.
+
+\Y\B\4\D$\\{active\_height}$ \5
+\\{active\_width}\C{new name for the six distance variables}\par
+\B\4\D$\\{cur\_height}$ \5
+\\{active\_height}[\T{1}]\C{the natural height}\par
+\B\4\D$\\{set\_height\_zero}(\|X)$ \5
+$\\{active\_height}[\|X]\K{}$\T{0}\C{initialize the height to zero}\Y\par
+\Y\B\&{pointer} \\{vert\_break}(\&{pointer} \|p${},\39{}$\&{scaled} \|h${},\39{}$\&{scaled} \|d)\C{finds optimum page break}\6
+${}\{{}$\5
+\1\&{pointer} \\{prev\_p};\C{if \|p is a glue node, \\{type}(\\{prev\_p}) determines whether \|p is a legal breakpoint}\6
+\&{pointer} \|q${},{}$ \|r;\C{glue specifications}\6
+\&{int} \\{pi};\C{penalty value}\6
+\&{int} \|b;\C{badness at a trial breakpoint}\6
+\&{int} \\{least\_cost};\C{the smallest badness plus penalties found so far}\6
+\&{pointer} \\{best\_place};\C{the most recent break that leads to \\{least\_cost}}\6
+\&{scaled} \\{prev\_dp};\C{depth of previous box in the list}\6
+\&{small\_number} \|t;\C{\\{type} of the node following a kern}\7
+${}\\{prev\_p}\K\|p{}$;\C{an initial glue node is not a legal breakpoint}\6
+${}\\{least\_cost}\K\\{awful\_bad};{}$\5
+\\{do\_all\_six}(\\{set\_height\_zero});\5
+${}\\{prev\_dp}\K\T{0};{}$\6
+\&{loop}\5
+${}\{{}$\5
+\1\X972:If node \|p is a legal breakpoint, check if this break is the best known, and \&{goto} \\{done} if \|p is null or if the page-so-far is already too full to accept more stuff\X;\6
+${}\\{prev\_p}\K\|p;{}$\5
+${}\|p\K\\{link}(\\{prev\_p});{}$\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+\&{return} \\{best\_place};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{971}A global variable \\{best\_height\_plus\_depth} will be set to the natural size
+of the box that corresponds to the optimum breakpoint found by \\{vert\_break}.
+(This value is used by the insertion-splitting algorithm of the page builder.)
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} \\{best\_height\_plus\_depth};\C{height of the best box, without stretching or shrinking}\par
+\fi
+
+\M{972}A subtle point to be noted here is that the maximum depth~\|d might be
+negative, so \\{cur\_height} and \\{prev\_dp} might need to be corrected even
+after a glue or kern node.
+
+\Y\B\4\X972:If node \|p is a legal breakpoint, check if this break is the best known, and \&{goto} \\{done} if \|p is null or if the page-so-far is already too full to accept more stuff\X${}\E{}$\6
+\&{if} ${}(\|p\E\\{null}){}$\1\5
+${}\\{pi}\K\\{eject\_penalty};{}$\2\6
+\&{else}\1\5
+\X973:Use node \|p to update the current height and depth measurements; if this node is not a legal breakpoint, \&{goto} \\{not\_found} or \\{update\_heights}, otherwise set \\{pi} to the associated penalty at the break\X;\2\6
+\X974:Check if node \|p is a new champion breakpoint; then \(go)\&{goto} \\{done} if \|p is a forced break or if the page-so-far is already too full\X;\6
+\&{if} ${}((\\{type}(\|p)<\\{glue\_node})\V(\\{type}(\|p)>\\{kern\_node})){}$\1\5
+\&{goto} \\{not\_found};\2\6
+\4\\{update\_heights}:\5
+\X976:Update the current height and depth measurements with respect to a glue or kern node~\|p\X;\6
+\4\\{not\_found}:\6
+\&{if} ${}(\\{prev\_dp}>\|d){}$\5
+${}\{{}$\5
+\1${}\\{cur\_height}\K\\{cur\_height}+\\{prev\_dp}-\|d;{}$\5
+${}\\{prev\_dp}\K\|d;{}$\6
+\4${}\}{}$\2\par
+\U970.\fi
+
+\M{973}\B\X973:Use node \|p to update the current height and depth measurements; if this node is not a legal breakpoint, \&{goto} \\{not\_found} or \\{update\_heights}, otherwise set \\{pi} to the associated penalty at the break\X${}\E{}$\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1\hbox{}\6
+${}\\{cur\_height}\K\\{cur\_height}+\\{prev\_dp}+\\{height}(\|p);{}$\5
+${}\\{prev\_dp}\K\\{depth}(\|p);{}$\5
+\&{goto} \\{not\_found};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1365:Process whatsit \|p in \\{vert\_break} loop, \&{goto} \\{not\_found}\X;\6
+\4\&{case} \\{glue\_node}:\6
+\&{if} (\\{precedes\_break}(\\{prev\_p}))\1\5
+${}\\{pi}\K\T{0};{}$\2\6
+\&{else}\1\5
+\&{goto} \\{update\_heights};\5
+\2\&{break};\6
+\4\&{case} \\{kern\_node}:\6
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\|p)\E\\{null}){}$\1\5
+${}\|t\K\\{penalty\_node};{}$\2\6
+\&{else}\1\5
+${}\|t\K\\{type}(\\{link}(\|p));{}$\2\6
+\&{if} ${}(\|t\E\\{glue\_node}){}$\1\5
+${}\\{pi}\K\T{0}{}$;\5
+\2\&{else}\1\5
+\&{goto} \\{update\_heights};\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{penalty\_node}:\5
+${}\\{pi}\K\\{penalty}(\|p){}$;\5
+\&{break};\6
+\4\&{case} \\{mark\_node}:\5
+\&{case} \\{ins\_node}:\5
+\&{goto} \\{not\_found};\6
+\4\&{default}:\5
+\\{confusion}(\X1686:\.{"vertbreak"}\X);\6
+\4${}\}{}$\2\par
+\U972.\fi
+
+\M{974}\B\D$\\{deplorable}$ \5
+\T{100000}\C{more than \\{inf\_bad}, but less than \\{awful\_bad}}\par
+\Y\B\4\X974:Check if node \|p is a new champion breakpoint; then \(go)\&{goto} \\{done} if \|p is a forced break or if the page-so-far is already too full\X${}\E{}$\6
+\&{if} ${}(\\{pi}<\\{inf\_penalty}){}$\5
+${}\{{}$\5
+\1\X975:Compute the badness, \|b, using \\{awful\_bad} if the box is too full\X;\6
+\&{if} ${}(\|b<\\{awful\_bad}){}$\1\6
+\&{if} ${}(\\{pi}\Z\\{eject\_penalty}){}$\1\5
+${}\|b\K\\{pi};{}$\2\6
+\&{else} \&{if} ${}(\|b<\\{inf\_bad}){}$\1\5
+${}\|b\K\|b+\\{pi};{}$\2\6
+\&{else}\1\5
+${}\|b\K\\{deplorable};{}$\2\2\6
+\&{if} ${}(\|b\Z\\{least\_cost}){}$\5
+${}\{{}$\5
+\1${}\\{best\_place}\K\|p;{}$\5
+${}\\{least\_cost}\K\|b;{}$\5
+${}\\{best\_height\_plus\_depth}\K\\{cur\_height}+\\{prev\_dp};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}((\|b\E\\{awful\_bad})\V(\\{pi}\Z\\{eject\_penalty})){}$\1\5
+\&{goto} \\{done};\2\6
+\4${}\}{}$\2\par
+\U972.\fi
+
+\M{975}\B\X975:Compute the badness, \|b, using \\{awful\_bad} if the box is too full\X${}\E{}$\6
+\&{if} ${}(\\{cur\_height}<\|h){}$\1\6
+\&{if} ${}((\\{active\_height}[\T{3}]\I\T{0})\V(\\{active\_height}[\T{4}]\I\T{0})\V(\\{active\_height}[\T{5}]\I\T{0})){}$\1\5
+${}\|b\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\|b\K\\{badness}(\|h-\\{cur\_height},\39\\{active\_height}[\T{2}]);{}$\2\2\6
+\&{else} \&{if} ${}(\\{cur\_height}-\|h>\\{active\_height}[\T{6}]){}$\1\5
+${}\|b\K\\{awful\_bad};{}$\2\6
+\&{else} $\|b\K\\{badness}(\\{cur\_height}-\|h,\39\\{active\_height}[\T{6}]{}$)\par
+\U974.\fi
+
+\M{976}Vertical lists that are subject to the \\{vert\_break} procedure should not
+contain infinite shrinkability, since that would permit any amount of
+information to ``fit'' on one page.
+
+\Y\B\4\X976:Update the current height and depth measurements with respect to a glue or kern node~\|p\X${}\E{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{kern\_node}){}$\1\5
+${}\|q\K\|p;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{glue\_ptr}(\|p);{}$\5
+${}\\{active\_height}[\T{2}+\\{stretch\_order}(\|q)]\K\30\\{active\_height}[\T{2}+\\{stretch\_order}(\|q)]+\\{stretch}(\|q){}$;\6
+${}\\{active\_height}[\T{6}]\K\\{active\_height}[\T{6}]+\\{shrink}(\|q);{}$\6
+\&{if} ${}((\\{shrink\_order}(\|q)\I\\{normal})\W(\\{shrink}(\|q)\I\T{0})){}$\5
+${}\{{}$\5
+\1\hbox{}\6
+\\{print\_err}(\.{"Infinite\ glue\ shrin}\)\.{kage\ found\ in\ box\ be}\)\.{ing\ split"});\6
+\\{help4}(\.{"The\ box\ you\ are\ \\\\v}\)\.{splitting\ contains\ s}\)\.{ome\ infinitely"})\6
+(\.{"shrinkable\ glue,\ e.}\)\.{g.,\ `\\\\vss'\ or\ `\\\\vs}\)\.{kip\ 0pt\ minus\ 1fil'.}\)\.{"})\6
+(\.{"Such\ glue\ doesn't\ b}\)\.{elong\ there;\ but\ you}\)\.{\ can\ safely\ proceed,}\)\.{"})\6
+(\.{"since\ the\ offensive}\)\.{\ shrinkability\ has\ b}\)\.{een\ made\ finite."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\|r\K\\{new\_spec}(\|q);{}$\5
+${}\\{shrink\_order}(\|r)\K\\{normal};{}$\5
+\\{delete\_glue\_ref}(\|q);\5
+${}\\{glue\_ptr}(\|p)\K\|r;{}$\5
+${}\|q\K\|r;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{cur\_height}\K\\{cur\_height}+\\{prev\_dp}+\\{width}(\|q);$ $\\{prev\_dp}\K{}$\T{0}\par
+\U972.\fi
+
+\M{977}Now we are ready to consider \\{vsplit} itself. Most of
+its work is accomplished by the two subroutines that we have just considered.
+
+Given the number of a vlist box \|n, and given a desired page height \|h,
+the \\{vsplit} function finds the best initial segment of the vlist and
+returns a box for a page of height~\|h. The remainder of the vlist, if
+any, replaces the original box, after removing glue and penalties and
+adjusting for \\{split\_top\_skip}. Mark nodes in the split-off box are used to
+set the values of \\{split\_first\_mark} and \\{split\_bot\_mark}; we use the
+fact that $\\{split\_first\_mark}\E\\{null}$ if and only if $\\{split\_bot\_mark}\E\\{null}$.
+
+The original box becomes ``void'' if and only if it has been entirely
+extracted. The extracted box is ``void'' if and only if the original
+box was void (or if it was, erroneously, an hlist box).
+
+\Y\B\&{pointer} \\{vsplit}(\&{eight\_bits} \|n${},\39{}$\&{scaled} \|h)\C{extracts a page of height \|h from box \|n}\6
+${}\{{}$\5
+\1\&{pointer} \|v;\C{the box to be split}\6
+\&{pointer} \|p;\C{runs through the vlist}\6
+\&{pointer} \|q;\C{points to where the break occurs}\7
+${}\|v\K\\{box}(\|n);{}$\6
+\&{if} ${}(\\{split\_first\_mark}\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{delete\_token\_ref}(\\{split\_first\_mark});\5
+${}\\{split\_first\_mark}\K\\{null};{}$\5
+\\{delete\_token\_ref}(\\{split\_bot\_mark});\5
+${}\\{split\_bot\_mark}\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\X978:Dispense with trivial cases of void or bad boxes\X;\6
+${}\|q\K\\{vert\_break}(\\{list\_ptr}(\|v),\39\|h,\39\\{split\_max\_depth});{}$\5
+\X979:Look at all the marks in nodes before the break, and set the final link to \\{null} at the break\X;\6
+${}\|q\K\\{prune\_page\_top}(\|q);{}$\5
+${}\|p\K\\{list\_ptr}(\|v);{}$\5
+${}\\{free\_node}(\|v,\39\\{box\_node\_size});{}$\6
+\&{if} ${}(\|q\E\\{null}){}$\1\5
+${}\\{box}(\|n)\K\\{null}{}$;\C{the \\{eq\_level} of the box stays the same}\2\6
+\&{else}\1\5
+${}\\{box}(\|n)\K\\{vpack}(\|q,\39\\{natural});{}$\2\6
+\&{return} \\{vpackage}${}(\|p,\39\|h,\39\\{exactly},\39\\{split\_max\_depth});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{978}\B\X978:Dispense with trivial cases of void or bad boxes\X${}\E{}$\6
+\&{if} ${}(\|v\E\\{null}){}$\5
+${}\{{}$\5
+\1\&{return} \\{null};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{type}(\|v)\I\\{vlist\_node}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{""});\5
+\\{print\_esc}(\X1687:\.{"vsplit"}\X);\5
+\\{print\_str}(\.{"\ needs\ a\ "});\5
+\\{print\_esc}(\X1688:\.{"vbox"}\X);\5
+\\{help2}(\.{"The\ box\ you\ are\ try}\)\.{ing\ to\ split\ is\ an\ \\}\)\.{\\hbox."})\6
+(\.{"I\ can't\ split\ such\ }\)\.{a\ box,\ so\ I'll\ leave}\)\.{\ it\ alone."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{return} \\{null};\6
+\4${}\}{}$\2\par
+\U977.\fi
+
+\M{979}It's possible that the box begins with a penalty node that is the
+``best'' break, so we must be careful to handle this special case correctly.
+
+\Y\B\4\X979:Look at all the marks in nodes before the break, and set the final link to \\{null} at the break\X${}\E{}$\6
+$\|p\K\\{list\_ptr}(\|v);{}$\6
+\&{if} ${}(\|p\E\|q){}$\1\5
+${}\\{list\_ptr}(\|v)\K\\{null};{}$\2\6
+\&{else}\1\6
+\&{loop}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|p)\E\\{mark\_node}){}$\1\6
+\&{if} ${}(\\{split\_first\_mark}\E\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{split\_first\_mark}\K\\{mark\_ptr}(\|p);{}$\5
+${}\\{split\_bot\_mark}\K\\{split\_first\_mark};{}$\5
+${}\\{token\_ref\_count}(\\{split\_first\_mark})\K\30\\{token\_ref\_count}(\\{split\_first\_mark})+\T{2};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{delete\_token\_ref}(\\{split\_bot\_mark});\5
+${}\\{split\_bot\_mark}\K\\{mark\_ptr}(\|p);{}$\5
+\\{add\_token\_ref}(\\{split\_bot\_mark});\6
+\4${}\}{}$\2\2\6
+\&{if} ${}(\\{link}(\|p)\E\|q){}$\5
+${}\{{}$\5
+\1${}\\{link}(\|p)\K\\{null};{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\2\6
+\\{done}:\par
+\U977.\fi
+
+\N{1}{980}The page builder.
+When \TeX\ appends new material to its main vlist in vertical mode, it uses
+a method something like \\{vsplit} to decide where a page ends, except that
+the calculations are done ``on line'' as new items come in.
+The main complication in this process is that insertions must be put
+into their boxes and removed from the vlist, in a more-or-less optimum manner.
+
+We shall use the term ``current page'' for that part of the main vlist that
+is being considered as a candidate for being broken off and sent to the
+user's output routine. The current page starts at \\{link}(\\{page\_head}), and
+it ends at \\{page\_tail}. We have $\\{page\_head}\E\\{page\_tail}$ if this list is empty.
+
+Utter chaos would reign if the user kept changing page specifications
+while a page is being constructed, so the page builder keeps the pertinent
+specifications frozen as soon as the page receives its first box or
+insertion. The global variable \\{page\_contents} is \\{empty} when the
+current page contains only mark nodes and content-less whatsit nodes; it
+is \\{inserts\_only} if the page contains only insertion nodes in addition to
+marks and whatsits. Glue nodes, kern nodes, and penalty nodes are
+discarded until a box or rule node appears, at which time \\{page\_contents}
+changes to \\{box\_there}. As soon as \\{page\_contents} becomes non-\\{empty},
+the current \\{vsize} and \\{max\_depth} are squirreled away into \\{page\_goal}
+and \\{page\_max\_depth}; the latter values will be used until the page has
+been forwarded to the user's output routine. The \.{\\topskip} adjustment
+is made when \\{page\_contents} changes to \\{box\_there}.
+
+Although \\{page\_goal} starts out equal to \\{vsize}, it is decreased by the
+scaled natural height-plus-depth of the insertions considered so far, and by
+the \.{\\skip} corrections for those insertions. Therefore it represents
+the size into which the non-inserted material should fit, assuming that
+all insertions in the current page have been made.
+
+The global variables \\{best\_page\_break} and \\{least\_page\_cost} correspond
+respectively to the local variables \\{best\_place} and \\{least\_cost} in the
+\\{vert\_break} routine that we have already studied; i.e., they record the
+location and value of the best place currently known for breaking the
+current page. The value of \\{page\_goal} at the time of the best break is
+stored in \\{best\_size}.
+
+\Y\B\4\D$\\{inserts\_only}$ \5
+\T{1}\C{\\{page\_contents} when an insert node has been contributed, but no boxes}\par
+\B\4\D$\\{box\_there}$ \5
+\T{2}\C{\\{page\_contents} when a box or rule has been contributed}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{page\_tail};\C{the final node on the current page}\6
+\&{uint8\_t} \\{page\_contents};\C{what is on the current page so far?}\6
+\&{scaled} \\{page\_max\_depth};\C{maximum box depth on page being built}\6
+\&{pointer} \\{best\_page\_break};\C{break here to get the best page known so far}\6
+\&{int} \\{least\_page\_cost};\C{the score for this currently best page}\6
+\&{scaled} \\{best\_size};\C{its \\{page\_goal}}\par
+\fi
+
+\M{981}The page builder has another data structure to keep track of insertions.
+This is a list of four-word nodes, starting and ending at \\{page\_ins\_head}.
+That is, the first element of the list is node $\|r\hbox{$_1$}\E\\{link}(\\{page\_ins\_head})$;
+node $r_j$ is followed by $\|r\hbox{$_{j+1}$}\E\\{link}(\|r\hbox{$_j$})$; and if there are
+\|n items we have $\|r\hbox{$_{n+1}$}\E\\{page\_ins\_head}$. The \\{subtype} field of
+each node in this list refers to an insertion number; for example, `\.{\\insert
+250}' would correspond to a node whose \\{subtype} is \\{qi}(\T{250})
+(the same as the \\{subtype} field of the relevant \\{ins\_node}). These \\{subtype}
+fields are in increasing order, and $\\{subtype}(\\{page\_ins\_head})\E\\{qi}(\T{255})$, so \\{page\_ins\_head} serves as a convenient sentinel
+at the end of the list. A record is present for each insertion number that
+appears in the current page.
+
+The \\{type} field in these nodes distinguishes two possibilities that
+might occur as we look ahead before deciding on the optimum page break.
+If $\\{type}(\|r)\E\\{inserting}$, then \\{height}(\|r) contains the total of the
+height-plus-depth dimensions of the box and all its inserts seen so far.
+If $\\{type}(\|r)\E\\{split\_up}$, then no more insertions will be made into this box,
+because at least one previous insertion was too big to fit on the current
+page; \\{broken\_ptr}(\|r) points to the node where that insertion will be
+split, if \TeX\ decides to split it, \\{broken\_ins}(\|r) points to the
+insertion node that was tentatively split, and \\{height}(\|r) includes also the
+natural height plus depth of the part that would be split off.
+
+In both cases, \\{last\_ins\_ptr}(\|r) points to the last \\{ins\_node}
+encountered for box \\{qo}(\\{subtype}(\|r)) that would be at least partially
+inserted on the next page; and \\{best\_ins\_ptr}(\|r) points to the last
+such \\{ins\_node} that should actually be inserted, to get the page with
+minimum badness among all page breaks considered so far. We have
+$\\{best\_ins\_ptr}(\|r)\E\\{null}$ if and only if no insertion for this box should
+be made to produce this optimum page.
+
+The data structure definitions here use the fact that the \\{height} field
+appears in the fourth word of a box node.
+
+\Y\B\4\D$\\{page\_ins\_node\_size}$ \5
+\T{4}\C{number of words for a page insertion node}\par
+\B\4\D$\\{inserting}$ \5
+\T{0}\C{an insertion class that has not yet overflowed}\par
+\B\4\D$\\{split\_up}$ \5
+\T{1}\C{an overflowed insertion class}\par
+\B\4\D$\\{broken\_ptr}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{an insertion for this class will break here if anywhere}\par
+\B\4\D$\\{broken\_ins}(\|X)$ \5
+$\\{info}(\|X+\T{1}{}$)\C{this insertion might break at \\{broken\_ptr}}\par
+\B\4\D$\\{last\_ins\_ptr}(\|X)$ \5
+$\\{link}(\|X+\T{2}{}$)\C{the most recent insertion for this \\{subtype}}\par
+\B\4\D$\\{best\_ins\_ptr}(\|X)$ \5
+$\\{info}(\|X+\T{2}{}$)\C{the optimum most recent insertion}\par
+\Y\B\4\X790:Initialize the special list heads and constant nodes\X${}\mathrel+\E{}$\6
+$\\{subtype}(\\{page\_ins\_head})\K\\{qi}(\T{255});{}$\5
+${}\\{type}(\\{page\_ins\_head})\K\\{split\_up};{}$\5
+${}\\{link}(\\{page\_ins\_head})\K\\{page\_ins\_head}{}$;\par
+\fi
+
+\M{982}An array \\{page\_so\_far} records the heights and depths of everything
+on the current page. This array contains six \&{scaled} numbers, like the
+similar arrays already considered in \\{line\_break} and \\{vert\_break}; and it
+also contains \\{page\_goal} and \\{page\_depth}, since these values are
+all accessible to the user via \\{set\_page\_dimen} commands. The
+value of \\{page\_so\_far}[\T{1}] is also called \\{page\_total}. The stretch
+and shrink components of the \.{\\skip} corrections for each insertion are
+included in \\{page\_so\_far}, but the natural space components of these
+corrections are not, since they have been subtracted from \\{page\_goal}.
+
+The variable \\{page\_depth} records the depth of the current page; it has been
+adjusted so that it is at most \\{page\_max\_depth}. The variable
+\\{last\_glue} points to the glue specification of the most recent node
+contributed from the contribution list, if this was a glue node; otherwise
+$\\{last\_glue}\E\\{max\_halfword}$. (If the contribution list is nonempty,
+however, the value of \\{last\_glue} is not necessarily accurate.)
+The variables \\{last\_penalty} and \\{last\_kern} are similar. And
+finally, \\{insert\_penalties} holds the sum of the penalties associated with
+all split and floating insertions.
+
+\Y\B\4\D$\\{page\_goal}$ \5
+\\{page\_so\_far}[\T{0}]\C{desired height of information on page being built}\par
+\B\4\D$\\{page\_total}$ \5
+\\{page\_so\_far}[\T{1}]\C{height of the current page}\par
+\B\4\D$\\{page\_shrink}$ \5
+\\{page\_so\_far}[\T{6}]\C{shrinkability of the current page}\par
+\B\4\D$\\{page\_depth}$ \5
+\\{page\_so\_far}[\T{7}]\C{depth of the current page}\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{scaled} \\{page\_so\_far}[\T{8}];\C{height and glue of the current page}\6
+\&{pointer} \\{last\_glue};\C{used to implement \.{\\lastskip}}\6
+\&{int} \\{last\_penalty};\C{used to implement \.{\\lastpenalty}}\6
+\&{scaled} \\{last\_kern};\C{used to implement \.{\\lastkern}}\6
+\&{int} \\{insert\_penalties};\C{sum of the penalties for held-over insertions}\par
+\fi
+
+\M{983}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1689:\.{"pagegoal"}\X,\39\\{set\_page\_dimen},\39\T{0});{}$\5
+${}\\{primitive}(\X1690:\.{"pagetotal"}\X,\39\\{set\_page\_dimen},\39\T{1});{}$\5
+${}\\{primitive}(\X1691:\.{"pagestretch"}\X,\39\\{set\_page\_dimen},\39\T{2});{}$\5
+${}\\{primitive}(\X1692:\.{"pagefilstretch"}\X,\39\\{set\_page\_dimen},\39\T{3});{}$\5
+${}\\{primitive}(\X1693:\.{"pagefillstretch"}\X,\39\\{set\_page\_dimen},\39\T{4});{}$\5
+${}\\{primitive}(\X1694:\.{"pagefilllstretch"}\X,\39\\{set\_page\_dimen},\39\T{5});{}$\5
+${}\\{primitive}(\X1695:\.{"pageshrink"}\X,\39\\{set\_page\_dimen},\39\T{6});{}$\5
+${}\\{primitive}(\X1696:\.{"pagedepth"}\X,\39\\{set\_page\_dimen},\39\T{7}){}$;\par
+\fi
+
+\M{984}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_page\_dimen}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+\\{print\_esc}(\X1689:\.{"pagegoal"}\X);\5
+\&{break};\6
+\4\&{case} \T{1}:\5
+\\{print\_esc}(\X1690:\.{"pagetotal"}\X);\5
+\&{break};\6
+\4\&{case} \T{2}:\5
+\\{print\_esc}(\X1691:\.{"pagestretch"}\X);\5
+\&{break};\6
+\4\&{case} \T{3}:\5
+\\{print\_esc}(\X1692:\.{"pagefilstretch"}\X);\5
+\&{break};\6
+\4\&{case} \T{4}:\5
+\\{print\_esc}(\X1693:\.{"pagefillstretch"}\X);\5
+\&{break};\6
+\4\&{case} \T{5}:\5
+\\{print\_esc}(\X1694:\.{"pagefilllstretch"}\X);\5
+\&{break};\6
+\4\&{case} \T{6}:\5
+\\{print\_esc}(\X1695:\.{"pageshrink"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1696:\.{"pagedepth"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{985}\B\D$\\{print\_plus\_end}(\|X)$ \5
+\\{print\_str}(\|X);\5
+$\}{}$\par
+\B\4\D$\\{print\_plus}(\|X)$ \5
+\&{if} ${}(\\{page\_so\_far}[\|X]\I\T{0})$ $\{{}$\5
+\\{print\_str}(\.{"\ plus\ "});\5
+\\{print\_scaled}(\\{page\_so\_far}[\|X]); \\{print\_plus\_end}\par
+\Y\B\&{void} \\{print\_totals}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_scaled}(\\{page\_total});\5
+\\{print\_plus}(\T{2})(\.{""});\5
+\\{print\_plus}(\T{3})(\.{"fil"});\5
+\\{print\_plus}(\T{4})(\.{"fill"});\5
+\\{print\_plus}(\T{5})(\.{"filll"});\6
+\&{if} ${}(\\{page\_shrink}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ minus\ "});\5
+\\{print\_scaled}(\\{page\_shrink});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{986}\B\X986:Show the status of the current page\X${}\E{}$\6
+\&{if} ${}(\\{page\_head}\I\\{page\_tail}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"\#\#\#\ current\ page:"});\6
+\&{if} (\\{output\_active})\1\5
+\\{print\_str}(\.{"\ (held\ over\ for\ nex}\)\.{t\ output)"});\2\6
+\\{show\_box}(\\{link}(\\{page\_head}));\6
+\&{if} ${}(\\{page\_contents}>\\{empty}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"total\ height\ "});\5
+\\{print\_totals}(\,);\5
+\\{print\_nl}(\.{"\ goal\ height\ "});\5
+\\{print\_scaled}(\\{page\_goal});\5
+${}\|r\K\\{link}(\\{page\_ins\_head});{}$\6
+\&{while} ${}(\|r\I\\{page\_ins\_head}){}$\5
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+\\{print\_esc}(\X1390:\.{"insert"}\X);\5
+${}\|t\K\\{qo}(\\{subtype}(\|r));{}$\5
+\\{print\_int}(\|t);\5
+\\{print\_str}(\.{"\ adds\ "});\6
+\&{if} ${}(\\{count}(\|t)\E\T{1000}){}$\1\5
+${}\|t\K\\{height}(\|r);{}$\2\6
+\&{else}\1\5
+${}\|t\K\\{x\_over\_n}(\\{height}(\|r),\39\T{1000})*\\{count}(\|t);{}$\2\6
+\\{print\_scaled}(\|t);\6
+\&{if} ${}(\\{type}(\|r)\E\\{split\_up}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{page\_head};{}$\5
+${}\|t\K\T{0}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|q\K\\{link}(\|q);{}$\6
+\&{if} ${}((\\{type}(\|q)\E\\{ins\_node})\W(\\{subtype}(\|q)\E\\{subtype}(\|r))){}$\1\5
+\\{incr}(\|t);\2\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{broken\_ins}(\|r)));{}$\5
+\\{print\_str}(\.{",\ \#"});\5
+\\{print\_int}(\|t);\5
+\\{print\_str}(\.{"\ might\ split"});\6
+\4${}\}{}$\2\6
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U218.\fi
+
+\M{987}Here is a procedure that is called when the \\{page\_contents} is changing
+from \\{empty} to \\{inserts\_only} or \\{box\_there}.
+
+\Y\B\4\D$\\{set\_page\_so\_far\_zero}(\|X)$ \5
+$\\{page\_so\_far}[\|X]\K{}$\T{0}\par
+\Y\B\&{void} \\{freeze\_page\_specs}(\&{small\_number} \|s)\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{page\_contents}\K\|s;{}$\5
+${}\\{page\_goal}\K\\{vsize};{}$\5
+${}\\{page\_max\_depth}\K\\{max\_depth};{}$\5
+${}\\{page\_depth}\K\T{0};{}$\5
+\\{do\_all\_six}(\\{set\_page\_so\_far\_zero});\5
+${}\\{least\_page\_cost}\K\\{awful\_bad};{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_pages}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"\%\%\ goal\ height="});\5
+\\{print\_scaled}(\\{page\_goal});\5
+\\{print\_str}(\.{",\ max\ depth="});\5
+\\{print\_scaled}(\\{page\_max\_depth});\5
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{988}Pages are built by appending nodes to the current list in \TeX's
+vertical mode, which is at the outermost level of the semantic nest. This
+vlist is split into two parts; the ``current page'' that we have been
+talking so much about already, and the ``contribution list'' that receives
+new nodes as they are created. The current page contains everything that
+the page builder has accounted for in its data structures, as described
+above, while the contribution list contains other things that have been
+generated by other parts of \TeX\ but have not yet been
+seen by the page builder.
+The contribution list starts at \\{link}(\\{contrib\_head}), and it ends at the
+current node in \TeX's vertical mode.
+
+When \TeX\ has appended new material in vertical mode, it calls the procedure
+\\{build\_page}, which tries to catch up by moving nodes from the contribution
+list to the current page. This procedure will succeed in its goal of
+emptying the contribution list, unless a page break is discovered, i.e.,
+unless the current page has grown to the point where the optimum next
+page break has been determined. In the latter case, the nodes after the
+optimum break will go back onto the contribution list, and control will
+effectively pass to the user's output routine.
+
+We make $\\{type}(\\{page\_head})\E\\{glue\_node}$, so that an initial glue node on
+the current page will not be considered a valid breakpoint.
+
+\Y\B\4\X790:Initialize the special list heads and constant nodes\X${}\mathrel+\E{}$\6
+$\\{type}(\\{page\_head})\K\\{glue\_node};{}$\5
+${}\\{subtype}(\\{page\_head})\K\\{normal}{}$;\par
+\fi
+
+\M{989}The global variable \\{output\_active} is true during the time the
+user's output routine is driving \TeX.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{output\_active};\C{are we in the midst of an output routine?}\par
+\fi
+
+\M{990}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{output\_active}\K\\{false};{}$\5
+${}\\{insert\_penalties}\K\T{0}{}$;\par
+\fi
+
+\M{991}The page builder is ready to start a fresh page if we initialize
+the following state variables. (However, the page insertion list is initialized
+elsewhere.)
+
+\Y\B\4\X991:Start a new current page\X${}\E{}$\6
+$\\{page\_contents}\K\\{empty};{}$\5
+${}\\{page\_tail}\K\\{page\_head};{}$\5
+${}\\{link}(\\{page\_head})\K\\{null}{}$;\6
+${}\\{last\_glue}\K\\{max\_halfword};{}$\5
+${}\\{last\_penalty}\K\T{0};{}$\5
+${}\\{last\_kern}\K\T{0};{}$\5
+${}\\{page\_depth}\K\T{0};$ $\\{page\_max\_depth}\K{}$\T{0}\par
+\Us215\ET1017.\fi
+
+\M{992}At certain times box 255 is supposed to be void (i.e., \\{null}),
+or an insertion box is supposed to be ready to accept a vertical list.
+If not, an error message is printed, and the following subroutine
+flushes the unwanted contents, reporting them to the user.
+
+\Y\B\&{void} \\{box\_error}(\&{eight\_bits} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{error} (\,)\1\5
+;\2\6
+\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"The\ following\ box\ h}\)\.{as\ been\ deleted:"});\5
+\\{show\_box}(\\{box}(\|n));\5
+\\{end\_diagnostic}(\\{true});\5
+\\{flush\_node\_list}(\\{box}(\|n));\5
+${}\\{box}(\|n)\K\\{null};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{993}The following procedure guarantees that a given box register
+does not contain an \.{\\hbox}.
+
+\Y\B\&{void} \\{ensure\_vbox}(\&{eight\_bits} \|n)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the box register contents}\7
+${}\|p\K\\{box}(\|n);{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}(\\{type}(\|p)\E\\{hlist\_node}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Insertions\ can\ only}\)\.{\ be\ added\ to\ a\ vbox"});\5
+\\{help3}(\.{"Tut\ tut:\ You're\ try}\)\.{ing\ to\ \\\\insert\ into}\)\.{\ a"})\6
+(\.{"\\\\box\ register\ that}\)\.{\ now\ contains\ an\ \\\\h}\)\.{box."})\6
+(\.{"Proceed,\ and\ I'll\ d}\)\.{iscard\ its\ present\ c}\)\.{ontents."});\5
+\\{box\_error}(\|n);\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{994}\TeX\ is not always in vertical mode at the time \\{build\_page}
+is called; the current mode reflects what \TeX\ should return to, after
+the contribution list has been emptied. A call on \\{build\_page} should
+be immediately followed by `\&{goto} \\{big\_switch}', which is \TeX's central
+control point.
+
+\Y\B\hbox{\4}\X1012:Declare the procedure called \\{fire\_up}\X\7
+\&{void} \\{build\_page}(\&{void})\C{append contributions to the current page}\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the node being appended}\6
+\&{pointer} \|q${},{}$ \|r;\C{nodes being examined}\6
+\&{int} \|b${},{}$ \|c;\C{badness and cost of current page}\6
+\&{int} \\{pi};\C{penalty to be added to the badness}\6
+\&{uint8\_t} \|n;\C{insertion box number}\6
+\&{scaled} \\{delta}${},{}$ \|h${},{}$ \|w;\C{sizes used for insertion calculations}\7
+\&{if} ${}((\\{link}(\\{contrib\_head})\E\\{null})\V\\{output\_active}){}$\1\5
+\&{return};\2\6
+\&{do}\5
+${}\{{}$\1\6
+\4\\{resume}:\5
+${}\|p\K\\{link}(\\{contrib\_head}){}$;\6
+\X996:Update the values of \\{last\_glue}, \\{last\_penalty}, and \\{last\_kern}\X;\6
+\X997:Move node \|p to the current page; if it is time for a page break, put the nodes following the break back onto the contribution list, and \&{return} to the user's output routine if there is one\X;\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{link}(\\{contrib\_head})\E\\{null}));{}$\5
+\X995:Make the contribution list empty by setting its tail to \\{contrib\_head}\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{995}\B\D$\\{contrib\_tail}$ \5
+$\\{nest}[\T{0}].{}$\\{tail\_field}\C{tail of the contribution list}\par
+\Y\B\4\X995:Make the contribution list empty by setting its tail to \\{contrib\_head}\X${}\E{}$\6
+\&{if} ${}(\\{nest\_ptr}\E\T{0}){}$\1\5
+${}\\{tail}\K\\{contrib\_head}{}$;\C{vertical mode}\2\6
+\&{else} $\\{contrib\_tail}\K{}$\\{contrib\_head}\C{other modes}\par
+\U994.\fi
+
+\M{996}\B\X996:Update the values of \\{last\_glue}, \\{last\_penalty}, and \\{last\_kern}\X${}\E{}$\6
+\&{if} ${}(\\{last\_glue}\I\\{max\_halfword}){}$\1\5
+\\{delete\_glue\_ref}(\\{last\_glue});\2\6
+${}\\{last\_penalty}\K\T{0};{}$\5
+${}\\{last\_kern}\K\T{0};{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{glue\_node}){}$\5
+${}\{{}$\5
+\1${}\\{last\_glue}\K\\{glue\_ptr}(\|p);{}$\5
+\\{add\_glue\_ref}(\\{last\_glue});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{last\_glue}\K\\{max\_halfword};{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{penalty\_node}){}$\1\5
+${}\\{last\_penalty}\K\\{penalty}(\|p);{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|p)\E\\{kern\_node}){}$\1\5
+${}\\{last\_kern}\K\\{width}(\|p);{}$\2\6
+\4${}\}{}$\2\par
+\U994.\fi
+
+\M{997}The code here is an example of a many-way switch into routines that
+merge together in different places. Some people call this unstructured
+programming, but the author doesn't see much wrong with it, as long as
+the various labels have a well-understood meaning.
+
+\Y\B\4\X997:Move node \|p to the current page; if it is time for a page break, put the nodes following the break back onto the contribution list, and \&{return} to the user's output routine if there is one\X${}\E{}$\6
+\X1000:If the current page is empty and node \|p is to be deleted, \&{goto} \\{done1}; otherwise use node \|p to update the state of the current page; if this node is an insertion, \&{goto} \\{contribute}; otherwise if this node is not a legal
+breakpoint, \&{goto} \\{contribute} or \\{update\_heights}; otherwise set \\{pi} to the penalty associated with this breakpoint\X;\6
+\X1005:Check if node \|p is a new champion breakpoint; then \(if)if it is time for a page break, prepare for output, and either fire up the user's output routine and \&{return} or ship out the page and \&{goto} \\{done}\X;\6
+\&{if} ${}((\\{type}(\|p)<\\{glue\_node})\V(\\{type}(\|p)>\\{kern\_node})){}$\1\5
+\&{goto} \\{contribute};\2\6
+\4\\{update\_heights}:\5
+\X1004:Update the current page measurements with respect to the glue or kern specified by node~\|p\X;\6
+\4\\{contribute}:\5
+\X1003:Make sure that \\{page\_max\_depth} is not exceeded\X;\6
+\X998:Link node \|p into the current page and \&{goto} \\{done}\X;\6
+\4\\{done1}:\5
+\X999:Recycle node \|p\X;\6
+\\{done}:\par
+\U994.\fi
+
+\M{998}\B\X998:Link node \|p into the current page and \&{goto} \\{done}\X${}\E{}$\6
+$\\{link}(\\{page\_tail})\K\|p;{}$\5
+${}\\{page\_tail}\K\|p;{}$\5
+${}\\{link}(\\{contrib\_head})\K\\{link}(\|p);{}$\5
+${}\\{link}(\|p)\K\\{null};$ \&{goto} \\{done}\par
+\U997.\fi
+
+\M{999}\B\X999:Recycle node \|p\X${}\E{}$\6
+$\\{link}(\\{contrib\_head})\K\\{link}(\|p);{}$\5
+${}\\{link}(\|p)\K\\{null};$ \\{flush\_node\_list}(\|p)\par
+\U997.\fi
+
+\M{1000}The title of this section is already so long, it seems best to avoid
+making it more accurate but still longer, by mentioning the fact that a
+kern node at the end of the contribution list will not be contributed until
+we know its successor.
+
+\Y\B\4\X1000:If the current page is empty and node \|p is to be deleted, \&{goto} \\{done1}; otherwise use node \|p to update the state of the current page; if this node is an insertion, \&{goto} \\{contribute}; otherwise if this node is not a legal
+breakpoint, \&{goto} \\{contribute} or \\{update\_heights}; otherwise set \\{pi} to the penalty associated with this breakpoint\X${}\E{}$\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\6
+\&{if} ${}(\\{page\_contents}<\\{box\_there}){}$\1\5
+\X1001:Initialize the current page, insert the \.{\\topskip} glue ahead of \|p, and \&{goto} \&{continue}\X\2\6
+\&{else}\1\5
+\X1002:Prepare to move a box or rule node to the current page, then \&{goto} \\{contribute}\X\5
+\2\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1364:Prepare to move whatsit \|p to the current page, then \&{goto} \\{contribute}\X;\6
+\4\&{case} \\{glue\_node}:\6
+\&{if} ${}(\\{page\_contents}<\\{box\_there}){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{else} \&{if} (\\{precedes\_break}(\\{page\_tail}))\1\5
+${}\\{pi}\K\T{0};{}$\2\6
+\&{else}\1\5
+\&{goto} \\{update\_heights};\5
+\2\&{break};\6
+\4\&{case} \\{kern\_node}:\6
+\&{if} ${}(\\{page\_contents}<\\{box\_there}){}$\1\5
+\&{goto} \\{done1};\2\6
+\&{else} \&{if} ${}(\\{link}(\|p)\E\\{null}){}$\1\5
+\&{return};\2\6
+\&{else} \&{if} ${}(\\{type}(\\{link}(\|p))\E\\{glue\_node}){}$\1\5
+${}\\{pi}\K\T{0};{}$\2\6
+\&{else}\1\5
+\&{goto} \\{update\_heights};\5
+\2\&{break};\6
+\4\&{case} \\{penalty\_node}:\6
+\&{if} ${}(\\{page\_contents}<\\{box\_there}){}$\1\5
+\&{goto} \\{done1};\5
+\2\&{else}\1\5
+${}\\{pi}\K\\{penalty}(\|p){}$;\5
+\2\&{break};\6
+\4\&{case} \\{mark\_node}:\5
+\&{goto} \\{contribute};\6
+\4\&{case} \\{ins\_node}:\5
+\X1008:Append an insertion to the current page and \&{goto} \\{contribute}\X\6
+\4\&{default}:\5
+\\{confusion}(\X1697:\.{"page"}\X);\6
+\4${}\}{}$\2\par
+\U997.\fi
+
+\M{1001}\B\X1001:Initialize the current page, insert the \.{\\topskip} glue ahead of \|p, and \&{goto} \&{continue}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{page\_contents}\E\\{empty}){}$\1\5
+\\{freeze\_page\_specs}(\\{box\_there});\2\6
+\&{else}\1\5
+${}\\{page\_contents}\K\\{box\_there};{}$\2\6
+${}\|q\K\\{new\_skip\_param}(\\{top\_skip\_code}){}$;\C{now $\\{temp\_ptr}\E\\{glue\_ptr}(\|q)$}\6
+\&{if} ${}(\\{width}(\\{temp\_ptr})>\\{height}(\|p)){}$\1\5
+${}\\{width}(\\{temp\_ptr})\K\\{width}(\\{temp\_ptr})-\\{height}(\|p);{}$\2\6
+\&{else}\1\5
+${}\\{width}(\\{temp\_ptr})\K\T{0};{}$\2\6
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\\{link}(\\{contrib\_head})\K\|q;{}$\5
+\&{goto} \\{resume};\6
+\4${}\}{}$\2\par
+\U1000.\fi
+
+\M{1002}\B\X1002:Prepare to move a box or rule node to the current page, then \&{goto} \\{contribute}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{page\_total}\K\\{page\_total}+\\{page\_depth}+\\{height}(\|p);{}$\5
+${}\\{page\_depth}\K\\{depth}(\|p);{}$\5
+\&{goto} \\{contribute};\6
+\4${}\}{}$\2\par
+\U1000.\fi
+
+\M{1003}\B\X1003:Make sure that \\{page\_max\_depth} is not exceeded\X${}\E{}$\6
+\&{if} ${}(\\{page\_depth}>\\{page\_max\_depth}){}$\5
+${}\{{}$\5
+\1${}\\{page\_total}\K\30\\{page\_total}+\\{page\_depth}-\\{page\_max\_depth}{}$;\6
+${}\\{page\_depth}\K\\{page\_max\_depth};{}$\6
+\4${}\}{}$\2\par
+\U997.\fi
+
+\M{1004}\B\X1004:Update the current page measurements with respect to the glue or kern specified by node~\|p\X${}\E{}$\6
+\&{if} ${}(\\{type}(\|p)\E\\{kern\_node}){}$\1\5
+${}\|q\K\|p;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{glue\_ptr}(\|p);{}$\5
+${}\\{page\_so\_far}[\T{2}+\\{stretch\_order}(\|q)]\K\30\\{page\_so\_far}[\T{2}+\\{stretch\_order}(\|q)]+\\{stretch}(\|q){}$;\6
+${}\\{page\_shrink}\K\\{page\_shrink}+\\{shrink}(\|q);{}$\6
+\&{if} ${}((\\{shrink\_order}(\|q)\I\\{normal})\W(\\{shrink}(\|q)\I\T{0})){}$\5
+${}\{{}$\5
+\1\hbox{}\6
+\\{print\_err}(\.{"Infinite\ glue\ shrin}\)\.{kage\ found\ on\ curren}\)\.{t\ page"});\6
+\\{help4}(\.{"The\ page\ about\ to\ b}\)\.{e\ output\ contains\ so}\)\.{me\ infinitely"})\6
+(\.{"shrinkable\ glue,\ e.}\)\.{g.,\ `\\\\vss'\ or\ `\\\\vs}\)\.{kip\ 0pt\ minus\ 1fil'.}\)\.{"})\6
+(\.{"Such\ glue\ doesn't\ b}\)\.{elong\ there;\ but\ you}\)\.{\ can\ safely\ proceed,}\)\.{"})\6
+(\.{"since\ the\ offensive}\)\.{\ shrinkability\ has\ b}\)\.{een\ made\ finite."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\|r\K\\{new\_spec}(\|q);{}$\5
+${}\\{shrink\_order}(\|r)\K\\{normal};{}$\5
+\\{delete\_glue\_ref}(\|q);\5
+${}\\{glue\_ptr}(\|p)\K\|r;{}$\5
+${}\|q\K\|r;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{page\_total}\K\\{page\_total}+\\{page\_depth}+\\{width}(\|q);$ $\\{page\_depth}\K{}$\T{0}\par
+\U997.\fi
+
+\M{1005}\B\X1005:Check if node \|p is a new champion breakpoint; then \(if)if it is time for a page break, prepare for output, and either fire up the user's output routine and \&{return} or ship out the page and \&{goto} \\{done}\X${}\E{}$\6
+\&{if} ${}(\\{pi}<\\{inf\_penalty}){}$\5
+${}\{{}$\5
+\1\X1007:Compute the badness, \|b, of the current page, using \\{awful\_bad} if the box is too full\X;\6
+\&{if} ${}(\|b<\\{awful\_bad}){}$\1\6
+\&{if} ${}(\\{pi}\Z\\{eject\_penalty}){}$\1\5
+${}\|c\K\\{pi};{}$\2\6
+\&{else} \&{if} ${}(\|b<\\{inf\_bad}){}$\1\5
+${}\|c\K\|b+\\{pi}+\\{insert\_penalties};{}$\2\6
+\&{else}\1\5
+${}\|c\K\\{deplorable};{}$\2\2\6
+\&{else}\1\5
+${}\|c\K\|b;{}$\2\6
+\&{if} ${}(\\{insert\_penalties}\G\T{10000}){}$\1\5
+${}\|c\K\\{awful\_bad};{}$\2\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_pages}>\T{0}){}$\1\5
+\X1006:Display the page break cost\X;\2\6
+\8\#\&{endif}\6
+\&{if} ${}(\|c\Z\\{least\_page\_cost}){}$\5
+${}\{{}$\5
+\1${}\\{best\_page\_break}\K\|p;{}$\5
+${}\\{best\_size}\K\\{page\_goal};{}$\5
+${}\\{least\_page\_cost}\K\|c;{}$\5
+${}\|r\K\\{link}(\\{page\_ins\_head});{}$\6
+\&{while} ${}(\|r\I\\{page\_ins\_head}){}$\5
+${}\{{}$\5
+\1${}\\{best\_ins\_ptr}(\|r)\K\\{last\_ins\_ptr}(\|r);{}$\5
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}((\|c\E\\{awful\_bad})\V(\\{pi}\Z\\{eject\_penalty})){}$\5
+${}\{{}$\5
+\1\\{fire\_up}(\|p);\C{output the current page at the best place}\6
+\&{if} (\\{output\_active})\1\5
+\&{return};\C{user's output routine will act}\2\6
+\&{goto} \\{done};\C{the page has been shipped out by default output routine}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U997.\fi
+
+\M{1006}\B\X1006:Display the page break cost\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"\%"});\5
+\\{print\_str}(\.{"\ t="});\5
+\\{print\_totals}(\,);\6
+\\{print\_str}(\.{"\ g="});\5
+\\{print\_scaled}(\\{page\_goal});\6
+\\{print\_str}(\.{"\ b="});\6
+\&{if} ${}(\|b\E\\{awful\_bad}){}$\1\5
+\\{print\_char}(\.{'*'});\5
+\2\&{else}\1\5
+\\{print\_int}(\|b);\2\6
+\\{print\_str}(\.{"\ p="});\5
+\\{print\_int}(\\{pi});\5
+\\{print\_str}(\.{"\ c="});\6
+\&{if} ${}(\|c\E\\{awful\_bad}){}$\1\5
+\\{print\_char}(\.{'*'});\5
+\2\&{else}\1\5
+\\{print\_int}(\|c);\2\6
+\&{if} ${}(\|c\Z\\{least\_page\_cost}){}$\1\5
+\\{print\_char}(\.{'\#'});\2\6
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\par
+\U1005.\fi
+
+\M{1007}\B\X1007:Compute the badness, \|b, of the current page, using \\{awful\_bad} if the box is too full\X${}\E{}$\6
+\&{if} ${}(\\{page\_total}<\\{page\_goal}){}$\1\6
+\&{if} ${}((\\{page\_so\_far}[\T{3}]\I\T{0})\V(\\{page\_so\_far}[\T{4}]\I\T{0})\V\30(\\{page\_so\_far}[\T{5}]\I\T{0})){}$\1\5
+${}\|b\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\|b\K\\{badness}(\\{page\_goal}-\\{page\_total},\39\\{page\_so\_far}[\T{2}]);{}$\2\2\6
+\&{else} \&{if} ${}(\\{page\_total}-\\{page\_goal}>\\{page\_shrink}){}$\1\5
+${}\|b\K\\{awful\_bad};{}$\2\6
+\&{else} $\|b\K\\{badness}(\\{page\_total}-\\{page\_goal},\39\\{page\_shrink}{}$)\par
+\U1005.\fi
+
+\M{1008}\B\X1008:Append an insertion to the current page and \&{goto} \\{contribute}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{page\_contents}\E\\{empty}){}$\1\5
+\\{freeze\_page\_specs}(\\{inserts\_only});\2\6
+${}\|n\K\\{subtype}(\|p);{}$\5
+${}\|r\K\\{page\_ins\_head};{}$\6
+\&{while} ${}(\|n\G\\{subtype}(\\{link}(\|r))){}$\1\5
+${}\|r\K\\{link}(\|r);{}$\2\6
+${}\|n\K\\{qo}(\|n);{}$\6
+\&{if} ${}(\\{subtype}(\|r)\I\\{qi}(\|n)){}$\1\5
+\X1009:Create a page insertion node with $\\{subtype}(\|r)\K\\{qi}(\|n)$, and include the glue correction for box \|n in the current page state\X;\2\6
+\&{if} ${}(\\{type}(\|r)\E\\{split\_up}){}$\1\5
+${}\\{insert\_penalties}\K\\{insert\_penalties}+\\{float\_cost}(\|p);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{last\_ins\_ptr}(\|r)\K\|p;{}$\5
+${}\\{delta}\K\\{page\_goal}-\\{page\_total}-\\{page\_depth}+\\{page\_shrink}{}$;\C{this much room is left if we shrink the maximum}\6
+\&{if} ${}(\\{count}(\|n)\E\T{1000}){}$\1\5
+${}\|h\K\\{height}(\|p);{}$\2\6
+\&{else}\1\5
+${}\|h\K\\{x\_over\_n}(\\{height}(\|p),\39\T{1000})*\\{count}(\|n){}$;\C{this much room is needed}\2\6
+\&{if} ${}(((\|h\Z\T{0})\V(\|h\Z\\{delta}))\W(\\{height}(\|p)+\\{height}(\|r)\Z\\{dimen}(\|n))){}$\5
+${}\{{}$\5
+\1${}\\{page\_goal}\K\\{page\_goal}-\|h;{}$\5
+${}\\{height}(\|r)\K\\{height}(\|r)+\\{height}(\|p);{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\X1010:Find the best way to split the insertion, and change \\{type}(\|r) to \\{split\_up}\X;\2\6
+\4${}\}{}$\2\6
+\&{goto} \\{contribute};\6
+\4${}\}{}$\2\par
+\U1000.\fi
+
+\M{1009}We take note of the value of \.{\\skip} \|n and the height plus depth
+of \.{\\box}~\|n only when the first \.{\\insert}~\|n node is
+encountered for a new page. A user who changes the contents of \.{\\box}~\|n
+after that first \.{\\insert}~\|n had better be either extremely careful
+or extremely lucky, or both.
+
+\Y\B\4\X1009:Create a page insertion node with $\\{subtype}(\|r)\K\\{qi}(\|n)$, and include the glue correction for box \|n in the current page state\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{get\_node}(\\{page\_ins\_node\_size});{}$\5
+${}\\{link}(\|q)\K\\{link}(\|r);{}$\5
+${}\\{link}(\|r)\K\|q;{}$\5
+${}\|r\K\|q;{}$\5
+${}\\{subtype}(\|r)\K\\{qi}(\|n);{}$\5
+${}\\{type}(\|r)\K\\{inserting};{}$\5
+\\{ensure\_vbox}(\|n);\6
+\&{if} ${}(\\{box}(\|n)\E\\{null}){}$\1\5
+${}\\{height}(\|r)\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\\{height}(\|r)\K\\{height}(\\{box}(\|n))+\\{depth}(\\{box}(\|n));{}$\2\6
+${}\\{best\_ins\_ptr}(\|r)\K\\{null}{}$;\6
+${}\|q\K\\{skip}(\|n);{}$\6
+\&{if} ${}(\\{count}(\|n)\E\T{1000}){}$\1\5
+${}\|h\K\\{height}(\|r);{}$\2\6
+\&{else}\1\5
+${}\|h\K\\{x\_over\_n}(\\{height}(\|r),\39\T{1000})*\\{count}(\|n);{}$\2\6
+${}\\{page\_goal}\K\\{page\_goal}-\|h-\\{width}(\|q){}$;\6
+${}\\{page\_so\_far}[\T{2}+\\{stretch\_order}(\|q)]\K\30\\{page\_so\_far}[\T{2}+\\{stretch\_order}(\|q)]+\\{stretch}(\|q){}$;\6
+${}\\{page\_shrink}\K\\{page\_shrink}+\\{shrink}(\|q);{}$\6
+\&{if} ${}((\\{shrink\_order}(\|q)\I\\{normal})\W(\\{shrink}(\|q)\I\T{0})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Infinite\ glue\ shrin}\)\.{kage\ inserted\ from\ "});\5
+\\{print\_esc}(\X1423:\.{"skip"}\X);\5
+\\{print\_int}(\|n);\5
+\\{help3}(\.{"The\ correction\ glue}\)\.{\ for\ page\ breaking\ w}\)\.{ith\ insertions"})\6
+(\.{"must\ have\ finite\ sh}\)\.{rinkability.\ But\ you}\)\.{\ may\ proceed,"})\6
+(\.{"since\ the\ offensive}\)\.{\ shrinkability\ has\ b}\)\.{een\ made\ finite."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1008.\fi
+
+\M{1010}Here is the code that will split a long footnote between pages, in an
+emergency. The current situation deserves to be recapitulated: Node \|p
+is an insertion into box \|n; the insertion will not fit, in its entirety,
+either because it would make the total contents of box \|n greater than
+\.{\\dimen} \|n, or because it would make the incremental amount of growth
+\|h greater than the available space \\{delta}, or both. (This amount \|h has
+been weighted by the insertion scaling factor, i.e., by \.{\\count} \|n
+over 1000.) Now we will choose the best way to break the vlist of the
+insertion, using the same criteria as in the \.{\\vsplit} operation.
+
+\Y\B\4\X1010:Find the best way to split the insertion, and change \\{type}(\|r) to \\{split\_up}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{count}(\|n)\Z\T{0}){}$\1\5
+${}\|w\K\\{max\_dimen};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|w\K\\{page\_goal}-\\{page\_total}-\\{page\_depth};{}$\6
+\&{if} ${}(\\{count}(\|n)\I\T{1000}){}$\1\5
+${}\|w\K\\{x\_over\_n}(\|w,\39\\{count}(\|n))*\T{1000};{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|w>\\{dimen}(\|n)-\\{height}(\|r)){}$\1\5
+${}\|w\K\\{dimen}(\|n)-\\{height}(\|r);{}$\2\6
+${}\|q\K\\{vert\_break}(\\{ins\_ptr}(\|p),\39\|w,\39\\{depth}(\|p));{}$\5
+${}\\{height}(\|r)\K\\{height}(\|r)+\\{best\_height\_plus\_depth};{}$\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_pages}>\T{0}){}$\1\5
+\X1011:Display the insertion split cost\X;\2\6
+\8\#\&{endif}\6
+\&{if} ${}(\\{count}(\|n)\I\T{1000}){}$\1\5
+${}\\{best\_height\_plus\_depth}\K\\{x\_over\_n}(\\{best\_height\_plus\_depth},\39\T{1000})*\\{count}(\|n);{}$\2\6
+${}\\{page\_goal}\K\\{page\_goal}-\\{best\_height\_plus\_depth};{}$\5
+${}\\{type}(\|r)\K\\{split\_up};{}$\5
+${}\\{broken\_ptr}(\|r)\K\|q;{}$\5
+${}\\{broken\_ins}(\|r)\K\|p;{}$\6
+\&{if} ${}(\|q\E\\{null}){}$\1\5
+${}\\{insert\_penalties}\K\\{insert\_penalties}+\\{eject\_penalty};{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|q)\E\\{penalty\_node}){}$\1\5
+${}\\{insert\_penalties}\K\\{insert\_penalties}+\\{penalty}(\|q);{}$\2\6
+\4${}\}{}$\2\par
+\U1008.\fi
+
+\M{1011}\B\X1011:Display the insertion split cost\X${}\E{}$\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"\%\ split"});\5
+\\{print\_int}(\|n);\5
+\\{print\_str}(\.{"\ to\ "});\5
+\\{print\_scaled}(\|w);\5
+\\{print\_char}(\.{','});\5
+\\{print\_scaled}(\\{best\_height\_plus\_depth});\6
+\\{print\_str}(\.{"\ p="});\6
+\&{if} ${}(\|q\E\\{null}){}$\1\5
+\\{print\_int}(\\{eject\_penalty});\2\6
+\&{else} \&{if} ${}(\\{type}(\|q)\E\\{penalty\_node}){}$\1\5
+\\{print\_int}(\\{penalty}(\|q));\2\6
+\&{else}\1\5
+\\{print\_char}(\.{'0'});\2\6
+\\{end\_diagnostic}(\\{false});\6
+\4${}\}{}$\2\par
+\U1010.\fi
+
+\M{1012}When the page builder has looked at as much material as could appear before
+the next page break, it makes its decision. The break that gave minimum
+badness will be used to put a completed ``page'' into box 255, with insertions
+appended to their other boxes.
+
+We also set the values of \\{top\_mark}, \\{first\_mark}, and \\{bot\_mark}. The
+program uses the fact that $\\{bot\_mark}\I\\{null}$ implies $\\{first\_mark}\I\\{null}$;
+it also knows that $\\{bot\_mark}\E\\{null}$ implies $\\{top\_mark}\E\\{first\_mark}\E\\{null}$.
+
+The \\{fire\_up} subroutine prepares to output the current page at the best
+place; then it fires up the user's output routine, if there is one,
+or it simply ships out the page. There is one parameter, \|c, which represents
+the node that was being contributed to the page when the decision to
+force an output was made.
+
+\Y\B\4\X1012:Declare the procedure called \\{fire\_up}\X${}\E{}$\6
+\&{void} \\{fire\_up}(\&{pointer} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q${},{}$ \|r${},{}$ \|s;\C{nodes being examined and/or changed}\6
+\&{pointer} \\{prev\_p};\C{predecessor of \|p}\6
+\&{uint8\_t} \|n;\C{insertion box number}\6
+\&{bool} \\{wait};\C{should the present insertion be held over?}\6
+\&{int} \\{save\_vbadness};\C{saved value of \\{vbadness}}\6
+\&{scaled} \\{save\_vfuzz};\C{saved value of \\{vfuzz}}\6
+\&{pointer} \\{save\_split\_top\_skip};\C{saved value of \\{split\_top\_skip}}\7
+\X1013:Set the value of \\{output\_penalty}\X;\6
+\&{if} ${}(\\{bot\_mark}\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{top\_mark}\I\\{null}){}$\1\5
+\\{delete\_token\_ref}(\\{top\_mark});\2\6
+${}\\{top\_mark}\K\\{bot\_mark};{}$\5
+\\{add\_token\_ref}(\\{top\_mark});\5
+\\{delete\_token\_ref}(\\{first\_mark});\5
+${}\\{first\_mark}\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\X1014:Put the \(o)optimal current page into box 255, update \\{first\_mark} and \\{bot\_mark}, append insertions to their boxes, and put the remaining nodes back on the contribution list\X;\6
+\&{if} ${}((\\{top\_mark}\I\\{null})\W(\\{first\_mark}\E\\{null})){}$\5
+${}\{{}$\5
+\1${}\\{first\_mark}\K\\{top\_mark};{}$\5
+\\{add\_token\_ref}(\\{top\_mark});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{output\_routine}\I\\{null}){}$\1\6
+\&{if} ${}(\\{dead\_cycles}\G\\{max\_dead\_cycles}){}$\1\5
+\X1024:Explain that too many dead cycles have occurred in a row\X\2\6
+\&{else}\1\5
+\X1025:Fire up the user's output routine and \&{return}\X;\2\2\6
+\X1023:Perform the default output routine\X;\6
+\4${}\}{}$\2\par
+\U994.\fi
+
+\M{1013}\B\X1013:Set the value of \\{output\_penalty}\X${}\E{}$\6
+\&{if} ${}(\\{type}(\\{best\_page\_break})\E\\{penalty\_node}){}$\5
+${}\{{}$\5
+\1${}\\{geq\_word\_define}(\\{int\_base}+\\{output\_penalty\_code},\39\\{penalty}(\\{best\_page\_break}));{}$\5
+${}\\{penalty}(\\{best\_page\_break})\K\\{inf\_penalty};{}$\6
+\4${}\}{}$\2\6
+\&{else} $\\{geq\_word\_define}(\\{int\_base}+\\{output\_penalty\_code},\39\\{inf\_penalty}{}$)\par
+\U1012.\fi
+
+\M{1014}As the page is finally being prepared for output,
+pointer \|p runs through the vlist, with \\{prev\_p} trailing behind;
+pointer \|q is the tail of a list of insertions that
+are being held over for a subsequent page.
+
+\Y\B\4\X1014:Put the \(o)optimal current page into box 255, update \\{first\_mark} and \\{bot\_mark}, append insertions to their boxes, and put the remaining nodes back on the contribution list\X${}\E{}$\6
+\&{if} ${}(\|c\E\\{best\_page\_break}){}$\1\5
+${}\\{best\_page\_break}\K\\{null}{}$;\C{\|c not yet linked in}\2\6
+\X1015:Ensure that box 255 is empty before output\X;\6
+${}\\{insert\_penalties}\K\T{0}{}$;\C{this will count the number of insertions held over}\6
+${}\\{save\_split\_top\_skip}\K\\{split\_top\_skip};{}$\6
+\&{if} ${}(\\{holding\_inserts}\Z\T{0}){}$\1\5
+\X1018:Prepare all the boxes involved in insertions to act as queues\X;\2\6
+${}\|q\K\\{hold\_head};{}$\5
+${}\\{link}(\|q)\K\\{null};{}$\5
+${}\\{prev\_p}\K\\{page\_head};{}$\5
+${}\|p\K\\{link}(\\{prev\_p});{}$\6
+\&{while} ${}(\|p\I\\{best\_page\_break}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|p)\E\\{ins\_node}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{holding\_inserts}\Z\T{0}){}$\1\5
+\X1020:Either insert the material specified by node \|p into the appropriate box, or hold it for the next page; also delete node \|p from the current page\X;\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|p)\E\\{mark\_node}){}$\1\5
+\X1016:Update the values of \\{first\_mark} and \\{bot\_mark}\X;\2\6
+${}\\{prev\_p}\K\|p;{}$\5
+${}\|p\K\\{link}(\\{prev\_p});{}$\6
+\4${}\}{}$\2\6
+${}\\{split\_top\_skip}\K\\{save\_split\_top\_skip};{}$\5
+\X1017:Break the current page at node \|p, put it in box~255, and put the remaining nodes on the contribution list\X;\6
+\X1019:Delete \(t)the page-insertion nodes\X\par
+\U1012.\fi
+
+\M{1015}\B\X1015:Ensure that box 255 is empty before output\X${}\E{}$\6
+\&{if} ${}(\\{box}(\T{255})\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{""});\5
+\\{print\_esc}(\X1437:\.{"box"}\X);\5
+\\{print\_str}(\.{"255\ is\ not\ void"});\5
+\\{help2}(\.{"You\ shouldn't\ use\ \\}\)\.{\\box255\ except\ in\ \\\\}\)\.{output\ routines."})\6
+(\.{"Proceed,\ and\ I'll\ d}\)\.{iscard\ its\ present\ c}\)\.{ontents."});\5
+\\{box\_error}(\T{255});\6
+\4${}\}{}$\2\par
+\U1014.\fi
+
+\M{1016}\B\X1016:Update the values of \\{first\_mark} and \\{bot\_mark}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{first\_mark}\E\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{first\_mark}\K\\{mark\_ptr}(\|p);{}$\5
+\\{add\_token\_ref}(\\{first\_mark});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{bot\_mark}\I\\{null}){}$\1\5
+\\{delete\_token\_ref}(\\{bot\_mark});\2\6
+${}\\{bot\_mark}\K\\{mark\_ptr}(\|p);{}$\5
+\\{add\_token\_ref}(\\{bot\_mark});\6
+\4${}\}{}$\2\par
+\U1014.\fi
+
+\M{1017}When the following code is executed, the current page runs from node
+\\{link}(\\{page\_head}) to node \\{prev\_p}, and the nodes from \|p to \\{page\_tail}
+are to be placed back at the front of the contribution list. Furthermore
+the heldover insertions appear in a list from \\{link}(\\{hold\_head}) to \|q; we
+will put them into the current page list for safekeeping while the user's
+output routine is active. We might have $\|q\E\\{hold\_head}$; and $\|p\E\\{null}$ if
+and only if $\\{prev\_p}\E\\{page\_tail}$. Error messages are suppressed within
+\\{vpackage}, since the box might appear to be overfull or underfull simply
+because the stretch and shrink from the \.{\\skip} registers for inserts
+are not actually present in the box.
+
+\Y\B\4\X1017:Break the current page at node \|p, put it in box~255, and put the remaining nodes on the contribution list\X${}\E{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\\{contrib\_head})\E\\{null}){}$\1\6
+\&{if} ${}(\\{nest\_ptr}\E\T{0}){}$\1\5
+${}\\{tail}\K\\{page\_tail};{}$\2\6
+\&{else}\1\5
+${}\\{contrib\_tail}\K\\{page\_tail};{}$\2\2\6
+${}\\{link}(\\{page\_tail})\K\\{link}(\\{contrib\_head});{}$\5
+${}\\{link}(\\{contrib\_head})\K\|p;{}$\5
+${}\\{link}(\\{prev\_p})\K\\{null};{}$\6
+\4${}\}{}$\2\6
+${}\\{save\_vbadness}\K\\{vbadness};{}$\5
+${}\\{vbadness}\K\\{inf\_bad};{}$\5
+${}\\{save\_vfuzz}\K\\{vfuzz};{}$\5
+${}\\{vfuzz}\K\\{max\_dimen}{}$;\C{inhibit error messages}\6
+${}\\{box}(\T{255})\K\\{vpackage}(\\{link}(\\{page\_head}),\39\\{best\_size},\39\\{exactly},\39\\{page\_max\_depth});{}$\5
+${}\\{vbadness}\K\\{save\_vbadness};{}$\5
+${}\\{vfuzz}\K\\{save\_vfuzz};{}$\6
+\&{if} ${}(\\{last\_glue}\I\\{max\_halfword}){}$\1\5
+\\{delete\_glue\_ref}(\\{last\_glue});\2\6
+\X991:Start a new current page\X;\C{this sets $\\{last\_glue}\K\\{max\_halfword}$}\6
+\&{if} ${}(\|q\I\\{hold\_head}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{page\_head})\K\\{link}(\\{hold\_head});{}$\5
+${}\\{page\_tail}\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U1014.\fi
+
+\M{1018}If many insertions are supposed to go into the same box, we want to know
+the position of the last node in that box, so that we don't need to waste time
+when linking further information into it. The \\{last\_ins\_ptr} fields of the
+page insertion nodes are therefore used for this purpose during the
+packaging phase.
+
+\Y\B\4\X1018:Prepare all the boxes involved in insertions to act as queues\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{page\_ins\_head});{}$\6
+\&{while} ${}(\|r\I\\{page\_ins\_head}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{best\_ins\_ptr}(\|r)\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|n\K\\{qo}(\\{subtype}(\|r));{}$\5
+\\{ensure\_vbox}(\|n);\6
+\&{if} ${}(\\{box}(\|n)\E\\{null}){}$\1\5
+${}\\{box}(\|n)\K\\{new\_null\_box}(\,);{}$\2\6
+${}\|p\K\\{box}(\|n)+\\{list\_offset};{}$\6
+\&{while} ${}(\\{link}(\|p)\I\\{null}){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+${}\\{last\_ins\_ptr}(\|r)\K\|p;{}$\6
+\4${}\}{}$\2\6
+${}\|r\K\\{link}(\|r);{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1014.\fi
+
+\M{1019}\B\X1019:Delete \(t)the page-insertion nodes\X${}\E{}$\6
+$\|r\K\\{link}(\\{page\_ins\_head});{}$\6
+\&{while} ${}(\|r\I\\{page\_ins\_head}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{link}(\|r);{}$\5
+${}\\{free\_node}(\|r,\39\\{page\_ins\_node\_size});{}$\5
+${}\|r\K\|q;{}$\6
+\4${}\}{}$\2\6
+$\\{link}(\\{page\_ins\_head})\K{}$\\{page\_ins\_head}\par
+\U1014.\fi
+
+\M{1020}We will set $\\{best\_ins\_ptr}\K\\{null}$ and package the box corresponding to
+insertion node~\|r, just after making the final insertion into that box.
+If this final insertion is `\\{split\_up}', the remainder after splitting
+and pruning (if any) will be carried over to the next page.
+
+\Y\B\4\X1020:Either insert the material specified by node \|p into the appropriate box, or hold it for the next page; also delete node \|p from the current page\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|r\K\\{link}(\\{page\_ins\_head});{}$\6
+\&{while} ${}(\\{subtype}(\|r)\I\\{subtype}(\|p)){}$\1\5
+${}\|r\K\\{link}(\|r);{}$\2\6
+\&{if} ${}(\\{best\_ins\_ptr}(\|r)\E\\{null}){}$\1\5
+${}\\{wait}\K\\{true};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{wait}\K\\{false};{}$\5
+${}\|s\K\\{last\_ins\_ptr}(\|r);{}$\5
+${}\\{link}(\|s)\K\\{ins\_ptr}(\|p);{}$\6
+\&{if} ${}(\\{best\_ins\_ptr}(\|r)\E\|p){}$\1\5
+\X1021:Wrap up the box specified by node \|r, splitting node \|p if called for; set \\{wait}: $\K$ \\{true} if node \|p holds a remainder after splitting\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{while} ${}(\\{link}(\|s)\I\\{null}){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+${}\\{last\_ins\_ptr}(\|r)\K\|s;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\X1022:Either append the insertion node \|p after node \|q, and remove it from the current page, or delete \\{node}(\|p)\X;\6
+\4${}\}{}$\2\par
+\U1014.\fi
+
+\M{1021}\B\X1021:Wrap up the box specified by node \|r, splitting node \|p if called for; set \\{wait}: $\K$ \\{true} if node \|p holds a remainder after splitting\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{type}(\|r)\E\\{split\_up}){}$\1\6
+\&{if} ${}((\\{broken\_ins}(\|r)\E\|p)\W(\\{broken\_ptr}(\|r)\I\\{null})){}$\5
+${}\{{}$\5
+\1\&{while} ${}(\\{link}(\|s)\I\\{broken\_ptr}(\|r)){}$\1\5
+${}\|s\K\\{link}(\|s);{}$\2\6
+${}\\{link}(\|s)\K\\{null};{}$\5
+${}\\{split\_top\_skip}\K\\{split\_top\_ptr}(\|p);{}$\5
+${}\\{ins\_ptr}(\|p)\K\\{prune\_page\_top}(\\{broken\_ptr}(\|r));{}$\6
+\&{if} ${}(\\{ins\_ptr}(\|p)\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{temp\_ptr}\K\\{vpack}(\\{ins\_ptr}(\|p),\39\\{natural});{}$\5
+${}\\{height}(\|p)\K\\{height}(\\{temp\_ptr})+\\{depth}(\\{temp\_ptr});{}$\5
+${}\\{free\_node}(\\{temp\_ptr},\39\\{box\_node\_size});{}$\5
+${}\\{wait}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\2\6
+${}\\{best\_ins\_ptr}(\|r)\K\\{null};{}$\5
+${}\|n\K\\{qo}(\\{subtype}(\|r));{}$\5
+${}\\{temp\_ptr}\K\\{list\_ptr}(\\{box}(\|n));{}$\5
+${}\\{free\_node}(\\{box}(\|n),\39\\{box\_node\_size});{}$\5
+${}\\{box}(\|n)\K\\{vpack}(\\{temp\_ptr},\39\\{natural});{}$\6
+\4${}\}{}$\2\par
+\U1020.\fi
+
+\M{1022}\B\X1022:Either append the insertion node \|p after node \|q, and remove it from the current page, or delete \\{node}(\|p)\X${}\E{}$\6
+$\\{link}(\\{prev\_p})\K\\{link}(\|p);{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\&{if} (\\{wait})\5
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\|p;{}$\5
+${}\|q\K\|p;{}$\5
+\\{incr}(\\{insert\_penalties});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{delete\_glue\_ref}(\\{split\_top\_ptr}(\|p));\5
+${}\\{free\_node}(\|p,\39\\{ins\_node\_size});{}$\6
+\4${}\}{}$\2\6
+$\|p\K{}$\\{prev\_p}\par
+\U1020.\fi
+
+\M{1023}The list of heldover insertions, running from \\{link}(\\{page\_head}) to
+\\{page\_tail}, must be moved to the contribution list when the user has
+specified no output routine.
+
+\Y\B\4\X1023:Perform the default output routine\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\\{page\_head})\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\\{contrib\_head})\E\\{null}){}$\1\6
+\&{if} ${}(\\{nest\_ptr}\E\T{0}){}$\1\5
+${}\\{tail}\K\\{page\_tail}{}$;\5
+\2\&{else}\1\5
+${}\\{contrib\_tail}\K\\{page\_tail};{}$\2\2\6
+\&{else}\1\5
+${}\\{link}(\\{page\_tail})\K\\{link}(\\{contrib\_head});{}$\2\6
+${}\\{link}(\\{contrib\_head})\K\\{link}(\\{page\_head});{}$\5
+${}\\{link}(\\{page\_head})\K\\{null};{}$\5
+${}\\{page\_tail}\K\\{page\_head};{}$\6
+\4${}\}{}$\2\6
+\\{ship\_out}(\\{box}(\T{255}));\5
+${}\\{box}(\T{255})\K\\{null};{}$\6
+\4${}\}{}$\2\par
+\U1012.\fi
+
+\M{1024}\B\X1024:Explain that too many dead cycles have occurred in a row\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Output\ loop---"});\5
+\\{print\_int}(\\{dead\_cycles});\5
+\\{print\_str}(\.{"\ consecutive\ dead\ c}\)\.{ycles"});\5
+\\{help3}(\.{"I've\ concluded\ that}\)\.{\ your\ \\\\output\ is\ aw}\)\.{ry;\ it\ never\ does\ a"})\6
+(\.{"\\\\shipout,\ so\ I'm\ s}\)\.{hipping\ \\\\box255\ out}\)\.{\ myself.\ Next\ time"})\6
+(\.{"increase\ \\\\maxdeadc}\)\.{ycles\ if\ you\ want\ me}\)\.{\ to\ be\ more\ patient!}\)\.{"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1012.\fi
+
+\M{1025}\B\X1025:Fire up the user's output routine and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{output\_active}\K\\{true};{}$\5
+\\{incr}(\\{dead\_cycles});\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{vmode};{}$\5
+${}\\{prev\_depth}\K\\{ignore\_depth};{}$\5
+${}\\{mode\_line}\K{-}\\{line};{}$\5
+${}\\{begin\_token\_list}(\\{output\_routine},\39\\{output\_text});{}$\5
+\\{new\_save\_level}(\\{output\_group});\5
+\\{normal\_paragraph}(\,);\5
+\\{scan\_left\_brace}(\,);\5
+\&{return};\6
+\4${}\}{}$\2\par
+\U1012.\fi
+
+\M{1026}When the user's output routine finishes, it has constructed a vlist
+in internal vertical mode, and \TeX\ will do the following:
+
+\Y\B\4\X1026:Resume the page builder after an output routine has come to an end\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\\{loc}\I\\{null})\V((\\{token\_type}\I\\{output\_text})\W(\\{token\_type}\I\\{backed\_up}))){}$\1\5
+\X1027:Recover from an unbalanced output routine\X;\2\6
+\\{end\_token\_list}(\,);\C{conserve stack space in case more outputs are triggered}\6
+\\{end\_graf}(\,);\5
+\\{unsave}(\,);\5
+${}\\{output\_active}\K\\{false};{}$\5
+${}\\{insert\_penalties}\K\T{0}{}$;\6
+\X1028:Ensure that box 255 is empty after output\X;\6
+\&{if} ${}(\\{tail}\I\\{head}{}$)\C{current list goes after heldover insertions}\6
+${}\{{}$\5
+\1${}\\{link}(\\{page\_tail})\K\\{link}(\\{head});{}$\5
+${}\\{page\_tail}\K\\{tail};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{link}(\\{page\_head})\I\\{null}{}$)\C{and both go before heldover contributions}\6
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\\{contrib\_head})\E\\{null}){}$\1\5
+${}\\{contrib\_tail}\K\\{page\_tail};{}$\2\6
+${}\\{link}(\\{page\_tail})\K\\{link}(\\{contrib\_head});{}$\5
+${}\\{link}(\\{contrib\_head})\K\\{link}(\\{page\_head});{}$\5
+${}\\{link}(\\{page\_head})\K\\{null};{}$\5
+${}\\{page\_tail}\K\\{page\_head};{}$\6
+\4${}\}{}$\2\6
+\\{pop\_nest}(\,);\5
+\\{build\_page}(\,);\6
+\4${}\}{}$\2\par
+\U1100.\fi
+
+\M{1027}\B\X1027:Recover from an unbalanced output routine\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Unbalanced\ output\ r}\)\.{outine"});\5
+\\{help2}(\.{"Your\ sneaky\ output\ }\)\.{routine\ has\ problema}\)\.{tic\ \{'s\ and/or\ \}'s."})\6
+(\.{"I\ can't\ handle\ that}\)\.{\ very\ well;\ good\ luc}\)\.{k."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{loc}\E\\{null}));{}$\6
+\4${}\}{}$\C{loops forever if reading from a file, since $\\{null}\E\\{min\_halfword}\Z\T{0}$}\2\par
+\U1026.\fi
+
+\M{1028}\B\X1028:Ensure that box 255 is empty after output\X${}\E{}$\6
+\&{if} ${}(\\{box}(\T{255})\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Output\ routine\ didn}\)\.{'t\ use\ all\ of\ "});\5
+\\{print\_esc}(\X1437:\.{"box"}\X);\5
+\\{print\_int}(\T{255});\5
+\\{help3}(\.{"Your\ \\\\output\ comma}\)\.{nds\ should\ empty\ \\\\b}\)\.{ox255,"})\6
+(\.{"e.g.,\ by\ saying\ `\\\\}\)\.{shipout\\\\box255'."})\6
+(\.{"Proceed;\ I'll\ disca}\)\.{rd\ its\ present\ conte}\)\.{nts."});\5
+\\{box\_error}(\T{255});\6
+\4${}\}{}$\2\par
+\U1026.\fi
+
+\N{1}{1029}The chief executive.
+We come now to the \\{main\_control} routine, which contains the master
+switch that causes all the various pieces of \TeX\ to do their things,
+in the right order.
+
+In a sense, this is the grand climax of the program: It applies all the
+tools that we have worked so hard to construct. In another sense, this is
+the messiest part of the program: It necessarily refers to other pieces
+of code all over the place, so that a person can't fully understand what is
+going on without paging back and forth to be reminded of conventions that
+are defined elsewhere. We are now at the hub of the web, the central nervous
+system that touches most of the other parts and ties them together.
+
+The structure of \\{main\_control} itself is quite simple. There's a label
+called \\{big\_switch}, at which point the next token of input is fetched
+using \\{get\_x\_token}. Then the program branches at high speed into one of
+about 100 possible directions, based on the value of the current
+mode and the newly fetched command code; the sum $\\{abs}(\\{mode})+\\{cur\_cmd}$
+indicates what to do next. For example, the case `$\\{vmode}+\\{letter}$' arises
+when a letter occurs in vertical mode (or internal vertical mode); this
+case leads to instructions that initialize a new paragraph and enter
+horizontal mode.
+
+The big \&{case} statement that contains this multiway switch has been labeled
+\\{reswitch}, so that the program can \&{goto} \\{reswitch} when the next token
+has already been fetched. Most of the cases are quite short; they call
+an ``action procedure'' that does the work for that case, and then they
+either \&{goto} \\{reswitch} or they ``fall through'' to the end of the \&{case}
+statement, which returns control back to \\{big\_switch}. Thus, \\{main\_control}
+is not an extremely large procedure, in spite of the multiplicity of things
+it must do; it is small enough to be handled by \PASCAL\ compilers that put
+severe restrictions on procedure size.
+
+One case is singled out for special treatment, because it accounts for most
+of \TeX's activities in typical applications. The process of reading simple
+text and converting it into \\{char\_node} records, while looking for ligatures
+and kerns, is part of \TeX's ``inner loop''; the whole program runs
+efficiently when its inner loop is fast, so this part has been written
+with particular care.
+
+\fi
+
+\M{1030}We shall concentrate first on the inner loop of \\{main\_control}, deferring
+consideration of the other cases until later.
+
+\Y\B\hbox{\4}\X1043:Declare action procedures for use by \\{main\_control}\X\6
+\hbox{\4}\X1068:Declare the procedure called \\{handle\_right\_brace}\X\7
+\&{void} \\{main\_control}(\&{void})\C{governs \TeX's activities}\6
+${}\{{}$\5
+\1\&{int} \|t;\C{general-purpose temporary variable}\7
+\&{if} ${}(\\{every\_job}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_job},\39\\{every\_job\_text});{}$\2\6
+\4\\{big\_switch}:\5
+\\{get\_x\_token}(\,);\6
+\4\\{reswitch}:\5
+\X1031:Give diagnostic information, if requested\X;\6
+\&{switch} ${}(\\{abs}(\\{mode})+\\{cur\_cmd}){}$\5
+${}\{{}$\1\6
+\4\&{case} \\{hmode}${}+\\{letter}{}$:\5
+\&{case} \\{hmode}${}+\\{other\_char}{}$:\5
+\&{case} \\{hmode}${}+\\{char\_given}{}$:\5
+\&{goto} \\{main\_loop};\6
+\4\&{case} \\{hmode}${}+\\{char\_num}{}$:\6
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\\{cur\_chr}\K\\{cur\_val};{}$\5
+\&{goto} \\{main\_loop};\5
+${}\}{}$\2\6
+\4\&{case} \\{hmode}${}+\\{no\_boundary}{}$:\6
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}((\\{cur\_cmd}\E\\{letter})\V(\\{cur\_cmd}\E\\{other\_char})\V(\\{cur\_cmd}\E\\{char\_given})\V(\\{cur\_cmd}\E\\{char\_num})){}$\1\5
+${}\\{cancel\_boundary}\K\\{true};{}$\2\6
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{hmode}${}+\\{spacer}{}$:\6
+\&{if} ${}(\\{space\_factor}\E\T{1000}){}$\1\5
+\&{goto} \\{append\_normal\_space};\2\6
+\&{else}\1\5
+\\{app\_space}(\,);\5
+\2\&{break};\6
+\4\&{case} \\{hmode}${}+\\{ex\_space}{}$:\5
+\&{case} \\{mmode}${}+\\{ex\_space}{}$:\5
+\&{goto} \\{append\_normal\_space};\5
+\hbox{\4}\X1045:Cases of \\{main\_control} that are not part of the inner loop\X\6
+\4${}\}{}$\C{of the big \&{case} statement}\2\6
+\&{goto} \\{big\_switch};\6
+\4\\{main\_loop}:\5
+\X1034:Append character \\{cur\_chr} and the following characters (if~any) to the current hlist in the current font; \&{goto} \\{reswitch} when a non-character has been fetched\X;\6
+\4\\{append\_normal\_space}:\5
+\X1041:Append a normal inter-word space to the current list, then \&{goto} \\{big\_switch}\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1031}When a new token has just been fetched at \\{big\_switch}, we have an
+ideal place to monitor \TeX's activity.
+
+\Y\B\4\X1031:Give diagnostic information, if requested\X${}\E{}$\6
+\&{if} ${}(\\{interrupt}\I\T{0}){}$\1\6
+\&{if} (\\{OK\_to\_interrupt})\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\\{check\_interrupt};\5
+\&{goto} \\{big\_switch};\6
+\4${}\}{}$\2\2\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\&{if} (\\{panicking})\1\5
+\\{check\_mem}(\\{false});\2\6
+\8\#\&{endif}\6
+\&{if} ${}(\\{tracing\_commands}>\T{0})$ \\{show\_cur\_cmd\_chr}(\,)\par
+\U1030.\fi
+
+\M{1032}The following part of the program was first written in a structured
+manner, according to the philosophy that ``premature optimization is
+the root of all evil.'' Then it was rearranged into pieces of
+spaghetti so that the most common actions could proceed with little or
+no redundancy.
+
+The original unoptimized form of this algorithm resembles the
+\\{reconstitute} procedure, which was described earlier in connection with
+hyphenation. Again we have an implied ``cursor'' between characters
+\\{cur\_l} and \\{cur\_r}. The main difference is that the \\{lig\_stack} can now
+contain a charnode as well as pseudo-ligatures; that stack is now
+usually nonempty, because the next character of input (if any) has been
+appended to it. In \\{main\_control} we have
+$$\\{cur\_r}=\cases{\\{character}(\\{lig\_stack}),&if $\\{lig\_stack}>\\{null}$;\cr
+\\{font\_bchar}[\\{cur\_font}],&otherwise;\cr}$$
+except when $\\{character}(\\{lig\_stack})\E\\{font\_false\_bchar}[\\{cur\_font}]$.
+Several additional global variables are needed.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{internal\_font\_number} \\{main\_f};\C{the current font}\6
+\&{four\_quarters} \\{main\_i};\C{character information bytes for \\{cur\_l}}\6
+\&{four\_quarters} \\{main\_j};\C{ligature/kern command}\6
+\&{font\_index} \\{main\_k};\C{index into \\{font\_info}}\6
+\&{pointer} \\{main\_p};\C{temporary register for list manipulation}\6
+\&{int} \\{main\_s};\C{space factor value}\6
+\&{halfword} \\{bchar};\C{right boundary character of current font, or \\{non\_char}}\6
+\&{halfword} \\{false\_bchar};\C{nonexistent character matching \\{bchar}, or \\{non\_char}}\6
+\&{bool} \\{cancel\_boundary};\C{should the left boundary be ignored?}\6
+\&{bool} \\{ins\_disc};\C{should we insert a discretionary node?}\par
+\fi
+
+\M{1033}The boolean variables of the main loop are normally false, and always reset
+to false before the loop is left. That saves us the extra work of initializing
+each time.
+
+\Y\B\4\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{ligature\_present}\K\\{false};{}$\5
+${}\\{cancel\_boundary}\K\\{false};{}$\5
+${}\\{lft\_hit}\K\\{false};{}$\5
+${}\\{rt\_hit}\K\\{false};{}$\5
+${}\\{ins\_disc}\K\\{false}{}$;\par
+\fi
+
+\M{1034}We leave the \\{space\_factor} unchanged if $\\{sf\_code}(\\{cur\_chr})\E\T{0}$; otherwise we
+set it equal to \\{sf\_code}(\\{cur\_chr}), except that it should never change
+from a value less than 1000 to a value exceeding 1000. The most common
+case is $\\{sf\_code}(\\{cur\_chr})\E\T{1000}$, so we want that case to be fast.
+
+The overall structure of the main loop is presented here. Some program labels
+are inside the individual sections.
+
+\Y\B\4\D$\\{adjust\_space\_factor}$ \5
+\hbox{}\6
+${}\\{main\_s}\K\\{sf\_code}(\\{cur\_chr});$ \6
+\&{if} ${}(\\{main\_s}\E\T{1000}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\&{else} \&{if} ${}(\\{main\_s}<\T{1000}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{main\_s}>\T{0}){}$\1\5
+${}\\{space\_factor}\K\\{main\_s};{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{space\_factor}<\T{1000}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\&{else} $\\{space\_factor}\K{}$\\{main\_s}\par
+\Y\B\4\X1034:Append character \\{cur\_chr} and the following characters (if~any) to the current hlist in the current font; \&{goto} \\{reswitch} when a non-character has been fetched\X${}\E{}$\6
+\\{adjust\_space\_factor};\6
+${}\\{main\_f}\K\\{cur\_font};{}$\5
+${}\\{bchar}\K\\{font\_bchar}[\\{main\_f}];{}$\5
+${}\\{false\_bchar}\K\\{font\_false\_bchar}[\\{main\_f}];{}$\6
+\&{if} ${}(\\{mode}>\T{0}){}$\1\6
+\&{if} ${}(\\{language}\I\\{clang}){}$\1\5
+\\{fix\_language}(\,);\2\2\6
+\\{fast\_get\_avail}(\\{lig\_stack});\5
+${}\\{font}(\\{lig\_stack})\K\\{main\_f};{}$\5
+${}\\{cur\_l}\K\\{qi}(\\{cur\_chr});{}$\5
+${}\\{character}(\\{lig\_stack})\K\\{cur\_l}{}$;\6
+${}\\{cur\_q}\K\\{tail};{}$\6
+\&{if} (\\{cancel\_boundary})\5
+${}\{{}$\5
+\1${}\\{cancel\_boundary}\K\\{false};{}$\5
+${}\\{main\_k}\K\\{non\_address};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{main\_k}\K\\{bchar\_label}[\\{main\_f}];{}$\2\6
+\&{if} ${}(\\{main\_k}\E\\{non\_address}){}$\1\5
+\&{goto} \\{main\_loop\_move2};\C{no left boundary processing}\2\6
+${}\\{cur\_r}\K\\{cur\_l};{}$\5
+${}\\{cur\_l}\K\\{non\_char};{}$\5
+\&{goto} \\{main\_lig\_loop1};\C{begin with cursor after left boundary}\7
+\4\\{main\_loop\_wrapup}:\5
+\X1035:Make a ligature node, if \\{ligature\_present}; insert a null discretionary, if appropriate\X;\6
+\4\\{main\_loop\_move}:\5
+\X1036:If the cursor is immediately followed by the right boundary, \&{goto} \\{reswitch}; if it's followed by an invalid character, \&{goto} \\{big\_switch}; otherwise move the cursor one step to the right and \&{goto} \\{main\_lig\_loop}\X;\6
+\4\\{main\_loop\_lookahead}:\5
+\X1038:Look ahead for another character, or leave \\{lig\_stack} empty if there's none there\X;\6
+\4\\{main\_lig\_loop}:\5
+\X1039:If there's a ligature/kern command relevant to \\{cur\_l} and \\{cur\_r}, adjust the text appropriately; exit to \\{main\_loop\_wrapup}\X;\6
+\4\\{main\_loop\_move\_lig}:\5
+\X1037:Move the cursor past a pseudo-ligature, then \&{goto} \\{main\_loop\_lookahead} or \\{main\_lig\_loop}\X\par
+\U1030.\fi
+
+\M{1035}If \\{link}(\\{cur\_q}) is nonnull when \\{wrapup} is invoked, \\{cur\_q} points to
+the list of characters that were consumed while building the ligature
+character~\\{cur\_l}.
+
+A discretionary break is not inserted for an explicit hyphen when we are in
+restricted horizontal mode. In particular, this avoids putting discretionary
+nodes inside of other discretionaries.
+
+\Y\B\4\D$\\{pack\_lig}(\|X)$ \C{the parameter is either \\{rt\_hit} or \\{false}}\6
+${}\{{}$\5
+\1${}\\{main\_p}\K\\{new\_ligature}(\\{main\_f},\39\\{cur\_l},\39\\{link}(\\{cur\_q}));{}$\6
+\&{if} (\\{lft\_hit})\5
+${}\{{}$\5
+\1${}\\{subtype}(\\{main\_p})\K\T{2};{}$\5
+${}\\{lft\_hit}\K\\{false};{}$\6
+\4${}\}{}$\2\6
+\&{if} (\|X)\1\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\5
+${}\{{}$\5
+\1\\{incr}(\\{subtype}(\\{main\_p}));\5
+${}\\{rt\_hit}\K\\{false};{}$\6
+\4${}\}{}$\2\2\6
+${}\\{link}(\\{cur\_q})\K\\{main\_p};{}$\5
+${}\\{tail}\K\\{main\_p};{}$\5
+${}\\{ligature\_present}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\B\4\D$\\{wrapup}(\|X)$ \6
+\&{if} ${}(\\{cur\_l}<\\{non\_char}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{link}(\\{cur\_q})>\\{null}){}$\1\6
+\&{if} ${}(\\{character}(\\{tail})\E\\{qi}(\\{hyphen\_char}[\\{main\_f}])){}$\1\5
+${}\\{ins\_disc}\K\\{true};{}$\2\2\6
+\&{if} (\\{ligature\_present})\1\5
+\\{pack\_lig}(\|X);\2\6
+\&{if} (\\{ins\_disc})\5
+${}\{{}$\5
+\1${}\\{ins\_disc}\K\\{false};{}$\6
+\&{if} ${}(\\{mode}>\T{0}){}$\1\5
+\\{tail\_append}(\\{new\_disc}(\,));\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\Y\B\4\X1035:Make a ligature node, if \\{ligature\_present}; insert a null discretionary, if appropriate\X${}\E{}$\6
+\\{wrapup}(\\{rt\_hit})\par
+\U1034.\fi
+
+\M{1036}\B\X1036:If the cursor is immediately followed by the right boundary, \&{goto} \\{reswitch}; if it's followed by an invalid character, \&{goto} \\{big\_switch}; otherwise move the cursor one step to the right and \&{goto} \\{main\_lig\_loop}\X${}%
+\E{}$\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\5
+\&{goto} \\{reswitch};\2\6
+${}\\{cur\_q}\K\\{tail};{}$\5
+${}\\{cur\_l}\K\\{character}(\\{lig\_stack});{}$\6
+\4\\{main\_loop\_move1}:\6
+\&{if} ${}(\R\\{is\_char\_node}(\\{lig\_stack})){}$\1\5
+\&{goto} \\{main\_loop\_move\_lig};\2\6
+\4\\{main\_loop\_move2}:\6
+\&{if} ${}((\\{cur\_chr}<\\{font\_bc}[\\{main\_f}])\V(\\{cur\_chr}>\\{font\_ec}[\\{main\_f}])){}$\5
+${}\{{}$\5
+\1${}\\{char\_warning}(\\{main\_f},\39\\{cur\_chr});{}$\5
+\\{free\_avail}(\\{lig\_stack});\5
+\&{goto} \\{big\_switch};\6
+\4${}\}{}$\2\6
+${}\\{main\_i}\K\\{char\_info}(\\{main\_f})(\\{cur\_l});{}$\6
+\&{if} ${}(\R\\{char\_exists}(\\{main\_i})){}$\5
+${}\{{}$\5
+\1${}\\{char\_warning}(\\{main\_f},\39\\{cur\_chr});{}$\5
+\\{free\_avail}(\\{lig\_stack});\5
+\&{goto} \\{big\_switch};\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\\{lig\_stack};$ $\\{tail}\K{}$\\{lig\_stack}\C{\\{main\_loop\_lookahead} is next}\par
+\U1034.\fi
+
+\M{1037}Here we are at \\{main\_loop\_move\_lig}.
+When we begin this code we have $\\{cur\_q}\E\\{tail}$ and $\\{cur\_l}\E\\{character}(\\{lig\_stack})$.
+
+\Y\B\4\X1037:Move the cursor past a pseudo-ligature, then \&{goto} \\{main\_loop\_lookahead} or \\{main\_lig\_loop}\X${}\E{}$\6
+$\\{main\_p}\K\\{lig\_ptr}(\\{lig\_stack});{}$\6
+\&{if} ${}(\\{main\_p}>\\{null}){}$\1\5
+\\{tail\_append}(\\{main\_p});\C{append a single character}\2\6
+${}\\{temp\_ptr}\K\\{lig\_stack};{}$\5
+${}\\{lig\_stack}\K\\{link}(\\{temp\_ptr});{}$\5
+${}\\{free\_node}(\\{temp\_ptr},\39\\{small\_node\_size});{}$\5
+${}\\{main\_i}\K\\{char\_info}(\\{main\_f})(\\{cur\_l});{}$\5
+${}\\{ligature\_present}\K\\{true};{}$\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\6
+\&{if} ${}(\\{main\_p}>\\{null}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead};\2\6
+\&{else}\1\5
+${}\\{cur\_r}\K\\{bchar};{}$\2\2\6
+\&{else}\1\5
+${}\\{cur\_r}\K\\{character}(\\{lig\_stack});{}$\2\6
+\&{goto} \\{main\_lig\_loop}\par
+\U1034.\fi
+
+\M{1038}The result of \.{\\char} can participate in a ligature or kern, so we must
+look ahead for it.
+
+\Y\B\4\X1038:Look ahead for another character, or leave \\{lig\_stack} empty if there's none there\X${}\E{}$\6
+\\{get\_next}(\,);\C{set only \\{cur\_cmd} and \\{cur\_chr}, for speed}\6
+\&{if} ${}(\\{cur\_cmd}\E\\{letter}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{other\_char}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{char\_given}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\\{x\_token}(\,);\C{now expand and set \\{cur\_cmd}, \\{cur\_chr}, \\{cur\_tok}}\6
+\&{if} ${}(\\{cur\_cmd}\E\\{letter}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{other\_char}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{char\_given}){}$\1\5
+\&{goto} \\{main\_loop\_lookahead1};\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{char\_num}){}$\5
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\\{cur\_chr}\K\\{cur\_val};{}$\5
+\&{goto} \\{main\_loop\_lookahead1};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{no\_boundary}){}$\1\5
+${}\\{bchar}\K\\{non\_char};{}$\2\6
+${}\\{cur\_r}\K\\{bchar};{}$\5
+${}\\{lig\_stack}\K\\{null};{}$\5
+\&{goto} \\{main\_lig\_loop};\6
+\4\\{main\_loop\_lookahead1}:\5
+\\{adjust\_space\_factor};\5
+\\{fast\_get\_avail}(\\{lig\_stack});\5
+${}\\{font}(\\{lig\_stack})\K\\{main\_f};{}$\5
+${}\\{cur\_r}\K\\{qi}(\\{cur\_chr});{}$\5
+${}\\{character}(\\{lig\_stack})\K\\{cur\_r};$ \&{if} ${}(\\{cur\_r}\E\\{false\_bchar})$ $\\{cur\_r}\K{}$\\{non\_char}\C{this prevents spurious ligatures}\par
+\U1034.\fi
+
+\M{1039}Even though comparatively few characters have a lig/kern program, several
+of the instructions here count as part of \TeX's inner loop, since a
+potentially long sequential search must be performed. For example, tests with
+Computer Modern Roman showed that about 40 per cent of all characters
+actually encountered in practice had a lig/kern program, and that about four
+lig/kern commands were investigated for every such character.
+
+At the beginning of this code we have $\\{main\_i}\E\\{char\_info}(\\{main\_f})(\\{cur\_l})$.
+
+\Y\B\4\X1039:If there's a ligature/kern command relevant to \\{cur\_l} and \\{cur\_r}, adjust the text appropriately; exit to \\{main\_loop\_wrapup}\X${}\E{}$\6
+\&{if} ${}(\\{char\_tag}(\\{main\_i})\I\\{lig\_tag}){}$\1\5
+\&{goto} \\{main\_loop\_wrapup};\2\6
+\&{if} ${}(\\{cur\_r}\E\\{non\_char}){}$\1\5
+\&{goto} \\{main\_loop\_wrapup};\2\6
+${}\\{main\_k}\K\\{lig\_kern\_start}(\\{main\_f})(\\{main\_i});{}$\5
+${}\\{main\_j}\K\\{font\_info}[\\{main\_k}].\\{qqqq};{}$\6
+\&{if} ${}(\\{skip\_byte}(\\{main\_j})\Z\\{stop\_flag}){}$\1\5
+\&{goto} \\{main\_lig\_loop2};\2\6
+${}\\{main\_k}\K\\{lig\_kern\_restart}(\\{main\_f})(\\{main\_j});{}$\6
+\4\\{main\_lig\_loop1}:\5
+${}\\{main\_j}\K\\{font\_info}[\\{main\_k}].\\{qqqq};{}$\6
+\4\\{main\_lig\_loop2}:\6
+\&{if} ${}(\\{next\_char}(\\{main\_j})\E\\{cur\_r}){}$\1\6
+\&{if} ${}(\\{skip\_byte}(\\{main\_j})\Z\\{stop\_flag}){}$\1\5
+\X1040:Do ligature or kern command, returning to \\{main\_lig\_loop} or \\{main\_loop\_wrapup} or \\{main\_loop\_move}\X;\2\2\6
+\&{if} ${}(\\{skip\_byte}(\\{main\_j})\E\\{qi}(\T{0})){}$\1\5
+\\{incr}(\\{main\_k});\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{skip\_byte}(\\{main\_j})\G\\{stop\_flag}){}$\1\5
+\&{goto} \\{main\_loop\_wrapup};\2\6
+${}\\{main\_k}\K\\{main\_k}+\\{qo}(\\{skip\_byte}(\\{main\_j}))+\T{1};{}$\6
+\4${}\}{}$\2\6
+\&{goto} \\{main\_lig\_loop1}\par
+\U1034.\fi
+
+\M{1040}When a ligature or kern instruction matches a character, we know from
+\\{read\_font\_info} that the character exists in the font, even though we
+haven't verified its existence in the normal way.
+
+This section could be made into a subroutine, if the code inside
+\\{main\_control} needs to be shortened.
+
+\chardef\?='174 % vertical line to indicate character retention
+
+\Y\B\4\X1040:Do ligature or kern command, returning to \\{main\_lig\_loop} or \\{main\_loop\_wrapup} or \\{main\_loop\_move}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{op\_byte}(\\{main\_j})\G\\{kern\_flag}){}$\5
+${}\{{}$\5
+\1\\{wrapup}(\\{rt\_hit});\5
+\\{tail\_append}(\\{new\_kern}(\\{char\_kern}(\\{main\_f})(\\{main\_j})));\5
+\&{goto} \\{main\_loop\_move};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_l}\E\\{non\_char}){}$\1\5
+${}\\{lft\_hit}\K\\{true};{}$\2\6
+\&{else} \&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\5
+${}\\{rt\_hit}\K\\{true};{}$\2\6
+\\{check\_interrupt};\C{allow a way out in case there's an infinite ligature loop}\6
+\&{switch} (\\{op\_byte}(\\{main\_j}))\5
+${}\{{}$\1\6
+\4\\{qi}(\&{case} \T{1}):\5
+\\{qi}(\&{case} \T{5}):\6
+${}\{{}$\5
+\1${}\\{cur\_l}\K\\{rem\_byte}(\\{main\_j}){}$;\C{\.{=:\?}, \.{=:\?>}}\6
+${}\\{main\_i}\K\\{char\_info}(\\{main\_f})(\\{cur\_l});{}$\5
+${}\\{ligature\_present}\K\\{true};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{2}):\5
+\\{qi}(\&{case} \T{6}):\6
+${}\{{}$\5
+\1${}\\{cur\_r}\K\\{rem\_byte}(\\{main\_j}){}$;\C{\.{\?=:}, \.{\?=:>}}\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}{}$)\C{right boundary character is being consumed}\6
+${}\{{}$\5
+\1${}\\{lig\_stack}\K\\{new\_lig\_item}(\\{cur\_r});{}$\5
+${}\\{bchar}\K\\{non\_char};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} (\\{is\_char\_node}(\\{lig\_stack}))\C{$\\{link}(\\{lig\_stack})\E\\{null}$}\6
+${}\{{}$\5
+\1${}\\{main\_p}\K\\{lig\_stack};{}$\5
+${}\\{lig\_stack}\K\\{new\_lig\_item}(\\{cur\_r});{}$\5
+${}\\{lig\_ptr}(\\{lig\_stack})\K\\{main\_p};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{character}(\\{lig\_stack})\K\\{cur\_r};{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{3}):\6
+${}\{{}$\5
+\1${}\\{cur\_r}\K\\{rem\_byte}(\\{main\_j}){}$;\C{\.{\?=:\?}}\6
+${}\\{main\_p}\K\\{lig\_stack};{}$\5
+${}\\{lig\_stack}\K\\{new\_lig\_item}(\\{cur\_r});{}$\5
+${}\\{link}(\\{lig\_stack})\K\\{main\_p};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{qi}(\&{case} \T{7}):\5
+\\{qi}(\&{case} \T{11}):\6
+${}\{{}$\5
+\1\\{wrapup}(\\{false});\C{\.{\?=:\?>}, \.{\?=:\?>>}}\6
+${}\\{cur\_q}\K\\{tail};{}$\5
+${}\\{cur\_l}\K\\{rem\_byte}(\\{main\_j});{}$\5
+${}\\{main\_i}\K\\{char\_info}(\\{main\_f})(\\{cur\_l});{}$\5
+${}\\{ligature\_present}\K\\{true};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1${}\\{cur\_l}\K\\{rem\_byte}(\\{main\_j});{}$\5
+${}\\{ligature\_present}\K\\{true}{}$;\C{\.{=:}}\6
+\&{if} ${}(\\{lig\_stack}\E\\{null}){}$\1\5
+\&{goto} \\{main\_loop\_wrapup};\2\6
+\&{else}\1\5
+\&{goto} \\{main\_loop\_move1};\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{op\_byte}(\\{main\_j})>\\{qi}(\T{4})){}$\1\6
+\&{if} ${}(\\{op\_byte}(\\{main\_j})\I\\{qi}(\T{7})){}$\1\5
+\&{goto} \\{main\_loop\_wrapup};\2\2\6
+\&{if} ${}(\\{cur\_l}<\\{non\_char}){}$\1\5
+\&{goto} \\{main\_lig\_loop};\2\6
+${}\\{main\_k}\K\\{bchar\_label}[\\{main\_f}];{}$\5
+\&{goto} \\{main\_lig\_loop1};\6
+\4${}\}{}$\2\par
+\U1039.\fi
+
+\M{1041}The occurrence of blank spaces is almost part of \TeX's inner loop,
+since we usually encounter about one space for every five non-blank characters.
+Therefore \\{main\_control} gives second-highest priority to ordinary spaces.
+
+When a glue parameter like \.{\\spaceskip} is set to `\.{0pt}', we will
+see to it later that the corresponding glue specification is precisely
+\\{zero\_glue}, not merely a pointer to some specification that happens
+to be full of zeroes. Therefore it is simple to test whether a glue parameter
+is zero or~not.
+
+\Y\B\4\X1041:Append a normal inter-word space to the current list, then \&{goto} \\{big\_switch}\X${}\E{}$\6
+\&{if} ${}(\\{space\_skip}\E\\{zero\_glue}){}$\5
+${}\{{}$\5
+\1\X1042:Find the glue specification, \\{main\_p}, for text spaces in the current font\X;\6
+${}\\{temp\_ptr}\K\\{new\_glue}(\\{main\_p});{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{temp\_ptr}\K\\{new\_param\_glue}(\\{space\_skip\_code});{}$\2\6
+${}\\{link}(\\{tail})\K\\{temp\_ptr};{}$\5
+${}\\{tail}\K\\{temp\_ptr};$ \&{goto} \\{big\_switch}\par
+\U1030.\fi
+
+\M{1042}Having \\{font\_glue} allocated for each text font saves both time and memory.
+If any of the three spacing parameters are subsequently changed by the
+use of \.{\\fontdimen}, the \\{find\_font\_dimen} procedure deallocates the
+\\{font\_glue} specification allocated here.
+
+\Y\B\4\X1042:Find the glue specification, \\{main\_p}, for text spaces in the current font\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{main\_p}\K\\{font\_glue}[\\{cur\_font}];{}$\6
+\&{if} ${}(\\{main\_p}\E\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{main\_p}\K\\{new\_spec}(\\{zero\_glue});{}$\5
+${}\\{main\_k}\K\\{param\_base}[\\{cur\_font}]+\\{space\_code};{}$\5
+${}\\{width}(\\{main\_p})\K\\{font\_info}[\\{main\_k}].\\{sc}{}$;\C{that's \\{space}(\\{cur\_font})}\6
+${}\\{stretch}(\\{main\_p})\K\\{font\_info}[\\{main\_k}+\T{1}].\\{sc}{}$;\C{and \\{space\_stretch}(\\{cur\_font})}\6
+${}\\{shrink}(\\{main\_p})\K\\{font\_info}[\\{main\_k}+\T{2}].\\{sc}{}$;\C{and \\{space\_shrink}(\\{cur\_font})}\6
+${}\\{font\_glue}[\\{cur\_font}]\K\\{main\_p};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\Us1041\ET1043.\fi
+
+\M{1043}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\E{}$\6
+\&{void} \\{app\_space}(\&{void})\C{handle spaces when $\\{space\_factor}\I\T{1000}$}\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{glue node}\7
+\&{if} ${}((\\{space\_factor}\G\T{2000})\W(\\{xspace\_skip}\I\\{zero\_glue})){}$\1\5
+${}\|q\K\\{new\_param\_glue}(\\{xspace\_skip\_code});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{space\_skip}\I\\{zero\_glue}){}$\1\5
+${}\\{main\_p}\K\\{space\_skip};{}$\2\6
+\&{else}\1\5
+\X1042:Find the glue specification, \\{main\_p}, for text spaces in the current font\X;\2\6
+${}\\{main\_p}\K\\{new\_spec}(\\{main\_p});{}$\5
+\X1044:Modify the glue specification in \\{main\_p} according to the space factor\X;\6
+${}\|q\K\\{new\_glue}(\\{main\_p});{}$\5
+${}\\{glue\_ref\_count}(\\{main\_p})\K\\{null};{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\|q;{}$\5
+${}\\{tail}\K\|q;{}$\6
+\4${}\}{}$\2\par
+\As1047, 1049, 1050, 1051, 1054, 1060, 1061, 1064, 1069, 1070, 1075, 1079, 1084, 1086, 1091, 1093, 1095, 1096, 1099, 1101, 1103, 1105, 1110, 1113, 1117, 1119, 1123, 1127, 1129, 1131, 1135, 1136, 1138, 1142, 1151, 1155, 1159, 1160, 1163, 1165, 1172, 1174,
+1176, 1181, 1191, 1194, 1200, 1211, 1270, 1275, 1279, 1288, 1293, 1302, 1348\ETs1376.
+\U1030.\fi
+
+\M{1044}\B\X1044:Modify the glue specification in \\{main\_p} according to the space factor\X${}\E{}$\6
+\&{if} ${}(\\{space\_factor}\G\T{2000}){}$\1\5
+${}\\{width}(\\{main\_p})\K\\{width}(\\{main\_p})+\\{extra\_space}(\\{cur\_font});{}$\2\6
+${}\\{stretch}(\\{main\_p})\K\\{xn\_over\_d}(\\{stretch}(\\{main\_p}),\39\\{space\_factor},\39\T{1000});$ $\\{shrink}(\\{main\_p})\K\\{xn\_over\_d}(\\{shrink}(\\{main\_p}),\39\T{1000},\39\\{space\_factor}{}$)\par
+\U1043.\fi
+
+\M{1045}Whew---that covers the main loop. We can now proceed at a leisurely
+pace through the other combinations of possibilities.
+
+\Y\B\4\D$\\{any\_mode}(\|X)$ \5
+\&{case} \\{vmode}${}+\|X{}$:\5
+\&{case} \\{hmode}${}+\|X{}$: \&{case} \\{mmode}${}+{}$\|X\C{for mode-independent commands}\par
+\Y\B\4\X1045:Cases of \\{main\_control} that are not part of the inner loop\X${}\E{}$\6
+\4\\{any\_mode}(\\{relax}):\5
+\&{case} \\{vmode}${}+\\{spacer}{}$:\5
+\&{case} \\{mmode}${}+\\{spacer}{}$:\5
+\&{case} \\{mmode}${}+\\{no\_boundary}{}$:\5
+\\{do\_nothing};\6
+\4\\{any\_mode}(\\{ignore\_spaces}):\6
+${}\{{}$\5
+\1\X406:Get the next non-blank non-call token\X;\6
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{vmode}${}+\\{stop}{}$:\6
+\&{if} (\\{its\_all\_over}(\,))\1\5
+\&{return};\5
+\2\&{break};\C{this is the only way out}\6
+\4\hbox{\4}\X1048:Forbidden cases detected in \\{main\_control}\X\5
+\,\\{any\_mode}(\\{mac\_param}):\5
+\\{report\_illegal\_case}(\,);\5
+\&{break};\6
+\4\X1046:Math-only cases in non-math modes, or vice versa\X:\5
+\\{insert\_dollar\_sign}(\,);\5
+\&{break};\5
+\hbox{\4}\X1056:Cases of \\{main\_control} that build boxes and lists\X\6
+\hbox{\4}\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X\6
+\hbox{\4}\X1347:Cases of \\{main\_control} that are for extensions to \TeX\X\par
+\U1030.\fi
+
+\M{1046}Here is a list of cases where the user has probably gotten into or out of math
+mode by mistake. \TeX\ will insert a dollar sign and rescan the current token.
+
+\Y\B\4\D$\\{non\_math}(\|X)$ \5
+\&{case} \\{vmode}${}+\|X{}$: \&{case} \\{hmode}${}+{}$\|X\par
+\Y\B\4\X1046:Math-only cases in non-math modes, or vice versa\X${}\E{}$\6
+\\{non\_math}(\\{sup\_mark}):\5
+\\{non\_math}(\\{sub\_mark}):\5
+\\{non\_math}(\\{math\_char\_num}):\5
+\\{non\_math}(\\{math\_given}):\5
+\\{non\_math}(\\{math\_comp}):\5
+\\{non\_math}(\\{delim\_num}):\5
+\\{non\_math}(\\{left\_right}):\5
+\\{non\_math}(\\{above}):\5
+\\{non\_math}(\\{radical}):\5
+\\{non\_math}(\\{math\_style}):\5
+\\{non\_math}(\\{math\_choice}):\5
+\\{non\_math}(\\{vcenter}):\5
+\\{non\_math}(\\{non\_script}):\5
+\\{non\_math}(\\{mkern}):\5
+\\{non\_math}(\\{limit\_switch}):\5
+\\{non\_math}(\\{mskip}):\5
+\\{non\_math}(\\{math\_accent}):\5
+\&{case} \\{mmode}${}+\\{endv}{}$:\5
+\&{case} \\{mmode}${}+\\{par\_end}{}$:\5
+\&{case} \\{mmode}${}+\\{stop}{}$:\5
+\&{case} \\{mmode}${}+\\{vskip}{}$:\5
+\&{case} \\{mmode}${}+\\{un\_vbox}{}$:\5
+\&{case} \\{mmode}${}+\\{valign}{}$: \&{case} \\{mmode}${}+{}$\\{hrule}\par
+\U1045.\fi
+
+\M{1047}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{insert\_dollar\_sign}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\\{math\_shift\_token}+\.{'\$'};{}$\5
+\\{print\_err}(\.{"Missing\ \$\ inserted"});\5
+\\{help2}(\.{"I've\ inserted\ a\ beg}\)\.{in-math/end-math\ sym}\)\.{bol\ since\ I\ think"})\6
+(\.{"you\ left\ one\ out.\ P}\)\.{roceed,\ with\ fingers}\)\.{\ crossed."});\5
+\\{ins\_error}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1048}When erroneous situations arise, \TeX\ usually issues an error message
+specific to the particular error. For example, `\.{\\noalign}' should
+not appear in any mode, since it is recognized by the \\{align\_peek} routine
+in all of its legitimate appearances; a special error message is given
+when `\.{\\noalign}' occurs elsewhere. But sometimes the most appropriate
+error message is simply that the user is not allowed to do what he or she
+has attempted. For example, `\.{\\moveleft}' is allowed only in vertical mode,
+and `\.{\\lower}' only in non-vertical modes. Such cases are enumerated
+here and in the other sections referred to under `See also \dots.'
+
+\Y\B\4\X1048:Forbidden cases detected in \\{main\_control}\X${}\E{}$\6
+\&{case} \\{vmode}${}+\\{vmove}{}$:\5
+\&{case} \\{hmode}${}+\\{hmove}{}$:\5
+\&{case} \\{mmode}${}+\\{hmove}{}$:\5
+\\{any\_mode}(\\{last\_item}):\par
+\As1098, 1111\ETs1144.
+\U1045.\fi
+
+\M{1049}The `\\{you\_cant}' procedure prints a line saying that the current command
+is illegal in the current mode; it identifies these things symbolically.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{you\_cant}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ `"});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_str}(\.{"'\ in\ "});\5
+\\{print\_mode}(\\{mode});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1050}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{report\_illegal\_case}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{you\_cant}(\,);\5
+\\{help4}(\.{"Sorry,\ but\ I'm\ not\ }\)\.{programmed\ to\ handle}\)\.{\ this\ case;"})\6
+(\.{"I'll\ just\ pretend\ t}\)\.{hat\ you\ didn't\ ask\ f}\)\.{or\ it."})\6
+(\.{"If\ you're\ in\ the\ wr}\)\.{ong\ mode,\ you\ might\ }\)\.{be\ able\ to"})\6
+(\.{"return\ to\ the\ right}\)\.{\ one\ by\ typing\ `I\}'\ }\)\.{or\ `I\$'\ or\ `I\\\\par'.}\)\.{"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1051}Some operations are allowed only in privileged modes, i.e., in cases
+that $\\{mode}>\T{0}$. The \\{privileged} function is used to detect violations
+of this rule; it issues an error message and returns \\{false} if the
+current \\{mode} is negative.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{bool} \\{privileged}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{mode}>\T{0}){}$\1\5
+\&{return} \\{true};\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{report\_illegal\_case}(\,);\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1052}Either \.{\\dump} or \.{\\end} will cause \\{main\_control} to enter the
+endgame, since both of them have `\\{stop}' as their command code.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1698:\.{"end"}\X,\39\\{stop},\39\T{0}){}$;\6
+${}\\{primitive}(\X1699:\.{"dump"}\X,\39\\{stop},\39\T{1}){}$;\par
+\fi
+
+\M{1053}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{stop}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1699:\.{"dump"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1698:\.{"end"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1054}We don't want to leave \\{main\_control} immediately when a \\{stop} command
+is sensed, because it may be necessary to invoke an \.{\\output} routine
+several times before things really grind to a halt. (The output routine
+might even say `\.{\\gdef\\end\{...\}}', to prolong the life of the job.)
+Therefore \\{its\_all\_over} is \\{true} only when the current page
+and contribution list are empty, and when the last output was not a
+``dead cycle.''
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{bool} \\{its\_all\_over}(\&{void})\C{do this when \.{\\end} or \.{\\dump} occurs}\6
+${}\{{}$\5
+\1\&{if} (\\{privileged}(\,))\5
+${}\{{}$\5
+\1\&{if} ${}((\\{page\_head}\E\\{page\_tail})\W(\\{head}\E\\{tail})\W(\\{dead\_cycles}\E\T{0})){}$\5
+${}\{{}$\5
+\1\&{return} \\{true};\6
+\4${}\}{}$\2\6
+\\{back\_input}(\,);\C{we will try to end again after ejecting residual material}\6
+\\{tail\_append}(\\{new\_null\_box}(\,));\5
+${}\\{width}(\\{tail})\K\\{hsize};{}$\5
+\\{tail\_append}(\\{new\_glue}(\\{fill\_glue}));\5
+${}\\{tail\_append}(\\{new\_penalty}({-}\T{\~10000000000})){}$;\6
+\\{build\_page}(\,);\C{append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000}}\6
+\4${}\}{}$\2\6
+\&{return} \\{false};\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{1055}Building boxes and lists.
+The most important parts of \\{main\_control} are concerned with \TeX's
+chief mission of box-making. We need to control the activities that put
+entries on vlists and hlists, as well as the activities that convert
+those lists into boxes. All of the necessary machinery has already been
+developed; it remains for us to ``push the buttons'' at the right times.
+
+\fi
+
+\M{1056}As an introduction to these routines, let's consider one of the simplest
+cases: What happens when `\.{\\hrule}' occurs in vertical mode, or
+`\.{\\vrule}' in horizontal mode or math mode? The code in \\{main\_control}
+is short, since the \\{scan\_rule\_spec} routine already does most of what is
+required; thus, there is no need for a special action procedure.
+
+Note that baselineskip calculations are disabled after a rule in vertical
+mode, by setting $\\{prev\_depth}\K\\{ignore\_depth}$.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\E{}$\6
+\4\&{case} \\{vmode}${}+\\{hrule}{}$:\5
+\&{case} \\{hmode}${}+\\{vrule}{}$:\5
+\&{case} \\{mmode}${}+\\{vrule}{}$:\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{scan\_rule\_spec}(\,));\6
+\&{if} ${}(\\{abs}(\\{mode})\E\\{vmode}){}$\1\5
+${}\\{prev\_depth}\K\\{ignore\_depth};{}$\2\6
+\&{else} \&{if} ${}(\\{abs}(\\{mode})\E\\{hmode}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\As1057, 1063, 1067, 1073, 1090, 1092, 1094, 1097, 1102, 1104, 1109, 1112, 1116, 1122, 1126, 1130, 1134, 1137, 1140, 1150, 1154, 1158, 1162, 1164, 1167, 1171, 1175, 1180, 1190\ETs1193.
+\U1045.\fi
+
+\M{1057}The processing of things like \.{\\hskip} and \.{\\vskip} is slightly
+more complicated. But the code in \\{main\_control} is very short, since
+it simply calls on the action routine \\{append\_glue}. Similarly, \.{\\kern}
+activates \\{append\_kern}.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{vskip}{}$:\5
+\&{case} \\{hmode}${}+\\{hskip}{}$:\5
+\&{case} \\{mmode}${}+\\{hskip}{}$:\5
+\&{case} \\{mmode}${}+\\{mskip}{}$:\5
+\\{append\_glue}(\,);\5
+\&{break};\6
+\4\\{any\_mode}(\\{kern}):\5
+\&{case} \\{mmode}${}+\\{mkern}{}$:\5
+\\{append\_kern}(\,);\5
+\&{break};\par
+\fi
+
+\M{1058}The \\{hskip} and \\{vskip} command codes are used for control sequences
+like \.{\\hss} and \.{\\vfil} as well as for \.{\\hskip} and \.{\\vskip}.
+The difference is in the value of \\{cur\_chr}.
+
+\Y\B\4\D$\\{fil\_code}$ \5
+\T{0}\C{identifies \.{\\hfil} and \.{\\vfil}}\par
+\B\4\D$\\{fill\_code}$ \5
+\T{1}\C{identifies \.{\\hfill} and \.{\\vfill}}\par
+\B\4\D$\\{ss\_code}$ \5
+\T{2}\C{identifies \.{\\hss} and \.{\\vss}}\par
+\B\4\D$\\{fil\_neg\_code}$ \5
+\T{3}\C{identifies \.{\\hfilneg} and \.{\\vfilneg}}\par
+\B\4\D$\\{skip\_code}$ \5
+\T{4}\C{identifies \.{\\hskip} and \.{\\vskip}}\par
+\B\4\D$\\{mskip\_code}$ \5
+\T{5}\C{identifies \.{\\mskip}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1700:\.{"hskip"}\X,\39\\{hskip},\39\\{skip\_code}){}$;\6
+${}\\{primitive}(\X1701:\.{"hfil"}\X,\39\\{hskip},\39\\{fil\_code});{}$\5
+${}\\{primitive}(\X1702:\.{"hfill"}\X,\39\\{hskip},\39\\{fill\_code}){}$;\6
+${}\\{primitive}(\X1703:\.{"hss"}\X,\39\\{hskip},\39\\{ss\_code});{}$\5
+${}\\{primitive}(\X1704:\.{"hfilneg"}\X,\39\\{hskip},\39\\{fil\_neg\_code}){}$;\6
+${}\\{primitive}(\X1705:\.{"vskip"}\X,\39\\{vskip},\39\\{skip\_code}){}$;\6
+${}\\{primitive}(\X1706:\.{"vfil"}\X,\39\\{vskip},\39\\{fil\_code});{}$\5
+${}\\{primitive}(\X1707:\.{"vfill"}\X,\39\\{vskip},\39\\{fill\_code}){}$;\6
+${}\\{primitive}(\X1708:\.{"vss"}\X,\39\\{vskip},\39\\{ss\_code});{}$\5
+${}\\{primitive}(\X1709:\.{"vfilneg"}\X,\39\\{vskip},\39\\{fil\_neg\_code}){}$;\6
+${}\\{primitive}(\X1393:\.{"mskip"}\X,\39\\{mskip},\39\\{mskip\_code}){}$;\6
+${}\\{primitive}(\X1396:\.{"kern"}\X,\39\\{kern},\39\&{explicit});{}$\5
+${}\\{primitive}(\X1397:\.{"mkern"}\X,\39\\{mkern},\39\\{mu\_glue}){}$;\par
+\fi
+
+\M{1059}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hskip}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{skip\_code}:\5
+\\{print\_esc}(\X1700:\.{"hskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{fil\_code}:\5
+\\{print\_esc}(\X1701:\.{"hfil"}\X);\5
+\&{break};\6
+\4\&{case} \\{fill\_code}:\5
+\\{print\_esc}(\X1702:\.{"hfill"}\X);\5
+\&{break};\6
+\4\&{case} \\{ss\_code}:\5
+\\{print\_esc}(\X1703:\.{"hss"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1704:\.{"hfilneg"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{vskip}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{skip\_code}:\5
+\\{print\_esc}(\X1705:\.{"vskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{fil\_code}:\5
+\\{print\_esc}(\X1706:\.{"vfil"}\X);\5
+\&{break};\6
+\4\&{case} \\{fill\_code}:\5
+\\{print\_esc}(\X1707:\.{"vfill"}\X);\5
+\&{break};\6
+\4\&{case} \\{ss\_code}:\5
+\\{print\_esc}(\X1708:\.{"vss"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1709:\.{"vfilneg"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mskip}:\5
+\\{print\_esc}(\X1393:\.{"mskip"}\X);\5
+\&{break};\6
+\4\&{case} \\{kern}:\5
+\\{print\_esc}(\X1396:\.{"kern"}\X);\5
+\&{break};\6
+\4\&{case} \\{mkern}:\5
+\\{print\_esc}(\X1397:\.{"mkern"}\X);\5
+\&{break};\par
+\fi
+
+\M{1060}All the work relating to glue creation has been relegated to the
+following subroutine. It does not call \\{build\_page}, because it is
+used in at least one place where that would be a mistake.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_glue}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|s;\C{modifier of skip command}\7
+${}\|s\K\\{cur\_chr};{}$\6
+\&{switch} (\|s)\5
+${}\{{}$\1\6
+\4\&{case} \\{fil\_code}:\5
+${}\\{cur\_val}\K\\{fil\_glue}{}$;\5
+\&{break};\6
+\4\&{case} \\{fill\_code}:\5
+${}\\{cur\_val}\K\\{fill\_glue}{}$;\5
+\&{break};\6
+\4\&{case} \\{ss\_code}:\5
+${}\\{cur\_val}\K\\{ss\_glue}{}$;\5
+\&{break};\6
+\4\&{case} \\{fil\_neg\_code}:\5
+${}\\{cur\_val}\K\\{fil\_neg\_glue}{}$;\5
+\&{break};\6
+\4\&{case} \\{skip\_code}:\5
+\\{scan\_glue}(\\{glue\_val});\5
+\&{break};\6
+\4\&{case} \\{mskip\_code}:\5
+\\{scan\_glue}(\\{mu\_val});\6
+\4${}\}{}$\C{now \\{cur\_val} points to the glue specification}\2\6
+\\{tail\_append}(\\{new\_glue}(\\{cur\_val}));\6
+\&{if} ${}(\|s\G\\{skip\_code}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{glue\_ref\_count}(\\{cur\_val}));\6
+\&{if} ${}(\|s>\\{skip\_code}){}$\1\5
+${}\\{subtype}(\\{tail})\K\\{mu\_glue};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1061}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_kern}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{quarterword} \|s;\C{\\{subtype} of the kern node}\7
+${}\|s\K\\{cur\_chr};{}$\5
+${}\\{scan\_dimen}(\|s\E\\{mu\_glue},\39\\{false},\39\\{false});{}$\5
+\\{tail\_append}(\\{new\_kern}(\\{cur\_val}));\5
+${}\\{subtype}(\\{tail})\K\|s;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1062}Many of the actions related to box-making are triggered by the appearance
+of braces in the input. For example, when the user says `\.{\\hbox}
+\.{to} \.{100pt\{$\langle\,\hbox{hlist}\,\rangle$\}}' in vertical mode,
+the information about the box size (100pt, \\{exactly}) is put onto \\{save\_stack}
+with a level boundary word just above it, and $\\{cur\_group}\K\\{adjusted\_hbox\_group}$;
+\TeX\ enters restricted horizontal mode to process the hlist. The right
+brace eventually causes \\{save\_stack} to be restored to its former state,
+at which time the information about the box size (100pt, \\{exactly}) is
+available once again; a box is packaged and we leave restricted horizontal
+mode, appending the new box to the current list of the enclosing mode
+(in this case to the current list of vertical mode), followed by any
+vertical adjustments that were removed from the box by \\{hpack}.
+
+The next few sections of the program are therefore concerned with the
+treatment of left and right curly braces.
+
+\fi
+
+\M{1063}If a left brace occurs in the middle of a page or paragraph, it simply
+introduces a new level of grouping, and the matching right brace will not have
+such a drastic effect. Such grouping affects neither the mode nor the
+current list.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{non\_math}(\\{left\_brace}):\5
+\\{new\_save\_level}(\\{simple\_group});\5
+\&{break};\6
+\4\\{any\_mode}(\\{begin\_group}):\5
+\\{new\_save\_level}(\\{semi\_simple\_group});\5
+\&{break};\6
+\4\\{any\_mode}(\\{end\_group}):\6
+\&{if} ${}(\\{cur\_group}\E\\{semi\_simple\_group}){}$\1\5
+\\{unsave}(\,);\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\5
+\2\&{break};\par
+\fi
+
+\M{1064}We have to deal with errors in which braces and such things are not
+properly nested. Sometimes the user makes an error of commission by
+inserting an extra symbol, but sometimes the user makes an error of omission.
+\TeX\ can't always tell one from the other, so it makes a guess and tries
+to avoid getting into a loop.
+
+The \\{off\_save} routine is called when the current group code is wrong. It tries
+to insert something into the user's input that will help clean off
+the top level.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{off\_save}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{inserted token}\7
+\&{if} ${}(\\{cur\_group}\E\\{bottom\_level}){}$\1\5
+\X1066:Drop current token and complain that it was unmatched\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\|p\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\\{temp\_head})\K\|p;{}$\5
+\\{print\_err}(\.{"Missing\ "});\5
+\X1065:Prepare to insert a token that matches \\{cur\_group}, and print what it is\X;\6
+\\{print\_str}(\.{"\ inserted"});\5
+\\{ins\_list}(\\{link}(\\{temp\_head}));\5
+\\{help5}(\.{"I've\ inserted\ somet}\)\.{hing\ that\ you\ may\ ha}\)\.{ve\ forgotten."})\6
+(\.{"(See\ the\ <inserted\ }\)\.{text>\ above.)"})\6
+(\.{"With\ luck,\ this\ wil}\)\.{l\ get\ me\ unwedged.\ B}\)\.{ut\ if\ you"})\6
+(\.{"really\ didn't\ forge}\)\.{t\ anything,\ try\ typi}\)\.{ng\ `2'\ now;\ then"})\6
+(\.{"my\ insertion\ and\ my}\)\.{\ current\ dilemma\ wil}\)\.{l\ both\ disappear."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1065}At this point, $\\{link}(\\{temp\_head})\E\|p$, a pointer to an empty one-word node.
+
+\Y\B\4\X1065:Prepare to insert a token that matches \\{cur\_group}, and print what it is\X${}\E{}$\6
+\&{switch} (\\{cur\_group})\5
+${}\{{}$\1\6
+\4\&{case} \\{semi\_simple\_group}:\6
+${}\{{}$\5
+\1${}\\{info}(\|p)\K\\{cs\_token\_flag}+\\{frozen\_end\_group};{}$\5
+\\{print\_esc}(\X1538:\.{"endgroup"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{math\_shift\_group}:\6
+${}\{{}$\5
+\1${}\\{info}(\|p)\K\\{math\_shift\_token}+\.{'\$'};{}$\5
+\\{print\_char}(\.{'\$'});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{math\_left\_group}:\6
+${}\{{}$\5
+\1${}\\{info}(\|p)\K\\{cs\_token\_flag}+\\{frozen\_right};{}$\5
+${}\\{link}(\|p)\K\\{get\_avail}(\,);{}$\5
+${}\|p\K\\{link}(\|p);{}$\5
+${}\\{info}(\|p)\K\\{other\_token}+\.{'.'};{}$\5
+\\{print\_esc}(\X1710:\.{"right."}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\6
+${}\{{}$\5
+\1${}\\{info}(\|p)\K\\{right\_brace\_token}+\.{'\}'};{}$\5
+\\{print\_char}(\.{'\}'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1064.\fi
+
+\M{1066}\B\X1066:Drop current token and complain that it was unmatched\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Extra\ "});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{help1}(\.{"Things\ are\ pretty\ m}\)\.{ixed\ up,\ but\ I\ think}\)\.{\ the\ worst\ is\ over."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1064.\fi
+
+\M{1067}The routine for a \\{right\_brace} character branches into many subcases,
+since a variety of things may happen, depending on \\{cur\_group}. Some
+types of groups are not supposed to be ended by a right brace; error
+messages are given in hopes of pinpointing the problem. Most branches
+of this routine will be filled in later, when we are ready to understand
+them; meanwhile, we must prepare ourselves to deal with such errors.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{right\_brace}):\5
+\\{handle\_right\_brace}(\,);\5
+\&{break};\par
+\fi
+
+\M{1068}\B\X1068:Declare the procedure called \\{handle\_right\_brace}\X${}\E{}$\6
+\&{void} \\{handle\_right\_brace}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\C{for short-term use}\6
+\&{scaled} \|d;\C{holds \\{split\_max\_depth} in \\{insert\_group}}\6
+\&{int} \|f;\C{holds \\{floating\_penalty} in \\{insert\_group}}\7
+\&{switch} (\\{cur\_group})\5
+${}\{{}$\1\6
+\4\&{case} \\{simple\_group}:\5
+\\{unsave}(\,);\5
+\&{break};\6
+\4\&{case} \\{bottom\_level}:\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Too\ many\ \}'s"});\5
+\\{help2}(\.{"You've\ closed\ more\ }\)\.{groups\ than\ you\ open}\)\.{ed."})\6
+(\.{"Such\ booboos\ are\ ge}\)\.{nerally\ harmless,\ so}\)\.{\ keep\ going."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{semi\_simple\_group}:\5
+\&{case} \\{math\_shift\_group}:\5
+\&{case} \\{math\_left\_group}:\5
+\\{extra\_right\_brace}(\,);\5
+\&{break};\5
+\hbox{\4}\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X\6
+\4\&{default}:\5
+\\{confusion}(\X1711:\.{"rightbrace"}\X);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1030.\fi
+
+\M{1069}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{extra\_right\_brace}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Extra\ \},\ or\ forgott}\)\.{en\ "});\6
+\&{switch} (\\{cur\_group})\5
+${}\{{}$\1\6
+\4\&{case} \\{semi\_simple\_group}:\5
+\\{print\_esc}(\X1538:\.{"endgroup"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_shift\_group}:\5
+\\{print\_char}(\.{'\$'});\5
+\&{break};\6
+\4\&{case} \\{math\_left\_group}:\5
+\\{print\_esc}(\X1660:\.{"right"}\X);\6
+\4${}\}{}$\2\6
+\\{help5}(\.{"I've\ deleted\ a\ grou}\)\.{p-closing\ symbol\ bec}\)\.{ause\ it\ seems\ to\ be"})\6
+(\.{"spurious,\ as\ in\ `\$x}\)\.{\}\$'.\ But\ perhaps\ the}\)\.{\ \}\ is\ legitimate\ and}\)\.{"})\6
+(\.{"you\ forgot\ somethin}\)\.{g\ else,\ as\ in\ `\\\\hbo}\)\.{x\{\$x\}'.\ In\ such\ case}\)\.{s"})\6
+(\.{"the\ way\ to\ recover\ }\)\.{is\ to\ insert\ both\ th}\)\.{e\ forgotten\ and\ the"})\6
+(\.{"deleted\ material,\ e}\)\.{.g.,\ by\ typing\ `I\$\}'}\)\.{."});\6
+\&{error} (\,)\1\5
+;\2\6
+\\{incr}(\\{align\_state});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1070}Here is where we clear the parameters that are supposed to revert to their
+default values after every paragraph and when internal vertical mode is entered.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{normal\_paragraph}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{looseness}\I\T{0}){}$\1\5
+${}\\{eq\_word\_define}(\\{int\_base}+\\{looseness\_code},\39\T{0});{}$\2\6
+\&{if} ${}(\\{hang\_indent}\I\T{0}){}$\1\5
+${}\\{eq\_word\_define}(\\{dimen\_base}+\\{hang\_indent\_code},\39\T{0});{}$\2\6
+\&{if} ${}(\\{hang\_after}\I\T{1}){}$\1\5
+${}\\{eq\_word\_define}(\\{int\_base}+\\{hang\_after\_code},\39\T{1});{}$\2\6
+\&{if} ${}(\\{par\_shape\_ptr}\I\\{null}){}$\1\5
+${}\\{eq\_define}(\\{par\_shape\_loc},\39\\{shape\_ref},\39\\{null});{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1071}Now let's turn to the question of how \.{\\hbox} is treated. We actually
+need to consider also a slightly larger context, since constructions like
+`\.{\\setbox3=}\penalty0\.{\\hbox...}' and
+`\.{\\leaders}\penalty0\.{\\hbox...}' and
+`\.{\\lower3.8pt\\hbox...}'
+are supposed to invoke quite
+different actions after the box has been packaged. Conversely,
+constructions like `\.{\\setbox3=}' can be followed by a variety of
+different kinds of boxes, and we would like to encode such things in an
+efficient way.
+
+In other words, there are two problems: to represent the context of a box,
+and to represent its type.
+
+The first problem is solved by putting a ``context code'' on the \\{save\_stack},
+just below the two entries that give the dimensions produced by \\{scan\_spec}.
+The context code is either a (signed) shift amount, or it is a large
+integer $\G$ \\{box\_flag}, where \\{box\_flag} $\E\hbox{$2^{30}$}$. Codes \\{box\_flag} through
+$\\{box\_flag}+\T{255}$ represent `\.{\\setbox0}' through `\.{\\setbox255}';
+codes $\\{box\_flag}+\T{256}$ through $\\{box\_flag}+\T{511}$ represent `\.{\\global\\setbox0}'
+through `\.{\\global\\setbox255}';
+code $\\{box\_flag}+\T{512}$ represents `\.{\\shipout}'; and codes $\\{box\_flag}+\T{513}$
+through $\\{box\_flag}+\T{515}$ represent `\.{\\leaders}', `\.{\\cleaders}',
+and `\.{\\xleaders}'.
+
+The second problem is solved by giving the command code \\{make\_box} to all
+control sequences that produce a box, and by using the following \\{chr\_code}
+values to distinguish between them: \\{box\_code}, \\{copy\_code}, \\{last\_box\_code},
+\\{vsplit\_code}, \\{vtop\_code}, $\\{vtop\_code}+\\{vmode}$, and $\\{vtop\_code}+\\{hmode}$, where
+the latter two are used to denote \.{\\vbox} and \.{\\hbox}, respectively.
+
+\Y\B\4\D$\\{box\_flag}$ \5
+\T{\~10000000000}\C{context code for `\.{\\setbox0}'}\par
+\B\4\D$\\{ship\_out\_flag}$ \5
+$\\{box\_flag}+{}$\T{512}\C{context code for `\.{\\shipout}'}\par
+\B\4\D$\\{leader\_flag}$ \5
+$\\{box\_flag}+{}$\T{513}\C{context code for `\.{\\leaders}'}\par
+\B\4\D$\\{box\_code}$ \5
+\T{0}\C{\\{chr\_code} for `\.{\\box}'}\par
+\B\4\D$\\{copy\_code}$ \5
+\T{1}\C{\\{chr\_code} for `\.{\\copy}'}\par
+\B\4\D$\\{last\_box\_code}$ \5
+\T{2}\C{\\{chr\_code} for `\.{\\lastbox}'}\par
+\B\4\D$\\{vsplit\_code}$ \5
+\T{3}\C{\\{chr\_code} for `\.{\\vsplit}'}\par
+\B\4\D$\\{vtop\_code}$ \5
+\T{4}\C{\\{chr\_code} for `\.{\\vtop}'}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1712:\.{"moveleft"}\X,\39\\{hmove},\39\T{1});{}$\5
+${}\\{primitive}(\X1713:\.{"moveright"}\X,\39\\{hmove},\39\T{0}){}$;\6
+${}\\{primitive}(\X1714:\.{"raise"}\X,\39\\{vmove},\39\T{1});{}$\5
+${}\\{primitive}(\X1715:\.{"lower"}\X,\39\\{vmove},\39\T{0}){}$;\7
+${}\\{primitive}(\X1437:\.{"box"}\X,\39\\{make\_box},\39\\{box\_code});{}$\5
+${}\\{primitive}(\X1716:\.{"copy"}\X,\39\\{make\_box},\39\\{copy\_code});{}$\5
+${}\\{primitive}(\X1717:\.{"lastbox"}\X,\39\\{make\_box},\39\\{last\_box\_code});{}$\5
+${}\\{primitive}(\X1687:\.{"vsplit"}\X,\39\\{make\_box},\39\\{vsplit\_code});{}$\5
+${}\\{primitive}(\X1718:\.{"vtop"}\X,\39\\{make\_box},\39\\{vtop\_code}){}$;\6
+${}\\{primitive}(\X1688:\.{"vbox"}\X,\39\\{make\_box},\39\\{vtop\_code}+\\{vmode});{}$\5
+${}\\{primitive}(\X1719:\.{"hbox"}\X,\39\\{make\_box},\39\\{vtop\_code}+\\{hmode}){}$;\6
+${}\\{primitive}(\X1720:\.{"shipout"}\X,\39\\{leader\_ship},\39\\{a\_leaders}-\T{1}){}$;\C{$\\{ship\_out\_flag}\E\\{leader\_flag}-\T{1}$}\6
+${}\\{primitive}(\X1721:\.{"leaders"}\X,\39\\{leader\_ship},\39\\{a\_leaders});{}$\5
+${}\\{primitive}(\X1722:\.{"cleaders"}\X,\39\\{leader\_ship},\39\\{c\_leaders});{}$\5
+${}\\{primitive}(\X1723:\.{"xleaders"}\X,\39\\{leader\_ship},\39\\{x\_leaders}){}$;\par
+\fi
+
+\M{1072}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmove}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1712:\.{"moveleft"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1713:\.{"moveright"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{vmove}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1714:\.{"raise"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1715:\.{"lower"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{make\_box}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{box\_code}:\5
+\\{print\_esc}(\X1437:\.{"box"}\X);\5
+\&{break};\6
+\4\&{case} \\{copy\_code}:\5
+\\{print\_esc}(\X1716:\.{"copy"}\X);\5
+\&{break};\6
+\4\&{case} \\{last\_box\_code}:\5
+\\{print\_esc}(\X1717:\.{"lastbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{vsplit\_code}:\5
+\\{print\_esc}(\X1687:\.{"vsplit"}\X);\5
+\&{break};\6
+\4\&{case} \\{vtop\_code}:\5
+\\{print\_esc}(\X1718:\.{"vtop"}\X);\5
+\&{break};\6
+\4\&{case} \\{vtop\_code}${}+\\{vmode}{}$:\5
+\\{print\_esc}(\X1688:\.{"vbox"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1719:\.{"hbox"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{leader\_ship}:\6
+\&{if} ${}(\\{chr\_code}\E\\{a\_leaders}){}$\1\5
+\\{print\_esc}(\X1721:\.{"leaders"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{c\_leaders}){}$\1\5
+\\{print\_esc}(\X1722:\.{"cleaders"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{x\_leaders}){}$\1\5
+\\{print\_esc}(\X1723:\.{"xleaders"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1720:\.{"shipout"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1073}Constructions that require a box are started by calling \\{scan\_box} with
+a specified context code. The \\{scan\_box} routine verifies
+that a \\{make\_box} command comes next and then it calls \\{begin\_box}.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{hmove}{}$:\5
+\&{case} \\{hmode}${}+\\{vmove}{}$:\5
+\&{case} \\{mmode}${}+\\{vmove}{}$:\6
+${}\{{}$\5
+\1${}\|t\K\\{cur\_chr};{}$\5
+\\{scan\_normal\_dimen};\6
+\&{if} ${}(\|t\E\T{0}){}$\1\5
+\\{scan\_box}(\\{cur\_val});\5
+\2\&{else}\1\5
+${}\\{scan\_box}({-}\\{cur\_val});{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\\{any\_mode}(\\{leader\_ship}):\5
+${}\\{scan\_box}(\\{leader\_flag}-\\{a\_leaders}+\\{cur\_chr}){}$;\5
+\&{break};\6
+\4\\{any\_mode}(\\{make\_box}):\5
+\\{begin\_box}(\T{0});\5
+\&{break};\par
+\fi
+
+\M{1074}The global variable \\{cur\_box} will point to a newly made box. If the box
+is void, we will have $\\{cur\_box}\E\\{null}$. Otherwise we will have
+$\\{type}(\\{cur\_box})\E\\{hlist\_node}$ or \\{vlist\_node} or \\{rule\_node}; the \\{rule\_node}
+case can occur only with leaders.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{cur\_box};\C{box to be placed into its context}\par
+\fi
+
+\M{1075}The \\{box\_end} procedure does the right thing with \\{cur\_box}, if
+\\{box\_context} represents the context as explained above.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{box\_end}(\&{int} \\{box\_context})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{\\{ord\_noad} for new box in math mode}\7
+\&{if} ${}(\\{box\_context}<\\{box\_flag}){}$\1\5
+\X1076:Append box \\{cur\_box} to the current list, shifted by \\{box\_context}\X\2\6
+\&{else} \&{if} ${}(\\{box\_context}<\\{ship\_out\_flag}){}$\1\5
+\X1077:Store \(c)\\{cur\_box} in a box register\X;\2\6
+\&{else} \&{if} ${}(\\{cur\_box}\I\\{null}){}$\1\6
+\&{if} ${}(\\{box\_context}>\\{ship\_out\_flag}){}$\1\5
+\X1078:Append a new leader node that uses \\{cur\_box}\X\2\6
+\&{else}\1\5
+\\{ship\_out}(\\{cur\_box});\2\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1076}The global variable \\{adjust\_tail} will be non-null if and only if the
+current box might include adjustments that should be appended to the
+current vertical list.
+
+\Y\B\4\X1076:Append box \\{cur\_box} to the current list, shifted by \\{box\_context}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_box}\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\\{shift\_amount}(\\{cur\_box})\K\\{box\_context};{}$\6
+\&{if} ${}(\\{abs}(\\{mode})\E\\{vmode}){}$\5
+${}\{{}$\5
+\1\\{append\_to\_vlist}(\\{cur\_box});\6
+\&{if} ${}(\\{adjust\_tail}\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{adjust\_head}\I\\{adjust\_tail}){}$\5
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\\{link}(\\{adjust\_head});{}$\5
+${}\\{tail}\K\\{adjust\_tail};{}$\6
+\4${}\}{}$\2\6
+${}\\{adjust\_tail}\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{mode}>\T{0}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{abs}(\\{mode})\E\\{hmode}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_noad}(\,);{}$\5
+${}\\{math\_type}(\\{nucleus}(\|p))\K\\{sub\_box};{}$\5
+${}\\{info}(\\{nucleus}(\|p))\K\\{cur\_box};{}$\5
+${}\\{cur\_box}\K\|p;{}$\6
+\4${}\}{}$\2\6
+${}\\{link}(\\{tail})\K\\{cur\_box};{}$\5
+${}\\{tail}\K\\{cur\_box};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1075.\fi
+
+\M{1077}\B\X1077:Store \(c)\\{cur\_box} in a box register\X${}\E{}$\6
+\&{if} ${}(\\{box\_context}<\\{box\_flag}+\T{256}){}$\1\5
+${}\\{eq\_define}(\\{box\_base}-\\{box\_flag}+\\{box\_context},\39\\{box\_ref},\39\\{cur\_box});{}$\2\6
+\&{else} $\\{geq\_define}(\\{box\_base}-\\{box\_flag}-\T{256}+\\{box\_context},\39\\{box\_ref},\39\\{cur\_box}{}$)\par
+\U1075.\fi
+
+\M{1078}\B\X1078:Append a new leader node that uses \\{cur\_box}\X${}\E{}$\6
+${}\{{}$\5
+\1\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(((\\{cur\_cmd}\E\\{hskip})\W(\\{abs}(\\{mode})\I\\{vmode}))\V\30((\\{cur\_cmd}\E\\{vskip})\W(\\{abs}(\\{mode})\E\\{vmode}))){}$\5
+${}\{{}$\5
+\1\\{append\_glue}(\,);\5
+${}\\{subtype}(\\{tail})\K\\{box\_context}-(\\{leader\_flag}-\\{a\_leaders});{}$\5
+${}\\{leader\_ptr}(\\{tail})\K\\{cur\_box};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Leaders\ not\ followe}\)\.{d\ by\ proper\ glue"});\5
+\\{help3}(\.{"You\ should\ say\ `\\\\l}\)\.{eaders\ <box\ or\ rule>}\)\.{<hskip\ or\ vskip>'."})\6
+(\.{"I\ found\ the\ <box\ or}\)\.{\ rule>,\ but\ there's\ }\)\.{no\ suitable"})\6
+(\.{"<hskip\ or\ vskip>,\ s}\)\.{o\ I'm\ ignoring\ these}\)\.{\ leaders."});\5
+\\{back\_error}(\,);\5
+\\{flush\_node\_list}(\\{cur\_box});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1075.\fi
+
+\M{1079}Now that we can see what eventually happens to boxes, we can consider
+the first steps in their creation. The \\{begin\_box} routine is called when
+\\{box\_context} is a context specification, \\{cur\_chr} specifies the type of
+box desired, and $\\{cur\_cmd}\E\\{make\_box}$.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{begin\_box}(\&{int} \\{box\_context})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\C{run through the current list}\6
+\&{int} \|m;\C{the length of a replacement list}\6
+\&{halfword} \|k;\C{0 or \\{vmode} or \\{hmode}}\6
+\&{eight\_bits} \|n;\C{a box number}\7
+\&{switch} (\\{cur\_chr})\5
+${}\{{}$\1\6
+\4\&{case} \\{box\_code}:\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\\{cur\_box}\K\\{box}(\\{cur\_val});{}$\5
+${}\\{box}(\\{cur\_val})\K\\{null}{}$;\C{the box becomes void, at the same level}\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{copy\_code}:\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\\{cur\_box}\K\\{copy\_node\_list}(\\{box}(\\{cur\_val}));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{last\_box\_code}:\5
+\X1080:If the current list ends with a box node, delete it from the list and make \\{cur\_box} point to it; otherwise set \\{cur\_box}: $\K$ \\{null}\X\5
+\&{break};\6
+\4\&{case} \\{vsplit\_code}:\5
+\X1082:Split off part of a vertical box, make \\{cur\_box} point to it\X\5
+\&{break};\6
+\4\&{default}:\5
+\X1083:Initiate the construction of an hbox or vbox, then \&{return}\X\6
+\4${}\}{}$\2\6
+\\{box\_end}(\\{box\_context});\C{in simple cases, we use the box immediately}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1080}Note that the condition $\R\\{is\_char\_node}(\\{tail})$ implies that $\\{head}\I\\{tail}$,
+since \\{head} is a one-word node.
+
+\Y\B\4\X1080:If the current list ends with a box node, delete it from the list and make \\{cur\_box} point to it; otherwise set \\{cur\_box}: $\K$ \\{null}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_box}\K\\{null};{}$\6
+\&{if} ${}(\\{abs}(\\{mode})\E\\{mmode}){}$\5
+${}\{{}$\5
+\1\\{you\_cant}(\,);\5
+\\{help1}(\.{"Sorry;\ this\ \\\\lastb}\)\.{ox\ will\ be\ void."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\\{mode}\E\\{vmode})\W(\\{head}\E\\{tail})){}$\5
+${}\{{}$\5
+\1\\{you\_cant}(\,);\5
+\\{help2}(\.{"Sorry...I\ usually\ c}\)\.{an't\ take\ things\ fro}\)\.{m\ the\ current\ page."})\6
+(\.{"This\ \\\\lastbox\ will}\)\.{\ therefore\ be\ void."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{is\_char\_node}(\\{tail})){}$\1\6
+\&{if} ${}((\\{type}(\\{tail})\E\\{hlist\_node})\V(\\{type}(\\{tail})\E\\{vlist\_node})){}$\1\5
+\X1081:Remove the last box, unless it's part of a discretionary\X;\2\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1079.\fi
+
+\M{1081}\B\X1081:Remove the last box, unless it's part of a discretionary\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{head}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|p\K\|q;{}$\6
+\&{if} ${}(\R\\{is\_char\_node}(\|q)){}$\1\6
+\&{if} ${}(\\{type}(\|q)\E\\{disc\_node}){}$\5
+${}\{{}$\5
+\1\&{for} ${}(\|m\K\T{1};{}$ ${}\|m\Z\\{replace\_count}(\|q);{}$ ${}\|m\PP){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+\&{if} ${}(\|p\E\\{tail}){}$\1\5
+\&{goto} \\{done};\2\6
+\4${}\}{}$\2\2\6
+${}\|q\K\\{link}(\|p);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{tail}));{}$\5
+${}\\{cur\_box}\K\\{tail};{}$\5
+${}\\{shift\_amount}(\\{cur\_box})\K\T{0};{}$\5
+${}\\{tail}\K\|p;{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\4\\{done}:\5
+;\6
+\4${}\}{}$\2\par
+\U1080.\fi
+
+\M{1082}Here we deal with things like `\.{\\vsplit 13 to 100pt}'.
+
+\Y\B\4\X1082:Split off part of a vertical box, make \\{cur\_box} point to it\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\|n\K\\{cur\_val};{}$\6
+\&{if} ${}(\R\\{scan\_keyword}(\X1642:\.{"to"}\X)){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ `to'\ insert}\)\.{ed"});\5
+\\{help2}(\.{"I'm\ working\ on\ `\\\\v}\)\.{split<box\ number>\ to}\)\.{\ <dimen>';"})\6
+(\.{"will\ look\ for\ the\ <}\)\.{dimen>\ next."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\\{scan\_normal\_dimen};\5
+${}\\{cur\_box}\K\\{vsplit}(\|n,\39\\{cur\_val});{}$\6
+\4${}\}{}$\2\par
+\U1079.\fi
+
+\M{1083}Here is where we enter restricted horizontal mode or internal vertical
+mode, in order to make a box.
+
+\Y\B\4\X1083:Initiate the construction of an hbox or vbox, then \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|k\K\\{cur\_chr}-\\{vtop\_code};{}$\5
+${}\\{saved}(\T{0})\K\\{box\_context};{}$\6
+\&{if} ${}(\|k\E\\{hmode}){}$\1\6
+\&{if} ${}((\\{box\_context}<\\{box\_flag})\W(\\{abs}(\\{mode})\E\\{vmode})){}$\1\5
+${}\\{scan\_spec}(\\{adjusted\_hbox\_group},\39\\{true});{}$\2\6
+\&{else}\1\5
+${}\\{scan\_spec}(\\{hbox\_group},\39\\{true});{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\|k\E\\{vmode}){}$\1\5
+${}\\{scan\_spec}(\\{vbox\_group},\39\\{true});{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{scan\_spec}(\\{vtop\_group},\39\\{true});{}$\5
+${}\|k\K\\{vmode};{}$\6
+\4${}\}{}$\2\6
+\\{normal\_paragraph}(\,);\6
+\4${}\}{}$\2\6
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\|k;{}$\6
+\&{if} ${}(\|k\E\\{vmode}){}$\5
+${}\{{}$\5
+\1${}\\{prev\_depth}\K\\{ignore\_depth};{}$\6
+\&{if} ${}(\\{every\_vbox}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_vbox},\39\\{every\_vbox\_text});{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{space\_factor}\K\T{1000};{}$\6
+\&{if} ${}(\\{every\_hbox}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_hbox},\39\\{every\_hbox\_text});{}$\2\6
+\4${}\}{}$\2\6
+\&{return};\6
+\4${}\}{}$\2\par
+\U1079.\fi
+
+\M{1084}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_box}(\&{int} \\{box\_context})\C{the next input should specify a box or perhaps a rule}\6
+${}\{{}$\5
+\1\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\E\\{make\_box}){}$\1\5
+\\{begin\_box}(\\{box\_context});\2\6
+\&{else} \&{if} ${}((\\{box\_context}\G\\{leader\_flag})\W((\\{cur\_cmd}\E\\{hrule})\V(\\{cur\_cmd}\E\\{vrule}))){}$\5
+${}\{{}$\5
+\1${}\\{cur\_box}\K\\{scan\_rule\_spec}(\,);{}$\5
+\\{box\_end}(\\{box\_context});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\hbox{}\6
+\\{print\_err}(\.{"A\ <box>\ was\ suppose}\)\.{d\ to\ be\ here"});\6
+\\{help3}(\.{"I\ was\ expecting\ to\ }\)\.{see\ \\\\hbox\ or\ \\\\vbox}\)\.{\ or\ \\\\copy\ or\ \\\\box\ }\)\.{or"})\6
+(\.{"something\ like\ that}\)\.{.\ So\ you\ might\ find\ }\)\.{something\ missing\ in}\)\.{"})\6
+(\.{"your\ output.\ But\ ke}\)\.{ep\ trying;\ you\ can\ f}\)\.{ix\ this\ later."});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1085}When the right brace occurs at the end of an \.{\\hbox} or \.{\\vbox} or
+\.{\\vtop} construction, the \\{package} routine comes into action. We might
+also have to finish a paragraph that hasn't ended.
+
+\Y\B\4\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\E{}$\6
+\4\&{case} \\{hbox\_group}:\5
+\\{package}(\T{0});\5
+\&{break};\6
+\4\&{case} \\{adjusted\_hbox\_group}:\6
+${}\{{}$\5
+\1${}\\{adjust\_tail}\K\\{adjust\_head};{}$\5
+\\{package}(\T{0});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{vbox\_group}:\6
+${}\{{}$\5
+\1\\{end\_graf}(\,);\5
+\\{package}(\T{0});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{vtop\_group}:\6
+${}\{{}$\5
+\1\\{end\_graf}(\,);\5
+\\{package}(\\{vtop\_code});\6
+\4${}\}{}$\5
+\2\&{break};\par
+\As1100, 1118, 1132, 1133, 1168, 1173\ETs1186.
+\U1068.\fi
+
+\M{1086}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{package}(\&{small\_number} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{scaled} \|h;\C{height of box}\6
+\&{pointer} \|p;\C{first node in a box}\6
+\&{scaled} \|d;\C{max depth}\7
+${}\|d\K\\{box\_max\_depth};{}$\5
+\\{unsave}(\,);\5
+${}\\{save\_ptr}\K\\{save\_ptr}-\T{3};{}$\6
+\&{if} ${}(\\{mode}\E{-}\\{hmode}){}$\1\5
+${}\\{cur\_box}\K\\{hpack}(\\{link}(\\{head}),\39\\{saved}(\T{2}),\39\\{saved}(\T{1}));{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{cur\_box}\K\\{vpackage}(\\{link}(\\{head}),\39\\{saved}(\T{2}),\39\\{saved}(\T{1}),\39\|d);{}$\6
+\&{if} ${}(\|c\E\\{vtop\_code}){}$\1\5
+\X1087:Readjust the height and depth of \\{cur\_box}, for \.{\\vtop}\X;\2\6
+\4${}\}{}$\2\6
+\\{pop\_nest}(\,);\5
+\\{box\_end}(\\{saved}(\T{0}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1087}The height of a `\.{\\vtop}' box is inherited from the first item on its list,
+if that item is an \\{hlist\_node}, \\{vlist\_node}, or \\{rule\_node}; otherwise
+the \.{\\vtop} height is zero.
+
+
+\Y\B\4\X1087:Readjust the height and depth of \\{cur\_box}, for \.{\\vtop}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|h\K\T{0};{}$\5
+${}\|p\K\\{list\_ptr}(\\{cur\_box});{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}(\\{type}(\|p)\Z\\{rule\_node}){}$\1\5
+${}\|h\K\\{height}(\|p);{}$\2\2\6
+${}\\{depth}(\\{cur\_box})\K\\{depth}(\\{cur\_box})-\|h+\\{height}(\\{cur\_box});{}$\5
+${}\\{height}(\\{cur\_box})\K\|h;{}$\6
+\4${}\}{}$\2\par
+\U1086.\fi
+
+\M{1088}A paragraph begins when horizontal-mode material occurs in vertical mode,
+or when the paragraph is explicitly started by `\.{\\indent}' or
+`\.{\\noindent}'.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1724:\.{"indent"}\X,\39\\{start\_par},\39\T{1});{}$\5
+${}\\{primitive}(\X1725:\.{"noindent"}\X,\39\\{start\_par},\39\T{0}){}$;\par
+\fi
+
+\M{1089}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{start\_par}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1725:\.{"noindent"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1724:\.{"indent"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1090}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{start\_par}{}$:\5
+${}\\{new\_graf}(\\{cur\_chr}>\T{0}){}$;\5
+\&{break};\6
+\4\&{case} \\{vmode}${}+\\{letter}{}$:\5
+\&{case} \\{vmode}${}+\\{other\_char}{}$:\5
+\&{case} \\{vmode}${}+\\{char\_num}{}$:\5
+\&{case} \\{vmode}${}+\\{char\_given}{}$:\5
+\&{case} \\{vmode}${}+\\{math\_shift}{}$:\5
+\&{case} \\{vmode}${}+\\{un\_hbox}{}$:\5
+\&{case} \\{vmode}${}+\\{vrule}{}$:\5
+\&{case} \\{vmode}${}+\\{accent}{}$:\5
+\&{case} \\{vmode}${}+\\{discretionary}{}$:\5
+\&{case} \\{vmode}${}+\\{hskip}{}$:\5
+\&{case} \\{vmode}${}+\\{valign}{}$:\5
+\&{case} \\{vmode}${}+\\{ex\_space}{}$:\5
+\&{case} \\{vmode}${}+\\{no\_boundary}{}$:\5
+\hbox{}\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\\{new\_graf}(\\{true});\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1091}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{small\_number} \\{norm\_min}(\&{int} \|h)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\|h\Z\T{0}){}$\1\5
+\&{return} \T{1};\5
+\2\&{else} \&{if} ${}(\|h\G\T{63}){}$\1\5
+\&{return} \T{63};\5
+\2\&{else}\1\5
+\&{return} \|h;\2\6
+\4${}\}{}$\2\7
+\&{void} \\{new\_graf}(\&{bool} \\{indented})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{prev\_graf}\K\T{0};{}$\6
+\&{if} ${}((\\{mode}\E\\{vmode})\V(\\{head}\I\\{tail})){}$\1\5
+\\{tail\_append}(\\{new\_param\_glue}(\\{par\_skip\_code}));\2\6
+\\{push\_nest}(\,);\5
+${}\\{mode}\K\\{hmode};{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\5
+\\{set\_cur\_lang};\5
+${}\\{clang}\K\\{cur\_lang};{}$\5
+${}\\{prev\_graf}\K(\\{norm\_min}(\\{left\_hyphen\_min})*\T{\~100}+\\{norm\_min}(\\{right\_hyphen\_min}))*\T{\~200000}+\\{cur\_lang};{}$\6
+\&{if} (\\{indented})\5
+${}\{{}$\5
+\1${}\\{tail}\K\\{new\_null\_box}(\,);{}$\5
+${}\\{link}(\\{head})\K\\{tail};{}$\5
+${}\\{width}(\\{tail})\K\\{par\_indent}{}$;\5
+${}\}{}$\2\6
+\&{if} ${}(\\{every\_par}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_par},\39\\{every\_par\_text});{}$\2\6
+\&{if} ${}(\\{nest\_ptr}\E\T{1}){}$\1\5
+\\{build\_page}(\,);\C{put \\{par\_skip} glue on current page}\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1092}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmode}${}+\\{start\_par}{}$:\5
+\&{case} \\{mmode}${}+\\{start\_par}{}$:\5
+\\{indent\_in\_hmode}(\,);\5
+\&{break};\par
+\fi
+
+\M{1093}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{indent\_in\_hmode}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\7
+\&{if} ${}(\\{cur\_chr}>\T{0}{}$)\C{\.{\\indent}}\6
+${}\{{}$\5
+\1${}\|p\K\\{new\_null\_box}(\,);{}$\5
+${}\\{width}(\|p)\K\\{par\_indent};{}$\6
+\&{if} ${}(\\{abs}(\\{mode})\E\\{hmode}){}$\1\5
+${}\\{space\_factor}\K\T{1000};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{new\_noad}(\,);{}$\5
+${}\\{math\_type}(\\{nucleus}(\|q))\K\\{sub\_box};{}$\5
+${}\\{info}(\\{nucleus}(\|q))\K\|p;{}$\5
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\6
+\\{tail\_append}(\|p);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1094}A paragraph ends when a \\{par\_end} command is sensed, or when we are in
+horizontal mode when reaching the right brace of vertical-mode routines
+like \.{\\vbox}, \.{\\insert}, or \.{\\output}.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{par\_end}{}$:\6
+${}\{{}$\5
+\1\\{normal\_paragraph}(\,);\6
+\&{if} ${}(\\{mode}>\T{0}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hmode}${}+\\{par\_end}{}$:\6
+${}\{{}$\5
+\1\&{if} ${}(\\{align\_state}<\T{0}){}$\1\5
+\\{off\_save}(\,);\C{this tries to recover from an alignment that didn't end properly}\2\6
+\\{end\_graf}(\,);\C{this takes us to the enclosing mode, if $\\{mode}>\T{0}$}\6
+\&{if} ${}(\\{mode}\E\\{vmode}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{hmode}${}+\\{stop}{}$:\5
+\&{case} \\{hmode}${}+\\{vskip}{}$:\5
+\&{case} \\{hmode}${}+\\{hrule}{}$:\5
+\&{case} \\{hmode}${}+\\{un\_vbox}{}$:\5
+\&{case} \\{hmode}${}+\\{halign}{}$:\5
+\\{head\_for\_vmode}(\,);\5
+\&{break};\par
+\fi
+
+\M{1095}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{head\_for\_vmode}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{mode}<\T{0}){}$\1\6
+\&{if} ${}(\\{cur\_cmd}\I\\{hrule}){}$\1\5
+\\{off\_save}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ `"});\5
+\\{print\_esc}(\X1543:\.{"hrule"}\X);\5
+\\{print\_str}(\.{"'\ here\ except\ with\ }\)\.{leaders"});\5
+\\{help2}(\.{"To\ put\ a\ horizontal}\)\.{\ rule\ in\ an\ hbox\ or\ }\)\.{an\ alignment,"})\6
+(\.{"you\ should\ use\ \\\\le}\)\.{aders\ or\ \\\\hrulefill}\)\.{\ (see\ The\ TeXbook)."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\\{par\_token};{}$\5
+\\{back\_input}(\,);\5
+${}\\{token\_type}\K\\{inserted};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1096}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{end\_graf}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{mode}\E\\{hmode}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{head}\E\\{tail}){}$\1\5
+\\{pop\_nest}(\,);\C{null paragraphs are ignored}\2\6
+\&{else}\1\5
+\\{line\_break}(\\{widow\_penalty});\2\6
+\\{normal\_paragraph}(\,);\5
+${}\\{error\_count}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1097}Insertion and adjustment and mark nodes are constructed by the following
+pieces of the program.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{insert}):\5
+\&{case} \\{hmode}${}+\\{vadjust}{}$:\5
+\&{case} \\{mmode}${}+\\{vadjust}{}$:\5
+\\{begin\_insert\_or\_adjust}(\,);\5
+\&{break};\6
+\4\\{any\_mode}(\\{mark}):\5
+\\{make\_mark}(\,);\5
+\&{break};\par
+\fi
+
+\M{1098}\B\X1048:Forbidden cases detected in \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{case} \\{vmode}${}+\\{vadjust}{}$:\par
+\fi
+
+\M{1099}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{begin\_insert\_or\_adjust}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_cmd}\E\\{vadjust}){}$\1\5
+${}\\{cur\_val}\K\T{255};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\6
+\&{if} ${}(\\{cur\_val}\E\T{255}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ "});\5
+\\{print\_esc}(\X1390:\.{"insert"}\X);\5
+\\{print\_int}(\T{255});\5
+\\{help1}(\.{"I'm\ changing\ to\ \\\\i}\)\.{nsert0;\ box\ 255\ is\ s}\)\.{pecial."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\\{saved}(\T{0})\K\\{cur\_val};{}$\5
+\\{incr}(\\{save\_ptr});\5
+\\{new\_save\_level}(\\{insert\_group});\5
+\\{scan\_left\_brace}(\,);\5
+\\{normal\_paragraph}(\,);\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{vmode};{}$\5
+${}\\{prev\_depth}\K\\{ignore\_depth};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1100}\B\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{insert\_group}:\6
+${}\{{}$\5
+\1\\{end\_graf}(\,);\5
+${}\|q\K\\{split\_top\_skip};{}$\5
+\\{add\_glue\_ref}(\|q);\5
+${}\|d\K\\{split\_max\_depth};{}$\5
+${}\|f\K\\{floating\_penalty};{}$\5
+\\{unsave}(\,);\5
+\\{decr}(\\{save\_ptr});\C{now \\{saved}(\T{0}) is the insertion number, or 255 for \\{vadjust}}\6
+${}\|p\K\\{vpack}(\\{link}(\\{head}),\39\\{natural});{}$\5
+\\{pop\_nest}(\,);\6
+\&{if} ${}(\\{saved}(\T{0})<\T{255}){}$\5
+${}\{{}$\5
+\1\\{tail\_append}(\\{get\_node}(\\{ins\_node\_size}));\5
+${}\\{type}(\\{tail})\K\\{ins\_node};{}$\5
+${}\\{subtype}(\\{tail})\K\\{qi}(\\{saved}(\T{0}));{}$\5
+${}\\{height}(\\{tail})\K\\{height}(\|p)+\\{depth}(\|p);{}$\5
+${}\\{ins\_ptr}(\\{tail})\K\\{list\_ptr}(\|p);{}$\5
+${}\\{split\_top\_ptr}(\\{tail})\K\|q;{}$\5
+${}\\{depth}(\\{tail})\K\|d;{}$\5
+${}\\{float\_cost}(\\{tail})\K\|f;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{tail\_append}(\\{get\_node}(\\{small\_node\_size}));\5
+${}\\{type}(\\{tail})\K\\{adjust\_node}{}$;\6
+${}\\{subtype}(\\{tail})\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+${}\\{adjust\_ptr}(\\{tail})\K\\{list\_ptr}(\|p);{}$\5
+\\{delete\_glue\_ref}(\|q);\6
+\4${}\}{}$\2\6
+${}\\{free\_node}(\|p,\39\\{box\_node\_size});{}$\6
+\&{if} ${}(\\{nest\_ptr}\E\T{0}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{output\_group}:\5
+\X1026:Resume the page builder after an output routine has come to an end\X\5
+\&{break};\par
+\fi
+
+\M{1101}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_mark}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{new node}\7
+${}\|p\K\\{scan\_toks}(\\{false},\39\\{true});{}$\5
+${}\|p\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{type}(\|p)\K\\{mark\_node};{}$\5
+${}\\{subtype}(\|p)\K\T{0}{}$;\C{the \\{subtype} is not used}\6
+${}\\{mark\_ptr}(\|p)\K\\{def\_ref};{}$\5
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1102}Penalty nodes get into a list via the \\{break\_penalty} command.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{break\_penalty}):\5
+\\{append\_penalty}(\,);\5
+\&{break};\par
+\fi
+
+\M{1103}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_penalty}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\5
+\\{tail\_append}(\\{new\_penalty}(\\{cur\_val}));\6
+\&{if} ${}(\\{mode}\E\\{vmode}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1104}The \\{remove\_item} command removes a penalty, kern, or glue node if it
+appears at the tail of the current list, using a brute-force linear scan.
+Like \.{\\lastbox}, this command is not allowed in vertical mode (except
+internal vertical mode), since the current list in vertical mode is sent
+to the page builder. But if we happen to be able to implement it in
+vertical mode, we do.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{remove\_item}):\5
+\\{delete\_last}(\,);\5
+\&{break};\par
+\fi
+
+\M{1105}When \\{delete\_last} is called, \\{cur\_chr} is the \\{type} of node that
+will be deleted, if present.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{delete\_last}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\C{run through the current list}\6
+\&{int} \|m;\C{the length of a replacement list}\7
+\&{if} ${}((\\{mode}\E\\{vmode})\W(\\{tail}\E\\{head})){}$\1\5
+\X1106:Apologize for inability to do the operation now, unless \.{\\unskip} follows non-glue\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{is\_char\_node}(\\{tail})){}$\1\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{cur\_chr}){}$\5
+${}\{{}$\5
+\1${}\|q\K\\{head}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|p\K\|q;{}$\6
+\&{if} ${}(\R\\{is\_char\_node}(\|q)){}$\1\6
+\&{if} ${}(\\{type}(\|q)\E\\{disc\_node}){}$\5
+${}\{{}$\5
+\1\&{for} ${}(\|m\K\T{1};{}$ ${}\|m\Z\\{replace\_count}(\|q);{}$ ${}\|m\PP){}$\1\5
+${}\|p\K\\{link}(\|p);{}$\2\6
+\&{if} ${}(\|p\E\\{tail}){}$\1\5
+\&{return};\2\6
+\4${}\}{}$\2\2\6
+${}\|q\K\\{link}(\|p);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{tail}));{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\5
+\\{flush\_node\_list}(\\{tail});\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1106}\B\X1106:Apologize for inability to do the operation now, unless \.{\\unskip} follows non-glue\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\\{cur\_chr}\I\\{glue\_node})\V(\\{last\_glue}\I\\{max\_halfword})){}$\5
+${}\{{}$\5
+\1\\{you\_cant}(\,);\5
+\\{help2}(\.{"Sorry...I\ usually\ c}\)\.{an't\ take\ things\ fro}\)\.{m\ the\ current\ page."})\6
+(\.{"Try\ `I\\\\vskip-\\\\las}\)\.{tskip'\ instead."});\6
+\&{if} ${}(\\{cur\_chr}\E\\{kern\_node}){}$\1\5
+${}\\{help\_line}[\T{0}]\K(\.{"Try\ `I\\\\kern-\\\\last}\)\.{kern'\ instead."});{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\I\\{glue\_node}){}$\1\5
+${}\\{help\_line}[\T{0}]\K\30(\.{"Perhaps\ you\ can\ mak}\)\.{e\ the\ output\ routine}\)\.{\ do\ it."});{}$\2\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1105.\fi
+
+\M{1107}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1726:\.{"unpenalty"}\X,\39\\{remove\_item},\39\\{penalty\_node}){}$;\6
+${}\\{primitive}(\X1727:\.{"unkern"}\X,\39\\{remove\_item},\39\\{kern\_node}){}$;\6
+${}\\{primitive}(\X1728:\.{"unskip"}\X,\39\\{remove\_item},\39\\{glue\_node}){}$;\6
+${}\\{primitive}(\X1729:\.{"unhbox"}\X,\39\\{un\_hbox},\39\\{box\_code}){}$;\6
+${}\\{primitive}(\X1730:\.{"unhcopy"}\X,\39\\{un\_hbox},\39\\{copy\_code}){}$;\6
+${}\\{primitive}(\X1731:\.{"unvbox"}\X,\39\\{un\_vbox},\39\\{box\_code}){}$;\6
+${}\\{primitive}(\X1732:\.{"unvcopy"}\X,\39\\{un\_vbox},\39\\{copy\_code}){}$;\par
+\fi
+
+\M{1108}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{remove\_item}:\6
+\&{if} ${}(\\{chr\_code}\E\\{glue\_node}){}$\1\5
+\\{print\_esc}(\X1728:\.{"unskip"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{kern\_node}){}$\1\5
+\\{print\_esc}(\X1727:\.{"unkern"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1726:\.{"unpenalty"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{un\_hbox}:\6
+\&{if} ${}(\\{chr\_code}\E\\{copy\_code}){}$\1\5
+\\{print\_esc}(\X1730:\.{"unhcopy"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1729:\.{"unhbox"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{un\_vbox}:\6
+\&{if} ${}(\\{chr\_code}\E\\{copy\_code}){}$\1\5
+\\{print\_esc}(\X1732:\.{"unvcopy"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1731:\.{"unvbox"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1109}The \\{un\_hbox} and \\{un\_vbox} commands unwrap one of the 256 current boxes.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{un\_vbox}{}$:\5
+\&{case} \\{hmode}${}+\\{un\_hbox}{}$:\5
+\&{case} \\{mmode}${}+\\{un\_hbox}{}$:\5
+\\{unpackage}(\,);\5
+\&{break};\par
+\fi
+
+\M{1110}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{unpackage}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the box}\6
+\&{uint8\_t} \|c;\C{should we copy?}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_eight\_bit\_int}(\,);\5
+${}\|p\K\\{box}(\\{cur\_val});{}$\6
+\&{if} ${}(\|p\E\\{null}){}$\1\5
+\&{return};\2\6
+\&{if} ${}((\\{abs}(\\{mode})\E\\{mmode})\V((\\{abs}(\\{mode})\E\\{vmode})\W(\\{type}(\|p)\I\\{vlist\_node}))\V\30((\\{abs}(\\{mode})\E\\{hmode})\W(\\{type}(\|p)\I\\{hlist\_node}))){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Incompatible\ list\ c}\)\.{an't\ be\ unboxed"});\5
+\\{help3}(\.{"Sorry,\ Pandora.\ (Yo}\)\.{u\ sneaky\ devil.)"})\6
+(\.{"I\ refuse\ to\ unbox\ a}\)\.{n\ \\\\hbox\ in\ vertical}\)\.{\ mode\ or\ vice\ versa.}\)\.{"})\6
+(\.{"And\ I\ can't\ open\ an}\)\.{y\ boxes\ in\ math\ mode}\)\.{."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|c\E\\{copy\_code}){}$\1\5
+${}\\{link}(\\{tail})\K\\{copy\_node\_list}(\\{list\_ptr}(\|p));{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\\{list\_ptr}(\|p);{}$\5
+${}\\{box}(\\{cur\_val})\K\\{null};{}$\5
+${}\\{free\_node}(\|p,\39\\{box\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\&{while} ${}(\\{link}(\\{tail})\I\\{null}){}$\1\5
+${}\\{tail}\K\\{link}(\\{tail});{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1111}\B\X1048:Forbidden cases detected in \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{case} \\{vmode}${}+\\{ital\_corr}{}$:\par
+\fi
+
+\M{1112}Italic corrections are converted to kern nodes when the \\{ital\_corr} command
+follows a character. In math mode the same effect is achieved by appending
+a kern of zero here, since italic corrections are supplied later.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmode}${}+\\{ital\_corr}{}$:\5
+\\{append\_italic\_correction}(\,);\5
+\&{break};\6
+\4\&{case} \\{mmode}${}+\\{ital\_corr}{}$:\5
+\\{tail\_append}(\\{new\_kern}(\T{0}))\5
+\&{break};\par
+\fi
+
+\M{1113}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_italic\_correction}(\&{void})\1\1 $\{{}$\5
+\&{pointer} \|p;\C{\\{char\_node} at the tail of the current list}\6
+\&{internal\_font\_number} \|f;\C{the font in the \\{char\_node}}\6
+\&{if} ${}(\\{tail}\I\\{head})$ $\{{}$\5
+\&{if} (\\{is\_char\_node}(\\{tail}))\1\5
+${}\|p\K\\{tail};{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\\{tail})\E\\{ligature\_node}){}$\1\5
+${}\|p\K\\{lig\_char}(\\{tail});{}$\2\6
+\&{else}\1\5
+\&{return};\2\6
+${}\|f\K\\{font}(\|p);{}$\5
+\\{tail\_append}(\\{new\_kern}(\\{char\_italic}(\|f)(\\{char\_info}(\|f)(\\{character}(\|p))))); \\{subtype}(\\{tail}) $\K$ \&{explicit}; $\}$ $\}{}$\par
+\fi
+
+\M{1114}Discretionary nodes are easy in the common case `\.{\\-}', but in the
+general case we must process three braces full of items.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\.{'-'},\39\\{discretionary},\39\T{1});{}$\5
+${}\\{primitive}(\X1400:\.{"discretionary"}\X,\39\\{discretionary},\39\T{0}){}$;\par
+\fi
+
+\M{1115}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{discretionary}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\.{'-'});\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1400:\.{"discretionary"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1116}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmode}${}+\\{discretionary}{}$:\5
+\&{case} \\{mmode}${}+\\{discretionary}{}$:\5
+\\{append\_discretionary}(\,);\5
+\&{break};\par
+\fi
+
+\M{1117}The space factor does not change when we append a discretionary node,
+but it starts out as 1000 in the subsidiary lists.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_discretionary}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|c;\C{hyphen character}\7
+\\{tail\_append}(\\{new\_disc}(\,));\6
+\&{if} ${}(\\{cur\_chr}\E\T{1}){}$\5
+${}\{{}$\5
+\1${}\|c\K\\{hyphen\_char}[\\{cur\_font}];{}$\6
+\&{if} ${}(\|c\G\T{0}){}$\1\6
+\&{if} ${}(\|c<\T{256}){}$\1\5
+${}\\{pre\_break}(\\{tail})\K\\{new\_character}(\\{cur\_font},\39\|c);{}$\2\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{incr}(\\{save\_ptr});\5
+${}\\{saved}({-}\T{1})\K\T{0};{}$\5
+\\{new\_save\_level}(\\{disc\_group});\5
+\\{scan\_left\_brace}(\,);\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{hmode};{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1118}The three discretionary lists are constructed somewhat as if they were
+hboxes. A~subroutine called \\{build\_discretionary} handles the transitions.
+(This is sort of fun.)
+
+\Y\B\4\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{disc\_group}:\5
+\\{build\_discretionary}(\,);\5
+\&{break};\par
+\fi
+
+\M{1119}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{build\_discretionary}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p${},{}$ \|q;\C{for link manipulation}\6
+\&{int} \|n;\C{length of discretionary list}\7
+\\{unsave}(\,);\5
+\X1121:Prune the current list, if necessary, until it contains only \\{char\_node}, \\{kern\_node}, \\{hlist\_node}, \\{vlist\_node}, \\{rule\_node}, and \\{ligature\_node} items; set \|n to the length of the list, and set \|q to the list's tail\X;\6
+${}\|p\K\\{link}(\\{head});{}$\5
+\\{pop\_nest}(\,);\6
+\&{switch} ${}(\\{saved}({-}\T{1})){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+${}\\{pre\_break}(\\{tail})\K\|p{}$;\5
+\&{break};\6
+\4\&{case} \T{1}:\5
+${}\\{post\_break}(\\{tail})\K\|p{}$;\5
+\&{break};\6
+\4\&{case} \T{2}:\5
+\X1120:Attach list \|p to the current list, and record its length; then finish up and \&{return}\X;\6
+\4${}\}{}$\C{there are no other cases}\2\6
+${}\\{incr}(\\{saved}({-}\T{1}));{}$\5
+\\{new\_save\_level}(\\{disc\_group});\5
+\\{scan\_left\_brace}(\,);\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{hmode};{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1120}\B\X1120:Attach list \|p to the current list, and record its length; then finish up and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\|n>\T{0})\W(\\{abs}(\\{mode})\E\\{mmode})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ math\ "});\5
+\\{print\_esc}(\X1400:\.{"discretionary"}\X);\5
+\\{help2}(\.{"Sorry:\ The\ third\ pa}\)\.{rt\ of\ a\ discretionar}\)\.{y\ break\ must\ be"})\6
+(\.{"empty,\ in\ math\ form}\)\.{ulas.\ I\ had\ to\ delet}\)\.{e\ your\ third\ part."});\5
+\\{flush\_node\_list}(\|p);\5
+${}\|n\K\T{0};{}$\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{link}(\\{tail})\K\|p;{}$\2\6
+\&{if} ${}(\|n\Z\\{max\_quarterword}){}$\1\5
+${}\\{replace\_count}(\\{tail})\K\|n;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Discretionary\ list\ }\)\.{is\ too\ long"});\5
+\\{help2}(\.{"Wow---I\ never\ thoug}\)\.{ht\ anybody\ would\ twe}\)\.{ak\ me\ here."})\6
+(\.{"You\ can't\ seriously}\)\.{\ need\ such\ a\ huge\ di}\)\.{scretionary\ list?"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|n>\T{0}){}$\1\5
+${}\\{tail}\K\|q;{}$\2\6
+\\{decr}(\\{save\_ptr});\5
+\&{return};\6
+\4${}\}{}$\2\par
+\U1119.\fi
+
+\M{1121}During this loop, $\|p\E\\{link}(\|q)$ and there are \|n items preceding \|p.
+
+\Y\B\4\X1121:Prune the current list, if necessary, until it contains only \\{char\_node}, \\{kern\_node}, \\{hlist\_node}, \\{vlist\_node}, \\{rule\_node}, and \\{ligature\_node} items; set \|n to the length of the list, and set \|q to the list's tail%
+\X${}\E{}$\6
+$\|q\K\\{head};{}$\5
+${}\|p\K\\{link}(\|q);{}$\5
+${}\|n\K\T{0};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{is\_char\_node}(\|p)){}$\1\6
+\&{if} ${}(\\{type}(\|p)>\\{rule\_node}){}$\1\6
+\&{if} ${}(\\{type}(\|p)\I\\{kern\_node}){}$\1\6
+\&{if} ${}(\\{type}(\|p)\I\\{ligature\_node}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ discretion}\)\.{ary\ list"});\5
+\\{help1}(\.{"Discretionary\ lists}\)\.{\ must\ contain\ only\ b}\)\.{oxes\ and\ kerns."});\6
+\&{error} (\,)\1\5
+;\2\6
+\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{"The\ following\ discr}\)\.{etionary\ sublist\ has}\)\.{\ been\ deleted:"});\5
+\\{show\_box}(\|p);\5
+\\{end\_diagnostic}(\\{true});\5
+\\{flush\_node\_list}(\|p);\5
+${}\\{link}(\|q)\K\\{null};{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\2\2\2\6
+${}\|q\K\|p;{}$\5
+${}\|p\K\\{link}(\|q);{}$\5
+\\{incr}(\|n);\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U1119.\fi
+
+\M{1122}We need only one more thing to complete the horizontal mode routines, namely
+the \.{\\accent} primitive.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmode}${}+\\{accent}{}$:\5
+\\{make\_accent}(\,);\5
+\&{break};\par
+\fi
+
+\M{1123}The positioning of accents is straightforward but tedious. Given an accent
+of width \|a, designed for characters of height \|x and slant \|s;
+and given a character of width \|w, height \|h, and slant \|t: We will shift
+the accent down by $\|x-\|h$, and we will insert kern nodes that have the effect of
+centering the accent over the character and shifting the accent to the
+right by $\delta={1\over2}(w-a)+h\cdot t-x\cdot s$. If either character is
+absent from the font, we will simply use the other, without shifting.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{make\_accent}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{double} \|s${},{}$ \|t;\C{amount of slant}\6
+\&{pointer} \|p${},{}$ \|q${},{}$ \|r;\C{character, box, and kern nodes}\6
+\&{internal\_font\_number} \|f;\C{relevant font}\6
+\&{scaled} \|a${},{}$ \|h${},{}$ \|x${},{}$ \|w${},{}$ \\{delta};\C{heights and widths, as explained above}\6
+\&{four\_quarters} \|i;\C{character information}\7
+\\{scan\_char\_num}(\,);\5
+${}\|f\K\\{cur\_font};{}$\5
+${}\|p\K\\{new\_character}(\|f,\39\\{cur\_val});{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1${}\|x\K\\{x\_height}(\|f);{}$\5
+${}\|s\K\\{slant}(\|f)/\\{float\_constant}(\T{65536});{}$\5
+${}\|a\K\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|p))){}$;\6
+\\{do\_assignments}(\,);\6
+\X1124:Create a character node \|q for the next character, but set \|q: $\K$ \\{null} if problems arise\X;\6
+\&{if} ${}(\|q\I\\{null}){}$\1\5
+\X1125:Append the accent with appropriate kerns, then set \|p: $\K$ \|q\X;\2\6
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1124}\B\X1124:Create a character node \|q for the next character, but set \|q: $\K$ \\{null} if problems arise\X${}\E{}$\6
+$\|q\K\\{null};{}$\5
+${}\|f\K\\{cur\_font};$ \6
+\&{if} ${}((\\{cur\_cmd}\E\\{letter})\V(\\{cur\_cmd}\E\\{other\_char})\V(\\{cur\_cmd}\E\\{char\_given})){}$\1\5
+${}\|q\K\\{new\_character}(\|f,\39\\{cur\_chr});{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_cmd}\E\\{char\_num}){}$\5
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\|q\K\\{new\_character}(\|f,\39\\{cur\_val});{}$\6
+\4${}\}{}$\2\6
+\&{else} \\{back\_input}(\,)\par
+\U1123.\fi
+
+\M{1125}The kern nodes appended here must be distinguished from other kerns, lest
+they be wiped away by the hyphenation algorithm or by a previous line break.
+
+The two kerns are computed with (machine-dependent) \&{double} arithmetic, but
+their sum is machine-independent; the net effect is machine-independent,
+because the user cannot remove these nodes nor access them via \.{\\lastkern}.
+
+\Y\B\4\X1125:Append the accent with appropriate kerns, then set \|p: $\K$ \|q\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|t\K\\{slant}(\|f)/\\{float\_constant}(\T{65536});{}$\5
+${}\|i\K\\{char\_info}(\|f)(\\{character}(\|q));{}$\5
+${}\|w\K\\{char\_width}(\|f)(\|i);{}$\5
+${}\|h\K\\{char\_height}(\|f)(\\{height\_depth}(\|i));{}$\6
+\&{if} ${}(\|h\I\|x{}$)\C{the accent must be shifted up or down}\6
+${}\{{}$\5
+\1${}\|p\K\\{hpack}(\|p,\39\\{natural});{}$\5
+${}\\{shift\_amount}(\|p)\K\|x-\|h;{}$\6
+\4${}\}{}$\2\6
+${}\\{delta}\K\\{round}((\|w-\|a)/\\{float\_constant}(\T{2})+\|h*\|t-\|x*\|s);{}$\5
+${}\|r\K\\{new\_kern}(\\{delta});{}$\5
+${}\\{subtype}(\|r)\K\\{acc\_kern};{}$\5
+${}\\{link}(\\{tail})\K\|r;{}$\5
+${}\\{link}(\|r)\K\|p;{}$\5
+${}\\{tail}\K\\{new\_kern}({-}\|a-\\{delta});{}$\5
+${}\\{subtype}(\\{tail})\K\\{acc\_kern};{}$\5
+${}\\{link}(\|p)\K\\{tail};{}$\5
+${}\|p\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U1123.\fi
+
+\M{1126}When `\.{\\cr}' or `\.{\\span}' or a tab mark comes through the scanner
+into \\{main\_control}, it might be that the user has foolishly inserted
+one of them into something that has nothing to do with alignment. But it is
+far more likely that a left brace or right brace has been omitted, since
+\\{get\_next} takes actions appropriate to alignment only when `\.{\\cr}'
+or `\.{\\span}' or tab marks occur with $\\{align\_state}\E\T{0}$. The following
+program attempts to make an appropriate recovery.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{car\_ret}):\5
+\\{any\_mode}(\\{tab\_mark}):\5
+\\{align\_error}(\,);\5
+\&{break};\6
+\4\\{any\_mode}(\\{no\_align}):\5
+\\{no\_align\_error}(\,);\5
+\&{break};\6
+\4\\{any\_mode}(\\{omit}):\5
+\\{omit\_error}(\,);\5
+\&{break};\par
+\fi
+
+\M{1127}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{align\_error}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{abs}(\\{align\_state})>\T{2}){}$\1\5
+\X1128:Express consternation over the fact that no alignment is in progress\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\6
+\&{if} ${}(\\{align\_state}<\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \{\ inserted"});\5
+\\{incr}(\\{align\_state});\5
+${}\\{cur\_tok}\K\\{left\_brace\_token}+\.{'\{'};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \}\ inserted"});\5
+\\{decr}(\\{align\_state});\5
+${}\\{cur\_tok}\K\\{right\_brace\_token}+\.{'\}'};{}$\6
+\4${}\}{}$\2\6
+\\{help3}(\.{"I've\ put\ in\ what\ se}\)\.{ems\ to\ be\ necessary\ }\)\.{to\ fix"})\6
+(\.{"the\ current\ column\ }\)\.{of\ the\ current\ align}\)\.{ment."})\6
+(\.{"Try\ to\ go\ on,\ since}\)\.{\ this\ might\ almost\ w}\)\.{ork."});\5
+\\{ins\_error}(\,);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1128}\B\X1128:Express consternation over the fact that no alignment is in progress\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Misplaced\ "});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\6
+\&{if} ${}(\\{cur\_tok}\E\\{tab\_token}+\.{'\&'}){}$\5
+${}\{{}$\5
+\1\\{help6}(\.{"I\ can't\ figure\ out\ }\)\.{why\ you\ would\ want\ t}\)\.{o\ use\ a\ tab\ mark"})\6
+(\.{"here.\ If\ you\ just\ w}\)\.{ant\ an\ ampersand,\ th}\)\.{e\ remedy\ is"})\6
+(\.{"simple:\ Just\ type\ `}\)\.{I\\\\\&'\ now.\ But\ if\ so}\)\.{me\ right\ brace"})\6
+(\.{"up\ above\ has\ ended\ }\)\.{a\ previous\ alignment}\)\.{\ prematurely,"})\6
+(\.{"you're\ probably\ due}\)\.{\ for\ more\ error\ mess}\)\.{ages,\ and\ you"})\6
+(\.{"might\ try\ typing\ `S}\)\.{'\ now\ just\ to\ see\ wh}\)\.{at\ is\ salvageable."});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{help5}(\.{"I\ can't\ figure\ out\ }\)\.{why\ you\ would\ want\ t}\)\.{o\ use\ a\ tab\ mark"})\6
+(\.{"or\ \\\\cr\ or\ \\\\span\ j}\)\.{ust\ now.\ If\ somethin}\)\.{g\ like\ a\ right\ brace}\)\.{"})\6
+(\.{"up\ above\ has\ ended\ }\)\.{a\ previous\ alignment}\)\.{\ prematurely,"})\6
+(\.{"you're\ probably\ due}\)\.{\ for\ more\ error\ mess}\)\.{ages,\ and\ you"})\6
+(\.{"might\ try\ typing\ `S}\)\.{'\ now\ just\ to\ see\ wh}\)\.{at\ is\ salvageable."});\6
+\4${}\}{}$\2\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1127.\fi
+
+\M{1129}The help messages here contain a little white lie, since \.{\\noalign}
+and \.{\\omit} are allowed also after `\.{\\noalign\{...\}}'.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{no\_align\_error}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Misplaced\ "});\5
+\\{print\_esc}(\X1549:\.{"noalign"}\X);\5
+\\{help2}(\.{"I\ expect\ to\ see\ \\\\n}\)\.{oalign\ only\ after\ th}\)\.{e\ \\\\cr\ of"})\6
+(\.{"an\ alignment.\ Proce}\)\.{ed,\ and\ I'll\ ignore\ }\)\.{this\ case."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\7
+\&{void} \\{omit\_error}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Misplaced\ "});\5
+\\{print\_esc}(\X1552:\.{"omit"}\X);\5
+\\{help2}(\.{"I\ expect\ to\ see\ \\\\o}\)\.{mit\ only\ after\ tab\ m}\)\.{arks\ or\ the\ \\\\cr\ of"})\6
+(\.{"an\ alignment.\ Proce}\)\.{ed,\ and\ I'll\ ignore\ }\)\.{this\ case."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1130}We've now covered most of the abuses of \.{\\halign} and \.{\\valign}.
+Let's take a look at what happens when they are used correctly.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vmode}${}+\\{halign}{}$:\5
+\&{case} \\{hmode}${}+\\{valign}{}$:\5
+\\{init\_align}(\,);\5
+\&{break};\6
+\4\&{case} \\{mmode}${}+\\{halign}{}$:\6
+\&{if} (\\{privileged}(\,))\1\6
+\&{if} ${}(\\{cur\_group}\E\\{math\_shift\_group}){}$\1\5
+\\{init\_align}(\,);\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\5
+\2\2\&{break};\6
+\4\&{case} \\{vmode}${}+\\{endv}{}$:\5
+\&{case} \\{hmode}${}+\\{endv}{}$:\5
+\\{do\_endv}(\,);\5
+\&{break};\par
+\fi
+
+\M{1131}An \\{align\_group} code is supposed to remain on the \\{save\_stack}
+during an entire alignment, until \\{fin\_align} removes it.
+
+A devious user might force an \\{endv} command to occur just about anywhere;
+we must defeat such hacks.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{do\_endv}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{base\_ptr}\K\\{input\_ptr};{}$\5
+${}\\{input\_stack}[\\{base\_ptr}]\K\\{cur\_input};{}$\6
+\&{while} ${}((\\{input\_stack}[\\{base\_ptr}].\\{index\_field}\I\\{v\_template})\W(\\{input\_stack}[\\{base\_ptr}].\\{loc\_field}\E\\{null})\W(\\{input\_stack}[\\{base\_ptr}].\\{state\_field}\E\\{token\_list})){}$\1\5
+\\{decr}(\\{base\_ptr});\2\6
+\&{if} ${}((\\{input\_stack}[\\{base\_ptr}].\\{index\_field}\I\\{v\_template})\V(\\{input\_stack}[\\{base\_ptr}].\\{loc\_field}\I\\{null})\V(\\{input\_stack}[\\{base\_ptr}].\\{state\_field}\I\\{token\_list})){}$\1\5
+\\{fatal\_error}(\.{"(interwoven\ alignme}\)\.{nt\ preambles\ are\ not}\)\.{\ allowed)"});\2\6
+\&{if} ${}(\\{cur\_group}\E\\{align\_group}){}$\5
+${}\{{}$\5
+\1\\{end\_graf}(\,);\6
+\&{if} (\\{fin\_col}(\,))\1\5
+\\{fin\_row}(\,);\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1132}\B\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{align\_group}:\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{frozen\_cr};{}$\5
+\\{print\_err}(\.{"Missing\ "});\5
+\\{print\_esc}(\X1670:\.{"cr"}\X);\5
+\\{print\_str}(\.{"\ inserted"});\5
+\\{help1}(\.{"I'm\ guessing\ that\ y}\)\.{ou\ meant\ to\ end\ an\ a}\)\.{lignment\ here."});\5
+\\{ins\_error}(\,);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1133}\B\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{no\_align\_group}:\6
+${}\{{}$\5
+\1\\{end\_graf}(\,);\5
+\\{unsave}(\,);\5
+\\{align\_peek}(\,);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1134}Finally, \.{\\endcsname} is not supposed to get through to \\{main\_control}.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{end\_cs\_name}):\5
+\\{cs\_error}(\,);\5
+\&{break};\par
+\fi
+
+\M{1135}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{cs\_error}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Extra\ "});\5
+\\{print\_esc}(\X1527:\.{"endcsname"}\X);\5
+\\{help1}(\.{"I'm\ ignoring\ this,\ }\)\.{since\ I\ wasn't\ doing}\)\.{\ a\ \\\\csname."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\N{1}{1136}Building math lists.
+The routines that \TeX\ uses to create mlists are similar to those we have
+just seen for the generation of hlists and vlists. But it is necessary to
+make ``noads'' as well as nodes, so the reader should review the
+discussion of math mode data structures before trying to make sense out of
+the following program.
+
+Here is a little routine that needs to be done whenever a subformula
+is about to be processed. The parameter is a code like \\{math\_group}.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{push\_math}(\&{group\_code} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{mmode};{}$\5
+${}\\{incompleat\_noad}\K\\{null};{}$\5
+\\{new\_save\_level}(\|c);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1137}We get into math mode from horizontal mode when a `\.\$' (i.e., a
+\\{math\_shift} character) is scanned. We must check to see whether this
+`\.\$' is immediately followed by another, in case display math mode is
+called for.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hmode}${}+\\{math\_shift}{}$:\5
+\\{init\_math}(\,);\5
+\&{break};\par
+\fi
+
+\M{1138}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{init\_math}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{scaled} \|w;\C{new or partial \\{pre\_display\_size}}\6
+\&{scaled} \|l;\C{new \\{display\_width}}\6
+\&{scaled} \|s;\C{new \\{display\_indent}}\6
+\&{pointer} \|p;\C{current node when calculating \\{pre\_display\_size}}\6
+\&{pointer} \|q;\C{glue specification when calculating \\{pre\_display\_size}}\6
+\&{internal\_font\_number} \|f;\C{font in current \\{char\_node}}\6
+\&{int} \|n;\C{scope of paragraph shape specification}\6
+\&{scaled} \|v;\C{\|w plus possible glue amount}\6
+\&{scaled} \|d;\C{increment to \|v}\7
+\\{get\_token}(\,);\C{\\{get\_x\_token} would fail on \.{\\ifmmode}\thinspace!}\6
+\&{if} ${}((\\{cur\_cmd}\E\\{math\_shift})\W(\\{mode}>\T{0})){}$\1\5
+\X1145:Go into display math mode\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\X1139:Go into ordinary math mode\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1139}\B\X1139:Go into ordinary math mode\X${}\E{}$\6
+${}\{{}$\5
+\1\\{push\_math}(\\{math\_shift\_group});\5
+${}\\{eq\_word\_define}(\\{int\_base}+\\{cur\_fam\_code},\39{-}\T{1});{}$\6
+\&{if} ${}(\\{every\_math}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_math},\39\\{every\_math\_text});{}$\2\6
+\4${}\}{}$\2\par
+\Us1138\ET1142.\fi
+
+\M{1140}We get into ordinary math mode from display math mode when `\.{\\eqno}' or
+`\.{\\leqno}' appears. In such cases \\{cur\_chr} will be 0 or~1, respectively;
+the value of \\{cur\_chr} is placed onto \\{save\_stack} for safe keeping.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{eq\_no}{}$:\6
+\&{if} (\\{privileged}(\,))\1\6
+\&{if} ${}(\\{cur\_group}\E\\{math\_shift\_group}){}$\1\5
+\\{start\_eq\_no}(\,);\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\5
+\2\2\&{break};\par
+\fi
+
+\M{1141}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1733:\.{"eqno"}\X,\39\\{eq\_no},\39\T{0});{}$\5
+${}\\{primitive}(\X1734:\.{"leqno"}\X,\39\\{eq\_no},\39\T{1}){}$;\par
+\fi
+
+\M{1142}When \TeX\ is in display math mode, $\\{cur\_group}\E\\{math\_shift\_group}$,
+so it is not necessary for the \\{start\_eq\_no} procedure to test for
+this condition.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{start\_eq\_no}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{saved}(\T{0})\K\\{cur\_chr};{}$\5
+\\{incr}(\\{save\_ptr});\5
+\X1139:Go into ordinary math mode\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1143}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{eq\_no}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1734:\.{"leqno"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1733:\.{"eqno"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1144}\B\X1048:Forbidden cases detected in \\{main\_control}\X${}\mathrel+\E{}$\6
+\\{non\_math}(\\{eq\_no}):\par
+\fi
+
+\M{1145}When we enter display math mode, we need to call \\{line\_break} to
+process the partial paragraph that has just been interrupted by the
+display. Then we can set the proper values of \\{display\_width} and
+\\{display\_indent} and \\{pre\_display\_size}.
+
+\Y\B\4\X1145:Go into display math mode\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{head}\E\\{tail}{}$)\C{`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'}\6
+${}\{{}$\5
+\1\\{pop\_nest}(\,);\5
+${}\|w\K{-}\\{max\_dimen};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{line\_break}(\\{display\_widow\_penalty});\6
+\X1146:Calculate the natural width, \|w, by which the characters of the final line extend to the right of the reference point, plus two ems; or set \|w: $\K$ \\{max\_dimen} if the non-blank information on that line is affected by stretching or shrinking%
+\X;\6
+\4${}\}{}$\C{now we are in vertical mode, working on the list that will contain the display}\2\6
+\X1149:Calculate the length, \|l, and the shift amount, \|s, of the display lines\X;\6
+\\{push\_math}(\\{math\_shift\_group});\5
+${}\\{mode}\K\\{mmode};{}$\5
+${}\\{eq\_word\_define}(\\{int\_base}+\\{cur\_fam\_code},\39{-}\T{1}){}$;\6
+${}\\{eq\_word\_define}(\\{dimen\_base}+\\{pre\_display\_size\_code},\39\|w);{}$\5
+${}\\{eq\_word\_define}(\\{dimen\_base}+\\{display\_width\_code},\39\|l);{}$\5
+${}\\{eq\_word\_define}(\\{dimen\_base}+\\{display\_indent\_code},\39\|s);{}$\6
+\&{if} ${}(\\{every\_display}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_display},\39\\{every\_display\_text});{}$\2\6
+\&{if} ${}(\\{nest\_ptr}\E\T{1}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\2\par
+\U1138.\fi
+
+\M{1146}\B\X1146:Calculate the natural width, \|w, by which the characters of the final line extend to the right of the reference point, plus two ems; or set \|w: $\K$ \\{max\_dimen} if the non-blank information on that line is affected by stretching or
+shrinking\X${}\E{}$\6
+$\|v\K\\{shift\_amount}(\\{just\_box})+\T{2}*\\{quad}(\\{cur\_font});{}$\5
+${}\|w\K{-}\\{max\_dimen};{}$\5
+${}\|p\K\\{list\_ptr}(\\{just\_box});{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\X1147:Let \|d be the natural width of node \|p; if the node is ``visible,'' \&{goto} \\{found}; if the node is glue that stretches or shrinks, set \|v: $\K$ \\{max\_dimen}\X;\6
+\&{if} ${}(\|v<\\{max\_dimen}){}$\1\5
+${}\|v\K\|v+\|d;{}$\2\6
+\&{goto} \\{not\_found};\6
+\4\\{found}:\6
+\&{if} ${}(\|v<\\{max\_dimen}){}$\5
+${}\{{}$\5
+\1${}\|v\K\|v+\|d;{}$\5
+${}\|w\K\|v;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|w\K\\{max\_dimen};{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\\{not\_found}:\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\\{done}:\par
+\U1145.\fi
+
+\M{1147}\B\X1147:Let \|d be the natural width of node \|p; if the node is ``visible,'' \&{goto} \\{found}; if the node is glue that stretches or shrinks, set \|v: $\K$ \\{max\_dimen}\X${}\E{}$\6
+\4\\{reswitch}:\6
+\&{if} (\\{is\_char\_node}(\|p))\5
+${}\{{}$\5
+\1${}\|f\K\\{font}(\|p);{}$\5
+${}\|d\K\\{char\_width}(\|f)(\\{char\_info}(\|f)(\\{character}(\|p)));{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\&{switch} (\\{type}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{hlist\_node}:\5
+\&{case} \\{vlist\_node}:\5
+\&{case} \\{rule\_node}:\6
+${}\{{}$\5
+\1${}\|d\K\\{width}(\|p);{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{ligature\_node}:\5
+\X652:Make node \|p look like a \\{char\_node} and \&{goto} \\{reswitch}\X\6
+\4\&{case} \\{kern\_node}:\5
+\&{case} \\{math\_node}:\5
+${}\|d\K\\{width}(\|p){}$;\5
+\&{break};\6
+\4\&{case} \\{glue\_node}:\5
+\X1148:Let \|d be the natural width of this glue; if stretching or shrinking, set \|v: $\K$ \\{max\_dimen}; \&{goto} \\{found} in the case of leaders\X\5
+\&{break};\6
+\4\&{case} \\{whatsit\_node}:\5
+\X1361:Let \|d be the width of the whatsit \|p\X;\5
+\&{break};\6
+\4\&{default}:\5
+${}\|d\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\U1146.\fi
+
+\M{1148}We need to be careful that \|w, \|v, and \|d do not depend on any \\{glue\_set}
+values, since such values are subject to system-dependent rounding.
+System-dependent numbers are not allowed to infiltrate parameters like
+\\{pre\_display\_size}, since \TeX82 is supposed to make the same decisions on all
+machines.
+
+\Y\B\4\X1148:Let \|d be the natural width of this glue; if stretching or shrinking, set \|v: $\K$ \\{max\_dimen}; \&{goto} \\{found} in the case of leaders\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{glue\_ptr}(\|p);{}$\5
+${}\|d\K\\{width}(\|q);{}$\6
+\&{if} ${}(\\{glue\_sign}(\\{just\_box})\E\\{stretching}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{glue\_order}(\\{just\_box})\E\\{stretch\_order}(\|q))\W\30(\\{stretch}(\|q)\I\T{0})){}$\1\5
+${}\|v\K\\{max\_dimen};{}$\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{glue\_sign}(\\{just\_box})\E\\{shrinking}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{glue\_order}(\\{just\_box})\E\\{shrink\_order}(\|q))\W\30(\\{shrink}(\|q)\I\T{0})){}$\1\5
+${}\|v\K\\{max\_dimen};{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{subtype}(\|p)\G\\{a\_leaders}){}$\1\5
+\&{goto} \\{found};\2\6
+\4${}\}{}$\2\par
+\U1147.\fi
+
+\M{1149}A displayed equation is considered to be three lines long, so we
+calculate the length and offset of line number $\\{prev\_graf}+\T{2}$.
+
+\Y\B\4\X1149:Calculate the length, \|l, and the shift amount, \|s, of the display lines\X${}\E{}$\6
+\&{if} ${}(\\{par\_shape\_ptr}\E\\{null}){}$\1\6
+\&{if} ${}((\\{hang\_indent}\I\T{0})\W\30(((\\{hang\_after}\G\T{0})\W(\\{prev\_graf}+\T{2}>\\{hang\_after}))\V\30(\\{prev\_graf}+\T{1}<{-}\\{hang\_after}))){}$\5
+${}\{{}$\5
+\1${}\|l\K\\{hsize}-\\{abs}(\\{hang\_indent});{}$\6
+\&{if} ${}(\\{hang\_indent}>\T{0}){}$\1\5
+${}\|s\K\\{hang\_indent}{}$;\5
+\2\&{else}\1\5
+${}\|s\K\T{0};{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|l\K\\{hsize};{}$\5
+${}\|s\K\T{0};{}$\6
+\4${}\}{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|n\K\\{info}(\\{par\_shape\_ptr});{}$\6
+\&{if} ${}(\\{prev\_graf}+\T{2}\G\|n){}$\1\5
+${}\|p\K\\{par\_shape\_ptr}+\T{2}*\|n;{}$\2\6
+\&{else}\1\5
+${}\|p\K\\{par\_shape\_ptr}+\T{2}*(\\{prev\_graf}+\T{2});{}$\2\6
+${}\|s\K\\{mem}[\|p-\T{1}].\\{sc};{}$\5
+${}\|l\K\\{mem}[\|p].\\{sc};{}$\6
+\4${}\}{}$\2\par
+\U1145.\fi
+
+\M{1150}Subformulas of math formulas cause a new level of math mode to be entered,
+on the semantic nest as well as the save stack. These subformulas arise in
+several ways: (1)~A left brace by itself indicates the beginning of a
+subformula that will be put into a box, thereby freezing its glue and
+preventing line breaks. (2)~A subscript or superscript is treated as a
+subformula if it is not a single character; the same applies to
+the nucleus of things like \.{\\underline}. (3)~The \.{\\left} primitive
+initiates a subformula that will be terminated by a matching \.{\\right}.
+The group codes placed on \\{save\_stack} in these three cases are
+\\{math\_group}, \\{math\_group}, and \\{math\_left\_group}, respectively.
+
+Here is the code that handles case (1); the other cases are not quite as
+trivial, so we shall consider them later.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{left\_brace}{}$:\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_noad}(\,));\5
+\\{back\_input}(\,);\5
+\\{scan\_math}(\\{nucleus}(\\{tail}));\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1151}Recall that the \\{nucleus}, \\{subscr}, and \\{supscr} fields in a noad are
+broken down into subfields called \\{math\_type} and either \\{info} or
+$(\\{fam},\\{character})$. The job of \\{scan\_math} is to figure out what to place
+in one of these principal fields; it looks at the subformula that
+comes next in the input, and places an encoding of that subformula
+into a given word of \\{mem}.
+
+\Y\B\4\D$\\{fam\_in\_range}$ \5
+$((\\{cur\_fam}\G\T{0})\W(\\{cur\_fam}<\T{16}){}$)\par
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_math}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|c;\C{math character code}\7
+\4\\{restart}:\5
+\X404:Get the next non-blank non-relax non-call token\X;\6
+\4\\{reswitch}:\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{letter}:\5
+\&{case} \\{other\_char}:\5
+\&{case} \\{char\_given}:\6
+${}\{{}$\5
+\1${}\|c\K\\{ho}(\\{math\_code}(\\{cur\_chr}));{}$\6
+\&{if} ${}(\|c\E\T{\~100000}){}$\5
+${}\{{}$\5
+\1\X1152:Treat \\{cur\_chr} as an active character\X;\6
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{char\_num}:\6
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\\{cur\_chr}\K\\{cur\_val};{}$\5
+${}\\{cur\_cmd}\K\\{char\_given};{}$\5
+\&{goto} \\{reswitch};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{math\_char\_num}:\6
+${}\{{}$\5
+\1\\{scan\_fifteen\_bit\_int}(\,);\5
+${}\|c\K\\{cur\_val};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{math\_given}:\5
+${}\|c\K\\{cur\_chr}{}$;\5
+\&{break};\6
+\4\&{case} \\{delim\_num}:\6
+${}\{{}$\5
+\1\\{scan\_twenty\_seven\_bit\_int}(\,);\5
+${}\|c\K\\{cur\_val}/\T{\~10000};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\X1153:Scan a subformula enclosed in braces and \&{return}\X\6
+\4${}\}{}$\2\6
+${}\\{math\_type}(\|p)\K\\{math\_char};{}$\5
+${}\\{character}(\|p)\K\\{qi}(\|c\MOD\T{256});{}$\6
+\&{if} ${}((\|c\G\\{var\_code})\W\\{fam\_in\_range}){}$\1\5
+${}\\{fam}(\|p)\K\\{cur\_fam};{}$\2\6
+\&{else}\1\5
+${}\\{fam}(\|p)\K(\|c/\T{256})\MOD\T{16};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1152}An active character that is an \\{outer\_call} is allowed here.
+
+\Y\B\4\X1152:Treat \\{cur\_chr} as an active character\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{cur\_cs}\K\\{cur\_chr}+\\{active\_base};{}$\5
+${}\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_cs});{}$\5
+${}\\{cur\_chr}\K\\{equiv}(\\{cur\_cs});{}$\5
+\\{x\_token}(\,);\5
+\\{back\_input}(\,);\6
+\4${}\}{}$\2\par
+\Us1151\ET1155.\fi
+
+\M{1153}The pointer \|p is placed on \\{save\_stack} while a complex subformula
+is being scanned.
+
+\Y\B\4\X1153:Scan a subformula enclosed in braces and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{back\_input}(\,);\5
+\\{scan\_left\_brace}(\,);\6
+${}\\{saved}(\T{0})\K\|p;{}$\5
+\\{incr}(\\{save\_ptr});\5
+\\{push\_math}(\\{math\_group});\5
+\&{return};\6
+\4${}\}{}$\2\par
+\U1151.\fi
+
+\M{1154}The simplest math formula is, of course, `\.{\${ }\$}', when no noads are
+generated. The next simplest cases involve a single character, e.g.,
+`\.{\$x\$}'. Even though such cases may not seem to be very interesting,
+the reader can perhaps understand how happy the author was when `\.{\$x\$}'
+was first properly typeset by \TeX. The code in this section was used.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{letter}{}$:\5
+\&{case} \\{mmode}${}+\\{other\_char}{}$:\5
+\&{case} \\{mmode}${}+\\{char\_given}{}$:\5
+\\{set\_math\_char}(\\{ho}(\\{math\_code}(\\{cur\_chr})));\5
+\&{break};\6
+\4\&{case} \\{mmode}${}+\\{char\_num}{}$:\6
+${}\{{}$\5
+\1\\{scan\_char\_num}(\,);\5
+${}\\{cur\_chr}\K\\{cur\_val};{}$\5
+\\{set\_math\_char}(\\{ho}(\\{math\_code}(\\{cur\_chr})));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mmode}${}+\\{math\_char\_num}{}$:\6
+${}\{{}$\5
+\1\\{scan\_fifteen\_bit\_int}(\,);\5
+\\{set\_math\_char}(\\{cur\_val});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mmode}${}+\\{math\_given}{}$:\5
+\\{set\_math\_char}(\\{cur\_chr});\5
+\&{break};\6
+\4\&{case} \\{mmode}${}+\\{delim\_num}{}$:\6
+${}\{{}$\5
+\1\\{scan\_twenty\_seven\_bit\_int}(\,);\5
+${}\\{set\_math\_char}(\\{cur\_val}/\T{\~10000});{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1155}The \\{set\_math\_char} procedure creates a new noad appropriate to a given
+math code, and appends it to the current mlist. However, if the math code
+is sufficiently large, the \\{cur\_chr} is treated as an active character and
+nothing is appended.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{set\_math\_char}(\&{int} \|c)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new noad}\7
+\&{if} ${}(\|c\G\T{\~100000}){}$\1\5
+\X1152:Treat \\{cur\_chr} as an active character\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_noad}(\,);{}$\5
+${}\\{math\_type}(\\{nucleus}(\|p))\K\\{math\_char};{}$\5
+${}\\{character}(\\{nucleus}(\|p))\K\\{qi}(\|c\MOD\T{256});{}$\5
+${}\\{fam}(\\{nucleus}(\|p))\K(\|c/\T{256})\MOD\T{16};{}$\6
+\&{if} ${}(\|c\G\\{var\_code}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{fam\_in\_range})\1\5
+${}\\{fam}(\\{nucleus}(\|p))\K\\{cur\_fam};{}$\2\6
+${}\\{type}(\|p)\K\\{ord\_noad};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{type}(\|p)\K\\{ord\_noad}+(\|c/\T{\~10000});{}$\2\6
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1156}Primitive math operators like \.{\\mathop} and \.{\\underline} are given
+the command code \\{math\_comp}, supplemented by the noad type that they
+generate.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1649:\.{"mathord"}\X,\39\\{math\_comp},\39\\{ord\_noad});{}$\5
+${}\\{primitive}(\X1650:\.{"mathop"}\X,\39\\{math\_comp},\39\\{op\_noad});{}$\5
+${}\\{primitive}(\X1651:\.{"mathbin"}\X,\39\\{math\_comp},\39\\{bin\_noad});{}$\5
+${}\\{primitive}(\X1652:\.{"mathrel"}\X,\39\\{math\_comp},\39\\{rel\_noad});{}$\5
+${}\\{primitive}(\X1653:\.{"mathopen"}\X,\39\\{math\_comp},\39\\{open\_noad});{}$\5
+${}\\{primitive}(\X1654:\.{"mathclose"}\X,\39\\{math\_comp},\39\\{close\_noad});{}$\5
+${}\\{primitive}(\X1655:\.{"mathpunct"}\X,\39\\{math\_comp},\39\\{punct\_noad});{}$\5
+${}\\{primitive}(\X1656:\.{"mathinner"}\X,\39\\{math\_comp},\39\\{inner\_noad});{}$\5
+${}\\{primitive}(\X1658:\.{"underline"}\X,\39\\{math\_comp},\39\\{under\_noad});{}$\5
+${}\\{primitive}(\X1657:\.{"overline"}\X,\39\\{math\_comp},\39\\{over\_noad}){}$;\6
+${}\\{primitive}(\X1735:\.{"displaylimits"}\X,\39\\{limit\_switch},\39\\{normal});{}$\5
+${}\\{primitive}(\X1661:\.{"limits"}\X,\39\\{limit\_switch},\39\\{limits});{}$\5
+${}\\{primitive}(\X1662:\.{"nolimits"}\X,\39\\{limit\_switch},\39\\{no\_limits}){}$;\par
+\fi
+
+\M{1157}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{math\_comp}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{ord\_noad}:\5
+\\{print\_esc}(\X1649:\.{"mathord"}\X);\5
+\&{break};\6
+\4\&{case} \\{op\_noad}:\5
+\\{print\_esc}(\X1650:\.{"mathop"}\X);\5
+\&{break};\6
+\4\&{case} \\{bin\_noad}:\5
+\\{print\_esc}(\X1651:\.{"mathbin"}\X);\5
+\&{break};\6
+\4\&{case} \\{rel\_noad}:\5
+\\{print\_esc}(\X1652:\.{"mathrel"}\X);\5
+\&{break};\6
+\4\&{case} \\{open\_noad}:\5
+\\{print\_esc}(\X1653:\.{"mathopen"}\X);\5
+\&{break};\6
+\4\&{case} \\{close\_noad}:\5
+\\{print\_esc}(\X1654:\.{"mathclose"}\X);\5
+\&{break};\6
+\4\&{case} \\{punct\_noad}:\5
+\\{print\_esc}(\X1655:\.{"mathpunct"}\X);\5
+\&{break};\6
+\4\&{case} \\{inner\_noad}:\5
+\\{print\_esc}(\X1656:\.{"mathinner"}\X);\5
+\&{break};\6
+\4\&{case} \\{under\_noad}:\5
+\\{print\_esc}(\X1658:\.{"underline"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1657:\.{"overline"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{limit\_switch}:\6
+\&{if} ${}(\\{chr\_code}\E\\{limits}){}$\1\5
+\\{print\_esc}(\X1661:\.{"limits"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{no\_limits}){}$\1\5
+\\{print\_esc}(\X1662:\.{"nolimits"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1735:\.{"displaylimits"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1158}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{math\_comp}{}$:\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_noad}(\,));\5
+${}\\{type}(\\{tail})\K\\{cur\_chr};{}$\5
+\\{scan\_math}(\\{nucleus}(\\{tail}));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mmode}${}+\\{limit\_switch}{}$:\5
+\\{math\_limit\_switch}(\,);\5
+\&{break};\par
+\fi
+
+\M{1159}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{math\_limit\_switch}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{head}\I\\{tail}){}$\1\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{op\_noad}){}$\5
+${}\{{}$\5
+\1${}\\{subtype}(\\{tail})\K\\{cur\_chr};{}$\5
+\&{return};\6
+\4${}\}{}$\2\2\6
+\\{print\_err}(\.{"Limit\ controls\ must}\)\.{\ follow\ a\ math\ opera}\)\.{tor"});\5
+\\{help1}(\.{"I'm\ ignoring\ this\ m}\)\.{isplaced\ \\\\limits\ or}\)\.{\ \\\\nolimits\ command.}\)\.{"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1160}Delimiter fields of noads are filled in by the \\{scan\_delimiter} routine.
+The first parameter of this procedure is the \\{mem} address where the
+delimiter is to be placed; the second tells if this delimiter follows
+\.{\\radical} or not.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{scan\_delimiter}(\&{pointer} \|p${},\39{}$\&{bool} \|r)\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} (\|r)\1\5
+\\{scan\_twenty\_seven\_bit\_int}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\4\&{case} \\{letter}:\5
+\&{case} \\{other\_char}:\5
+${}\\{cur\_val}\K\\{del\_code}(\\{cur\_chr}){}$;\5
+\&{break};\6
+\4\&{case} \\{delim\_num}:\5
+\\{scan\_twenty\_seven\_bit\_int}(\,);\5
+\&{break};\6
+\4\&{default}:\5
+${}\\{cur\_val}\K{-}\T{1};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_val}<\T{0}){}$\1\5
+\X1161:Report that an invalid delimiter code is being changed to null; set~\\{cur\_val}: $\K$ \T{0}\X;\2\6
+${}\\{small\_fam}(\|p)\K(\\{cur\_val}/\T{\~4000000})\MOD\T{16};{}$\5
+${}\\{small\_char}(\|p)\K\\{qi}((\\{cur\_val}/\T{\~10000})\MOD\T{256});{}$\5
+${}\\{large\_fam}(\|p)\K(\\{cur\_val}/\T{256})\MOD\T{16};{}$\5
+${}\\{large\_char}(\|p)\K\\{qi}(\\{cur\_val}\MOD\T{256});{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1161}\B\X1161:Report that an invalid delimiter code is being changed to null; set~\\{cur\_val}: $\K$ \T{0}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ delimiter\ (}\)\.{.\ inserted)"});\5
+\\{help6}(\.{"I\ was\ expecting\ to\ }\)\.{see\ something\ like\ `}\)\.{('\ or\ `\\\\\{'\ or"})\6
+(\.{"`\\\\\}'\ here.\ If\ you\ }\)\.{typed,\ e.g.,\ `\{'\ ins}\)\.{tead\ of\ `\\\\\{',\ you"})\6
+(\.{"should\ probably\ del}\)\.{ete\ the\ `\{'\ by\ typin}\)\.{g\ `1'\ now,\ so\ that"})\6
+(\.{"braces\ don't\ get\ un}\)\.{balanced.\ Otherwise\ }\)\.{just\ proceed."})\6
+(\.{"Acceptable\ delimite}\)\.{rs\ are\ characters\ wh}\)\.{ose\ \\\\delcode\ is"})\6
+(\.{"nonnegative,\ or\ you}\)\.{\ can\ use\ `\\\\delimite}\)\.{r\ <delimiter\ code>'.}\)\.{"});\5
+\\{back\_error}(\,);\5
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\U1160.\fi
+
+\M{1162}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{radical}{}$:\5
+\\{math\_radical}(\,);\5
+\&{break};\par
+\fi
+
+\M{1163}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{math\_radical}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{get\_node}(\\{radical\_noad\_size}));\5
+${}\\{type}(\\{tail})\K\\{radical\_noad};{}$\5
+${}\\{subtype}(\\{tail})\K\\{normal};{}$\5
+${}\\{mem}[\\{nucleus}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{subscr}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{supscr}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{scan\_delimiter}(\\{left\_delimiter}(\\{tail}),\39\\{true});{}$\5
+\\{scan\_math}(\\{nucleus}(\\{tail}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1164}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{accent}{}$:\5
+\&{case} \\{mmode}${}+\\{math\_accent}{}$:\5
+\\{math\_ac}(\,);\5
+\&{break};\par
+\fi
+
+\M{1165}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{math\_ac}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_cmd}\E\\{accent}){}$\1\5
+\X1166:Complain that the user should have said \.{\\mathaccent}\X;\2\6
+\\{tail\_append}(\\{get\_node}(\\{accent\_noad\_size}));\5
+${}\\{type}(\\{tail})\K\\{accent\_noad};{}$\5
+${}\\{subtype}(\\{tail})\K\\{normal};{}$\5
+${}\\{mem}[\\{nucleus}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{subscr}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{supscr}(\\{tail})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{math\_type}(\\{accent\_chr}(\\{tail}))\K\\{math\_char};{}$\5
+\\{scan\_fifteen\_bit\_int}(\,);\5
+${}\\{character}(\\{accent\_chr}(\\{tail}))\K\\{qi}(\\{cur\_val}\MOD\T{256});{}$\6
+\&{if} ${}((\\{cur\_val}\G\\{var\_code})\W\\{fam\_in\_range}){}$\1\5
+${}\\{fam}(\\{accent\_chr}(\\{tail}))\K\\{cur\_fam};{}$\2\6
+\&{else}\1\5
+${}\\{fam}(\\{accent\_chr}(\\{tail}))\K(\\{cur\_val}/\T{256})\MOD\T{16};{}$\2\6
+\\{scan\_math}(\\{nucleus}(\\{tail}));\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1166}\B\X1166:Complain that the user should have said \.{\\mathaccent}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Please\ use\ "});\5
+\\{print\_esc}(\X1545:\.{"mathaccent"}\X);\5
+\\{print\_str}(\.{"\ for\ accents\ in\ mat}\)\.{h\ mode"});\5
+\\{help2}(\.{"I'm\ changing\ \\\\acce}\)\.{nt\ to\ \\\\mathaccent\ h}\)\.{ere;\ wish\ me\ luck."})\6
+(\.{"(Accents\ are\ not\ th}\)\.{e\ same\ in\ formulas\ a}\)\.{s\ they\ are\ in\ text.)}\)\.{"});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1165.\fi
+
+\M{1167}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{vcenter}{}$:\6
+${}\{{}$\5
+\1${}\\{scan\_spec}(\\{vcenter\_group},\39\\{false});{}$\5
+\\{normal\_paragraph}(\,);\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K{-}\\{vmode};{}$\5
+${}\\{prev\_depth}\K\\{ignore\_depth};{}$\6
+\&{if} ${}(\\{every\_vbox}\I\\{null}){}$\1\5
+${}\\{begin\_token\_list}(\\{every\_vbox},\39\\{every\_vbox\_text});{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1168}\B\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{vcenter\_group}:\6
+${}\{{}$\5
+\1\\{end\_graf}(\,);\5
+\\{unsave}(\,);\5
+${}\\{save\_ptr}\K\\{save\_ptr}-\T{2};{}$\5
+${}\|p\K\\{vpack}(\\{link}(\\{head}),\39\\{saved}(\T{1}),\39\\{saved}(\T{0}));{}$\5
+\\{pop\_nest}(\,);\5
+\\{tail\_append}(\\{new\_noad}(\,));\5
+${}\\{type}(\\{tail})\K\\{vcenter\_noad};{}$\5
+${}\\{math\_type}(\\{nucleus}(\\{tail}))\K\\{sub\_box};{}$\5
+${}\\{info}(\\{nucleus}(\\{tail}))\K\|p;{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1169}The routine that inserts a \\{style\_node} holds no surprises.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1645:\.{"displaystyle"}\X,\39\\{math\_style},\39\\{display\_style});{}$\5
+${}\\{primitive}(\X1646:\.{"textstyle"}\X,\39\\{math\_style},\39\\{text\_style});{}$\5
+${}\\{primitive}(\X1647:\.{"scriptstyle"}\X,\39\\{math\_style},\39\\{script\_style});{}$\5
+${}\\{primitive}(\X1648:\.{"scriptscriptstyle"}\X,\39\\{math\_style},\39\\{script\_script\_style}){}$;\par
+\fi
+
+\M{1170}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{math\_style}:\5
+\\{print\_style}(\\{chr\_code});\5
+\&{break};\par
+\fi
+
+\M{1171}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{math\_style}{}$:\5
+\\{tail\_append}(\\{new\_style}(\\{cur\_chr}))\5
+\&{break};\6
+\4\&{case} \\{mmode}${}+\\{non\_script}{}$:\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_glue}(\\{zero\_glue}));\5
+${}\\{subtype}(\\{tail})\K\\{cond\_math\_glue};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{mmode}${}+\\{math\_choice}{}$:\5
+\\{append\_choices}(\,);\5
+\&{break};\par
+\fi
+
+\M{1172}The routine that scans the four mlists of a \.{\\mathchoice} is very
+much like the routine that builds discretionary nodes.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{append\_choices}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_choice}(\,));\5
+\\{incr}(\\{save\_ptr});\5
+${}\\{saved}({-}\T{1})\K\T{0};{}$\5
+\\{push\_math}(\\{math\_choice\_group});\5
+\\{scan\_left\_brace}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1173}\B\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{math\_choice\_group}:\5
+\\{build\_choices}(\,);\5
+\&{break};\par
+\fi
+
+\M{1174}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\hbox{\4}\X1184:Declare the function called \\{fin\_mlist}\X\hbox{}\7
+\&{void} \\{build\_choices}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the current mlist}\7
+\\{unsave}(\,);\5
+${}\|p\K\\{fin\_mlist}(\\{null});{}$\6
+\&{switch} ${}(\\{saved}({-}\T{1})){}$\5
+${}\{{}$\1\6
+\4\&{case} \T{0}:\5
+${}\\{display\_mlist}(\\{tail})\K\|p{}$;\5
+\&{break};\6
+\4\&{case} \T{1}:\5
+${}\\{text\_mlist}(\\{tail})\K\|p{}$;\5
+\&{break};\6
+\4\&{case} \T{2}:\5
+${}\\{script\_mlist}(\\{tail})\K\|p{}$;\5
+\&{break};\6
+\4\&{case} \T{3}:\6
+${}\{{}$\5
+\1${}\\{script\_script\_mlist}(\\{tail})\K\|p;{}$\5
+\\{decr}(\\{save\_ptr});\5
+\&{return};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\C{there are no other cases}\2\6
+${}\\{incr}(\\{saved}({-}\T{1}));{}$\5
+\\{push\_math}(\\{math\_choice\_group});\5
+\\{scan\_left\_brace}(\,);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1175}Subscripts and superscripts are attached to the previous nucleus by the
+action procedure called \\{sub\_sup}. We use the facts that $\\{sub\_mark}\E\\{sup\_mark}+\T{1}$
+and $\\{subscr}(\|p)\E\\{supscr}(\|p)+\T{1}$.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{sub\_mark}{}$:\5
+\&{case} \\{mmode}${}+\\{sup\_mark}{}$:\5
+\\{sub\_sup}(\,);\5
+\&{break};\par
+\fi
+
+\M{1176}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{sub\_sup}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|t;\C{type of previous sub/superscript}\6
+\&{pointer} \|p;\C{field to be filled by \\{scan\_math}}\7
+${}\|t\K\\{empty};{}$\5
+${}\|p\K\\{null};{}$\6
+\&{if} ${}(\\{tail}\I\\{head}){}$\1\6
+\&{if} (\\{scripts\_allowed}(\\{tail}))\5
+${}\{{}$\5
+\1${}\|p\K\\{supscr}(\\{tail})+\\{cur\_cmd}-\\{sup\_mark}{}$;\C{\\{supscr} or \\{subscr}}\6
+${}\|t\K\\{math\_type}(\|p);{}$\6
+\4${}\}{}$\2\2\6
+\&{if} ${}((\|p\E\\{null})\V(\|t\I\\{empty})){}$\1\5
+\X1177:Insert a dummy noad to be sub/superscripted\X;\2\6
+\\{scan\_math}(\|p);\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1177}\B\X1177:Insert a dummy noad to be sub/superscripted\X${}\E{}$\6
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_noad}(\,));\5
+${}\|p\K\\{supscr}(\\{tail})+\\{cur\_cmd}-\\{sup\_mark}{}$;\C{\\{supscr} or \\{subscr}}\6
+\&{if} ${}(\|t\I\\{empty}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_cmd}\E\\{sup\_mark}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Double\ superscript"});\5
+\\{help1}(\.{"I\ treat\ `x\^1\^2'\ ess}\)\.{entially\ like\ `x\^1\{\}}\)\.{\^2'."});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Double\ subscript"});\5
+\\{help1}(\.{"I\ treat\ `x\_1\_2'\ ess}\)\.{entially\ like\ `x\_1\{\}}\)\.{\_2'."});\6
+\4${}\}{}$\2\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1176.\fi
+
+\M{1178}An operation like `\.{\\over}' causes the current mlist to go into a
+state of suspended animation: \\{incompleat\_noad} points to a \\{fraction\_noad}
+that contains the mlist-so-far as its numerator, while the denominator
+is yet to come. Finally when the mlist is finished, the denominator will
+go into the incompleat fraction noad, and that noad will become the
+whole formula, unless it is surrounded by `\.{\\left}' and `\.{\\right}'
+delimiters.
+
+\Y\B\4\D$\\{above\_code}$ \5
+\T{0}\C{ `\.{\\above}' }\par
+\B\4\D$\\{over\_code}$ \5
+\T{1}\C{ `\.{\\over}' }\par
+\B\4\D$\\{atop\_code}$ \5
+\T{2}\C{ `\.{\\atop}' }\par
+\B\4\D$\\{delimited\_code}$ \5
+\T{3}\C{ `\.{\\abovewithdelims}', etc.}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1736:\.{"above"}\X,\39\\{above},\39\\{above\_code}){}$;\6
+${}\\{primitive}(\X1737:\.{"over"}\X,\39\\{above},\39\\{over\_code}){}$;\6
+${}\\{primitive}(\X1738:\.{"atop"}\X,\39\\{above},\39\\{atop\_code}){}$;\6
+${}\\{primitive}(\X1739:\.{"abovewithdelims"}\X,\39\\{above},\39\\{delimited\_code}+\\{above\_code}){}$;\6
+${}\\{primitive}(\X1740:\.{"overwithdelims"}\X,\39\\{above},\39\\{delimited\_code}+\\{over\_code}){}$;\6
+${}\\{primitive}(\X1741:\.{"atopwithdelims"}\X,\39\\{above},\39\\{delimited\_code}+\\{atop\_code}){}$;\par
+\fi
+
+\M{1179}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{above}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{over\_code}:\5
+\\{print\_esc}(\X1737:\.{"over"}\X);\5
+\&{break};\6
+\4\&{case} \\{atop\_code}:\5
+\\{print\_esc}(\X1738:\.{"atop"}\X);\5
+\&{break};\6
+\4\&{case} \\{delimited\_code}${}+\\{above\_code}{}$:\5
+\\{print\_esc}(\X1739:\.{"abovewithdelims"}\X);\5
+\&{break};\6
+\4\&{case} \\{delimited\_code}${}+\\{over\_code}{}$:\5
+\\{print\_esc}(\X1740:\.{"overwithdelims"}\X);\5
+\&{break};\6
+\4\&{case} \\{delimited\_code}${}+\\{atop\_code}{}$:\5
+\\{print\_esc}(\X1741:\.{"atopwithdelims"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1736:\.{"above"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1180}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{above}{}$:\5
+\\{math\_fraction}(\,);\5
+\&{break};\par
+\fi
+
+\M{1181}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{math\_fraction}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|c;\C{the type of generalized fraction we are scanning}\7
+${}\|c\K\\{cur\_chr};{}$\6
+\&{if} ${}(\\{incompleat\_noad}\I\\{null}){}$\1\5
+\X1183:Ignore the fraction operation and complain about this ambiguous case\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{incompleat\_noad}\K\\{get\_node}(\\{fraction\_noad\_size});{}$\5
+${}\\{type}(\\{incompleat\_noad})\K\\{fraction\_noad};{}$\5
+${}\\{subtype}(\\{incompleat\_noad})\K\\{normal};{}$\5
+${}\\{math\_type}(\\{numerator}(\\{incompleat\_noad}))\K\\{sub\_mlist};{}$\5
+${}\\{info}(\\{numerator}(\\{incompleat\_noad}))\K\\{link}(\\{head});{}$\5
+${}\\{mem}[\\{denominator}(\\{incompleat\_noad})].\\{hh}\K\\{empty\_field};{}$\5
+${}\\{mem}[\\{left\_delimiter}(\\{incompleat\_noad})].\\{qqqq}\K\\{null\_delimiter};{}$\5
+${}\\{mem}[\\{right\_delimiter}(\\{incompleat\_noad})].\\{qqqq}\K\\{null\_delimiter}{}$;\6
+${}\\{link}(\\{head})\K\\{null};{}$\5
+${}\\{tail}\K\\{head};{}$\5
+\X1182:Use code \|c to distinguish between generalized fractions\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1182}\B\X1182:Use code \|c to distinguish between generalized fractions\X${}\E{}$\6
+\&{if} ${}(\|c\G\\{delimited\_code}){}$\5
+${}\{{}$\5
+\1${}\\{scan\_delimiter}(\\{left\_delimiter}(\\{incompleat\_noad}),\39\\{false});{}$\5
+${}\\{scan\_delimiter}(\\{right\_delimiter}(\\{incompleat\_noad}),\39\\{false});{}$\6
+\4${}\}{}$\2\6
+\&{switch} ${}(\|c\MOD\\{delimited\_code}){}$\5
+${}\{{}$\1\6
+\4\&{case} \\{above\_code}:\6
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{thickness}(\\{incompleat\_noad})\K\\{cur\_val};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{over\_code}:\5
+${}\\{thickness}(\\{incompleat\_noad})\K\\{default\_code}{}$;\5
+\&{break};\6
+\4\&{case} \\{atop\_code}:\5
+${}\\{thickness}(\\{incompleat\_noad})\K\T{0};{}$\6
+\4${}\}{}$\C{there are no other cases}\2\par
+\U1181.\fi
+
+\M{1183}\B\X1183:Ignore the fraction operation and complain about this ambiguous case\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\|c\G\\{delimited\_code}){}$\5
+${}\{{}$\5
+\1${}\\{scan\_delimiter}(\\{garbage},\39\\{false});{}$\5
+${}\\{scan\_delimiter}(\\{garbage},\39\\{false});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|c\MOD\\{delimited\_code}\E\\{above\_code}){}$\1\5
+\\{scan\_normal\_dimen};\2\6
+\\{print\_err}(\.{"Ambiguous;\ you\ need}\)\.{\ another\ \{\ and\ \}"});\5
+\\{help3}(\.{"I'm\ ignoring\ this\ f}\)\.{raction\ specificatio}\)\.{n,\ since\ I\ don't"})\6
+(\.{"know\ whether\ a\ cons}\)\.{truction\ like\ `x\ \\\\o}\)\.{ver\ y\ \\\\over\ z'"})\6
+(\.{"means\ `\{x\ \\\\over\ y\}}\)\.{\ \\\\over\ z'\ or\ `x\ \\\\o}\)\.{ver\ \{y\ \\\\over\ z\}'."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1181.\fi
+
+\M{1184}At the end of a math formula or subformula, the \\{fin\_mlist} routine is
+called upon to return a pointer to the newly completed mlist, and to
+pop the nest back to the enclosing semantic level. The parameter to
+\\{fin\_mlist}, if not null, points to a \\{right\_noad} that ends the
+current mlist; this \\{right\_noad} has not yet been appended.
+
+\Y\B\4\X1184:Declare the function called \\{fin\_mlist}\X${}\E{}$\6
+\&{pointer} \\{fin\_mlist}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|q;\C{the mlist to return}\7
+\&{if} ${}(\\{incompleat\_noad}\I\\{null}){}$\1\5
+\X1185:Compleat the incompleat noad\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\|q\K\\{link}(\\{head});{}$\6
+\4${}\}{}$\2\6
+\\{pop\_nest}(\,);\5
+\&{return} \|q;\6
+\4${}\}{}$\2\par
+\U1174.\fi
+
+\M{1185}\B\X1185:Compleat the incompleat noad\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{math\_type}(\\{denominator}(\\{incompleat\_noad}))\K\\{sub\_mlist};{}$\5
+${}\\{info}(\\{denominator}(\\{incompleat\_noad}))\K\\{link}(\\{head});{}$\6
+\&{if} ${}(\|p\E\\{null}){}$\1\5
+${}\|q\K\\{incompleat\_noad};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|q\K\\{info}(\\{numerator}(\\{incompleat\_noad}));{}$\6
+\&{if} ${}(\\{type}(\|q)\I\\{left\_noad}){}$\1\5
+\\{confusion}(\X1660:\.{"right"}\X);\2\6
+${}\\{info}(\\{numerator}(\\{incompleat\_noad}))\K\\{link}(\|q);{}$\5
+${}\\{link}(\|q)\K\\{incompleat\_noad};{}$\5
+${}\\{link}(\\{incompleat\_noad})\K\|p;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1184.\fi
+
+\M{1186}Now at last we're ready to see what happens when a right brace occurs
+in a math formula. Two special cases are simplified here: Braces are effectively
+removed when they surround a single Ord without sub/superscripts, or when they
+surround an accent that is the nucleus of an Ord atom.
+
+\Y\B\4\X1085:Cases of \\{handle\_right\_brace} where a \\{right\_brace} triggers a delayed action\X${}\mathrel+\E{}$\6
+\4\&{case} \\{math\_group}:\6
+${}\{{}$\5
+\1\\{unsave}(\,);\5
+\\{decr}(\\{save\_ptr});\6
+${}\\{math\_type}(\\{saved}(\T{0}))\K\\{sub\_mlist};{}$\5
+${}\|p\K\\{fin\_mlist}(\\{null});{}$\5
+${}\\{info}(\\{saved}(\T{0}))\K\|p;{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}(\\{link}(\|p)\E\\{null}){}$\1\6
+\&{if} ${}(\\{type}(\|p)\E\\{ord\_noad}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{math\_type}(\\{subscr}(\|p))\E\\{empty}){}$\1\6
+\&{if} ${}(\\{math\_type}(\\{supscr}(\|p))\E\\{empty}){}$\5
+${}\{{}$\5
+\1${}\\{mem}[\\{saved}(\T{0})].\\{hh}\K\\{mem}[\\{nucleus}(\|p)].\\{hh};{}$\5
+${}\\{free\_node}(\|p,\39\\{noad\_size});{}$\6
+\4${}\}{}$\2\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{type}(\|p)\E\\{accent\_noad}){}$\1\6
+\&{if} ${}(\\{saved}(\T{0})\E\\{nucleus}(\\{tail})){}$\1\6
+\&{if} ${}(\\{type}(\\{tail})\E\\{ord\_noad}){}$\1\5
+\X1187:Replace the tail of the list by \|p\X;\2\2\2\2\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1187}\B\X1187:Replace the tail of the list by \|p\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{head};{}$\6
+\&{while} ${}(\\{link}(\|q)\I\\{tail}){}$\1\5
+${}\|q\K\\{link}(\|q);{}$\2\6
+${}\\{link}(\|q)\K\|p;{}$\5
+${}\\{free\_node}(\\{tail},\39\\{noad\_size});{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\par
+\U1186.\fi
+
+\M{1188}We have dealt with all constructions of math mode except `\.{\\left}' and
+`\.{\\right}', so the picture is completed by the following sections of
+the program.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1659:\.{"left"}\X,\39\\{left\_right},\39\\{left\_noad});{}$\5
+${}\\{primitive}(\X1660:\.{"right"}\X,\39\\{left\_right},\39\\{right\_noad});{}$\5
+${}\\{text}(\\{frozen\_right})\K\X1660:\.{"right"}\X;{}$\5
+${}\\{eqtb}[\\{frozen\_right}]\K\\{eqtb}[\\{cur\_val}]{}$;\par
+\fi
+
+\M{1189}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{left\_right}:\6
+\&{if} ${}(\\{chr\_code}\E\\{left\_noad}){}$\1\5
+\\{print\_esc}(\X1659:\.{"left"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1660:\.{"right"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1190}\B\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{left\_right}{}$:\5
+\\{math\_left\_right}(\,);\5
+\&{break};\par
+\fi
+
+\M{1191}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{math\_left\_right}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|t;\C{\\{left\_noad} or \\{right\_noad}}\6
+\&{pointer} \|p;\C{new noad}\7
+${}\|t\K\\{cur\_chr};{}$\6
+\&{if} ${}((\|t\E\\{right\_noad})\W(\\{cur\_group}\I\\{math\_left\_group})){}$\1\5
+\X1192:Try to recover from mismatched \.{\\right}\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{new\_noad}(\,);{}$\5
+${}\\{type}(\|p)\K\|t;{}$\5
+${}\\{scan\_delimiter}(\\{delimiter}(\|p),\39\\{false});{}$\6
+\&{if} ${}(\|t\E\\{left\_noad}){}$\5
+${}\{{}$\5
+\1\\{push\_math}(\\{math\_left\_group});\5
+${}\\{link}(\\{head})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{fin\_mlist}(\|p);{}$\5
+\\{unsave}(\,);\C{end of \\{math\_left\_group}}\6
+\\{tail\_append}(\\{new\_noad}(\,));\5
+${}\\{type}(\\{tail})\K\\{inner\_noad};{}$\5
+${}\\{math\_type}(\\{nucleus}(\\{tail}))\K\\{sub\_mlist};{}$\5
+${}\\{info}(\\{nucleus}(\\{tail}))\K\|p;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1192}\B\X1192:Try to recover from mismatched \.{\\right}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_group}\E\\{math\_shift\_group}){}$\5
+${}\{{}$\5
+\1${}\\{scan\_delimiter}(\\{garbage},\39\\{false});{}$\5
+\\{print\_err}(\.{"Extra\ "});\5
+\\{print\_esc}(\X1660:\.{"right"}\X);\5
+\\{help1}(\.{"I'm\ ignoring\ a\ \\\\ri}\)\.{ght\ that\ had\ no\ matc}\)\.{hing\ \\\\left."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\2\6
+\4${}\}{}$\2\par
+\U1191.\fi
+
+\M{1193}Here is the only way out of math mode.
+
+\Y\B\4\X1056:Cases of \\{main\_control} that build boxes and lists\X${}\mathrel+\E{}$\6
+\4\&{case} \\{mmode}${}+\\{math\_shift}{}$:\6
+\&{if} ${}(\\{cur\_group}\E\\{math\_shift\_group}){}$\1\5
+\\{after\_math}(\,);\2\6
+\&{else}\1\5
+\\{off\_save}(\,);\5
+\2\&{break};\par
+\fi
+
+\M{1194}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{after\_math}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{bool} \|l;\C{`\.{\\leqno}' instead of `\.{\\eqno}'}\6
+\&{bool} \\{danger};\C{not enough symbol fonts are present}\6
+\&{int} \|m;\C{\\{mmode} or ${-}\\{mmode}$}\6
+\&{pointer} \|p;\C{the formula}\6
+\&{pointer} \|a;\C{box containing equation number}\7
+\X1198:Local variables for finishing a displayed formula\X\6
+${}\\{danger}\K\\{false};{}$\5
+\X1195:Check that the necessary fonts for math symbols are present; if not, flush the current math lists and set \\{danger}: $\K$ \\{true}\X;\6
+${}\|m\K\\{mode};{}$\5
+${}\|l\K\\{false};{}$\5
+${}\|p\K\\{fin\_mlist}(\\{null}){}$;\C{this pops the nest}\6
+\&{if} ${}(\\{mode}\E{-}\|m{}$)\C{end of equation number}\6
+${}\{{}$\5
+\1\X1197:Check that another \.\$ follows\X;\6
+${}\\{cur\_mlist}\K\|p;{}$\5
+${}\\{cur\_style}\K\\{text\_style};{}$\5
+${}\\{mlist\_penalties}\K\\{false};{}$\5
+\\{mlist\_to\_hlist}(\,);\5
+${}\|a\K\\{hpack}(\\{link}(\\{temp\_head}),\39\\{natural});{}$\5
+\\{unsave}(\,);\5
+\\{decr}(\\{save\_ptr});\C{now $\\{cur\_group}\E\\{math\_shift\_group}$}\6
+\&{if} ${}(\\{saved}(\T{0})\E\T{1}){}$\1\5
+${}\|l\K\\{true};{}$\2\6
+${}\\{danger}\K\\{false};{}$\5
+\X1195:Check that the necessary fonts for math symbols are present; if not, flush the current math lists and set \\{danger}: $\K$ \\{true}\X;\6
+${}\|m\K\\{mode};{}$\5
+${}\|p\K\\{fin\_mlist}(\\{null});{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\|a\K\\{null};{}$\2\6
+\&{if} ${}(\|m<\T{0}){}$\1\5
+\X1196:Finish math in text\X\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\|a\E\\{null}){}$\1\5
+\X1197:Check that another \.\$ follows\X;\2\6
+\X1199:Finish displayed math\X;\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1195}\B\X1195:Check that the necessary fonts for math symbols are present; if not, flush the current math lists and set \\{danger}: $\K$ \\{true}\X${}\E{}$\6
+\&{if} ${}((\\{font\_params}[\\{fam\_fnt}(\T{2}+\\{text\_size})]<\\{total\_mathsy\_params})\V\30(\\{font\_params}[\\{fam\_fnt}(\T{2}+\\{script\_size})]<\\{total\_mathsy\_params})\V\30(\\{font\_params}[\\{fam\_fnt}(\T{2}+\\{script\_script\_size})]<%
+\\{total\_mathsy\_params})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Math\ formula\ delete}\)\.{d:\ Insufficient\ symb}\)\.{ol\ fonts"});\6
+\\{help3}(\.{"Sorry,\ but\ I\ can't\ }\)\.{typeset\ math\ unless\ }\)\.{\\\\textfont\ 2"})\6
+(\.{"and\ \\\\scriptfont\ 2\ }\)\.{and\ \\\\scriptscriptfo}\)\.{nt\ 2\ have\ all"})\6
+(\.{"the\ \\\\fontdimen\ val}\)\.{ues\ needed\ in\ math\ s}\)\.{ymbol\ fonts."});\6
+\&{error} (\,)\1\5
+;\2\6
+\\{flush\_math}(\,);\5
+${}\\{danger}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}((\\{font\_params}[\\{fam\_fnt}(\T{3}+\\{text\_size})]<\\{total\_mathex\_params})\V\30(\\{font\_params}[\\{fam\_fnt}(\T{3}+\\{script\_size})]<\\{total\_mathex\_params})\V\30(\\{font\_params}[\\{fam\_fnt}(\T{3}+\\{script\_script%
+\_size})]<\\{total\_mathex\_params})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Math\ formula\ delete}\)\.{d:\ Insufficient\ exte}\)\.{nsion\ fonts"});\6
+\\{help3}(\.{"Sorry,\ but\ I\ can't\ }\)\.{typeset\ math\ unless\ }\)\.{\\\\textfont\ 3"})\6
+(\.{"and\ \\\\scriptfont\ 3\ }\)\.{and\ \\\\scriptscriptfo}\)\.{nt\ 3\ have\ all"})\6
+(\.{"the\ \\\\fontdimen\ val}\)\.{ues\ needed\ in\ math\ e}\)\.{xtension\ fonts."});\6
+\&{error} (\,)\1\5
+;\2\6
+\\{flush\_math}(\,);\5
+${}\\{danger}\K\\{true};{}$\6
+\4${}\}{}$\2\par
+\U1194.\fi
+
+\M{1196}The \\{unsave} is done after everything else here; hence an appearance of
+`\.{\\mathsurround}' inside of `\.{\$...\$}' affects the spacing at these
+particular \.\$'s. This is consistent with the conventions of
+`\.{\$\$...\$\$}', since `\.{\\abovedisplayskip}' inside a display affects the
+space above that display.
+
+\Y\B\4\X1196:Finish math in text\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{tail\_append}(\\{new\_math}(\\{math\_surround},\39\\{before}));{}$\5
+${}\\{cur\_mlist}\K\|p;{}$\5
+${}\\{cur\_style}\K\\{text\_style};{}$\5
+${}\\{mlist\_penalties}\K(\\{mode}>\T{0});{}$\5
+\\{mlist\_to\_hlist}(\,);\5
+${}\\{link}(\\{tail})\K\\{link}(\\{temp\_head});{}$\6
+\&{while} ${}(\\{link}(\\{tail})\I\\{null}){}$\1\5
+${}\\{tail}\K\\{link}(\\{tail});{}$\2\6
+${}\\{tail\_append}(\\{new\_math}(\\{math\_surround},\39\\{after}));{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\5
+\\{unsave}(\,);\6
+\4${}\}{}$\2\par
+\U1194.\fi
+
+\M{1197}\TeX\ gets to the following part of the program when the first `\.\$' ending
+a display has been scanned.
+
+\Y\B\4\X1197:Check that another \.\$ follows\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\I\\{math\_shift}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Display\ math\ should}\)\.{\ end\ with\ \$\$"});\5
+\\{help2}(\.{"The\ `\$'\ that\ I\ just}\)\.{\ saw\ supposedly\ matc}\)\.{hes\ a\ previous\ `\$\$'.}\)\.{"})\6
+(\.{"So\ I\ shall\ assume\ t}\)\.{hat\ you\ typed\ `\$\$'\ b}\)\.{oth\ times."});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\Us1194\ET1206.\fi
+
+\M{1198}We have saved the worst for last: The fussiest part of math mode processing
+occurs when a displayed formula is being centered and placed with an optional
+equation number.
+
+\Y\B\4\X1198:Local variables for finishing a displayed formula\X${}\E{}$\6
+\&{pointer} \|b;\C{box containing the equation}\6
+\&{scaled} \|w;\C{width of the equation}\6
+\&{scaled} \|z;\C{width of the line}\6
+\&{scaled} \|e;\C{width of equation number}\6
+\&{scaled} \|q;\C{width of equation number plus space to separate from equation}\6
+\&{scaled} \|d;\C{displacement of equation in the line}\6
+\&{scaled} \|s;\C{move the line right this much}\6
+\&{small\_number} \\{g1}${},{}$ \\{g2};\C{glue parameter codes for before and after}\6
+\&{pointer} \|r;\C{kern node used to position the display}\6
+\&{pointer} \|t;\C{tail of adjustment list}\par
+\U1194.\fi
+
+\M{1199}At this time \|p points to the mlist for the formula; \|a is either
+\\{null} or it points to a box containing the equation number; and we are in
+vertical mode (or internal vertical mode).
+
+\Y\B\4\X1199:Finish displayed math\X${}\E{}$\6
+$\\{cur\_mlist}\K\|p;{}$\5
+${}\\{cur\_style}\K\\{display\_style};{}$\5
+${}\\{mlist\_penalties}\K\\{false};{}$\5
+\\{mlist\_to\_hlist}(\,);\5
+${}\|p\K\\{link}(\\{temp\_head}){}$;\6
+${}\\{adjust\_tail}\K\\{adjust\_head};{}$\5
+${}\|b\K\\{hpack}(\|p,\39\\{natural});{}$\5
+${}\|p\K\\{list\_ptr}(\|b);{}$\5
+${}\|t\K\\{adjust\_tail};{}$\5
+${}\\{adjust\_tail}\K\\{null}{}$;\6
+${}\|w\K\\{width}(\|b);{}$\5
+${}\|z\K\\{display\_width};{}$\5
+${}\|s\K\\{display\_indent};{}$\6
+\&{if} ${}((\|a\E\\{null})\V\\{danger}){}$\5
+${}\{{}$\5
+\1${}\|e\K\T{0};{}$\5
+${}\|q\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|e\K\\{width}(\|a);{}$\5
+${}\|q\K\|e+\\{math\_quad}(\\{text\_size});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|w+\|q>\|z){}$\1\5
+\X1201:Squeeze the equation as much as possible; if there is an equation number that should go on a separate line by itself, set~\|e: $\K$ \T{0}\X;\2\6
+\X1202:Determine the displacement, \|d, of the left edge of the equation, with respect to the line size \|z, assuming that $\|l\K\\{false}$\X;\6
+\X1203:Append the glue or equation number preceding the display\X;\6
+\X1204:Append the display and perhaps also the equation number\X;\6
+\X1205:Append the glue or equation number following the display\X;\6
+\\{resume\_after\_display}(\,)\par
+\U1194.\fi
+
+\M{1200}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{resume\_after\_display}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_group}\I\\{math\_shift\_group}){}$\1\5
+\\{confusion}(\X1742:\.{"display"}\X);\2\6
+\\{unsave}(\,);\5
+${}\\{prev\_graf}\K\\{prev\_graf}+\T{3};{}$\5
+\\{push\_nest}(\,);\5
+${}\\{mode}\K\\{hmode};{}$\5
+${}\\{space\_factor}\K\T{1000};{}$\5
+\\{set\_cur\_lang};\5
+${}\\{clang}\K\\{cur\_lang};{}$\5
+${}\\{prev\_graf}\K(\\{norm\_min}(\\{left\_hyphen\_min})*\T{\~100}+\\{norm\_min}(\\{right\_hyphen\_min}))*\T{\~200000}+\\{cur\_lang};{}$\5
+\X443:Scan an optional space\X;\6
+\&{if} ${}(\\{nest\_ptr}\E\T{1}){}$\1\5
+\\{build\_page}(\,);\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1201}The user can force the equation number to go on a separate line
+by causing its width to be zero.
+
+\Y\B\4\X1201:Squeeze the equation as much as possible; if there is an equation number that should go on a separate line by itself, set~\|e: $\K$ \T{0}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}((\|e\I\T{0})\W((\|w-\\{total\_shrink}[\\{normal}]+\|q\Z\|z)\V\30(\\{total\_shrink}[\\{fil}]\I\T{0})\V(\\{total\_shrink}[\\{fill}]\I\T{0})\V(\\{total\_shrink}[\\{filll}]\I\T{0}))){}$\5
+${}\{{}$\5
+\1${}\\{free\_node}(\|b,\39\\{box\_node\_size});{}$\5
+${}\|b\K\\{hpack}(\|p,\39\|z-\|q,\39\\{exactly});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|e\K\T{0};{}$\6
+\&{if} ${}(\|w>\|z){}$\5
+${}\{{}$\5
+\1${}\\{free\_node}(\|b,\39\\{box\_node\_size});{}$\5
+${}\|b\K\\{hpack}(\|p,\39\|z,\39\\{exactly});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+${}\|w\K\\{width}(\|b);{}$\6
+\4${}\}{}$\2\par
+\U1199.\fi
+
+\M{1202}We try first to center the display without regard to the existence of
+the equation number. If that would make it too close (where ``too close''
+means that the space between display and equation number is less than the
+width of the equation number), we either center it in the remaining space
+or move it as far from the equation number as possible. The latter alternative
+is taken only if the display begins with glue, since we assume that the
+user put glue there to control the spacing precisely.
+
+\Y\B\4\X1202:Determine the displacement, \|d, of the left edge of the equation, with respect to the line size \|z, assuming that $\|l\K\\{false}$\X${}\E{}$\6
+$\|d\K\\{half}(\|z-\|w);{}$\6
+\&{if} ${}((\|e>\T{0})\W(\|d<\T{2}*\|e){}$)\C{too close}\6
+${}\{{}$\5
+\1${}\|d\K\\{half}(\|z-\|w-\|e);{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\6
+\&{if} ${}(\R\\{is\_char\_node}(\|p)){}$\1\6
+\&{if} ${}(\\{type}(\|p)\E\\{glue\_node}){}$\1\5
+${}\|d\K\T{0};{}$\2\2\2\6
+\4${}\}{}$\2\par
+\U1199.\fi
+
+\M{1203}If the equation number is set on a line by itself, either before or
+after the formula, we append an infinite penalty so that no page break will
+separate the display from its number; and we use the same size and
+displacement for all three potential lines of the display, even though
+`\.{\\parshape}' may specify them differently.
+
+\Y\B\4\X1203:Append the glue or equation number preceding the display\X${}\E{}$\6
+\\{tail\_append}(\\{new\_penalty}(\\{pre\_display\_penalty}));\6
+\&{if} ${}((\|d+\|s\Z\\{pre\_display\_size})\V\|l{}$)\C{not enough clearance}\6
+${}\{{}$\5
+\1${}\\{g1}\K\\{above\_display\_skip\_code};{}$\5
+${}\\{g2}\K\\{below\_display\_skip\_code};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{g1}\K\\{above\_display\_short\_skip\_code};{}$\5
+${}\\{g2}\K\\{below\_display\_short\_skip\_code};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|l\W(\|e\E\T{0}){}$)\C{it follows that $\\{type}(\|a)\E\\{hlist\_node}$}\6
+${}\{{}$\5
+\1${}\\{shift\_amount}(\|a)\K\|s;{}$\5
+\\{append\_to\_vlist}(\|a);\5
+\\{tail\_append}(\\{new\_penalty}(\\{inf\_penalty}));\6
+\4${}\}{}$\2\6
+\&{else} \\{tail\_append}(\\{new\_param\_glue}(\\{g1}))\par
+\U1199.\fi
+
+\M{1204}\B\X1204:Append the display and perhaps also the equation number\X${}\E{}$\6
+\&{if} ${}(\|e\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\|r\K\\{new\_kern}(\|z-\|w-\|e-\|d);{}$\6
+\&{if} (\|l)\5
+${}\{{}$\5
+\1${}\\{link}(\|a)\K\|r;{}$\5
+${}\\{link}(\|r)\K\|b;{}$\5
+${}\|b\K\|a;{}$\5
+${}\|d\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{link}(\|b)\K\|r;{}$\5
+${}\\{link}(\|r)\K\|a;{}$\6
+\4${}\}{}$\2\6
+${}\|b\K\\{hpack}(\|b,\39\\{natural});{}$\6
+\4${}\}{}$\2\6
+${}\\{shift\_amount}(\|b)\K\|s+\|d;$ \\{append\_to\_vlist}(\|b)\par
+\U1199.\fi
+
+\M{1205}\B\X1205:Append the glue or equation number following the display\X${}\E{}$\6
+\&{if} ${}((\|a\I\\{null})\W(\|e\E\T{0})\W\R\|l){}$\5
+${}\{{}$\5
+\1\\{tail\_append}(\\{new\_penalty}(\\{inf\_penalty}));\5
+${}\\{shift\_amount}(\|a)\K\|s+\|z-\\{width}(\|a);{}$\5
+\\{append\_to\_vlist}(\|a);\5
+${}\\{g2}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|t\I\\{adjust\_head}{}$)\C{migrating material comes after equation number}\6
+${}\{{}$\5
+\1${}\\{link}(\\{tail})\K\\{link}(\\{adjust\_head});{}$\5
+${}\\{tail}\K\|t;{}$\6
+\4${}\}{}$\2\6
+\\{tail\_append}(\\{new\_penalty}(\\{post\_display\_penalty})); \&{if} ${}(\\{g2}>\T{0})$ \\{tail\_append}(\\{new\_param\_glue}(\\{g2}))\par
+\U1199.\fi
+
+\M{1206}When \.{\\halign} appears in a display, the alignment routines operate
+essentially as they do in vertical mode. Then the following program is
+activated, with \|p and \|q pointing to the beginning and end of the
+resulting list, and with \\{aux\_save} holding the \\{prev\_depth} value.
+
+\Y\B\4\X1206:Finish an alignment in a display\X${}\E{}$\6
+${}\{{}$\5
+\1\\{do\_assignments}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\I\\{math\_shift}){}$\1\5
+\X1207:Pontificate about improper alignment in display\X\2\6
+\&{else}\1\5
+\X1197:Check that another \.\$ follows\X;\2\6
+\\{pop\_nest}(\,);\5
+\\{tail\_append}(\\{new\_penalty}(\\{pre\_display\_penalty}));\5
+\\{tail\_append}(\\{new\_param\_glue}(\\{above\_display\_skip\_code}));\5
+${}\\{link}(\\{tail})\K\|p;{}$\6
+\&{if} ${}(\|p\I\\{null}){}$\1\5
+${}\\{tail}\K\|q;{}$\2\6
+\\{tail\_append}(\\{new\_penalty}(\\{post\_display\_penalty}));\5
+\\{tail\_append}(\\{new\_param\_glue}(\\{below\_display\_skip\_code}));\5
+${}\\{prev\_depth}\K\\{aux\_save}.\\{sc};{}$\5
+\\{resume\_after\_display}(\,);\6
+\4${}\}{}$\2\par
+\U812.\fi
+
+\M{1207}\B\X1207:Pontificate about improper alignment in display\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ \$\$\ inserted}\)\.{"});\5
+\\{help2}(\.{"Displays\ can\ use\ sp}\)\.{ecial\ alignments\ (li}\)\.{ke\ \\\\eqalignno)"})\6
+(\.{"only\ if\ nothing\ but}\)\.{\ the\ alignment\ itsel}\)\.{f\ is\ between\ \$\$'s."});\5
+\\{back\_error}(\,);\6
+\4${}\}{}$\2\par
+\U1206.\fi
+
+\N{1}{1208}Mode-independent processing.
+The long \\{main\_control} procedure has now been fully specified, except for
+certain activities that are independent of the current mode. These activities
+do not change the current vlist or hlist or mlist; if they change anything,
+it is the value of a parameter or the meaning of a control sequence.
+
+Assignments to values in \\{eqtb} can be global or local. Furthermore, a
+control sequence can be defined to be `\.{\\long}' or `\.{\\outer}', and
+it might or might not be expanded. The prefixes `\.{\\global}', `\.{\\long}',
+and `\.{\\outer}' can occur in any order. Therefore we assign binary numeric
+codes, making it possible to accumulate the union of all specified prefixes
+by adding the corresponding codes. (\PASCAL's \\{set} operations could also
+have been used.)
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1743:\.{"long"}\X,\39\\{prefix},\39\T{1});{}$\5
+${}\\{primitive}(\X1744:\.{"outer"}\X,\39\\{prefix},\39\T{2});{}$\5
+${}\\{primitive}(\X1745:\.{"global"}\X,\39\\{prefix},\39\T{4});{}$\5
+${}\\{primitive}(\X1746:\.{"def"}\X,\39\\{def},\39\T{0});{}$\5
+${}\\{primitive}(\X1747:\.{"gdef"}\X,\39\\{def},\39\T{1});{}$\5
+${}\\{primitive}(\X1748:\.{"edef"}\X,\39\\{def},\39\T{2});{}$\5
+${}\\{primitive}(\X1749:\.{"xdef"}\X,\39\\{def},\39\T{3}){}$;\par
+\fi
+
+\M{1209}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{prefix}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1743:\.{"long"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\T{2}){}$\1\5
+\\{print\_esc}(\X1744:\.{"outer"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1745:\.{"global"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{def}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1746:\.{"def"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1747:\.{"gdef"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\T{2}){}$\1\5
+\\{print\_esc}(\X1748:\.{"edef"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1749:\.{"xdef"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1210}Every prefix, and every command code that might or might not be prefixed,
+calls the action procedure \\{prefixed\_command}. This routine accumulates
+a sequence of prefixes until coming to a non-prefix, then it carries out
+the command.
+
+\Y\B\4\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\E{}$\6
+\\{any\_mode}(\\{toks\_register}):\5
+\\{any\_mode}(\\{assign\_toks}):\5
+\\{any\_mode}(\\{assign\_int}):\5
+\\{any\_mode}(\\{assign\_dimen}):\5
+\\{any\_mode}(\\{assign\_glue}):\5
+\\{any\_mode}(\\{assign\_mu\_glue}):\5
+\\{any\_mode}(\\{assign\_font\_dimen}):\5
+\\{any\_mode}(\\{assign\_font\_int}):\5
+\\{any\_mode}(\\{set\_aux}):\5
+\\{any\_mode}(\\{set\_prev\_graf}):\5
+\\{any\_mode}(\\{set\_page\_dimen}):\5
+\\{any\_mode}(\\{set\_page\_int}):\5
+\\{any\_mode}(\\{set\_box\_dimen}):\5
+\\{any\_mode}(\\{set\_shape}):\5
+\\{any\_mode}(\\{def\_code}):\5
+\\{any\_mode}(\\{def\_family}):\5
+\\{any\_mode}(\\{set\_font}):\5
+\\{any\_mode}(\\{def\_font}): \\{any\_mode}(\&{register}) : \6
+\4\\{any\_mode}(\\{advance}):\5
+\\{any\_mode}(\\{multiply}):\5
+\\{any\_mode}(\\{divide}):\5
+\\{any\_mode}(\\{prefix}):\5
+\\{any\_mode}(\\{let}):\5
+\\{any\_mode}(\\{shorthand\_def}):\5
+\\{any\_mode}(\\{read\_to\_cs}):\5
+\\{any\_mode}(\\{def}):\5
+\\{any\_mode}(\\{set\_box}):\5
+\\{any\_mode}(\\{hyph\_data}):\5
+\\{any\_mode}(\\{set\_interaction}):\5
+\\{prefixed\_command}(\,);\5
+\&{break};\par
+\As1268, 1271, 1274, 1276, 1285\ETs1290.
+\U1045.\fi
+
+\M{1211}If the user says, e.g., `\.{\\global\\global}', the redundancy is
+silently accepted.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\hbox{\4}\X1215:Declare subprocedures for \\{prefixed\_command}\X\hbox{}\7
+\&{void} \\{prefixed\_command}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|a;\C{accumulated prefix codes so far}\6
+\&{internal\_font\_number} \|f;\C{identifies a font}\6
+\&{int} \|j;\C{index into a \.{\\parshape} specification}\6
+\&{font\_index} \|k;\C{index into \\{font\_info}}\6
+\&{pointer} \|p${},{}$ \|q;\C{for temporary short-term use}\6
+\&{int} \|n;\C{ditto}\6
+\&{bool} \|e;\C{should a definition be expanded? or was \.{\\let} not done?}\7
+${}\|a\K\T{0};{}$\6
+\&{while} ${}(\\{cur\_cmd}\E\\{prefix}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{odd}(\|a/\\{cur\_chr})){}$\1\5
+${}\|a\K\|a+\\{cur\_chr};{}$\2\6
+\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{max\_non\_prefixed\_command}){}$\1\5
+\X1212:Discard erroneous prefixes and \&{return}\X;\2\6
+\4${}\}{}$\2\6
+\X1213:Discard the prefixes \.{\\long} and \.{\\outer} if they are irrelevant\X;\6
+\X1214:Adjust \(f)for the setting of \.{\\globaldefs}\X;\6
+\&{switch} (\\{cur\_cmd})\5
+${}\{{}$\1\6
+\hbox{\4}\X1217:Assignments\X\6
+\4\&{default}:\5
+\\{confusion}(\X1750:\.{"prefix"}\X);\6
+\4${}\}{}$\2\6
+\4\\{done}:\5
+\X1269:Insert a token saved by \.{\\afterassignment}, if any\X;\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1212}\B\X1212:Discard erroneous prefixes and \&{return}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ a\ pre}\)\.{fix\ with\ `"});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_char}(\.{'\\''});\5
+\\{help1}(\.{"I'll\ pretend\ you\ di}\)\.{dn't\ say\ \\\\long\ or\ \\}\)\.{\\outer\ or\ \\\\global."});\5
+\\{back\_error}(\,);\5
+\&{return};\6
+\4${}\}{}$\2\par
+\U1211.\fi
+
+\M{1213}\B\X1213:Discard the prefixes \.{\\long} and \.{\\outer} if they are irrelevant\X${}\E{}$\6
+\&{if} ${}((\\{cur\_cmd}\I\\{def})\W(\|a\MOD\T{4}\I\T{0})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ `"});\5
+\\{print\_esc}(\X1743:\.{"long"}\X);\5
+\\{print\_str}(\.{"'\ or\ `"});\5
+\\{print\_esc}(\X1744:\.{"outer"}\X);\5
+\\{print\_str}(\.{"'\ with\ `"});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_char}(\.{'\\''});\5
+\\{help1}(\.{"I'll\ pretend\ you\ di}\)\.{dn't\ say\ \\\\long\ or\ \\}\)\.{\\outer\ here."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\U1211.\fi
+
+\M{1214}The previous routine does not have to adjust \|a so that $\|a\MOD\T{4}\E\T{0}$,
+since the following routines test for the \.{\\global} prefix as follows.
+
+\Y\B\4\D$\\{global}$ \5
+$(\|a\G\T{4}{}$)\par
+\B\4\D$\&{define}(\|X,\|Y,\|Z)$ \6
+\&{if} (\\{global})\1\5
+${}\\{geq\_define}(\|X,\39\|Y,\39\|Z){}$;\5
+\2\&{else} $\\{eq\_define}(\|X,\39\|Y,\39\|Z{}$)\par
+\B\4\D$\\{word\_define}(\|X,\|Y)$ \6
+\&{if} (\\{global})\1\5
+${}\\{geq\_word\_define}(\|X,\39\|Y){}$;\5
+\2\&{else} $\\{eq\_word\_define}(\|X,\39\|Y{}$)\par
+\Y\B\4\X1214:Adjust \(f)for the setting of \.{\\globaldefs}\X${}\E{}$\6
+\&{if} ${}(\\{global\_defs}\I\T{0}){}$\1\6
+\&{if} ${}(\\{global\_defs}<\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} (\\{global})\1\5
+${}\|a\K\|a-\T{4};{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\R\\{global}){}$\1\5
+${}\|a\K\|a+\T{4};{}$\2\6
+\4${}\}{}$\2\2\par
+\U1211.\fi
+
+\M{1215}When a control sequence is to be defined, by \.{\\def} or \.{\\let} or
+something similar, the \\{get\_r\_token} routine will substitute a special
+control sequence for a token that is not redefinable.
+
+\Y\B\4\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\E{}$\6
+\&{void} \\{get\_r\_token}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{restart}:\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_tok}\I\\{space\_token}));{}$\6
+\&{if} ${}((\\{cur\_cs}\E\T{0})\V(\\{cur\_cs}>\\{frozen\_control\_sequence})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ control\ seq}\)\.{uence\ inserted"});\5
+\\{help5}(\.{"Please\ don't\ say\ `\\}\)\.{\\def\ cs\{...\}',\ say\ `}\)\.{\\\\def\\\\cs\{...\}'."})\6
+(\.{"I've\ inserted\ an\ in}\)\.{accessible\ control\ s}\)\.{equence\ so\ that\ your}\)\.{"})\6
+(\.{"definition\ will\ be\ }\)\.{completed\ without\ mi}\)\.{xing\ me\ up\ too\ badly}\)\.{."})\6
+(\.{"You\ can\ recover\ gra}\)\.{ciously\ from\ this\ er}\)\.{ror,\ if\ you're"})\6
+(\.{"careful;\ see\ exerci}\)\.{se\ 27.2\ in\ The\ TeXbo}\)\.{ok."});\6
+\&{if} ${}(\\{cur\_cs}\E\T{0}){}$\1\5
+\\{back\_input}(\,);\2\6
+${}\\{cur\_tok}\K\\{cs\_token\_flag}+\\{frozen\_protection};{}$\5
+\\{ins\_error}(\,);\5
+\&{goto} \\{restart};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\As1229, 1236, 1243, 1244, 1245, 1246, 1247, 1257\ETs1265.
+\U1211.\fi
+
+\M{1216}\B\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{text}(\\{frozen\_protection})\K\X1751:\.{"inaccessible"}\X{}$;\par
+\fi
+
+\M{1217}Here's an example of the way many of the following routines operate.
+(Unfortunately, they aren't all as simple as this.)
+
+\Y\B\4\X1217:Assignments\X${}\E{}$\6
+\&{case} \\{set\_font}: \&{define} $(\\{cur\_font\_loc},\39\\{data},\39\\{cur\_chr}){}$;\5
+\&{break};\par
+\As1218, 1221, 1224, 1225, 1226, 1228, 1232, 1234, 1235, 1241, 1242, 1248, 1252, 1253, 1256\ETs1264.
+\U1211.\fi
+
+\M{1218}When a \\{def} command has been scanned,
+\\{cur\_chr} is odd if the definition is supposed to be global, and
+$\\{cur\_chr}\G\T{2}$ if the definition is supposed to be expanded.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{def}: $\{{}$\5
+\&{if} ${}(\\{odd}(\\{cur\_chr})\W\R\\{global}\W(\\{global\_defs}\G\T{0})){}$\1\5
+${}\|a\K\|a+\T{4};{}$\2\6
+${}\|e\K(\\{cur\_chr}\G\T{2});{}$\5
+\\{get\_r\_token}(\,);\5
+${}\|p\K\\{cur\_cs};{}$\5
+${}\|q\K\\{scan\_toks}(\\{true},\39\|e);$ \&{define} $(\|p,\39\\{call}+(\|a\MOD\T{4}),\39\\{def\_ref});$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1219}Both \.{\\let} and \.{\\futurelet} share the command code \\{let}.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1752:\.{"let"}\X,\39\\{let},\39\\{normal}){}$;\6
+${}\\{primitive}(\X1753:\.{"futurelet"}\X,\39\\{let},\39\\{normal}+\T{1}){}$;\par
+\fi
+
+\M{1220}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{let}:\6
+\&{if} ${}(\\{chr\_code}\I\\{normal}){}$\1\5
+\\{print\_esc}(\X1753:\.{"futurelet"}\X);\5
+\2\&{else}\1\5
+\\{print\_esc}(\X1752:\.{"let"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1221}\B\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{let}: $\{{}$\5
+$\|n\K\\{cur\_chr};{}$\5
+\\{get\_r\_token}(\,);\5
+${}\|p\K\\{cur\_cs};{}$\6
+\&{if} ${}(\|n\E\\{normal}){}$\5
+${}\{{}$\5
+\1\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_cmd}\I\\{spacer}));{}$\6
+\&{if} ${}(\\{cur\_tok}\E\\{other\_token}+\.{'='}){}$\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\6
+\&{if} ${}(\\{cur\_cmd}\E\\{spacer}){}$\1\5
+\\{get\_token}(\,);\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{get\_token}(\,);\5
+${}\|q\K\\{cur\_tok};{}$\5
+\\{get\_token}(\,);\5
+\\{back\_input}(\,);\5
+${}\\{cur\_tok}\K\|q;{}$\5
+\\{back\_input}(\,);\C{look ahead, then back up}\6
+\4${}\}{}$\C{note that \\{back\_input} doesn't affect \\{cur\_cmd}, \\{cur\_chr}}\2\6
+\&{if} ${}(\\{cur\_cmd}\G\\{call}){}$\1\5
+\\{add\_token\_ref}(\\{cur\_chr});\2\6
+\&{define} $(\|p,\39\\{cur\_cmd},\39\\{cur\_chr});$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1222}A \.{\\chardef} creates a control sequence whose \\{cmd} is \\{char\_given};
+a \.{\\mathchardef} creates a control sequence whose \\{cmd} is \\{math\_given};
+and the corresponding \\{chr} is the character code or math code. A \.{\\countdef}
+or \.{\\dimendef} or \.{\\skipdef} or \.{\\muskipdef} creates a control
+sequence whose \\{cmd} is \\{assign\_int} or \dots\ or \\{assign\_mu\_glue}, and the
+corresponding \\{chr} is the \\{eqtb} location of the internal register in question.
+
+\Y\B\4\D$\\{char\_def\_code}$ \5
+\T{0}\C{\\{shorthand\_def} for \.{\\chardef}}\par
+\B\4\D$\\{math\_char\_def\_code}$ \5
+\T{1}\C{\\{shorthand\_def} for \.{\\mathchardef}}\par
+\B\4\D$\\{count\_def\_code}$ \5
+\T{2}\C{\\{shorthand\_def} for \.{\\countdef}}\par
+\B\4\D$\\{dimen\_def\_code}$ \5
+\T{3}\C{\\{shorthand\_def} for \.{\\dimendef}}\par
+\B\4\D$\\{skip\_def\_code}$ \5
+\T{4}\C{\\{shorthand\_def} for \.{\\skipdef}}\par
+\B\4\D$\\{mu\_skip\_def\_code}$ \5
+\T{5}\C{\\{shorthand\_def} for \.{\\muskipdef}}\par
+\B\4\D$\\{toks\_def\_code}$ \5
+\T{6}\C{\\{shorthand\_def} for \.{\\toksdef}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1754:\.{"chardef"}\X,\39\\{shorthand\_def},\39\\{char\_def\_code}){}$;\6
+${}\\{primitive}(\X1755:\.{"mathchardef"}\X,\39\\{shorthand\_def},\39\\{math\_char\_def\_code}){}$;\6
+${}\\{primitive}(\X1756:\.{"countdef"}\X,\39\\{shorthand\_def},\39\\{count\_def\_code}){}$;\6
+${}\\{primitive}(\X1757:\.{"dimendef"}\X,\39\\{shorthand\_def},\39\\{dimen\_def\_code}){}$;\6
+${}\\{primitive}(\X1758:\.{"skipdef"}\X,\39\\{shorthand\_def},\39\\{skip\_def\_code}){}$;\6
+${}\\{primitive}(\X1759:\.{"muskipdef"}\X,\39\\{shorthand\_def},\39\\{mu\_skip\_def\_code}){}$;\6
+${}\\{primitive}(\X1760:\.{"toksdef"}\X,\39\\{shorthand\_def},\39\\{toks\_def\_code}){}$;\par
+\fi
+
+\M{1223}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{shorthand\_def}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{char\_def\_code}:\5
+\\{print\_esc}(\X1754:\.{"chardef"}\X);\5
+\&{break};\6
+\4\&{case} \\{math\_char\_def\_code}:\5
+\\{print\_esc}(\X1755:\.{"mathchardef"}\X);\5
+\&{break};\6
+\4\&{case} \\{count\_def\_code}:\5
+\\{print\_esc}(\X1756:\.{"countdef"}\X);\5
+\&{break};\6
+\4\&{case} \\{dimen\_def\_code}:\5
+\\{print\_esc}(\X1757:\.{"dimendef"}\X);\5
+\&{break};\6
+\4\&{case} \\{skip\_def\_code}:\5
+\\{print\_esc}(\X1758:\.{"skipdef"}\X);\5
+\&{break};\6
+\4\&{case} \\{mu\_skip\_def\_code}:\5
+\\{print\_esc}(\X1759:\.{"muskipdef"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1760:\.{"toksdef"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{char\_given}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1535:\.{"char"}\X);\5
+\\{print\_hex}(\\{chr\_code});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{math\_given}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1546:\.{"mathchar"}\X);\5
+\\{print\_hex}(\\{chr\_code});\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1224}We temporarily define \|p to be \\{relax}, so that an occurrence of \|p
+while scanning the definition will simply stop the scanning instead of
+producing an ``undefined control sequence'' error or expanding the
+previous meaning. This allows, for instance, `\.{\\chardef\\foo=123\\foo}'.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{shorthand\_def}: $\{{}$\5
+$\|n\K\\{cur\_chr};{}$\5
+\\{get\_r\_token}(\,);\5
+${}\|p\K\\{cur\_cs};$ \&{define} $(\|p,\39\\{relax},\39\T{256});{}$\5
+\\{scan\_optional\_equals}(\,); \&{switch} (\|n) $\{$ \&{case} \\{char\_def\_code}: $\{{}$\5
+\\{scan\_char\_num}(\,); \&{define} $(\|p,\39\\{char\_given},\39\\{cur\_val});$ $\}{}$\5
+\&{break}; \&{case} \\{math\_char\_def\_code}: $\{{}$\5
+\\{scan\_fifteen\_bit\_int}(\,); \&{define} $(\|p,\39\\{math\_given},\39\\{cur\_val});$ $\}{}$\5
+\&{break}; \&{default}: $\{{}$\5
+\\{scan\_eight\_bit\_int}(\,); \&{switch} (\|n) $\{$ \&{case} \\{count\_def\_code}: \&{define} $(\|p,\39\\{assign\_int},\39\\{count\_base}+\\{cur\_val}){}$;\5
+\&{break}; \&{case} \\{dimen\_def\_code}: \&{define} $(\|p,\39\\{assign\_dimen},\39\\{scaled\_base}+\\{cur\_val}){}$;\5
+\&{break}; \&{case} \\{skip\_def\_code}: \&{define} $(\|p,\39\\{assign\_glue},\39\\{skip\_base}+\\{cur\_val}){}$;\5
+\&{break}; \&{case} \\{mu\_skip\_def\_code}: \&{define} $(\|p,\39\\{assign\_mu\_glue},\39\\{mu\_skip\_base}+\\{cur\_val}){}$;\5
+\&{break}; \&{case} \\{toks\_def\_code}: \&{define} $(\|p,\39\\{assign\_toks},\39\\{toks\_base}+\\{cur\_val});$ $\}{}$\C{there are no other cases}\6
+$\}$ $\}$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1225}\B\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{read\_to\_cs}: $\{{}$\5
+\\{scan\_int}(\,);\5
+${}\|n\K\\{cur\_val};{}$\6
+\&{if} ${}(\R\\{scan\_keyword}(\X1642:\.{"to"}\X)){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Missing\ `to'\ insert}\)\.{ed"});\5
+\\{help2}(\.{"You\ should\ have\ sai}\)\.{d\ `\\\\read<number>\ to}\)\.{\ \\\\cs'."})\6
+(\.{"I'm\ going\ to\ look\ f}\)\.{or\ the\ \\\\cs\ now."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\\{get\_r\_token}(\,);\5
+${}\|p\K\\{cur\_cs};{}$\5
+${}\\{read\_toks}(\|n,\39\|p);$ \&{define} $(\|p,\39\\{call},\39\\{cur\_val});$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1226}The token-list parameters, \.{\\output} and \.{\\everypar}, etc., receive
+their values in the following way. (For safety's sake, we place an
+enclosing pair of braces around an \.{\\output} list.)
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{toks\_register}:\5
+\&{case} \\{assign\_toks}: $\{{}$\5
+$\|q\K\\{cur\_cs};{}$\6
+\&{if} ${}(\\{cur\_cmd}\E\\{toks\_register}){}$\5
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\|p\K\\{toks\_base}+\\{cur\_val};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\|p\K\\{cur\_chr}{}$;\C{$\|p\E\\{every\_par\_loc}$ or \\{output\_routine\_loc} or \dots}\2\6
+\\{scan\_optional\_equals}(\,);\5
+\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\I\\{left\_brace}){}$\1\5
+\X1227:If the right-hand side is a token parameter or token register, finish the assignment and \&{goto} \\{done}\X;\2\6
+\\{back\_input}(\,);\5
+${}\\{cur\_cs}\K\|q;{}$\5
+${}\|q\K\\{scan\_toks}(\\{false},\39\\{false});$ \&{if} ${}(\\{link}(\\{def\_ref})\E\\{null}{}$)\C{empty list: revert to the default}\6
+$\{{}$\5
+\&{define} $(\|p,\39\\{undefined\_cs},\39\\{null});{}$\5
+\\{free\_avail}(\\{def\_ref}); $\}$ \&{else} $\{{}$\5
+\&{if} ${}(\|p\E\\{output\_routine\_loc}{}$)\C{enclose in curlies}\6
+${}\{{}$\5
+\1${}\\{link}(\|q)\K\\{get\_avail}(\,);{}$\5
+${}\|q\K\\{link}(\|q);{}$\5
+${}\\{info}(\|q)\K\\{right\_brace\_token}+\.{'\}'};{}$\5
+${}\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|q)\K\\{left\_brace\_token}+\.{'\{'};{}$\5
+${}\\{link}(\|q)\K\\{link}(\\{def\_ref});{}$\5
+${}\\{link}(\\{def\_ref})\K\|q;{}$\6
+\4${}\}{}$\2\6
+\&{define} $(\|p,\39\\{call},\39\\{def\_ref});$ $\}$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1227}\B\X1227:If the right-hand side is a token parameter or token register, finish the assignment and \&{goto} \\{done}\X${}\E{}$\6
+$\{{}$\5
+\&{if} ${}(\\{cur\_cmd}\E\\{toks\_register}){}$\5
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+${}\\{cur\_cmd}\K\\{assign\_toks};{}$\5
+${}\\{cur\_chr}\K\\{toks\_base}+\\{cur\_val};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_cmd}\E\\{assign\_toks})$ $\{{}$\5
+$\|q\K\\{equiv}(\\{cur\_chr});$ \&{if} ${}(\|q\E\\{null})$ \&{define} $(\|p,\39\\{undefined\_cs},\39\\{null});$ \&{else} $\{{}$\5
+\\{add\_token\_ref}(\|q); \&{define} $(\|p,\39\\{call},\39\|q);$ $\}$ \&{goto} \\{done}; $\}$ $\}{}$\par
+\U1226.\fi
+
+\M{1228}Similar routines are used to assign values to the numeric parameters.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_int}:\6
+${}\{{}$\5
+\1${}\|p\K\\{cur\_chr};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\5
+${}\\{word\_define}(\|p,\39\\{cur\_val});{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{assign\_dimen}:\6
+${}\{{}$\5
+\1${}\|p\K\\{cur\_chr};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_normal\_dimen};\5
+${}\\{word\_define}(\|p,\39\\{cur\_val});{}$\6
+\4${}\}{}$\5
+\2\&{break}; \&{case} \\{assign\_glue}:\5
+\&{case} \\{assign\_mu\_glue}: $\{{}$\5
+$\|p\K\\{cur\_chr};{}$\5
+${}\|n\K\\{cur\_cmd};{}$\5
+\\{scan\_optional\_equals}(\,);\6
+\&{if} ${}(\|n\E\\{assign\_mu\_glue}){}$\1\5
+\\{scan\_glue}(\\{mu\_val});\5
+\2\&{else}\1\5
+\\{scan\_glue}(\\{glue\_val});\2\6
+\\{trap\_zero\_glue}(\,); \&{define} $(\|p,\39\\{glue\_ref},\39\\{cur\_val});$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1229}When a glue register or parameter becomes zero, it will always point to
+\\{zero\_glue} because of the following procedure. (Exception: The tabskip
+glue isn't trapped while preambles are being scanned.)
+
+\Y\B\4\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{trap\_zero\_glue}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{if} ${}((\\{width}(\\{cur\_val})\E\T{0})\W(\\{stretch}(\\{cur\_val})\E\T{0})\W(\\{shrink}(\\{cur\_val})\E\T{0})){}$\5
+${}\{{}$\5
+\1\\{add\_glue\_ref}(\\{zero\_glue});\5
+\\{delete\_glue\_ref}(\\{cur\_val});\5
+${}\\{cur\_val}\K\\{zero\_glue};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1230}The various character code tables are changed by the \\{def\_code} commands,
+and the font families are declared by \\{def\_family}.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1441:\.{"catcode"}\X,\39\\{def\_code},\39\\{cat\_code\_base});{}$\5
+${}\\{primitive}(\X1445:\.{"mathcode"}\X,\39\\{def\_code},\39\\{math\_code\_base});{}$\5
+${}\\{primitive}(\X1442:\.{"lccode"}\X,\39\\{def\_code},\39\\{lc\_code\_base});{}$\5
+${}\\{primitive}(\X1443:\.{"uccode"}\X,\39\\{def\_code},\39\\{uc\_code\_base});{}$\5
+${}\\{primitive}(\X1444:\.{"sfcode"}\X,\39\\{def\_code},\39\\{sf\_code\_base});{}$\5
+${}\\{primitive}(\X1502:\.{"delcode"}\X,\39\\{def\_code},\39\\{del\_code\_base});{}$\5
+${}\\{primitive}(\X1438:\.{"textfont"}\X,\39\\{def\_family},\39\\{math\_font\_base});{}$\5
+${}\\{primitive}(\X1439:\.{"scriptfont"}\X,\39\\{def\_family},\39\\{math\_font\_base}+\\{script\_size});{}$\5
+${}\\{primitive}(\X1440:\.{"scriptscriptfont"}\X,\39\\{def\_family},\39\\{math\_font\_base}+\\{script\_script\_size}){}$;\par
+\fi
+
+\M{1231}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{def\_code}:\6
+\&{if} ${}(\\{chr\_code}\E\\{cat\_code\_base}){}$\1\5
+\\{print\_esc}(\X1441:\.{"catcode"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{math\_code\_base}){}$\1\5
+\\{print\_esc}(\X1445:\.{"mathcode"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{lc\_code\_base}){}$\1\5
+\\{print\_esc}(\X1442:\.{"lccode"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{uc\_code\_base}){}$\1\5
+\\{print\_esc}(\X1443:\.{"uccode"}\X);\2\6
+\&{else} \&{if} ${}(\\{chr\_code}\E\\{sf\_code\_base}){}$\1\5
+\\{print\_esc}(\X1444:\.{"sfcode"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1502:\.{"delcode"}\X);\5
+\2\&{break};\6
+\4\&{case} \\{def\_family}:\5
+${}\\{print\_size}(\\{chr\_code}-\\{math\_font\_base}){}$;\5
+\&{break};\par
+\fi
+
+\M{1232}The different types of code values have different legal ranges; the
+following program is careful to check each case properly.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{def\_code}: $\{{}$\5
+\X1233:Let \|n be the largest legal code value, based on \\{cur\_chr}\X;\6
+${}\|p\K\\{cur\_chr};{}$\5
+\\{scan\_char\_num}(\,);\5
+${}\|p\K\|p+\\{cur\_val};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\6
+\&{if} ${}(((\\{cur\_val}<\T{0})\W(\|p<\\{del\_code\_base}))\V(\\{cur\_val}>\|n)){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Invalid\ code\ ("});\5
+\\{print\_int}(\\{cur\_val});\6
+\&{if} ${}(\|p<\\{del\_code\_base}){}$\1\5
+\\{print\_str}(\.{"),\ should\ be\ in\ the}\)\.{\ range\ 0.."});\2\6
+\&{else}\1\5
+\\{print\_str}(\.{"),\ should\ be\ at\ mos}\)\.{t\ "});\2\6
+\\{print\_int}(\|n);\5
+\\{help1}(\.{"I'm\ going\ to\ use\ 0\ }\)\.{instead\ of\ that\ ille}\)\.{gal\ code\ value."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{cur\_val}\K\T{0};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|p<\\{math\_code\_base})$ \&{define} $(\|p,\39\\{data},\39\\{cur\_val});$ \&{else} \&{if} ${}(\|p<\\{del\_code\_base})$ \&{define} $(\|p,\39\\{data},\39\\{hi}(\\{cur\_val}));{}$\6
+\&{else}\1\5
+${}\\{word\_define}(\|p,\39\\{cur\_val});{}$\2\6
+$\}{}$\5
+\&{break};\par
+\fi
+
+\M{1233}\B\X1233:Let \|n be the largest legal code value, based on \\{cur\_chr}\X${}\E{}$\6
+\&{if} ${}(\\{cur\_chr}\E\\{cat\_code\_base}){}$\1\5
+${}\|n\K\\{max\_char\_code};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\E\\{math\_code\_base}){}$\1\5
+${}\|n\K\T{\~100000};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\E\\{sf\_code\_base}){}$\1\5
+${}\|n\K\T{\~77777};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_chr}\E\\{del\_code\_base}){}$\1\5
+${}\|n\K\T{\~77777777};{}$\2\6
+\&{else} $\|n\K{}$\T{255}\par
+\U1232.\fi
+
+\M{1234}\B\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{def\_family}: $\{{}$\5
+$\|p\K\\{cur\_chr};{}$\5
+\\{scan\_four\_bit\_int}(\,);\5
+${}\|p\K\|p+\\{cur\_val};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_font\_ident}(\,); \&{define} $(\|p,\39\\{data},\39\\{cur\_val});$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1235}Next we consider changes to \TeX's numeric registers.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \&{register} : \6
+\4\&{case} \\{advance}:\5
+\&{case} \\{multiply}:\5
+\&{case} \\{divide}:\5
+\\{do\_register\_command}(\|a);\5
+\&{break};\par
+\fi
+
+\M{1236}We use the fact that \&{register} $<$ $\\{advance}<\\{multiply}<\\{divide}$.
+
+\Y\B\4\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{do\_register\_command}(\&{small\_number} \|a)\1\1 $\{{}$\5
+\&{pointer} \|l${},{}$ \|q${},{}$ \|r${},{}$ \|s;\C{for list manipulation}\6
+\&{uint8\_t} \|p;\C{type of register involved}\7
+${}\|q\K\\{cur\_cmd};{}$\5
+\X1237:Compute the register location \|l and its type \|p; but \&{return} if invalid\X;\6
+\&{if} ( \|q $\E$ \&{register} ) \\{scan\_optional\_equals}(\,);\6
+\&{else}\1\6
+\&{if} (\\{scan\_keyword}(\X1761:\.{"by"}\X))\1\5
+\\{do\_nothing};\C{optional `\.{by}'}\2\2\6
+${}\\{arith\_error}\K\\{false};{}$\6
+\&{if} ${}(\|q<\\{multiply}){}$\1\5
+\X1238:Compute result of \&{register} or \\{advance}, put it in \\{cur\_val}\X\2\6
+\&{else}\1\5
+\X1240:Compute result of \\{multiply} or \\{divide}, put it in \\{cur\_val}\X;\2\6
+\&{if} (\\{arith\_error})\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Arithmetic\ overflow}\)\.{"});\5
+\\{help2}(\.{"I\ can't\ carry\ out\ t}\)\.{hat\ multiplication\ o}\)\.{r\ division,"})\6
+(\.{"since\ the\ result\ is}\)\.{\ out\ of\ range."});\6
+\&{if} ${}(\|p\G\\{glue\_val}){}$\1\5
+\\{delete\_glue\_ref}(\\{cur\_val});\2\6
+\&{error} (\,)\1\5
+;\2\6
+\&{return};\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|p<\\{glue\_val}){}$\1\5
+${}\\{word\_define}(\|l,\39\\{cur\_val});{}$\2\6
+\&{else} $\{{}$\5
+\\{trap\_zero\_glue}(\,); \&{define} $(\|l,\39\\{glue\_ref},\39\\{cur\_val});$ $\}$ $\}{}$\par
+\fi
+
+\M{1237}Here we use the fact that the consecutive codes $\\{int\_val}\dotdot\\{mu\_val}$ and
+$\\{assign\_int}\dotdot\\{assign\_mu\_glue}$ correspond to each other nicely.
+
+\Y\B\4\X1237:Compute the register location \|l and its type \|p; but \&{return} if invalid\X${}\E{}$\6
+$\{{}$\5
+\&{if} ( \|q $\I$ \&{register} ) $\{{}$\5
+\\{get\_x\_token}(\,);\6
+\&{if} ${}((\\{cur\_cmd}\G\\{assign\_int})\W(\\{cur\_cmd}\Z\\{assign\_mu\_glue})){}$\5
+${}\{{}$\5
+\1${}\|l\K\\{cur\_chr};{}$\5
+${}\|p\K\\{cur\_cmd}-\\{assign\_int};{}$\5
+\&{goto} \\{found};\6
+\4${}\}{}$\2\6
+\&{if} ( \\{cur\_cmd} $\I$ \&{register} ) \6
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ use\ `"});\5
+${}\\{print\_cmd\_chr}(\\{cur\_cmd},\39\\{cur\_chr});{}$\5
+\\{print\_str}(\.{"'\ after\ "});\5
+${}\\{print\_cmd\_chr}(\|q,\39\T{0});{}$\5
+\\{help1}(\.{"I'm\ forgetting\ what}\)\.{\ you\ said\ and\ not\ ch}\)\.{anging\ anything."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{return};\6
+\4${}\}{}$\2\6
+$\}$ $\|p\K\\{cur\_chr};{}$\5
+\\{scan\_eight\_bit\_int}(\,);\6
+\&{switch} (\|p)\5
+${}\{{}$\1\6
+\4\&{case} \\{int\_val}:\5
+${}\|l\K\\{cur\_val}+\\{count\_base}{}$;\5
+\&{break};\6
+\4\&{case} \\{dimen\_val}:\5
+${}\|l\K\\{cur\_val}+\\{scaled\_base}{}$;\5
+\&{break};\6
+\4\&{case} \\{glue\_val}:\5
+${}\|l\K\\{cur\_val}+\\{skip\_base}{}$;\5
+\&{break};\6
+\4\&{case} \\{mu\_val}:\5
+${}\|l\K\\{cur\_val}+\\{mu\_skip\_base};{}$\6
+\4${}\}{}$\C{there are no other cases}\2\6
+$\}$ \\{found}:\par
+\U1236.\fi
+
+\M{1238}\B\X1238:Compute result of \&{register} or \\{advance}, put it in \\{cur\_val}\X${}\E{}$\6
+\&{if} ${}(\|p<\\{glue\_val}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|p\E\\{int\_val}){}$\1\5
+\\{scan\_int}(\,);\5
+\2\&{else}\1\5
+\\{scan\_normal\_dimen};\2\6
+\&{if} ${}(\|q\E\\{advance}){}$\1\5
+${}\\{cur\_val}\K\\{cur\_val}+\\{eqtb}[\|l].\|i;{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{scan\_glue}(\|p);\6
+\&{if} ${}(\|q\E\\{advance}){}$\1\5
+\X1239:Compute the sum of two glue specs\X;\2\6
+\4${}\}{}$\2\par
+\U1236.\fi
+
+\M{1239}\B\X1239:Compute the sum of two glue specs\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|q\K\\{new\_spec}(\\{cur\_val});{}$\5
+${}\|r\K\\{equiv}(\|l);{}$\5
+\\{delete\_glue\_ref}(\\{cur\_val});\5
+${}\\{width}(\|q)\K\\{width}(\|q)+\\{width}(\|r);{}$\6
+\&{if} ${}(\\{stretch}(\|q)\E\T{0}){}$\1\5
+${}\\{stretch\_order}(\|q)\K\\{normal};{}$\2\6
+\&{if} ${}(\\{stretch\_order}(\|q)\E\\{stretch\_order}(\|r)){}$\1\5
+${}\\{stretch}(\|q)\K\\{stretch}(\|q)+\\{stretch}(\|r);{}$\2\6
+\&{else} \&{if} ${}((\\{stretch\_order}(\|q)<\\{stretch\_order}(\|r))\W(\\{stretch}(\|r)\I\T{0})){}$\5
+${}\{{}$\5
+\1${}\\{stretch}(\|q)\K\\{stretch}(\|r);{}$\5
+${}\\{stretch\_order}(\|q)\K\\{stretch\_order}(\|r);{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{shrink}(\|q)\E\T{0}){}$\1\5
+${}\\{shrink\_order}(\|q)\K\\{normal};{}$\2\6
+\&{if} ${}(\\{shrink\_order}(\|q)\E\\{shrink\_order}(\|r)){}$\1\5
+${}\\{shrink}(\|q)\K\\{shrink}(\|q)+\\{shrink}(\|r);{}$\2\6
+\&{else} \&{if} ${}((\\{shrink\_order}(\|q)<\\{shrink\_order}(\|r))\W(\\{shrink}(\|r)\I\T{0})){}$\5
+${}\{{}$\5
+\1${}\\{shrink}(\|q)\K\\{shrink}(\|r);{}$\5
+${}\\{shrink\_order}(\|q)\K\\{shrink\_order}(\|r);{}$\6
+\4${}\}{}$\2\6
+${}\\{cur\_val}\K\|q;{}$\6
+\4${}\}{}$\2\par
+\U1238.\fi
+
+\M{1240}\B\X1240:Compute result of \\{multiply} or \\{divide}, put it in \\{cur\_val}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}(\|p<\\{glue\_val}){}$\1\6
+\&{if} ${}(\|q\E\\{multiply}){}$\1\6
+\&{if} ${}(\|p\E\\{int\_val}){}$\1\5
+${}\\{cur\_val}\K\\{mult\_integers}(\\{eqtb}[\|l].\|i,\39\\{cur\_val});{}$\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{nx\_plus\_y}(\\{eqtb}[\|l].\|i,\39\\{cur\_val},\39\T{0});{}$\2\2\6
+\&{else}\1\5
+${}\\{cur\_val}\K\\{x\_over\_n}(\\{eqtb}[\|l].\|i,\39\\{cur\_val});{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|s\K\\{equiv}(\|l);{}$\5
+${}\|r\K\\{new\_spec}(\|s);{}$\6
+\&{if} ${}(\|q\E\\{multiply}){}$\5
+${}\{{}$\5
+\1${}\\{width}(\|r)\K\\{nx\_plus\_y}(\\{width}(\|s),\39\\{cur\_val},\39\T{0});{}$\5
+${}\\{stretch}(\|r)\K\\{nx\_plus\_y}(\\{stretch}(\|s),\39\\{cur\_val},\39\T{0});{}$\5
+${}\\{shrink}(\|r)\K\\{nx\_plus\_y}(\\{shrink}(\|s),\39\\{cur\_val},\39\T{0});{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{width}(\|r)\K\\{x\_over\_n}(\\{width}(\|s),\39\\{cur\_val});{}$\5
+${}\\{stretch}(\|r)\K\\{x\_over\_n}(\\{stretch}(\|s),\39\\{cur\_val});{}$\5
+${}\\{shrink}(\|r)\K\\{x\_over\_n}(\\{shrink}(\|s),\39\\{cur\_val});{}$\6
+\4${}\}{}$\2\6
+${}\\{cur\_val}\K\|r;{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1236.\fi
+
+\M{1241}The processing of boxes is somewhat different, because we may need
+to scan and create an entire box before we actually change the value of the old
+one.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_box}:\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\6
+\&{if} (\\{global})\1\5
+${}\|n\K\T{256}+\\{cur\_val}{}$;\5
+\2\&{else}\1\5
+${}\|n\K\\{cur\_val};{}$\2\6
+\\{scan\_optional\_equals}(\,);\6
+\&{if} (\\{set\_box\_allowed})\1\5
+${}\\{scan\_box}(\\{box\_flag}+\|n);{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ "});\5
+\\{print\_esc}(\X1558:\.{"setbox"}\X);\5
+\\{help2}(\.{"Sorry,\ \\\\setbox\ is\ }\)\.{not\ allowed\ after\ \\\\}\)\.{halign\ in\ a\ display,}\)\.{"})\6
+(\.{"or\ between\ \\\\accent}\)\.{\ and\ an\ accented\ cha}\)\.{racter."});\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1242}The \\{space\_factor} or \\{prev\_depth} settings are changed when a \\{set\_aux}
+command is sensed. Similarly, \\{prev\_graf} is changed in the presence of
+\\{set\_prev\_graf}, and \\{dead\_cycles} or \\{insert\_penalties} in the presence of
+\\{set\_page\_int}. These definitions are always global.
+
+When some dimension of a box register is changed, the change isn't exactly
+global; but \TeX\ does not look at the \.{\\global} switch.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_aux}:\5
+\\{alter\_aux}(\,);\5
+\&{break};\6
+\4\&{case} \\{set\_prev\_graf}:\5
+\\{alter\_prev\_graf}(\,);\5
+\&{break};\6
+\4\&{case} \\{set\_page\_dimen}:\5
+\\{alter\_page\_so\_far}(\,);\5
+\&{break};\6
+\4\&{case} \\{set\_page\_int}:\5
+\\{alter\_integer}(\,);\5
+\&{break};\6
+\4\&{case} \\{set\_box\_dimen}:\5
+\\{alter\_box\_dimen}(\,);\5
+\&{break};\par
+\fi
+
+\M{1243}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{alter\_aux}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{halfword} \|c;\C{\\{hmode} or \\{vmode}}\7
+\&{if} ${}(\\{cur\_chr}\I\\{abs}(\\{mode})){}$\1\5
+\\{report\_illegal\_case}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_optional\_equals}(\,);\6
+\&{if} ${}(\|c\E\\{vmode}){}$\5
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{prev\_depth}\K\\{cur\_val};{}$\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}((\\{cur\_val}\Z\T{0})\V(\\{cur\_val}>\T{32767})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ space\ factor"});\5
+\\{help1}(\.{"I\ allow\ only\ values}\)\.{\ in\ the\ range\ 1..327}\)\.{67\ here."});\5
+\\{int\_error}(\\{cur\_val});\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\\{space\_factor}\K\\{cur\_val};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1244}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{alter\_prev\_graf}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \|p;\C{index into \\{nest}}\7
+${}\\{nest}[\\{nest\_ptr}]\K\\{cur\_list};{}$\5
+${}\|p\K\\{nest\_ptr};{}$\6
+\&{while} ${}(\\{abs}(\\{nest}[\|p].\\{mode\_field})\I\\{vmode}){}$\1\5
+\\{decr}(\|p);\2\6
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\6
+\&{if} ${}(\\{cur\_val}<\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Bad\ "});\5
+\\{print\_esc}(\X1554:\.{"prevgraf"}\X);\5
+\\{help1}(\.{"I\ allow\ only\ nonneg}\)\.{ative\ values\ here."});\5
+\\{int\_error}(\\{cur\_val});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{nest}[\|p].\\{pg\_field}\K\\{cur\_val};{}$\5
+${}\\{cur\_list}\K\\{nest}[\\{nest\_ptr}];{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1245}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{alter\_page\_so\_far}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \|c;\C{index into \\{page\_so\_far}}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_normal\_dimen};\5
+${}\\{page\_so\_far}[\|c]\K\\{cur\_val};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1246}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{alter\_integer}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \|c;\C{0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\6
+\&{if} ${}(\|c\E\T{0}){}$\1\5
+${}\\{dead\_cycles}\K\\{cur\_val};{}$\2\6
+\&{else}\1\5
+${}\\{insert\_penalties}\K\\{cur\_val};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1247}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{alter\_box\_dimen}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|c;\C{\\{width\_offset} or \\{height\_offset} or \\{depth\_offset}}\6
+\&{eight\_bits} \|b;\C{box number}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_eight\_bit\_int}(\,);\5
+${}\|b\K\\{cur\_val};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_normal\_dimen};\6
+\&{if} ${}(\\{box}(\|b)\I\\{null}){}$\1\5
+${}\\{mem}[\\{box}(\|b)+\|c].\\{sc}\K\\{cur\_val};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1248}Paragraph shapes are set up in the obvious way.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\&{case} \\{set\_shape}: $\{{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\5
+${}\|n\K\\{cur\_val};{}$\6
+\&{if} ${}(\|n\Z\T{0}){}$\1\5
+${}\|p\K\\{null};{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\|p\K\\{get\_node}(\T{2}*\|n+\T{1});{}$\5
+${}\\{info}(\|p)\K\|n;{}$\6
+\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\|n;{}$ ${}\|j\PP){}$\5
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\\{mem}[\|p+\T{2}*\|j-\T{1}].\\{sc}\K\\{cur\_val}{}$;\C{indentation}\6
+\\{scan\_normal\_dimen};\5
+${}\\{mem}[\|p+\T{2}*\|j].\\{sc}\K\\{cur\_val}{}$;\C{width}\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{define} $(\\{par\_shape\_loc},\39\\{shape\_ref},\39\|p);$ $\}{}$\5
+\&{break};\par
+\fi
+
+\M{1249}Here's something that isn't quite so obvious. It guarantees that
+\\{info}(\\{par\_shape\_ptr}) can hold any positive~\|n for which $\\{get\_node}(\T{2}*\|n+\T{1})$
+doesn't overflow the memory capacity.
+
+\Y\B\4\X14:Check the ``constant'' values for consistency\X${}\mathrel+\E{}$\6
+\&{if} ${}(\T{2}*\\{max\_halfword}<\\{mem\_top}-\\{mem\_min}){}$\1\5
+${}\\{bad}\K\T{41}{}$;\2\par
+\fi
+
+\M{1250}New hyphenation data is loaded by the \\{hyph\_data} command.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1683:\.{"hyphenation"}\X,\39\\{hyph\_data},\39\T{0});{}$\5
+${}\\{primitive}(\X1684:\.{"patterns"}\X,\39\\{hyph\_data},\39\T{1}){}$;\par
+\fi
+
+\M{1251}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hyph\_data}:\6
+\&{if} ${}(\\{chr\_code}\E\T{1}){}$\1\5
+\\{print\_esc}(\X1684:\.{"patterns"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1683:\.{"hyphenation"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1252}\B\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{hyph\_data}:\6
+\&{if} ${}(\\{cur\_chr}\E\T{1}){}$\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{INIT}\1\6
+\\{new\_patterns}(\,);\5
+\&{goto} \\{done};\6
+\8\#\&{endif}\6
+\\{print\_err}(\.{"Patterns\ can\ be\ loa}\)\.{ded\ only\ by\ INITEX"});\5
+\\{help0};\6
+\&{error} (\,)\1\5
+;\2\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_cmd}\E\\{right\_brace})){}$;\C{flush the patterns}\6
+\&{return};\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{new\_hyph\_exceptions}(\,);\5
+\&{goto} \\{done};\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1253}All of \TeX's parameters are kept in \\{eqtb} except the font information,
+the interaction mode, and the hyphenation tables; these are strictly global.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_font\_dimen}:\6
+${}\{{}$\5
+\1\\{find\_font\_dimen}(\\{true});\5
+${}\|k\K\\{cur\_val};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_normal\_dimen};\5
+${}\\{font\_info}[\|k].\\{sc}\K\\{cur\_val};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{assign\_font\_int}:\6
+${}\{{}$\5
+\1${}\|n\K\\{cur\_chr};{}$\5
+\\{scan\_font\_ident}(\,);\5
+${}\|f\K\\{cur\_val};{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_int}(\,);\6
+\&{if} ${}(\|n\E\T{0}){}$\1\5
+${}\\{hyphen\_char}[\|f]\K\\{cur\_val}{}$;\5
+\2\&{else}\1\5
+${}\\{skew\_char}[\|f]\K\\{cur\_val};{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1254}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1762:\.{"hyphenchar"}\X,\39\\{assign\_font\_int},\39\T{0});{}$\5
+${}\\{primitive}(\X1763:\.{"skewchar"}\X,\39\\{assign\_font\_int},\39\T{1}){}$;\par
+\fi
+
+\M{1255}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{assign\_font\_int}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1762:\.{"hyphenchar"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1763:\.{"skewchar"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1256}Here is where the information for a new font gets loaded.
+
+\Y\B\4\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{def\_font}:\5
+\\{new\_font}(\|a);\5
+\&{break};\par
+\fi
+
+\M{1257}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{new\_font}(\&{small\_number} \|a)\1\1 $\{{}$\5
+\&{pointer} \|u;\C{user's font identifier}\6
+\&{scaled} \|s;\C{stated ``at'' size, or negative of scaled magnification}\6
+\&{int} \|f;\C{runs through existing fonts}\6
+\&{str\_number} \|t;\C{name for the frozen font identifier}\6
+\&{uint8\_t} \\{old\_setting};\C{holds \\{selector} setting}\6
+\&{str\_number} \\{flushable\_string};\C{string not yet referenced}\7
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+\\{open\_log\_file}(\,);\C{avoid confusing \.{texput} with the font name}\2\6
+\\{get\_r\_token}(\,);\5
+${}\|u\K\\{cur\_cs};{}$\6
+\&{if} ${}(\|u\G\\{hash\_base}){}$\1\5
+${}\|t\K\\{text}(\|u);{}$\2\6
+\&{else} \&{if} ${}(\|u\G\\{single\_base}){}$\1\6
+\&{if} ${}(\|u\E\\{null\_cs}){}$\1\5
+${}\|t\K\X1764:\.{"FONT"}\X{}$;\5
+\2\&{else}\1\5
+${}\|t\K\|u-\\{single\_base};{}$\2\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+\\{print\_str}(\.{"FONT"});\5
+${}\\{print}(\|u-\\{active\_base});{}$\5
+${}\\{selector}\K\\{old\_setting};{}$\5
+\\{str\_room}(\T{1});\5
+${}\|t\K\\{make\_string}(\,);{}$\6
+\4${}\}{}$\2\6
+\&{define} $(\|u,\39\\{set\_font},\39\\{null\_font});{}$\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_file\_name}(\,);\5
+\X1258:Scan the font size specification\X;\6
+\X1260:If this font has already been loaded, set \|f to the internal font number and \&{goto} \\{common\_ending}\X;\6
+${}\|f\K\\{read\_font\_info}(\|u,\39\\{cur\_name},\39\\{cur\_area},\39\|s);{}$\6
+\4\\{common\_ending}:\5
+${}\\{equiv}(\|u)\K\|f;{}$\5
+${}\\{eqtb}[\\{font\_id\_base}+\|f]\K\\{eqtb}[\|u];{}$\5
+${}\\{font\_id\_text}(\|f)\K\|t;$ $\}{}$\par
+\fi
+
+\M{1258}\B\X1258:Scan the font size specification\X${}\E{}$\6
+$\\{name\_in\_progress}\K\\{true}{}$;\C{this keeps \\{cur\_name} from being changed}\6
+\&{if} (\\{scan\_keyword}(\X1765:\.{"at"}\X))\1\5
+\X1259:Put the \(p)(positive) `at' size into \|s\X\2\6
+\&{else} \&{if} (\\{scan\_keyword}(\X1766:\.{"scaled"}\X))\5
+${}\{{}$\5
+\1\\{scan\_int}(\,);\5
+${}\|s\K{-}\\{cur\_val};{}$\6
+\&{if} ${}((\\{cur\_val}\Z\T{0})\V(\\{cur\_val}>\T{32768})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Illegal\ magnificati}\)\.{on\ has\ been\ changed\ }\)\.{to\ 1000"});\6
+\\{help1}(\.{"The\ magnification\ r}\)\.{atio\ must\ be\ between}\)\.{\ 1\ and\ 32768."});\5
+\\{int\_error}(\\{cur\_val});\5
+${}\|s\K{-}\T{1000};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+${}\|s\K{-}\T{1000};{}$\2\6
+$\\{name\_in\_progress}\K{}$\\{false}\par
+\U1257.\fi
+
+\M{1259}\B\X1259:Put the \(p)(positive) `at' size into \|s\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_normal\_dimen};\5
+${}\|s\K\\{cur\_val};{}$\6
+\&{if} ${}((\|s\Z\T{0})\V(\|s\G\T{\~1000000000})){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"Improper\ `at'\ size\ }\)\.{("});\5
+\\{print\_scaled}(\|s);\5
+\\{print\_str}(\.{"pt),\ replaced\ by\ 10}\)\.{pt"});\5
+\\{help2}(\.{"I\ can\ only\ handle\ f}\)\.{onts\ at\ positive\ siz}\)\.{es\ that\ are"})\6
+(\.{"less\ than\ 2048pt,\ s}\)\.{o\ I've\ changed\ what\ }\)\.{you\ said\ to\ 10pt."});\6
+\&{error} (\,)\1\5
+;\2\6
+${}\|s\K\T{10}*\\{unity};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1258.\fi
+
+\M{1260}When the user gives a new identifier to a font that was previously loaded,
+the new name becomes the font identifier of record. Font names `\.{xyz}' and
+`\.{XYZ}' are considered to be different.
+
+\Y\B\4\X1260:If this font has already been loaded, set \|f to the internal font number and \&{goto} \\{common\_ending}\X${}\E{}$\6
+$\\{flushable\_string}\K\\{str\_ptr}-\T{1};{}$\6
+\&{for} ${}(\|f\K\\{font\_base}+\T{1};{}$ ${}\|f\Z\\{font\_ptr};{}$ ${}\|f\PP){}$\1\6
+\&{if} ${}(\\{str\_eq\_str}(\\{font\_name}[\|f],\39\\{cur\_name})\W\\{str\_eq\_str}(\\{font\_area}[\|f],\39\\{cur\_area})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{cur\_name}\E\\{flushable\_string}){}$\5
+${}\{{}$\5
+\1\\{flush\_string};\5
+${}\\{cur\_name}\K\\{font\_name}[\|f];{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|s>\T{0}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\|s\E\\{font\_size}[\|f]){}$\1\5
+\&{goto} \\{common\_ending};\2\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{font\_size}[\|f]\E\\{xn\_over\_d}(\\{font\_dsize}[\|f],\39{-}\|s,\39\T{1000})){}$\1\5
+\&{goto} \\{common\_ending};\2\6
+\4${}\}{}$\2\2\par
+\U1257.\fi
+
+\M{1261}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_font}:\6
+${}\{{}$\5
+\1\\{print\_str}(\.{"select\ font\ "});\5
+\\{slow\_print}(\\{font\_name}[\\{chr\_code}]);\6
+\&{if} ${}(\\{font\_size}[\\{chr\_code}]\I\\{font\_dsize}[\\{chr\_code}]){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ at\ "});\5
+\\{print\_scaled}(\\{font\_size}[\\{chr\_code}]);\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1262}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1383:\.{"batchmode"}\X,\39\\{set\_interaction},\39\\{batch\_mode});{}$\5
+${}\\{primitive}(\X1384:\.{"nonstopmode"}\X,\39\\{set\_interaction},\39\\{nonstop\_mode});{}$\5
+${}\\{primitive}(\X1385:\.{"scrollmode"}\X,\39\\{set\_interaction},\39\\{scroll\_mode});{}$\5
+${}\\{primitive}(\X1767:\.{"errorstopmode"}\X,\39\\{set\_interaction},\39\\{error\_stop\_mode}){}$;\par
+\fi
+
+\M{1263}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_interaction}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{batch\_mode}:\5
+\\{print\_esc}(\X1383:\.{"batchmode"}\X);\5
+\&{break};\6
+\4\&{case} \\{nonstop\_mode}:\5
+\\{print\_esc}(\X1384:\.{"nonstopmode"}\X);\5
+\&{break};\6
+\4\&{case} \\{scroll\_mode}:\5
+\\{print\_esc}(\X1385:\.{"scrollmode"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1767:\.{"errorstopmode"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1264}\B\X1217:Assignments\X${}\mathrel+\E{}$\6
+\4\&{case} \\{set\_interaction}:\5
+\\{new\_interaction}(\,);\5
+\&{break};\par
+\fi
+
+\M{1265}\B\X1215:Declare subprocedures for \\{prefixed\_command}\X${}\mathrel+\E{}$\6
+\&{void} \\{new\_interaction}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_ln}(\,);\5
+${}\\{interaction}\K\\{cur\_chr};{}$\5
+\X75:Initialize the print \\{selector} based on \\{interaction}\X;\6
+\&{if} (\\{log\_opened})\1\5
+${}\\{selector}\K\\{selector}+\T{2};{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1266}The \.{\\afterassignment} command puts a token into the global
+variable \\{after\_token}. This global variable is examined just after
+every assignment has been performed.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{halfword} \\{after\_token};\C{zero, or a saved token}\par
+\fi
+
+\M{1267}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{after\_token}\K\T{0}{}$;\par
+\fi
+
+\M{1268}\B\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{after\_assignment}):\6
+${}\{{}$\5
+\1\\{get\_token}(\,);\5
+${}\\{after\_token}\K\\{cur\_tok};{}$\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1269}\B\X1269:Insert a token saved by \.{\\afterassignment}, if any\X${}\E{}$\6
+\&{if} ${}(\\{after\_token}\I\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_tok}\K\\{after\_token};{}$\5
+\\{back\_input}(\,);\5
+${}\\{after\_token}\K\T{0};{}$\6
+\4${}\}{}$\2\par
+\U1211.\fi
+
+\M{1270}Here is a procedure that might be called `Get the next non-blank non-relax
+non-call non-assignment token'.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{do\_assignments}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{loop}\5
+${}\{{}$\5
+\1\X404:Get the next non-blank non-relax non-call token\X;\6
+\&{if} ${}(\\{cur\_cmd}\Z\\{max\_non\_prefixed\_command}){}$\1\5
+\&{return};\2\6
+${}\\{set\_box\_allowed}\K\\{false};{}$\5
+\\{prefixed\_command}(\,);\5
+${}\\{set\_box\_allowed}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1271}\B\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{after\_group}):\6
+${}\{{}$\5
+\1\\{get\_token}(\,);\5
+\\{save\_for\_after}(\\{cur\_tok});\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1272}Files for \.{\\read} are opened and closed by the \\{in\_stream} command.
+
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1768:\.{"openin"}\X,\39\\{in\_stream},\39\T{1});{}$\5
+${}\\{primitive}(\X1769:\.{"closein"}\X,\39\\{in\_stream},\39\T{0}){}$;\par
+\fi
+
+\M{1273}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{in\_stream}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1769:\.{"closein"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1768:\.{"openin"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1274}\B\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{in\_stream}):\5
+\\{open\_or\_close\_in}(\,);\5
+\&{break};\par
+\fi
+
+\M{1275}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{open\_or\_close\_in}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \|c;\C{1 for \.{\\openin}, 0 for \.{\\closein}}\6
+\&{uint8\_t} \|n;\C{stream number}\7
+${}\|c\K\\{cur\_chr};{}$\5
+\\{scan\_four\_bit\_int}(\,);\5
+${}\|n\K\\{cur\_val};{}$\6
+\&{if} ${}(\\{read\_open}[\|n]\I\\{closed}){}$\5
+${}\{{}$\5
+\1${}\\{a\_close}({\AND}\\{read\_file}[\|n]);{}$\5
+${}\\{read\_open}[\|n]\K\\{closed};{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\|c\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{scan\_optional\_equals}(\,);\5
+\\{scan\_file\_name}(\,);\6
+\&{if} ${}(\\{cur\_ext}\E\\{empty\_string}){}$\1\5
+${}\\{cur\_ext}\K\X1637:\.{".tex"}\X;{}$\2\6
+\\{pack\_cur\_name};\6
+\&{if} ${}(\\{a\_open\_in}({\AND}\\{read\_file}[\|n])){}$\1\5
+${}\\{read\_open}[\|n]\K\\{just\_open};{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1276}The user can issue messages to the terminal, regardless of the
+current mode.
+
+\Y\B\4\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{message}):\5
+\\{issue\_message}(\,);\5
+\&{break};\par
+\fi
+
+\M{1277}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1770:\.{"message"}\X,\39\\{message},\39\T{0});{}$\5
+${}\\{primitive}(\X1771:\.{"errmessage"}\X,\39\\{message},\39\T{1}){}$;\par
+\fi
+
+\M{1278}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{message}:\6
+\&{if} ${}(\\{chr\_code}\E\T{0}){}$\1\5
+\\{print\_esc}(\X1770:\.{"message"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1771:\.{"errmessage"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1279}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{issue\_message}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{holds \\{selector} setting}\6
+\&{uint8\_t} \|c;\C{identifies \.{\\message} and \.{\\errmessage}}\6
+\&{str\_number} \|s;\C{the message}\7
+${}\|c\K\\{cur\_chr};{}$\5
+${}\\{link}(\\{garbage})\K\\{scan\_toks}(\\{false},\39\\{true});{}$\5
+${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+\\{token\_show}(\\{def\_ref});\5
+${}\\{selector}\K\\{old\_setting};{}$\5
+\\{flush\_list}(\\{def\_ref});\5
+\\{str\_room}(\T{1});\5
+${}\|s\K\\{make\_string}(\,);{}$\6
+\&{if} ${}(\|c\E\T{0}){}$\1\5
+\X1280:Print string \|s on the terminal\X\2\6
+\&{else}\1\5
+\X1283:Print string \|s as an error message\X;\2\6
+\\{flush\_string};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1280}\B\X1280:Print string \|s on the terminal\X${}\E{}$\6
+${}\{{}$\5
+\1\&{if} ${}(\\{term\_offset}+\\{length}(\|s)>\\{max\_print\_line}-\T{2}){}$\1\5
+\\{print\_ln}(\,);\2\6
+\&{else} \&{if} ${}((\\{term\_offset}>\T{0})\V(\\{file\_offset}>\T{0})){}$\1\5
+\\{print\_char}(\.{'\ '});\2\6
+\\{slow\_print}(\|s);\5
+\\{update\_terminal};\6
+\4${}\}{}$\2\par
+\U1279.\fi
+
+\M{1281}If \.{\\errmessage} occurs often in \\{scroll\_mode}, without user-defined
+\.{\\errhelp}, we don't want to give a long help message each time. So we
+give a verbose explanation only once.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{bool} \\{long\_help\_seen};\C{has the long \.{\\errmessage} help been used?}\par
+\fi
+
+\M{1282}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{long\_help\_seen}\K\\{false}{}$;\par
+\fi
+
+\M{1283}\B\X1283:Print string \|s as an error message\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{""});\5
+\\{slow\_print}(\|s);\6
+\&{if} ${}(\\{err\_help}\I\\{null}){}$\1\5
+${}\\{use\_err\_help}\K\\{true};{}$\2\6
+\&{else} \&{if} (\\{long\_help\_seen})\1\5
+\\{help1}(\.{"(That\ was\ another\ \\}\)\.{\\errmessage.)"})\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} ${}(\\{interaction}<\\{error\_stop\_mode}){}$\1\5
+${}\\{long\_help\_seen}\K\\{true};{}$\2\6
+\\{help4}(\.{"This\ error\ message\ }\)\.{was\ generated\ by\ an\ }\)\.{\\\\errmessage"})\6
+(\.{"command,\ so\ I\ can't}\)\.{\ give\ any\ explicit\ h}\)\.{elp."})\6
+(\.{"Pretend\ that\ you're}\)\.{\ Hercule\ Poirot:\ Exa}\)\.{mine\ all\ clues,"})\6
+(\.{"and\ deduce\ the\ trut}\)\.{h\ by\ order\ and\ metho}\)\.{d."});\6
+\4${}\}{}$\2\6
+\&{error} (\,)\1\5
+;\2\6
+${}\\{use\_err\_help}\K\\{false};{}$\6
+\4${}\}{}$\2\par
+\U1279.\fi
+
+\M{1284}The \&{error} routine calls on \\{give\_err\_help} if help is requested from
+the \\{err\_help} parameter.
+
+\Y\B\&{void} \\{give\_err\_help}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\\{token\_show}(\\{err\_help});\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1285}The \.{\\uppercase} and \.{\\lowercase} commands are implemented by
+building a token list and then changing the cases of the letters in it.
+
+\Y\B\4\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{case\_shift}):\5
+\\{shift\_case}(\,);\5
+\&{break};\par
+\fi
+
+\M{1286}\B\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1772:\.{"lowercase"}\X,\39\\{case\_shift},\39\\{lc\_code\_base});{}$\5
+${}\\{primitive}(\X1773:\.{"uppercase"}\X,\39\\{case\_shift},\39\\{uc\_code\_base}){}$;\par
+\fi
+
+\M{1287}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{case\_shift}:\6
+\&{if} ${}(\\{chr\_code}\E\\{lc\_code\_base}){}$\1\5
+\\{print\_esc}(\X1772:\.{"lowercase"}\X);\2\6
+\&{else}\1\5
+\\{print\_esc}(\X1773:\.{"uppercase"}\X);\5
+\2\&{break};\par
+\fi
+
+\M{1288}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{shift\_case}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|b;\C{\\{lc\_code\_base} or \\{uc\_code\_base}}\6
+\&{pointer} \|p;\C{runs through the token list}\6
+\&{halfword} \|t;\C{token}\6
+\&{eight\_bits} \|c;\C{character code}\7
+${}\|b\K\\{cur\_chr};{}$\5
+${}\|p\K\\{scan\_toks}(\\{false},\39\\{false});{}$\5
+${}\|p\K\\{link}(\\{def\_ref});{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\X1289:Change the case of the token in \|p, if a change is appropriate\X;\6
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\\{back\_list}(\\{link}(\\{def\_ref}));\5
+\\{free\_avail}(\\{def\_ref});\C{omit reference count}\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1289}When the case of a \\{chr\_code} changes, we don't change the \\{cmd}.
+We also change active characters, using the fact that
+$\\{cs\_token\_flag}+\\{active\_base}$ is a multiple of~256.
+
+\Y\B\4\X1289:Change the case of the token in \|p, if a change is appropriate\X${}\E{}$\6
+$\|t\K\\{info}(\|p);{}$\6
+\&{if} ${}(\|t<\\{cs\_token\_flag}+\\{single\_base}){}$\5
+${}\{{}$\5
+\1${}\|c\K\|t\MOD\T{256};{}$\6
+\&{if} ${}(\\{equiv}(\|b+\|c)\I\T{0}){}$\1\5
+${}\\{info}(\|p)\K\|t-\|c+\\{equiv}(\|b+\|c);{}$\2\6
+\4${}\}{}$\2\par
+\U1288.\fi
+
+\M{1290}We come finally to the last pieces missing from \\{main\_control}, namely the
+`\.{\\show}' commands that are useful when debugging.
+
+\Y\B\4\X1210:Cases of \\{main\_control} that don't depend on \\{mode}\X${}\mathrel+\E{}$\6
+\4\\{any\_mode}(\\{xray}):\5
+\\{show\_whatever}(\,);\5
+\&{break};\par
+\fi
+
+\M{1291}\B\D$\\{show\_code}$ \5
+\T{0}\C{ \.{\\show} }\par
+\B\4\D$\\{show\_box\_code}$ \5
+\T{1}\C{ \.{\\showbox} }\par
+\B\4\D$\\{show\_the\_code}$ \5
+\T{2}\C{ \.{\\showthe} }\par
+\B\4\D$\\{show\_lists}$ \5
+\T{3}\C{ \.{\\showlists} }\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1774:\.{"show"}\X,\39\\{xray},\39\\{show\_code});{}$\5
+${}\\{primitive}(\X1775:\.{"showbox"}\X,\39\\{xray},\39\\{show\_box\_code});{}$\5
+${}\\{primitive}(\X1776:\.{"showthe"}\X,\39\\{xray},\39\\{show\_the\_code});{}$\5
+${}\\{primitive}(\X1777:\.{"showlists"}\X,\39\\{xray},\39\\{show\_lists}){}$;\par
+\fi
+
+\M{1292}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{xray}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{show\_box\_code}:\5
+\\{print\_esc}(\X1775:\.{"showbox"}\X);\5
+\&{break};\6
+\4\&{case} \\{show\_the\_code}:\5
+\\{print\_esc}(\X1776:\.{"showthe"}\X);\5
+\&{break};\6
+\4\&{case} \\{show\_lists}:\5
+\\{print\_esc}(\X1777:\.{"showlists"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_esc}(\X1774:\.{"show"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1293}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{show\_whatever}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{tail of a token list to show}\7
+\&{switch} (\\{cur\_chr})\5
+${}\{{}$\1\6
+\4\&{case} \\{show\_lists}:\6
+${}\{{}$\5
+\1\\{begin\_diagnostic}(\,);\5
+\\{show\_activities}(\,);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{show\_box\_code}:\5
+\X1296:Show the current contents of a box\X\5
+\&{break};\6
+\4\&{case} \\{show\_code}:\5
+\X1294:Show the current meaning of a token, then \&{goto} \\{common\_ending}\X\6
+\4\&{default}:\5
+\X1297:Show the current value of some parameter or register, then \&{goto} \\{common\_ending}\X\6
+\4${}\}{}$\2\6
+\X1298:Complete a potentially long \.{\\show} command\X;\6
+\4\\{common\_ending}:\6
+\&{if} ${}(\\{interaction}<\\{error\_stop\_mode}){}$\5
+${}\{{}$\5
+\1\\{help0};\5
+\\{decr}(\\{error\_count});\6
+\4${}\}{}$\2\6
+\&{else} \&{if} ${}(\\{tracing\_online}>\T{0}){}$\5
+${}\{{}$\5
+\1\hbox{}\6
+\\{help3}(\.{"This\ isn't\ an\ error}\)\.{\ message;\ I'm\ just\ \\}\)\.{\\showing\ something."})\6
+(\.{"Type\ `I\\\\show...'\ t}\)\.{o\ show\ more\ (e.g.,\ \\}\)\.{\\show\\\\cs,"})\6
+(\.{"\\\\showthe\\\\count10,}\)\.{\ \\\\showbox255,\ \\\\sho}\)\.{wlists)."});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\hbox{}\6
+\\{help5}(\.{"This\ isn't\ an\ error}\)\.{\ message;\ I'm\ just\ \\}\)\.{\\showing\ something."})\6
+(\.{"Type\ `I\\\\show...'\ t}\)\.{o\ show\ more\ (e.g.,\ \\}\)\.{\\show\\\\cs,"})\6
+(\.{"\\\\showthe\\\\count10,}\)\.{\ \\\\showbox255,\ \\\\sho}\)\.{wlists)."})\6
+(\.{"And\ type\ `I\\\\tracin}\)\.{gonline=1\\\\show...'\ }\)\.{to\ show\ boxes\ and"})\6
+(\.{"lists\ on\ your\ termi}\)\.{nal\ as\ well\ as\ in\ th}\)\.{e\ transcript\ file."});\6
+\4${}\}{}$\2\6
+\&{error} (\,)\1\5
+;\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1294}\B\X1294:Show the current meaning of a token, then \&{goto} \\{common\_ending}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_token}(\,);\6
+\&{if} ${}(\\{interaction}\E\\{error\_stop\_mode}){}$\1\5
+\\{wake\_up\_terminal};\2\6
+\\{print\_nl}(\.{">\ "});\6
+\&{if} ${}(\\{cur\_cs}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{sprint\_cs}(\\{cur\_cs});\5
+\\{print\_char}(\.{'='});\6
+\4${}\}{}$\2\6
+\\{print\_meaning}(\,);\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\par
+\U1293.\fi
+
+\M{1295}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{undefined\_cs}:\5
+\\{print\_str}(\.{"undefined"});\5
+\&{break};\6
+\4\&{case} \\{call}:\5
+\\{print\_str}(\.{"macro"});\5
+\&{break};\6
+\4\&{case} \\{long\_call}:\5
+\\{print\_esc}(\X1778:\.{"long\ macro"}\X);\5
+\&{break};\6
+\4\&{case} \\{outer\_call}:\5
+\\{print\_esc}(\X1779:\.{"outer\ macro"}\X);\5
+\&{break};\6
+\4\&{case} \\{long\_outer\_call}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1743:\.{"long"}\X);\5
+\\{print\_esc}(\X1779:\.{"outer\ macro"}\X);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{end\_template}:\5
+\\{print\_esc}(\X1780:\.{"outer\ endtemplate"}\X);\5
+\&{break};\par
+\fi
+
+\M{1296}\B\X1296:Show the current contents of a box\X${}\E{}$\6
+${}\{{}$\5
+\1\\{scan\_eight\_bit\_int}(\,);\5
+\\{begin\_diagnostic}(\,);\5
+\\{print\_nl}(\.{">\ \\\\box"});\5
+\\{print\_int}(\\{cur\_val});\5
+\\{print\_char}(\.{'='});\6
+\&{if} ${}(\\{box}(\\{cur\_val})\E\\{null}){}$\1\5
+\\{print\_str}(\.{"void"});\2\6
+\&{else}\1\5
+\\{show\_box}(\\{box}(\\{cur\_val}));\2\6
+\4${}\}{}$\2\par
+\U1293.\fi
+
+\M{1297}\B\X1297:Show the current value of some parameter or register, then \&{goto} \\{common\_ending}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|p\K\\{the\_toks}(\,);{}$\6
+\&{if} ${}(\\{interaction}\E\\{error\_stop\_mode}){}$\1\5
+\\{wake\_up\_terminal};\2\6
+\\{print\_nl}(\.{">\ "});\5
+\\{token\_show}(\\{temp\_head});\5
+\\{flush\_list}(\\{link}(\\{temp\_head}));\5
+\&{goto} \\{common\_ending};\6
+\4${}\}{}$\2\par
+\U1293.\fi
+
+\M{1298}\B\X1298:Complete a potentially long \.{\\show} command\X${}\E{}$\6
+\\{end\_diagnostic}(\\{true});\5
+\\{print\_err}(\.{"OK"});\6
+\&{if} ${}(\\{selector}\E\\{term\_and\_log}){}$\1\6
+\&{if} ${}(\\{tracing\_online}\Z\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{selector}\K\\{term\_only};{}$\5
+\\{print\_str}(\.{"\ (see\ the\ transcrip}\)\.{t\ file)"});\5
+${}\\{selector}\K\\{term\_and\_log};{}$\6
+\4${}\}{}$\2\2\par
+\U1293.\fi
+
+\N{1}{1299}Dumping and undumping the tables.
+After \.{INITEX} has seen a collection of fonts and macros, it
+can write all the necessary information on an auxiliary file so
+that production versions of \TeX\ are able to initialize their
+memory at high speed. The present section of the program takes
+care of such output and input. We shall consider simultaneously
+the processes of storing and restoring,
+so that the inverse relation between them is clear.
+
+The global variable \\{format\_ident} is a string that is printed right
+after the \\{banner} line when \TeX\ is ready to start. For \.{INITEX} this
+string says simply `\.{(INITEX)}'; for other versions of \TeX\ it says,
+for example, `\.{(preloaded format=plain 1982.11.19)}', showing the year,
+month, and day that the format file was created. We have $\\{format\_ident}\E\T{0}$
+before \TeX's tables are loaded.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{str\_number} \\{format\_ident};\par
+\fi
+
+\M{1300}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+$\\{format\_ident}\K\T{0}{}$;\par
+\fi
+
+\M{1301}\B\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{format\_ident}\K\X1781:\.{"\ (INITEX)"}\X{}$;\par
+\fi
+
+\M{1302}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{void} \\{store\_fmt\_file}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|j${},{}$ \|k${},{}$ \|l;\C{all-purpose indices}\6
+\&{pointer} \|p${},{}$ \|q;\C{all-purpose pointers}\6
+\&{int} \|x;\C{something to dump}\6
+\&{four\_quarters} \|w;\C{four ASCII codes}\7
+\X1304:If dumping is not allowed, abort\X;\6
+\X1328:Create the \\{format\_ident}, open the format file, and inform the user that dumping has begun\X;\6
+\X1307:Dump constants for consistency check\X;\6
+\X1309:Dump the string pool\X;\6
+\X1311:Dump the dynamic memory\X;\6
+\X1313:Dump the table of equivalents\X;\6
+\X1320:Dump the font information\X;\6
+\X1324:Dump the hyphenation tables\X;\6
+\X1326:Dump a couple more things and the closing check word\X;\6
+\X1329:Close the format file\X;\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{1303}Corresponding to the procedure that dumps a format file, we have a function
+that reads one in. The function returns \\{false} if the dumped format is
+incompatible with the present \TeX\ table sizes, etc.
+
+\Y\B\4\D$\\{too\_small}(\|X)$ \6
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+${}\\{wterm\_ln}(\.{"---!\ Must\ increase\ }\)\.{the\ \%s"},\39\|X);{}$\5
+\&{goto} \\{bad\_fmt};\6
+\4${}\}{}$\2\par
+\Y\B\hbox{\4}\X523:Declare the function called \\{open\_fmt\_file}\X\7
+\&{bool} \\{load\_fmt\_file}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|j${},{}$ \|k;\C{all-purpose indices}\6
+\&{pointer} \|p${},{}$ \|q;\C{all-purpose pointers}\6
+\&{int} \|x;\C{something undumped}\6
+\&{four\_quarters} \|w;\C{four ASCII codes}\7
+\X1308:Undump constants for consistency check\X;\6
+\X1310:Undump the string pool\X;\6
+\X1312:Undump the dynamic memory\X;\6
+\X1314:Undump the table of equivalents\X;\6
+\X1321:Undump the font information\X;\6
+\X1325:Undump the hyphenation tables\X;\6
+\X1327:Undump a couple more things and the closing check word\X;\6
+\&{return} \\{true};\C{it worked!}\6
+\4\\{bad\_fmt}:\5
+\\{wake\_up\_terminal};\5
+\\{wterm\_ln}(\.{"(Fatal\ format\ file\ }\)\.{error;\ I'm\ stymied)"});\5
+\&{return} \\{false};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1304}The user is not allowed to dump a format file unless $\\{save\_ptr}\E\T{0}$.
+This condition implies that $\\{cur\_level}\E\\{level\_one}$, hence
+the \\{xeq\_level} array is constant and it need not be dumped.
+
+\Y\B\4\X1304:If dumping is not allowed, abort\X${}\E{}$\6
+\&{if} ${}(\\{save\_ptr}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_err}(\.{"You\ can't\ dump\ insi}\)\.{de\ a\ group"});\5
+\\{help1}(\.{"`\{...\\\\dump\}'\ is\ a\ }\)\.{no-no."});\5
+\\{succumb};\6
+\4${}\}{}$\2\par
+\U1302.\fi
+
+\M{1305}Format files consist of \&{memory\_word} items, and we use the following
+macros to dump words of different types:
+
+\Y\B\4\D$\\{dump\_wd}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{fmt\_file}.\|d\K\|X;{}$\5
+\\{put}(\\{fmt\_file});\5
+${}\}{}$\2\par
+\B\4\D$\\{dump\_int}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{fmt\_file}.\|d.\|i\K\|X;{}$\5
+\\{put}(\\{fmt\_file});\5
+${}\}{}$\2\par
+\B\4\D$\\{dump\_hh}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{fmt\_file}.\|d.\\{hh}\K\|X;{}$\5
+\\{put}(\\{fmt\_file});\5
+${}\}{}$\2\par
+\B\4\D$\\{dump\_qqqq}(\|X)$ \6
+${}\{{}$\5
+\1${}\\{fmt\_file}.\|d.\\{qqqq}\K\|X;{}$\5
+\\{put}(\\{fmt\_file});\5
+${}\}{}$\2\par
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{word\_file} \\{fmt\_file};\C{for input or output of format information}\par
+\fi
+
+\M{1306}The inverse macros are slightly more complicated, since we need to check
+the range of the values we are reading in. We say `\\{undump}(\|a)(\|b)(\|x)' to
+read an integer value \|x that is supposed to be in the range $\|a\Z\|x\Z\|b$.
+
+\Y\B\4\D$\\{undump\_wd}(\|X)$ \6
+${}\{{}$\5
+\1\\{get}(\\{fmt\_file});\5
+${}\|X\K\\{fmt\_file}.\|d{}$;\5
+${}\}{}$\2\par
+\B\4\D$\\{undump\_int}(\|X)$ \6
+${}\{{}$\5
+\1\\{get}(\\{fmt\_file});\5
+${}\|X\K\\{fmt\_file}.\|d.\|i{}$;\5
+${}\}{}$\2\par
+\B\4\D$\\{undump\_hh}(\|X)$ \6
+${}\{{}$\5
+\1\\{get}(\\{fmt\_file});\5
+${}\|X\K\\{fmt\_file}.\|d.\\{hh}{}$;\5
+${}\}{}$\2\par
+\B\4\D$\\{undump\_qqqq}(\|X)$ \6
+${}\{{}$\5
+\1\\{get}(\\{fmt\_file});\5
+${}\|X\K\\{fmt\_file}.\|d.\\{qqqq}{}$;\5
+${}\}{}$\2\par
+\B\4\D$\\{undump\_end\_end}(\|X)$ \5
+$\|X\K\|x{}$;\5
+$\}{}$\par
+\B\4\D$\\{undump\_end}(\|X)$ \5
+$(\|x>\|X)$ ) \&{goto} \\{bad\_fmt};\5
+\&{else} \\{undump\_end\_end}\par
+\B\4\D$\\{undump}(\|X)$ \5
+$\{{}$\5
+\\{undump\_int}(\|x); \&{if} ( $(\|x<\|X)\V{}$\\{undump\_end}\par
+\B\4\D$\\{undump\_size\_end\_end}(\|X)$ \5
+\\{too\_small}(\|X)\5
+\&{else} \\{undump\_end\_end}\par
+\B\4\D$\\{undump\_size\_end}(\|X)$ \5
+\&{if} ${}(\|x>\|X)$ \\{undump\_size\_end\_end}\par
+\B\4\D$\\{undump\_size}(\|X)$ \5
+$\{{}$\5
+\\{undump\_int}(\|x);\6
+\&{if} ${}(\|x<\|X){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\\{undump\_size\_end}\par
+\fi
+
+\M{1307}The next few sections of the program should make it clear how we use the
+dump/undump macros.
+
+\Y\B\4\X1307:Dump constants for consistency check\X${}\E{}$\6
+\\{dump\_int}(\T{0});\6
+\\{dump\_int}(\\{mem\_bot});\6
+\\{dump\_int}(\\{mem\_top});\6
+\\{dump\_int}(\\{eqtb\_size});\6
+\\{dump\_int}(\\{hash\_prime});\6
+\\{dump\_int}(\\{hyph\_size})\par
+\U1302.\fi
+
+\M{1308}Sections of a \.{WEB} program that are ``commented out'' still contribute
+strings to the string pool; therefore \.{INITEX} and \TeX\ will have
+the same strings. (And it is, of course, a good thing that they do.)
+
+\Y\B\4\X1308:Undump constants for consistency check\X${}\E{}$\6
+$\|x\K\\{fmt\_file}.\|d.\|i;{}$\6
+\&{if} ${}(\|x\I\T{0}){}$\1\5
+\&{goto} \\{bad\_fmt};\C{check that strings are the same}\2\6
+\\{undump\_int}(\|x);\6
+\&{if} ${}(\|x\I\\{mem\_bot}){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\\{undump\_int}(\|x);\6
+\&{if} ${}(\|x\I\\{mem\_top}){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\\{undump\_int}(\|x);\6
+\&{if} ${}(\|x\I\\{eqtb\_size}){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\\{undump\_int}(\|x);\6
+\&{if} ${}(\|x\I\\{hash\_prime}){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\\{undump\_int}(\|x); \&{if} ${}(\|x\I\\{hyph\_size})$ \&{goto} \\{bad\_fmt}\par
+\U1303.\fi
+
+\M{1309}\B\D$\\{dump\_four\_ASCII}$ \5
+$\|w.\\{b0}\K\\{qi}(\\{so}(\\{str\_pool}[\|k]));{}$\5
+${}\|w.\\{b1}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+\T{1}]));{}$\5
+${}\|w.\\{b2}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+\T{2}]));{}$\5
+${}\|w.\\{b3}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+\T{3}]));$ \\{dump\_qqqq}(\|w)\par
+\Y\B\4\X1309:Dump the string pool\X${}\E{}$\6
+\\{dump\_int}(\\{pool\_ptr});\5
+\\{dump\_int}(\\{str\_ptr});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{str\_ptr};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_int}(\\{str\_start}[\|k]);\2\6
+${}\|k\K\T{0};{}$\6
+\&{while} ${}(\|k+\T{4}<\\{pool\_ptr}){}$\5
+${}\{{}$\5
+\1\\{dump\_four\_ASCII};\5
+${}\|k\K\|k+\T{4};{}$\6
+\4${}\}{}$\2\6
+${}\|k\K\\{pool\_ptr}-\T{4};{}$\5
+\\{dump\_four\_ASCII};\5
+\\{print\_ln}(\,);\5
+\\{print\_int}(\\{str\_ptr});\5
+\\{print\_str}(\.{"\ strings\ of\ total\ l}\)\.{ength\ "}); \\{print\_int}(\\{pool\_ptr})\par
+\U1302.\fi
+
+\M{1310}\B\D$\\{undump\_four\_ASCII}$ \5
+\\{undump\_qqqq}(\|w);\5
+${}\\{str\_pool}[\|k]\K\\{si}(\\{qo}(\|w.\\{b0}));{}$\5
+${}\\{str\_pool}[\|k+\T{1}]\K\\{si}(\\{qo}(\|w.\\{b1}));{}$\5
+${}\\{str\_pool}[\|k+\T{2}]\K\\{si}(\\{qo}(\|w.\\{b2}));$ $\\{str\_pool}[\|k+\T{3}]\K\\{si}(\\{qo}(\|w.\\{b3}){}$)\par
+\Y\B\4\X1310:Undump the string pool\X${}\E{}$\6
+\\{undump\_size}(\T{0})(\\{pool\_size})(\.{"string\ pool\ size"})(\\{pool\_ptr});\5
+\\{undump\_size}(\T{0})(\\{max\_strings})(\.{"max\ strings"})(\\{str\_ptr});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{str\_ptr};{}$ ${}\|k\PP){}$\1\5
+\\{undump}(\T{0})(\\{pool\_ptr})(\\{str\_start}[\|k]);\2\6
+${}\|k\K\T{0};{}$\6
+\&{while} ${}(\|k+\T{4}<\\{pool\_ptr}){}$\5
+${}\{{}$\5
+\1\\{undump\_four\_ASCII};\5
+${}\|k\K\|k+\T{4};{}$\6
+\4${}\}{}$\2\6
+${}\|k\K\\{pool\_ptr}-\T{4};{}$\5
+\\{undump\_four\_ASCII};\5
+${}\\{init\_str\_ptr}\K\\{str\_ptr};$ $\\{init\_pool\_ptr}\K{}$\\{pool\_ptr}\par
+\U1303.\fi
+
+\M{1311}By sorting the list of available spaces in the variable-size portion of
+\\{mem}, we are usually able to get by without having to dump very much
+of the dynamic memory.
+
+We recompute \\{var\_used} and \\{dyn\_used}, so that \.{INITEX} dumps valid
+information even when it has not been gathering statistics.
+
+\Y\B\4\X1311:Dump the dynamic memory\X${}\E{}$\6
+\\{sort\_avail}(\,);\5
+${}\\{var\_used}\K\T{0};{}$\5
+\\{dump\_int}(\\{lo\_mem\_max});\5
+\\{dump\_int}(\\{rover});\5
+${}\|p\K\\{mem\_bot};{}$\5
+${}\|q\K\\{rover};{}$\5
+${}\|x\K\T{0}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{for} ${}(\|k\K\|p;{}$ ${}\|k\Z\|q+\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_wd}(\\{mem}[\|k]);\2\6
+${}\|x\K\|x+\|q+\T{2}-\|p;{}$\5
+${}\\{var\_used}\K\\{var\_used}+\|q-\|p;{}$\5
+${}\|p\K\|q+\\{node\_size}(\|q);{}$\5
+${}\|q\K\\{rlink}(\|q);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{rover}));{}$\5
+${}\\{var\_used}\K\\{var\_used}+\\{lo\_mem\_max}-\|p;{}$\5
+${}\\{dyn\_used}\K\\{mem\_end}+\T{1}-\\{hi\_mem\_min}{}$;\6
+\&{for} ${}(\|k\K\|p;{}$ ${}\|k\Z\\{lo\_mem\_max};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_wd}(\\{mem}[\|k]);\2\6
+${}\|x\K\|x+\\{lo\_mem\_max}+\T{1}-\|p;{}$\5
+\\{dump\_int}(\\{hi\_mem\_min});\5
+\\{dump\_int}(\\{avail});\6
+\&{for} ${}(\|k\K\\{hi\_mem\_min};{}$ ${}\|k\Z\\{mem\_end};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_wd}(\\{mem}[\|k]);\2\6
+${}\|x\K\|x+\\{mem\_end}+\T{1}-\\{hi\_mem\_min};{}$\5
+${}\|p\K\\{avail};{}$\6
+\&{while} ${}(\|p\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{decr}(\\{dyn\_used});\5
+${}\|p\K\\{link}(\|p);{}$\6
+\4${}\}{}$\2\6
+\\{dump\_int}(\\{var\_used});\5
+\\{dump\_int}(\\{dyn\_used});\5
+\\{print\_ln}(\,);\5
+\\{print\_int}(\|x);\5
+\\{print\_str}(\.{"\ memory\ locations\ d}\)\.{umped;\ current\ usage}\)\.{\ is\ "});\5
+\\{print\_int}(\\{var\_used});\5
+\\{print\_char}(\.{'\&'}); \\{print\_int}(\\{dyn\_used})\par
+\U1302.\fi
+
+\M{1312}\B\X1312:Undump the dynamic memory\X${}\E{}$\6
+$\\{undump}(\\{lo\_mem\_stat\_max}+\T{1000})(\\{hi\_mem\_stat\_min}-\T{1})(\\{lo\_mem\_max});{}$\5
+${}\\{undump}(\\{lo\_mem\_stat\_max}+\T{1})(\\{lo\_mem\_max})(\\{rover});{}$\5
+${}\|p\K\\{mem\_bot};{}$\5
+${}\|q\K\\{rover}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\&{for} ${}(\|k\K\|p;{}$ ${}\|k\Z\|q+\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{undump\_wd}(\\{mem}[\|k]);\2\6
+${}\|p\K\|q+\\{node\_size}(\|q);{}$\6
+\&{if} ${}((\|p>\\{lo\_mem\_max})\V((\|q\G\\{rlink}(\|q))\W(\\{rlink}(\|q)\I\\{rover}))){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+${}\|q\K\\{rlink}(\|q);{}$\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|q\E\\{rover}));{}$\6
+\&{for} ${}(\|k\K\|p;{}$ ${}\|k\Z\\{lo\_mem\_max};{}$ ${}\|k\PP){}$\1\5
+\\{undump\_wd}(\\{mem}[\|k]);\2\6
+\&{if} ${}(\\{mem\_min}<\\{mem\_bot}-\T{2}{}$)\C{make more low memory available}\6
+${}\{{}$\5
+\1${}\|p\K\\{llink}(\\{rover});{}$\5
+${}\|q\K\\{mem\_min}+\T{1};{}$\5
+${}\\{link}(\\{mem\_min})\K\\{null};{}$\5
+${}\\{info}(\\{mem\_min})\K\\{null}{}$;\C{we don't use the bottom word}\6
+${}\\{rlink}(\|p)\K\|q;{}$\5
+${}\\{llink}(\\{rover})\K\|q{}$;\6
+${}\\{rlink}(\|q)\K\\{rover};{}$\5
+${}\\{llink}(\|q)\K\|p;{}$\5
+${}\\{link}(\|q)\K\\{empty\_flag};{}$\5
+${}\\{node\_size}(\|q)\K\\{mem\_bot}-\|q;{}$\6
+\4${}\}{}$\2\6
+${}\\{undump}(\\{lo\_mem\_max}+\T{1})(\\{hi\_mem\_stat\_min})(\\{hi\_mem\_min});{}$\5
+\\{undump}(\\{null})(\\{mem\_top})(\\{avail});\5
+${}\\{mem\_end}\K\\{mem\_top};{}$\6
+\&{for} ${}(\|k\K\\{hi\_mem\_min};{}$ ${}\|k\Z\\{mem\_end};{}$ ${}\|k\PP){}$\1\5
+\\{undump\_wd}(\\{mem}[\|k]);\2\6
+\\{undump\_int}(\\{var\_used}); \\{undump\_int}(\\{dyn\_used})\par
+\U1303.\fi
+
+\M{1313}\B\X1313:Dump the table of equivalents\X${}\E{}$\6
+\X1315:Dump regions 1 to 4 of \\{eqtb}\X;\6
+\X1316:Dump regions 5 and 6 of \\{eqtb}\X;\6
+\\{dump\_int}(\\{par\_loc});\5
+\\{dump\_int}(\\{write\_loc});\6
+\X1318:Dump the hash table\X\par
+\U1302.\fi
+
+\M{1314}\B\X1314:Undump the table of equivalents\X${}\E{}$\6
+\X1317:Undump regions 1 to 6 of \\{eqtb}\X;\6
+\\{undump}(\\{hash\_base})(\\{frozen\_control\_sequence})(\\{par\_loc});\5
+${}\\{par\_token}\K\\{cs\_token\_flag}+\\{par\_loc}{}$;\6
+\\{undump}(\\{hash\_base})(\\{frozen\_control\_sequence})(\\{write\_loc});\6
+\X1319:Undump the hash table\X\par
+\U1303.\fi
+
+\M{1315}The table of equivalents usually contains repeated information, so we dump it
+in compressed form: The sequence of $n+2$ values $(n,x_1,\ldots,x_n,m)$ in the
+format file represents $n+m$ consecutive entries of \\{eqtb}, with \|m extra
+copies of $x_n$, namely $(x_1,\ldots,x_n,x_n,\ldots,x_n)$.
+
+\Y\B\4\X1315:Dump regions 1 to 4 of \\{eqtb}\X${}\E{}$\6
+$\|k\K\\{active\_base}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|j\K\|k;{}$\6
+\&{while} ${}(\|j<\\{int\_base}-\T{1}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{equiv}(\|j)\E\\{equiv}(\|j+\T{1}))\W(\\{eq\_type}(\|j)\E\\{eq\_type}(\|j+\T{1}))\W\30(\\{eq\_level}(\|j)\E\\{eq\_level}(\|j+\T{1}))){}$\1\5
+\&{goto} \\{found1};\2\6
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+${}\|l\K\\{int\_base};{}$\5
+\&{goto} \\{done1};\C{$\|j\E\\{int\_base}-\T{1}$}\6
+\4\\{found1}:\5
+\\{incr}(\|j);\5
+${}\|l\K\|j;{}$\6
+\&{while} ${}(\|j<\\{int\_base}-\T{1}){}$\5
+${}\{{}$\5
+\1\&{if} ${}((\\{equiv}(\|j)\I\\{equiv}(\|j+\T{1}))\V(\\{eq\_type}(\|j)\I\\{eq\_type}(\|j+\T{1}))\V\30(\\{eq\_level}(\|j)\I\\{eq\_level}(\|j+\T{1}))){}$\1\5
+\&{goto} \\{done1};\2\6
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+\4\\{done1}:\5
+${}\\{dump\_int}(\|l-\|k);{}$\6
+\&{while} ${}(\|k<\|l){}$\5
+${}\{{}$\5
+\1\\{dump\_wd}(\\{eqtb}[\|k]);\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+${}\|k\K\|j+\T{1};{}$\5
+${}\\{dump\_int}(\|k-\|l);{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|k\E\\{int\_base}){}$)\par
+\U1313.\fi
+
+\M{1316}\B\X1316:Dump regions 5 and 6 of \\{eqtb}\X${}\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+${}\|j\K\|k;{}$\6
+\&{while} ${}(\|j<\\{eqtb\_size}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{eqtb}[\|j].\|i\E\\{eqtb}[\|j+\T{1}].\|i){}$\1\5
+\&{goto} \\{found2};\2\6
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+${}\|l\K\\{eqtb\_size}+\T{1};{}$\5
+\&{goto} \\{done2};\C{$\|j\E\\{eqtb\_size}$}\6
+\4\\{found2}:\5
+\\{incr}(\|j);\5
+${}\|l\K\|j;{}$\6
+\&{while} ${}(\|j<\\{eqtb\_size}){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{eqtb}[\|j].\|i\I\\{eqtb}[\|j+\T{1}].\|i){}$\1\5
+\&{goto} \\{done2};\2\6
+\\{incr}(\|j);\6
+\4${}\}{}$\2\6
+\4\\{done2}:\5
+${}\\{dump\_int}(\|l-\|k);{}$\6
+\&{while} ${}(\|k<\|l){}$\5
+${}\{{}$\5
+\1\\{dump\_wd}(\\{eqtb}[\|k]);\5
+\\{incr}(\|k);\6
+\4${}\}{}$\2\6
+${}\|k\K\|j+\T{1};{}$\5
+${}\\{dump\_int}(\|k-\|l);{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|k>\\{eqtb\_size}){}$)\par
+\U1313.\fi
+
+\M{1317}\B\X1317:Undump regions 1 to 6 of \\{eqtb}\X${}\E{}$\6
+$\|k\K\\{active\_base}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+\\{undump\_int}(\|x);\6
+\&{if} ${}((\|x<\T{1})\V(\|k+\|x>\\{eqtb\_size}+\T{1})){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\&{for} ${}(\|j\K\|k;{}$ ${}\|j\Z\|k+\|x-\T{1};{}$ ${}\|j\PP){}$\1\5
+\\{undump\_wd}(\\{eqtb}[\|j]);\2\6
+${}\|k\K\|k+\|x;{}$\5
+\\{undump\_int}(\|x);\6
+\&{if} ${}((\|x<\T{0})\V(\|k+\|x>\\{eqtb\_size}+\T{1})){}$\1\5
+\&{goto} \\{bad\_fmt};\2\6
+\&{for} ${}(\|j\K\|k;{}$ ${}\|j\Z\|k+\|x-\T{1};{}$ ${}\|j\PP){}$\1\5
+${}\\{eqtb}[\|j]\K\\{eqtb}[\|k-\T{1}];{}$\2\6
+${}\|k\K\|k+\|x;{}$\6
+\4${}\}{}$\5
+\2\&{while} ${}(\R(\|k>\\{eqtb\_size}){}$)\par
+\U1314.\fi
+
+\M{1318}A different scheme is used to compress the hash table, since its lower
+region is usually sparse. When $\\{text}(\|p)\I\T{0}$ for $\|p\Z\\{hash\_used}$, we output
+two words, \|p and \\{hash}[\|p]. The hash table is, of course, densely packed
+for $\|p\G\\{hash\_used}$, so the remaining entries are output in a~block.
+
+\Y\B\4\X1318:Dump the hash table\X${}\E{}$\6
+\\{dump\_int}(\\{hash\_used});\5
+${}\\{cs\_count}\K\\{frozen\_control\_sequence}-\T{1}-\\{hash\_used};{}$\6
+\&{for} ${}(\|p\K\\{hash\_base};{}$ ${}\|p\Z\\{hash\_used};{}$ ${}\|p\PP){}$\1\6
+\&{if} ${}(\\{text}(\|p)\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{dump\_int}(\|p);\5
+\\{dump\_hh}(\\{hash}[\|p]);\5
+\\{incr}(\\{cs\_count});\6
+\4${}\}{}$\2\2\6
+\&{for} ${}(\|p\K\\{hash\_used}+\T{1};{}$ ${}\|p\Z\\{undefined\_control\_sequence}-\T{1};{}$ ${}\|p\PP){}$\1\5
+\\{dump\_hh}(\\{hash}[\|p]);\2\6
+\\{dump\_int}(\\{cs\_count});\6
+\\{print\_ln}(\,);\5
+\\{print\_int}(\\{cs\_count}); \\{print\_str}(\.{"\ multiletter\ contro}\)\.{l\ sequences"})\par
+\U1313.\fi
+
+\M{1319}\B\X1319:Undump the hash table\X${}\E{}$\6
+\\{undump}(\\{hash\_base})(\\{frozen\_control\_sequence})(\\{hash\_used});\5
+${}\|p\K\\{hash\_base}-\T{1}{}$;\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{undump}(\|p+\T{1})(\\{hash\_used})(\|p);{}$\5
+\\{undump\_hh}(\\{hash}[\|p]);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\|p\E\\{hash\_used}));{}$\6
+\&{for} ${}(\|p\K\\{hash\_used}+\T{1};{}$ ${}\|p\Z\\{undefined\_control\_sequence}-\T{1};{}$ ${}\|p\PP){}$\1\5
+\\{undump\_hh}(\\{hash}[\|p]);\2\6
+\\{undump\_int}(\\{cs\_count})\par
+\U1314.\fi
+
+\M{1320}\B\X1320:Dump the font information\X${}\E{}$\6
+\\{dump\_int}(\\{fmem\_ptr});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{fmem\_ptr}-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_wd}(\\{font\_info}[\|k]);\2\6
+\\{dump\_int}(\\{font\_ptr});\6
+\&{for} ${}(\|k\K\\{null\_font};{}$ ${}\|k\Z\\{font\_ptr};{}$ ${}\|k\PP){}$\1\5
+\X1322:Dump the array info for internal font number \|k\X;\2\6
+\\{print\_ln}(\,);\5
+${}\\{print\_int}(\\{fmem\_ptr}-\T{7});{}$\5
+\\{print\_str}(\.{"\ words\ of\ font\ info}\)\.{\ for\ "});\5
+${}\\{print\_int}(\\{font\_ptr}-\\{font\_base});{}$\5
+\\{print\_str}(\.{"\ preloaded\ font"}); \&{if} ${}(\\{font\_ptr}\I\\{font\_base}+\T{1})$ \\{print\_char}(\.{'s'})\par
+\U1302.\fi
+
+\M{1321}\B\X1321:Undump the font information\X${}\E{}$\6
+\\{undump\_size}(\T{7})(\\{font\_mem\_size})(\.{"font\ mem\ size"})(\\{fmem\_ptr});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{fmem\_ptr}-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{undump\_wd}(\\{font\_info}[\|k]);\2\6
+\\{undump\_size}(\\{font\_base})(\\{font\_max})(\.{"font\ max"})(\\{font\_ptr});\6
+\&{for} ${}(\|k\K\\{null\_font};{}$ ${}\|k\Z\\{font\_ptr};{}$ ${}\|k\PP){}$\1\5
+\X1323:Undump the array info for internal font number \|k\X\2\par
+\U1303.\fi
+
+\M{1322}\B\X1322:Dump the array info for internal font number \|k\X${}\E{}$\6
+${}\{{}$\5
+\1\\{dump\_qqqq}(\\{font\_check}[\|k]);\5
+\\{dump\_int}(\\{font\_size}[\|k]);\5
+\\{dump\_int}(\\{font\_dsize}[\|k]);\5
+\\{dump\_int}(\\{font\_params}[\|k]);\6
+\\{dump\_int}(\\{hyphen\_char}[\|k]);\5
+\\{dump\_int}(\\{skew\_char}[\|k]);\6
+\\{dump\_int}(\\{font\_name}[\|k]);\5
+\\{dump\_int}(\\{font\_area}[\|k]);\6
+\\{dump\_int}(\\{font\_bc}[\|k]);\5
+\\{dump\_int}(\\{font\_ec}[\|k]);\6
+\\{dump\_int}(\\{char\_base}[\|k]);\5
+\\{dump\_int}(\\{width\_base}[\|k]);\5
+\\{dump\_int}(\\{height\_base}[\|k]);\6
+\\{dump\_int}(\\{depth\_base}[\|k]);\5
+\\{dump\_int}(\\{italic\_base}[\|k]);\5
+\\{dump\_int}(\\{lig\_kern\_base}[\|k]);\6
+\\{dump\_int}(\\{kern\_base}[\|k]);\5
+\\{dump\_int}(\\{exten\_base}[\|k]);\5
+\\{dump\_int}(\\{param\_base}[\|k]);\6
+\\{dump\_int}(\\{font\_glue}[\|k]);\6
+\\{dump\_int}(\\{bchar\_label}[\|k]);\5
+\\{dump\_int}(\\{font\_bchar}[\|k]);\5
+\\{dump\_int}(\\{font\_false\_bchar}[\|k]);\6
+\\{print\_nl}(\.{"\\\\font"});\5
+\\{print\_esc}(\\{font\_id\_text}(\|k));\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_file\_name}(\\{font\_name}[\|k],\39\\{font\_area}[\|k],\39\\{empty\_string});{}$\6
+\&{if} ${}(\\{font\_size}[\|k]\I\\{font\_dsize}[\|k]){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ at\ "});\5
+\\{print\_scaled}(\\{font\_size}[\|k]);\5
+\\{print\_str}(\.{"pt"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1320.\fi
+
+\M{1323}\B\X1323:Undump the array info for internal font number \|k\X${}\E{}$\6
+${}\{{}$\5
+\1\\{undump\_qqqq}(\\{font\_check}[\|k]);\6
+\\{undump\_int}(\\{font\_size}[\|k]);\5
+\\{undump\_int}(\\{font\_dsize}[\|k]);\5
+\\{undump}(\\{min\_halfword})(\\{max\_halfword})(\\{font\_params}[\|k]);\6
+\\{undump\_int}(\\{hyphen\_char}[\|k]);\5
+\\{undump\_int}(\\{skew\_char}[\|k]);\6
+\\{undump}(\T{0})(\\{str\_ptr})(\\{font\_name}[\|k]);\5
+\\{undump}(\T{0})(\\{str\_ptr})(\\{font\_area}[\|k]);\6
+\\{undump}(\T{0})(\T{255})(\\{font\_bc}[\|k]);\5
+\\{undump}(\T{0})(\T{255})(\\{font\_ec}[\|k]);\6
+\\{undump\_int}(\\{char\_base}[\|k]);\5
+\\{undump\_int}(\\{width\_base}[\|k]);\5
+\\{undump\_int}(\\{height\_base}[\|k]);\6
+\\{undump\_int}(\\{depth\_base}[\|k]);\5
+\\{undump\_int}(\\{italic\_base}[\|k]);\5
+\\{undump\_int}(\\{lig\_kern\_base}[\|k]);\6
+\\{undump\_int}(\\{kern\_base}[\|k]);\5
+\\{undump\_int}(\\{exten\_base}[\|k]);\5
+\\{undump\_int}(\\{param\_base}[\|k]);\6
+\\{undump}(\\{min\_halfword})(\\{lo\_mem\_max})(\\{font\_glue}[\|k]);\6
+${}\\{undump}(\T{0})(\\{fmem\_ptr}-\T{1})(\\{bchar\_label}[\|k]);{}$\5
+\\{undump}(\\{min\_quarterword})(\\{non\_char})(\\{font\_bchar}[\|k]);\5
+\\{undump}(\\{min\_quarterword})(\\{non\_char})(\\{font\_false\_bchar}[\|k]);\6
+\4${}\}{}$\2\par
+\U1321.\fi
+
+\M{1324}\B\X1324:Dump the hyphenation tables\X${}\E{}$\6
+\\{dump\_int}(\\{hyph\_count});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{hyph\_size};{}$ ${}\|k\PP){}$\1\6
+\&{if} ${}(\\{hyph\_word}[\|k]\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{dump\_int}(\|k);\5
+\\{dump\_int}(\\{hyph\_word}[\|k]);\5
+\\{dump\_int}(\\{hyph\_list}[\|k]);\6
+\4${}\}{}$\2\2\6
+\\{print\_ln}(\,);\5
+\\{print\_int}(\\{hyph\_count});\5
+\\{print\_str}(\.{"\ hyphenation\ except}\)\.{ion"});\6
+\&{if} ${}(\\{hyph\_count}\I\T{1}){}$\1\5
+\\{print\_char}(\.{'s'});\2\6
+\&{if} (\\{trie\_not\_ready})\1\5
+\\{init\_trie}(\,);\2\6
+\\{dump\_int}(\\{trie\_max});\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\\{trie\_max};{}$ ${}\|k\PP){}$\1\5
+\\{dump\_hh}(\\{trie}[\|k]);\2\6
+\\{dump\_int}(\\{trie\_op\_ptr});\6
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{trie\_op\_ptr};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1\\{dump\_int}(\\{hyf\_distance}[\|k]);\5
+\\{dump\_int}(\\{hyf\_num}[\|k]);\5
+\\{dump\_int}(\\{hyf\_next}[\|k]);\6
+\4${}\}{}$\2\6
+\\{print\_nl}(\.{"Hyphenation\ trie\ of}\)\.{\ length\ "});\5
+\\{print\_int}(\\{trie\_max});\5
+\\{print\_str}(\.{"\ has\ "});\5
+\\{print\_int}(\\{trie\_op\_ptr});\5
+\\{print\_str}(\.{"\ op"});\6
+\&{if} ${}(\\{trie\_op\_ptr}\I\T{1}){}$\1\5
+\\{print\_char}(\.{'s'});\2\6
+\\{print\_str}(\.{"\ out\ of\ "});\5
+\\{print\_int}(\\{trie\_op\_size});\6
+\&{for} ${}(\|k\K\T{255};{}$ ${}\|k\G\T{0};{}$ ${}\|k\MM){}$\1\6
+\&{if} ${}(\\{trie\_used}[\|k]>\\{min\_quarterword}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"\ \ "});\5
+\\{print\_int}(\\{qo}(\\{trie\_used}[\|k]));\5
+\\{print\_str}(\.{"\ for\ language\ "});\5
+\\{print\_int}(\|k);\5
+\\{dump\_int}(\|k);\5
+\\{dump\_int}(\\{qo}(\\{trie\_used}[\|k]));\6
+\4${}\}{}$\2\2\par
+\U1302.\fi
+
+\M{1325}Only ``nonempty'' parts of \\{op\_start} need to be restored.
+
+\Y\B\4\X1325:Undump the hyphenation tables\X${}\E{}$\6
+\\{undump}(\T{0})(\\{hyph\_size})(\\{hyph\_count});\6
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{hyph\_count};{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1\\{undump}(\T{0})(\\{hyph\_size})(\|j);\5
+\\{undump}(\T{0})(\\{str\_ptr})(\\{hyph\_word}[\|j]);\5
+\\{undump}(\\{min\_halfword})(\\{max\_halfword})(\\{hyph\_list}[\|j]);\6
+\4${}\}{}$\2\6
+\\{undump\_size}(\T{0})(\\{trie\_size})(\.{"trie\ size"})(\|j);\6
+\8\#\&{ifdef} \.{INIT}\6
+${}\\{trie\_max}\K\|j;{}$\6
+\8\#\&{endif}\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\|j;{}$ ${}\|k\PP){}$\1\5
+\\{undump\_hh}(\\{trie}[\|k]);\2\6
+\\{undump\_size}(\T{0})(\\{trie\_op\_size})(\.{"trie\ op\ size"})(\|j);\6
+\8\#\&{ifdef} \.{INIT}\6
+${}\\{trie\_op\_ptr}\K\|j;{}$\6
+\8\#\&{endif}\6
+\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\|j;{}$ ${}\|k\PP){}$\5
+${}\{{}$\5
+\1\\{undump}(\T{0})(\T{63})(\\{hyf\_distance}[\|k]);\C{a \&{small\_number}}\6
+\\{undump}(\T{0})(\T{63})(\\{hyf\_num}[\|k]);\5
+\\{undump}(\\{min\_quarterword})(\\{max\_quarterword})(\\{hyf\_next}[\|k]);\6
+\4${}\}{}$\2\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{255};{}$ ${}\|k\PP){}$\1\5
+${}\\{trie\_used}[\|k]\K\\{min\_quarterword};{}$\2\6
+\8\#\&{endif}\6
+${}\|k\K\T{256};{}$\6
+\&{while} ${}(\|j>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{undump}(\T{0})(\|k-\T{1})(\|k);{}$\5
+\\{undump}(\T{1})(\|j)(\|x);\6
+\8\#\&{ifdef} \.{INIT}\6
+${}\\{trie\_used}[\|k]\K\\{qi}(\|x);{}$\6
+\8\#\&{endif}\6
+${}\|j\K\|j-\|x;{}$\5
+${}\\{op\_start}[\|k]\K\\{qo}(\|j);{}$\6
+\4${}\}{}$\2\6
+\8\#\&{ifdef} \.{INIT}\6
+$\\{trie\_not\_ready}\K\\{false}{}$\6
+\8\#\&{endif}\par
+\U1303.\fi
+
+\M{1326}We have already printed a lot of statistics, so we set $\\{tracing\_stats}\K\T{0}$
+to prevent them from appearing again.
+
+\Y\B\4\X1326:Dump a couple more things and the closing check word\X${}\E{}$\6
+\\{dump\_int}(\\{interaction});\5
+\\{dump\_int}(\\{format\_ident});\5
+\\{dump\_int}(\T{69069}); $\\{tracing\_stats}\K{}$\T{0}\par
+\U1302.\fi
+
+\M{1327}\B\X1327:Undump a couple more things and the closing check word\X${}\E{}$\6
+\\{undump}(\\{batch\_mode})(\\{error\_stop\_mode})(\\{interaction});\5
+\\{undump}(\T{0})(\\{str\_ptr})(\\{format\_ident});\5
+\\{undump\_int}(\|x); \&{if} ${}((\|x\I\T{69069})\V\\{eof}(\\{fmt\_file}))$ \&{goto} \\{bad\_fmt}\par
+\U1303.\fi
+
+\M{1328}\B\X1328:Create the \\{format\_ident}, open the format file, and inform the user that dumping has begun\X${}\E{}$\6
+$\\{selector}\K\\{new\_string};{}$\5
+\\{print\_str}(\.{"\ (preloaded\ format=}\)\.{"});\5
+\\{print}(\\{job\_name});\5
+\\{print\_char}(\.{'\ '});\5
+\\{print\_int}(\\{year});\5
+\\{print\_char}(\.{'.'});\5
+\\{print\_int}(\\{month});\5
+\\{print\_char}(\.{'.'});\5
+\\{print\_int}(\\{day});\5
+\\{print\_char}(\.{')'});\6
+\&{if} ${}(\\{interaction}\E\\{batch\_mode}){}$\1\5
+${}\\{selector}\K\\{log\_only};{}$\2\6
+\&{else}\1\5
+${}\\{selector}\K\\{term\_and\_log};{}$\2\6
+\\{str\_room}(\T{1});\5
+${}\\{format\_ident}\K\\{make\_string}(\,);{}$\5
+\\{pack\_job\_name}(\\{format\_extension});\6
+\&{while} ${}(\R\\{w\_open\_out}({\AND}\\{fmt\_file})){}$\1\5
+${}\\{prompt\_file\_name}(\.{"format\ file\ name"},\39\\{format\_extension});{}$\2\6
+\\{print\_nl}(\.{"Beginning\ to\ dump\ o}\)\.{n\ file\ "});\5
+${}\\{slow\_print}(\\{w\_make\_name\_string}({\AND}\\{fmt\_file}));{}$\5
+\\{flush\_string};\5
+\\{print\_nl}(\.{""}); \\{slow\_print}(\\{format\_ident})\par
+\U1302.\fi
+
+\M{1329}\B\X1329:Close the format file\X${}\E{}$\6
+$\\{w\_close}({\AND}\\{fmt\_file}{}$)\par
+\U1302.\fi
+
+\N{1}{1330}The main program.
+This is it: the part of \TeX\ that executes all those procedures we have
+written.
+
+Well---almost. Let's leave space for a few more routines that we may
+have forgotten.
+
+\Y\B\X1333:Last-minute procedures\X\par
+\fi
+
+\M{1331}We have noted that there are two versions of \TeX82. One, called \.{INITEX},
+has to be run first; it initializes everything from scratch, without
+reading a format file, and it has the capability of dumping a format file.
+The other one is called `\.{VIRTEX}'; it is a ``virgin'' program that needs
+to input a format file in order to get started. \.{VIRTEX} typically has
+more memory capacity than \.{INITEX}, because it does not need the space
+consumed by the auxiliary hyphenation tables and the numerous calls on
+\\{primitive}, etc.
+
+The \.{VIRTEX} program cannot read a format file instantaneously, of course;
+the best implementations therefore allow for production versions of \TeX\ that
+not only avoid the loading routine for \PASCAL\ object code, they also have
+a format file pre-loaded. This is impossible to do if we stick to standard
+\PASCAL; but there is a simple way to fool many systems into avoiding the
+initialization, as follows:\quad(1)~We declare a global integer variable
+called \\{ready\_already}. The probability is negligible that this
+variable holds any particular value like 314159 when \.{VIRTEX} is first
+loaded.\quad(2)~After we have read in a format file and initialized
+everything, we set $\\{ready\_already}\K\T{314159}$.\quad(3)~Soon \.{VIRTEX}
+will print `\.*', waiting for more input; and at this point we
+interrupt the program and save its core image in some form that the
+operating system can reload speedily.\quad(4)~When that core image is
+activated, the program starts again at the beginning; but now
+$\\{ready\_already}\E\T{314159}$ and all the other global variables have
+their initial values too. The former chastity has vanished!
+
+In other words, if we allow ourselves to test the condition
+$\\{ready\_already}\E\T{314159}$, before \\{ready\_already} has been
+assigned a value, we can avoid the lengthy initialization. Dirty tricks
+rarely pay off so handsomely.
+
+On systems that allow such preloading, the standard program called \.{TeX}
+should be the one that has \.{plain} format preloaded, since that agrees
+with {\sl The \TeX book}. Other versions, e.g., \.{AmSTeX}, should also
+be provided for commonly used formats.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{int} \\{ready\_already};\C{a sacrifice of purity for economy}\par
+\fi
+
+\M{1332}Now this is really it: \TeX\ starts and ends here.
+
+The initial test involving \\{ready\_already} should be deleted if the
+\PASCAL\ runtime system is smart enough to detect such a ``mistake.''
+
+\Y\B\&{int} \\{main}(\&{void})\1\1\2\2\6
+${}\{{}$\C{\\{start\_here}}\1\6
+${}\\{history}\K\\{fatal\_error\_stop}{}$;\C{in case we quit during initialization}\6
+\\{t\_open\_out};\C{open the terminal for output}\6
+\&{if} ${}(\\{ready\_already}\E\T{314159}){}$\1\5
+\&{goto} \\{start\_of\_TEX};\2\6
+\X14:Check the ``constant'' values for consistency\X\6
+\&{if} ${}(\\{bad}>\T{0}){}$\5
+${}\{{}$\5
+\1${}\\{wterm\_ln}(\.{"Ouch---my\ internal\ }\)\.{constants\ have\ been\ }\)\.{clobbered!"}\.{"---case\ \%d"},\39\\{bad});{}$\5
+\\{exit}(\T{0});\6
+\4${}\}{}$\2\6
+\\{initialize}(\,);\C{set global variables to their starting values}\6
+\8\#\&{ifdef} \.{INIT}\6
+\\{init\_prim}(\,);\C{call \\{primitive} for each primitive}\6
+${}\\{init\_str\_ptr}\K\\{str\_ptr};{}$\5
+${}\\{init\_pool\_ptr}\K\\{pool\_ptr};{}$\5
+\\{fix\_date\_and\_time}(\,);\6
+\8\#\&{endif}\6
+${}\\{ready\_already}\K\T{314159};{}$\6
+\4\\{start\_of\_TEX}:\5
+\X55:Initialize the output routines\X;\6
+\X1337:Get the first line of input and prepare to start\X;\6
+${}\\{history}\K\\{spotless}{}$;\C{ready to go!}\6
+\\{main\_control}(\,);\C{come to life}\6
+\\{final\_cleanup}(\,);\C{prepare for death}\6
+\\{close\_files\_and\_terminate}(\,);\5
+${}\\{ready\_already}\K\T{0};{}$\5
+\&{return} \T{0};\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1333}Here we do whatever is needed to complete \TeX's job gracefully on the
+local operating system. The code here might come into play after a fatal
+error; it must therefore consist entirely of ``safe'' operations that
+cannot produce error messages. For example, it would be a mistake to call
+\\{str\_room} or \\{make\_string} at this time, because a call on \\{overflow}
+might lead to an infinite loop.
+
+Actually there's one way to get error messages, via \\{prepare\_mag};
+but that can't cause infinite recursion.
+
+This program doesn't bother to close the input files that may still be open.
+
+\Y\B\4\X1333:Last-minute procedures\X${}\E{}$\6
+\&{void} \\{close\_files\_and\_terminate}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{all-purpose index}\7
+\X1378:Finish the extensions\X;\6
+\8\#\&{ifdef} \.{STAT}\6
+\&{if} ${}(\\{tracing\_stats}>\T{0}){}$\1\5
+\X1334:Output statistics about this job\X;\2\6
+\8\#\&{endif}\6
+\\{wake\_up\_terminal};\5
+\X642:Finish the \.{DVI} file\X;\6
+\&{if} (\\{log\_opened})\5
+${}\{{}$\5
+\1\\{wlog\_cr};\5
+${}\\{a\_close}({\AND}\\{log\_file});{}$\5
+${}\\{selector}\K\\{selector}-\T{2};{}$\6
+\&{if} ${}(\\{selector}\E\\{term\_only}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"Transcript\ written\ }\)\.{on\ "});\5
+\\{slow\_print}(\\{log\_name});\5
+\\{print\_char}(\.{'.'});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\As1335, 1336\ETs1338.
+\U1330.\fi
+
+\M{1334}The present section goes directly to the log file instead of using
+\\{print} commands, because there's no need for these strings to take
+up \\{str\_pool} memory when a non-{\bf stat} version of \TeX\ is being used.
+
+\Y\B\4\X1334:Output statistics about this job\X${}\E{}$\6
+\&{if} (\\{log\_opened})\5
+${}\{{}$\5
+\1\\{wlog\_ln}(\.{"\ "});\5
+\\{wlog\_ln}(\.{"Here\ is\ how\ much\ of}\)\.{\ TeX's\ memory\ you\ us}\)\.{ed:"});\5
+${}\\{wlog}(\.{"\ \%d\ string"},\39\\{str\_ptr}-\\{init\_str\_ptr});{}$\6
+\&{if} ${}(\\{str\_ptr}\I\\{init\_str\_ptr}+\T{1}){}$\1\5
+\\{wlog}(\.{"s"});\2\6
+${}\\{wlog\_ln}(\.{"\ out\ of\ \%d"},\39\\{max\_strings}-\\{init\_str\_ptr}){}$;\6
+${}\\{wlog\_ln}(\.{"\ \%d\ string\ characte}\)\.{rs\ out\ of\ \%d"},\39\\{pool\_ptr}-\\{init\_pool\_ptr},\39\\{pool\_size}-\\{init\_pool\_ptr}){}$;\6
+${}\\{wlog\_ln}(\.{"\ \%d\ words\ of\ memory}\)\.{\ out\ of\ \%d"},\39\\{lo\_mem\_max}-\\{mem\_min}+\\{mem\_end}-\\{hi\_mem\_min}+\T{2},\30\39\\{mem\_end}+\T{1}-\\{mem\_min}){}$;\6
+${}\\{wlog\_ln}(\.{"\ \%d\ multiletter\ con}\)\.{trol\ sequences\ out\ o}\)\.{f\ \%d"},\39\\{cs\_count},\39\\{hash\_size}){}$;\6
+${}\\{wlog}(\.{"\ \%d\ words\ of\ font\ i}\)\.{nfo\ for\ \%d\ font"},\39\\{fmem\_ptr},\39\\{font\_ptr}-\\{font\_base});{}$\6
+\&{if} ${}(\\{font\_ptr}\I\\{font\_base}+\T{1}){}$\1\5
+\\{wlog}(\.{"s"});\2\6
+${}\\{wlog\_ln}(\.{",\ out\ of\ \%d\ for\ \%d"},\39\\{font\_mem\_size},\39\\{font\_max}-\\{font\_base}){}$;\6
+${}\\{wlog}(\.{"\ \%d\ hyphenation\ exc}\)\.{eption"},\39\\{hyph\_count});{}$\6
+\&{if} ${}(\\{hyph\_count}\I\T{1}){}$\1\5
+\\{wlog}(\.{"s"});\2\6
+${}\\{wlog\_ln}(\.{"\ out\ of\ \%d"},\39\\{hyph\_size}){}$;\6
+${}\\{wlog\_ln}(\.{"\ \%di,\%dn,\%dp,\%db,\%d}\)\.{s\ stack\ positions\ ou}\)\.{t\ of\ \%di,\%dn,\%dp,\%db}\)\.{,\%ds"},\39\\{max\_in\_stack},\39\\{max\_nest\_stack},\30\39\\{max\_param\_stack},\30\39\\{max\_buf\_stack}+\T{1},\30\39\\{max\_save\_stack}+%
+\T{6},\30\39\\{stack\_size},\39\\{nest\_size},\39\\{param\_size},\39\\{buf\_size},\39\\{save\_size});{}$\6
+\4${}\}{}$\2\par
+\U1333.\fi
+
+\M{1335}We get to the \\{final\_cleanup} routine when \.{\\end} or \.{\\dump} has
+been scanned and \\{its\_all\_over}\kern-2pt.
+
+\Y\B\4\X1333:Last-minute procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{final\_cleanup}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|c;\C{0 for \.{\\end}, 1 for \.{\\dump}}\7
+${}\|c\K\\{cur\_chr};{}$\6
+\&{if} ${}(\\{job\_name}\E\T{0}){}$\1\5
+\\{open\_log\_file}(\,);\2\6
+\&{while} ${}(\\{input\_ptr}>\T{0}){}$\1\6
+\&{if} ${}(\\{state}\E\\{token\_list}){}$\1\5
+\\{end\_token\_list}(\,);\5
+\2\&{else}\1\5
+\\{end\_file\_reading}(\,);\2\2\6
+\&{while} ${}(\\{open\_parens}>\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ )"});\5
+\\{decr}(\\{open\_parens});\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{cur\_level}>\\{level\_one}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"("});\5
+\\{print\_esc}(\X1782:\.{"end\ occurred\ "}\X);\5
+\\{print\_str}(\.{"inside\ a\ group\ at\ l}\)\.{evel\ "});\5
+${}\\{print\_int}(\\{cur\_level}-\\{level\_one});{}$\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\2\6
+\&{while} ${}(\\{cond\_ptr}\I\\{null}){}$\5
+${}\{{}$\5
+\1\\{print\_nl}(\.{"("});\5
+\\{print\_esc}(\X1782:\.{"end\ occurred\ "}\X);\5
+\\{print\_str}(\.{"when\ "});\5
+${}\\{print\_cmd\_chr}(\\{if\_test},\39\\{cur\_if});{}$\6
+\&{if} ${}(\\{if\_line}\I\T{0}){}$\5
+${}\{{}$\5
+\1\\{print\_str}(\.{"\ on\ line\ "});\5
+\\{print\_int}(\\{if\_line});\6
+\4${}\}{}$\2\6
+\\{print\_str}(\.{"\ was\ incomplete)"});\5
+${}\\{if\_line}\K\\{if\_line\_field}(\\{cond\_ptr});{}$\5
+${}\\{cur\_if}\K\\{subtype}(\\{cond\_ptr});{}$\5
+${}\\{temp\_ptr}\K\\{cond\_ptr};{}$\5
+${}\\{cond\_ptr}\K\\{link}(\\{cond\_ptr});{}$\5
+${}\\{free\_node}(\\{temp\_ptr},\39\\{if\_node\_size});{}$\6
+\4${}\}{}$\2\6
+\&{if} ${}(\\{history}\I\\{spotless}){}$\1\6
+\&{if} ${}(((\\{history}\E\\{warning\_issued})\V(\\{interaction}<\\{error\_stop\_mode}))){}$\1\6
+\&{if} ${}(\\{selector}\E\\{term\_and\_log}){}$\5
+${}\{{}$\5
+\1${}\\{selector}\K\\{term\_only};{}$\5
+\\{print\_nl}(\.{"(see\ the\ transcript}\)\.{\ file\ for\ additional}\)\.{\ information)"});\5
+${}\\{selector}\K\\{term\_and\_log};{}$\6
+\4${}\}{}$\2\2\2\6
+\&{if} ${}(\|c\E\T{1}){}$\5
+${}\{{}$\6
+\8\#\&{ifdef} \.{INIT}\1\6
+\&{for} ${}(\|c\K\\{top\_mark\_code};{}$ ${}\|c\Z\\{split\_bot\_mark\_code};{}$ ${}\|c\PP){}$\1\6
+\&{if} ${}(\\{cur\_mark}[\|c]\I\\{null}){}$\1\5
+\\{delete\_token\_ref}(\\{cur\_mark}[\|c]);\2\2\6
+\&{if} ${}(\\{last\_glue}\I\\{max\_halfword}){}$\1\5
+\\{delete\_glue\_ref}(\\{last\_glue});\2\6
+\\{store\_fmt\_file}(\,);\5
+\&{return};\6
+\8\#\&{endif}\6
+\\{print\_nl}(\.{"(\\\\dump\ is\ performe}\)\.{d\ only\ by\ INITEX)"});\5
+\&{return};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1336}\B\X1333:Last-minute procedures\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{INIT}\6
+\&{void} \\{init\_prim}(\&{void})\C{initialize all the primitives}\6
+${}\{{}$\5
+\1${}\\{no\_new\_control\_sequence}\K\\{false};{}$\5
+\X226:Put each of \TeX's primitives into the hash table\X;\6
+${}\\{no\_new\_control\_sequence}\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{1337}When we begin the following code, \TeX's tables may still contain garbage;
+the strings might not even be present. Thus we must proceed cautiously to get
+bootstrapped in.
+
+But when we finish this part of the program, \TeX\ is ready to call on the
+\\{main\_control} routine to do its work.
+
+\Y\B\4\X1337:Get the first line of input and prepare to start\X${}\E{}$\6
+${}\{{}$\5
+\1\X331:Initialize the input routines\X;\6
+\&{if} ${}((\\{format\_ident}\E\T{0})\V(\\{buffer}[\\{loc}]\E\.{'\&'})){}$\5
+${}\{{}$\5
+\1\&{if} ${}(\\{format\_ident}\I\T{0}){}$\1\5
+\\{initialize}(\,);\C{erase preloaded format}\2\6
+\&{if} ${}(\R\\{open\_fmt\_file}(\,)){}$\1\5
+\\{exit}(\T{0});\2\6
+\&{if} ${}(\R\\{load\_fmt\_file}(\,)){}$\5
+${}\{{}$\5
+\1${}\\{w\_close}({\AND}\\{fmt\_file});{}$\5
+\\{exit}(\T{0});\6
+\4${}\}{}$\2\6
+${}\\{w\_close}({\AND}\\{fmt\_file});{}$\6
+\&{while} ${}((\\{loc}<\\{limit})\W(\\{buffer}[\\{loc}]\E\.{'\ '})){}$\1\5
+\\{incr}(\\{loc});\2\6
+\4${}\}{}$\2\6
+\&{if} (\\{end\_line\_char\_inactive})\1\5
+\\{decr}(\\{limit});\2\6
+\&{else}\1\5
+${}\\{buffer}[\\{limit}]\K\\{end\_line\_char};{}$\2\6
+\\{fix\_date\_and\_time}(\,);\6
+\X765:Compute the magic offset\X;\6
+\X75:Initialize the print \\{selector} based on \\{interaction}\X;\6
+\&{if} ${}((\\{loc}<\\{limit})\W(\\{cat\_code}(\\{buffer}[\\{loc}])\I\\{escape})){}$\1\5
+\\{start\_input}(\,);\C{\.{\\input} assumed}\2\6
+\4${}\}{}$\2\par
+\U1332.\fi
+
+\N{1}{1338}Debugging.
+Once \TeX\ is working, you should be able to diagnose most errors with
+the \.{\\show} commands and other diagnostic features. But for the initial
+stages of debugging, and for the revelation of really deep mysteries, you
+can compile \TeX\ with a few more aids, including the \PASCAL\ runtime
+checks and its debugger. An additional routine called \\{debug\_help}
+will also come into play when you type `\.D' after an error message;
+\\{debug\_help} also occurs just before a fatal error causes \TeX\ to succumb.
+
+The interface to \\{debug\_help} is primitive, but it is good enough when used
+with a \PASCAL\ debugger that allows you to set breakpoints and to read
+variables and change their values. After getting the prompt `\.{debug \#}', you
+type either a negative number (this exits \\{debug\_help}), or zero (this
+goes to a location where you can set a breakpoint, thereby entering into
+dialog with the \PASCAL\ debugger), or a positive number \|m followed by
+an argument \|n. The meaning of \|m and \|n will be clear from the
+program below. (If $\|m\E\T{13}$, there is an additional argument, \|l.)
+
+\Y\B\4\X1333:Last-minute procedures\X${}\mathrel+\E{}$\6
+\8\#\&{ifdef} \.{DEBUG}\6
+\&{void} \\{debug\_help}(\&{void})\C{routine to display various things}\6
+${}\{{}$\5
+\1\&{int} \|k${},{}$ \|l${},{}$ \|m${},{}$ \|n;\7
+\&{loop}\5
+${}\{{}$\5
+\1\\{wake\_up\_terminal};\5
+\\{print\_nl}(\.{"debug\ \#\ (-1\ to\ exit}\)\.{):"});\5
+\\{update\_terminal};\6
+\&{if} ${}(\\{fscanf}(\\{term\_in}.\|f,\39\.{"\ \%d"},\39{\AND}\|m)<\T{1}\V\|m<\T{0}){}$\1\5
+\&{return};\2\6
+\&{else} \&{if} ${}(\|m\E\T{0}){}$\5
+${}\{{}$\5
+\1\&{goto} \\{breakpoint};\C{go to every label at least once}\6
+\4\\{breakpoint}:\5
+${}\|m\K\T{0}{}$;\C{'BREAKPOINT'}\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{fscanf}(\\{term\_in}.\|f,\39\.{"\ \%d"},\39{\AND}\|n);{}$\6
+\&{switch} (\|m)\5
+${}\{{}$\1\6
+\hbox{\4}\X1339:Numbered cases for \\{debug\_help}\X\6
+\4\&{default}:\5
+\\{print\_str}(\.{"?"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\8\#\&{endif}\par
+\fi
+
+\M{1339}\B\X1339:Numbered cases for \\{debug\_help}\X${}\E{}$\6
+\4\&{case} \T{1}:\5
+\\{print\_word}(\\{mem}[\|n]);\5
+\&{break};\C{display \\{mem}[\|n] in all forms}\6
+\4\&{case} \T{2}:\5
+\\{print\_int}(\\{info}(\|n));\5
+\&{break};\6
+\4\&{case} \T{3}:\5
+\\{print\_int}(\\{link}(\|n));\5
+\&{break};\6
+\4\&{case} \T{4}:\5
+\\{print\_word}(\\{eqtb}[\|n]);\5
+\&{break};\6
+\4\&{case} \T{5}:\5
+\\{print\_word}(\\{font\_info}[\|n]);\5
+\&{break};\6
+\4\&{case} \T{6}:\5
+\\{print\_word}(\\{save\_stack}[\|n]);\5
+\&{break};\6
+\4\&{case} \T{7}:\5
+\\{show\_box}(\|n);\5
+\&{break};\C{show a box, abbreviated by \\{show\_box\_depth} and \\{show\_box\_breadth}}\6
+\4\&{case} \T{8}:\6
+${}\{{}$\5
+\1${}\\{breadth\_max}\K\T{10000};{}$\5
+${}\\{depth\_threshold}\K\\{pool\_size}-\\{pool\_ptr}-\T{10};{}$\5
+\\{show\_node\_list}(\|n);\C{show a box in its entirety}\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \T{9}:\5
+${}\\{show\_token\_list}(\|n,\39\\{null},\39\T{1000}){}$;\5
+\&{break};\6
+\4\&{case} \T{10}:\5
+\\{slow\_print}(\|n);\5
+\&{break};\6
+\4\&{case} \T{11}:\5
+${}\\{check\_mem}(\|n>\T{0}){}$;\5
+\&{break};\C{check wellformedness; print new busy locations if $\|n>\T{0}$}\6
+\4\&{case} \T{12}:\5
+\\{search\_mem}(\|n);\5
+\&{break};\C{look for pointers to \|n}\6
+\4\&{case} \T{13}:\6
+${}\{{}$\5
+\1${}\\{fscanf}(\\{term\_in}.\|f,\39\.{"\ \%d"},\39{\AND}\|l);{}$\5
+${}\\{print\_cmd\_chr}(\|n,\39\|l);{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \T{14}:\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\|n;{}$ ${}\|k\PP){}$\1\5
+\\{print}(\\{buffer}[\|k]);\5
+\2\&{break};\6
+\4\&{case} \T{15}:\6
+${}\{{}$\5
+\1${}\\{font\_in\_short\_display}\K\\{null\_font};{}$\5
+\\{short\_display}(\|n);\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \T{16}:\5
+${}\\{panicking}\K\R\\{panicking}{}$;\5
+\&{break};\par
+\U1338.\fi
+
+\N{1}{1340}Extensions.
+The program above includes a bunch of ``hooks'' that allow further
+capabilities to be added without upsetting \TeX's basic structure.
+Most of these hooks are concerned with ``whatsit'' nodes, which are
+intended to be used for special purposes; whenever a new extension to
+\TeX\ involves a new kind of whatsit node, a corresponding change needs
+to be made to the routines below that deal with such nodes,
+but it will usually be unnecessary to make many changes to the
+other parts of this program.
+
+In order to demonstrate how extensions can be made, we shall treat
+`\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
+`\.{\\special}', and `\.{\\setlanguage}' as if they were extensions.
+These commands are actually primitives of \TeX, and they should
+appear in all implementations of the system; but let's try to imagine
+that they aren't. Then the program below illustrates how a person
+could add them.
+
+Sometimes, of course, an extension will require changes to \TeX\ itself;
+no system of hooks could be complete enough for all conceivable extensions.
+The features associated with `\.{\\write}' are almost all confined to the
+following paragraphs, but there are small parts of the \\{print\_ln} and
+\\{print\_char} procedures that were introduced specifically to \.{\\write}
+characters. Furthermore one of the token lists recognized by the scanner
+is a \\{write\_text}; and there are a few other miscellaneous places where we
+have already provided for some aspect of \.{\\write}. The goal of a \TeX\
+extender should be to minimize alterations to the standard parts of the
+program, and to avoid them completely if possible. He or she should also
+be quite sure that there's no easy way to accomplish the desired goals
+with the standard features that \TeX\ already has. ``Think thrice before
+extending,'' because that may save a lot of work, and it will also keep
+incompatible extensions of \TeX\ from proliferating.
+
+\fi
+
+\M{1341}First let's consider the format of whatsit nodes that are used to represent
+the data associated with \.{\\write} and its relatives. Recall that a whatsit
+has $\\{type}\E\\{whatsit\_node}$, and the \\{subtype} is supposed to distinguish
+different kinds of whatsits. Each node occupies two or more words; the
+exact number is immaterial, as long as it is readily determined from the
+\\{subtype} or other data.
+
+We shall introduce five \\{subtype} values here, corresponding to the
+control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, \.{\\special}, and
+\.{\\setlanguage}. The second word of I/O whatsits has a \\{write\_stream} field
+that identifies the write-stream number (0 to 15, or 16 for out-of-range and
+positive, or 17 for out-of-range and negative).
+In the case of \.{\\write} and \.{\\special}, there is also a field that
+points to the reference count of a token list that should be sent. In the
+case of \.{\\openout}, we need three words and three auxiliary subfields
+to hold the string numbers for name, area, and extension.
+
+\Y\B\4\D$\\{write\_node\_size}$ \5
+\T{2}\C{number of words in a write/whatsit node}\par
+\B\4\D$\\{open\_node\_size}$ \5
+\T{3}\C{number of words in an open/whatsit node}\par
+\B\4\D$\\{open\_node}$ \5
+\T{0}\C{\\{subtype} in whatsits that represent files to \.{\\openout}}\par
+\B\4\D$\\{write\_node}$ \5
+\T{1}\C{\\{subtype} in whatsits that represent things to \.{\\write}}\par
+\B\4\D$\\{close\_node}$ \5
+\T{2}\C{\\{subtype} in whatsits that represent streams to \.{\\closeout}}\par
+\B\4\D$\\{special\_node}$ \5
+\T{3}\C{\\{subtype} in whatsits that represent \.{\\special} things}\par
+\B\4\D$\\{language\_node}$ \5
+\T{4}\C{\\{subtype} in whatsits that change the current language}\par
+\B\4\D$\\{what\_lang}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{language number, in the range $\T{0}\dotdot\T{255}$}\par
+\B\4\D$\\{what\_lhm}(\|X)$ \5
+$\\{type}(\|X+\T{1}{}$)\C{minimum left fragment, in the range $\T{1}\dotdot\T{63}$}\par
+\B\4\D$\\{what\_rhm}(\|X)$ \5
+$\\{subtype}(\|X+\T{1}{}$)\C{minimum right fragment, in the range $\T{1}\dotdot\T{63}$}\par
+\B\4\D$\\{write\_tokens}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{reference count of token list to write}\par
+\B\4\D$\\{write\_stream}(\|X)$ \5
+$\\{info}(\|X+\T{1}{}$)\C{stream number (0 to 17)}\par
+\B\4\D$\\{open\_name}(\|X)$ \5
+$\\{link}(\|X+\T{1}{}$)\C{string number of file name to open}\par
+\B\4\D$\\{open\_area}(\|X)$ \5
+$\\{info}(\|X+\T{2}{}$)\C{string number of file area for \\{open\_name}}\par
+\B\4\D$\\{open\_ext}(\|X)$ \5
+$\\{link}(\|X+\T{2}{}$)\C{string number of file extension for \\{open\_name}}\par
+\fi
+
+\M{1342}The sixteen possible \.{\\write} streams are represented by the \\{write\_file}
+array. The \|jth file is open if and only if $\\{write\_open}[\|j]\E\\{true}$. The last
+two streams are special; \\{write\_open}[\T{16}] represents a stream number
+greater than 15, while \\{write\_open}[\T{17}] represents a negative stream number,
+and both of these variables are always \\{false}.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{alpha\_file} \\{write\_file}[\T{16}];\6
+\&{bool} \\{write\_open}[\T{18}];\par
+\fi
+
+\M{1343}\B\X21:Set initial values of key variables\X${}\mathrel+\E{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{17};{}$ ${}\|k\PP){}$\1\5
+${}\\{write\_open}[\|k]\K\\{false}{}$;\2\par
+\fi
+
+\M{1344}Extensions might introduce new command codes; but it's best to use
+\\{extension} with a modifier, whenever possible, so that \\{main\_control}
+stays the same.
+
+\Y\B\4\D$\\{immediate\_code}$ \5
+\T{4}\C{command modifier for \.{\\immediate}}\par
+\B\4\D$\\{set\_language\_code}$ \5
+\T{5}\C{command modifier for \.{\\setlanguage}}\par
+\Y\B\4\X226:Put each of \TeX's primitives into the hash table\X${}\mathrel+\E{}$\6
+$\\{primitive}(\X1783:\.{"openout"}\X,\39\\{extension},\39\\{open\_node}){}$;\6
+${}\\{primitive}(\X1568:\.{"write"}\X,\39\\{extension},\39\\{write\_node});{}$\5
+${}\\{write\_loc}\K\\{cur\_val}{}$;\6
+${}\\{primitive}(\X1784:\.{"closeout"}\X,\39\\{extension},\39\\{close\_node}){}$;\6
+${}\\{primitive}(\X1785:\.{"special"}\X,\39\\{extension},\39\\{special\_node}){}$;\6
+${}\\{primitive}(\X1786:\.{"immediate"}\X,\39\\{extension},\39\\{immediate\_code}){}$;\6
+${}\\{primitive}(\X1787:\.{"setlanguage"}\X,\39\\{extension},\39\\{set\_language\_code}){}$;\par
+\fi
+
+\M{1345}The variable \\{write\_loc} just introduced is used to provide an
+appropriate error message in case of ``runaway'' write texts.
+
+\Y\B\4\X13:Global variables\X${}\mathrel+\E{}$\6
+\&{pointer} \\{write\_loc};\C{\\{eqtb} address of \.{\\write}}\par
+\fi
+
+\M{1346}\B\X227:Cases of \\{print\_cmd\_chr} for symbolic printing of primitives\X${}\mathrel+\E{}$\6
+\4\&{case} \\{extension}:\6
+\&{switch} (\\{chr\_code})\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\5
+\\{print\_esc}(\X1783:\.{"openout"}\X);\5
+\&{break};\6
+\4\&{case} \\{write\_node}:\5
+\\{print\_esc}(\X1568:\.{"write"}\X);\5
+\&{break};\6
+\4\&{case} \\{close\_node}:\5
+\\{print\_esc}(\X1784:\.{"closeout"}\X);\5
+\&{break};\6
+\4\&{case} \\{special\_node}:\5
+\\{print\_esc}(\X1785:\.{"special"}\X);\5
+\&{break};\6
+\4\&{case} \\{immediate\_code}:\5
+\\{print\_esc}(\X1786:\.{"immediate"}\X);\5
+\&{break};\6
+\4\&{case} \\{set\_language\_code}:\5
+\\{print\_esc}(\X1787:\.{"setlanguage"}\X);\5
+\&{break};\6
+\4\&{default}:\5
+\\{print\_str}(\.{"[unknown\ extension!}\)\.{]"});\6
+\4${}\}{}$\5
+\2\&{break};\par
+\fi
+
+\M{1347}When an \\{extension} command occurs in \\{main\_control}, in any mode,
+the \\{do\_extension} routine is called.
+
+\Y\B\4\X1347:Cases of \\{main\_control} that are for extensions to \TeX\X${}\E{}$\6
+\4\\{any\_mode}(\\{extension}):\5
+\\{do\_extension}(\,);\par
+\U1045.\fi
+
+\M{1348}\B\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\hbox{\4}\X1349:Declare procedures needed in \\{do\_extension}\X\7
+\&{void} \\{do\_extension}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{int} \|k;\C{all-purpose integer}\6
+\&{pointer} \|p;\C{all-purpose pointer}\7
+\&{switch} (\\{cur\_chr})\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\5
+\X1351:Implement \.{\\openout}\X\5
+\&{break};\6
+\4\&{case} \\{write\_node}:\5
+\X1352:Implement \.{\\write}\X\5
+\&{break};\6
+\4\&{case} \\{close\_node}:\5
+\X1353:Implement \.{\\closeout}\X\5
+\&{break};\6
+\4\&{case} \\{special\_node}:\5
+\X1354:Implement \.{\\special}\X\5
+\&{break};\6
+\4\&{case} \\{immediate\_code}:\5
+\X1375:Implement \.{\\immediate}\X\5
+\&{break};\6
+\4\&{case} \\{set\_language\_code}:\5
+\X1377:Implement \.{\\setlanguage}\X\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1788:\.{"ext1"}\X);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1349}Here is a subroutine that creates a whatsit node having a given \\{subtype}
+and a given number of words. It initializes only the first word of the whatsit,
+and appends it to the current list.
+
+\Y\B\4\X1349:Declare procedures needed in \\{do\_extension}\X${}\E{}$\6
+\&{void} \\{new\_whatsit}(\&{small\_number} \|s${},\39{}$\&{small\_number} \|w)\1\1\2\2\6
+${}\{{}$\5
+\1\&{pointer} \|p;\C{the new node}\7
+${}\|p\K\\{get\_node}(\|w);{}$\5
+${}\\{type}(\|p)\K\\{whatsit\_node};{}$\5
+${}\\{subtype}(\|p)\K\|s;{}$\5
+${}\\{link}(\\{tail})\K\|p;{}$\5
+${}\\{tail}\K\|p;{}$\6
+\4${}\}{}$\2\par
+\A1350.
+\U1348.\fi
+
+\M{1350}The next subroutine uses \\{cur\_chr} to decide what sort of whatsit is
+involved, and also inserts a \\{write\_stream} number.
+
+\Y\B\4\X1349:Declare procedures needed in \\{do\_extension}\X${}\mathrel+\E{}$\6
+\&{void} \\{new\_write\_whatsit}(\&{small\_number} \|w)\1\1\2\2\6
+${}\{{}$\5
+\1${}\\{new\_whatsit}(\\{cur\_chr},\39\|w);{}$\6
+\&{if} ${}(\|w\I\\{write\_node\_size}){}$\1\5
+\\{scan\_four\_bit\_int}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{scan\_int}(\,);\6
+\&{if} ${}(\\{cur\_val}<\T{0}){}$\1\5
+${}\\{cur\_val}\K\T{17};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_val}>\T{15}){}$\1\5
+${}\\{cur\_val}\K\T{16};{}$\2\6
+\4${}\}{}$\2\6
+${}\\{write\_stream}(\\{tail})\K\\{cur\_val};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1351}\B\X1351:Implement \.{\\openout}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{new\_write\_whatsit}(\\{open\_node\_size});\5
+\\{scan\_optional\_equals}(\,);\5
+\\{scan\_file\_name}(\,);\6
+${}\\{open\_name}(\\{tail})\K\\{cur\_name};{}$\5
+${}\\{open\_area}(\\{tail})\K\\{cur\_area};{}$\5
+${}\\{open\_ext}(\\{tail})\K\\{cur\_ext};{}$\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1352}When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
+without expanding its macros; the macros will be expanded later when this
+token list is rescanned.
+
+\Y\B\4\X1352:Implement \.{\\write}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\|k\K\\{cur\_cs};{}$\5
+\\{new\_write\_whatsit}(\\{write\_node\_size});\6
+${}\\{cur\_cs}\K\|k;{}$\5
+${}\|p\K\\{scan\_toks}(\\{false},\39\\{false});{}$\5
+${}\\{write\_tokens}(\\{tail})\K\\{def\_ref};{}$\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1353}\B\X1353:Implement \.{\\closeout}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{new\_write\_whatsit}(\\{write\_node\_size});\5
+${}\\{write\_tokens}(\\{tail})\K\\{null};{}$\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1354}When `\.{\\special\{...\}}' appears, we expand the macros in the token
+list as in \.{\\xdef} and \.{\\mark}.
+
+\Y\B\4\X1354:Implement \.{\\special}\X${}\E{}$\6
+${}\{{}$\5
+\1${}\\{new\_whatsit}(\\{special\_node},\39\\{write\_node\_size});{}$\5
+${}\\{write\_stream}(\\{tail})\K\\{null};{}$\5
+${}\|p\K\\{scan\_toks}(\\{false},\39\\{true});{}$\5
+${}\\{write\_tokens}(\\{tail})\K\\{def\_ref};{}$\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1355}Each new type of node that appears in our data structure must be capable
+of being displayed, copied, destroyed, and so on. The routines that we
+need for write-oriented whatsits are somewhat like those for mark nodes;
+other extensions might, of course, involve more subtlety here.
+
+\Y\B\4\X57:Basic printing procedures\X${}\mathrel+\E{}$\6
+\&{void} \\{print\_write\_whatsit}(\&{str\_number} \|s${},\39{}$\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\\{print\_esc}(\|s);\6
+\&{if} ${}(\\{write\_stream}(\|p)<\T{16}){}$\1\5
+\\{print\_int}(\\{write\_stream}(\|p));\2\6
+\&{else} \&{if} ${}(\\{write\_stream}(\|p)\E\T{16}){}$\1\5
+\\{print\_char}(\.{'*'});\2\6
+\&{else}\1\5
+\\{print\_char}(\.{'-'});\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1356}\B\X1356:Display the whatsit node \|p\X${}\E{}$\6
+\&{switch} (\\{subtype}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\6
+${}\{{}$\5
+\1${}\\{print\_write\_whatsit}(\X1783:\.{"openout"}\X,\39\|p);{}$\5
+\\{print\_char}(\.{'='});\5
+${}\\{print\_file\_name}(\\{open\_name}(\|p),\39\\{open\_area}(\|p),\39\\{open\_ext}(\|p));{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{write\_node}:\6
+${}\{{}$\5
+\1${}\\{print\_write\_whatsit}(\X1568:\.{"write"}\X,\39\|p);{}$\5
+\\{print\_mark}(\\{write\_tokens}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{close\_node}:\5
+${}\\{print\_write\_whatsit}(\X1784:\.{"closeout"}\X,\39\|p){}$;\5
+\&{break};\6
+\4\&{case} \\{special\_node}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1785:\.{"special"}\X);\5
+\\{print\_mark}(\\{write\_tokens}(\|p));\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{language\_node}:\6
+${}\{{}$\5
+\1\\{print\_esc}(\X1787:\.{"setlanguage"}\X);\5
+\\{print\_int}(\\{what\_lang}(\|p));\5
+\\{print\_str}(\.{"\ (hyphenmin\ "});\5
+\\{print\_int}(\\{what\_lhm}(\|p));\5
+\\{print\_char}(\.{','});\5
+\\{print\_int}(\\{what\_rhm}(\|p));\5
+\\{print\_char}(\.{')'});\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{print\_str}(\.{"whatsit?"});\6
+\4${}\}{}$\2\par
+\U183.\fi
+
+\M{1357}\B\X1357:Make a partial copy of the whatsit node \|p and make \|r point to it; set \\{words} to the number of initial words not yet copied\X${}\E{}$\6
+\&{switch} (\\{subtype}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{open\_node\_size});{}$\5
+${}\\{words}\K\\{open\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{write\_node}:\5
+\&{case} \\{special\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{write\_node\_size});{}$\5
+\\{add\_token\_ref}(\\{write\_tokens}(\|p));\5
+${}\\{words}\K\\{write\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{case} \\{close\_node}:\5
+\&{case} \\{language\_node}:\6
+${}\{{}$\5
+\1${}\|r\K\\{get\_node}(\\{small\_node\_size});{}$\5
+${}\\{words}\K\\{small\_node\_size};{}$\6
+\4${}\}{}$\5
+\2\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1789:\.{"ext2"}\X);\6
+\4${}\}{}$\2\par
+\U206.\fi
+
+\M{1358}\B\X1358:Wipe out the whatsit node \|p and \&{goto} \\{done}\X${}\E{}$\6
+${}\{{}$\5
+\1\&{switch} (\\{subtype}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\5
+${}\\{free\_node}(\|p,\39\\{open\_node\_size}){}$;\5
+\&{break};\6
+\4\&{case} \\{write\_node}:\5
+\&{case} \\{special\_node}:\6
+${}\{{}$\5
+\1\\{delete\_token\_ref}(\\{write\_tokens}(\|p));\5
+${}\\{free\_node}(\|p,\39\\{write\_node\_size});{}$\5
+\&{goto} \\{done};\6
+\4${}\}{}$\2\6
+\4\&{case} \\{close\_node}:\5
+\&{case} \\{language\_node}:\5
+${}\\{free\_node}(\|p,\39\\{small\_node\_size}){}$;\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1790:\.{"ext3"}\X);\6
+\4${}\}{}$\2\6
+\&{goto} \\{done};\6
+\4${}\}{}$\2\par
+\U202.\fi
+
+\M{1359}\B\X1359:Incorporate a whatsit node into a vbox\X${}\E{}$\6
+\\{do\_nothing}\par
+\U669.\fi
+
+\M{1360}\B\X1360:Incorporate a whatsit node into an hbox\X${}\E{}$\6
+\\{do\_nothing}\par
+\U651.\fi
+
+\M{1361}\B\X1361:Let \|d be the width of the whatsit \|p\X${}\E{}$\6
+$\|d\K{}$\T{0}\par
+\U1147.\fi
+
+\M{1362}\B\D$\\{adv\_past}(\|X)$ \5
+\&{if} ${}(\\{subtype}(\|X)\E\\{language\_node}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_lang}\K\\{what\_lang}(\|X);{}$\5
+${}\\{l\_hyf}\K\\{what\_lhm}(\|X);{}$\5
+${}\\{r\_hyf}\K\\{what\_rhm}(\|X){}$;\5
+${}\}{}$\2\par
+\Y\B\4\X1362:Advance \(p)past a whatsit node in the \(l)\\{line\_break} loop\X${}\E{}$\5
+\\{adv\_past}(\\{cur\_p})\par
+\U866.\fi
+
+\M{1363}\B\X1363:Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop\X${}\E{}$\5
+\\{adv\_past}(\|s)\par
+\U896.\fi
+
+\M{1364}\B\X1364:Prepare to move whatsit \|p to the current page, then \&{goto} \\{contribute}\X${}\E{}$\6
+\&{goto} \\{contribute}\par
+\U1000.\fi
+
+\M{1365}\B\X1365:Process whatsit \|p in \\{vert\_break} loop, \&{goto} \\{not\_found}\X${}\E{}$\6
+\&{goto} \\{not\_found}\par
+\U973.\fi
+
+\M{1366}\B\X1366:Output the whatsit node \|p in a vlist\X${}\E{}$\6
+\\{out\_what}(\|p)\par
+\U631.\fi
+
+\M{1367}\B\X1367:Output the whatsit node \|p in an hlist\X${}\E{}$\6
+\\{out\_what}(\|p)\par
+\U622.\fi
+
+\M{1368}After all this preliminary shuffling, we come finally to the routines
+that actually send out the requested data. Let's do \.{\\special} first
+(it's easier).
+
+\Y\B\4\X1368:Declare procedures needed in \\{hlist\_out}, \\{vlist\_out}\X${}\E{}$\6
+\&{void} \\{special\_out}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{holds print \\{selector}}\6
+\&{int} \|k;\C{index into \\{str\_pool}}\7
+\\{synch\_h};\5
+\\{synch\_v};\6
+${}\\{old\_setting}\K\\{selector};{}$\5
+${}\\{selector}\K\\{new\_string};{}$\5
+${}\\{show\_token\_list}(\\{link}(\\{write\_tokens}(\|p)),\39\\{null},\39\\{pool\_size}-\\{pool\_ptr});{}$\5
+${}\\{selector}\K\\{old\_setting};{}$\5
+\\{str\_room}(\T{1});\6
+\&{if} ${}(\\{cur\_length}<\T{256}){}$\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{xxx1});\5
+\\{dvi\_out}(\\{cur\_length});\6
+\4${}\}{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\1\\{dvi\_out}(\\{xxx4});\5
+\\{dvi\_four}(\\{cur\_length});\6
+\4${}\}{}$\2\6
+\&{for} ${}(\|k\K\\{str\_start}[\\{str\_ptr}];{}$ ${}\|k\Z\\{pool\_ptr}-\T{1};{}$ ${}\|k\PP){}$\1\5
+\\{dvi\_out}(\\{so}(\\{str\_pool}[\|k]));\2\6
+${}\\{pool\_ptr}\K\\{str\_start}[\\{str\_ptr}]{}$;\C{erase the string}\6
+\4${}\}{}$\2\par
+\As1370\ET1373.
+\U619.\fi
+
+\M{1369}To write a token list, we must run it through \TeX's scanner, expanding
+macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
+if a delimited macro parameter isn't matched, and runaways would be
+extremely confusing since we are calling on \TeX's scanner in the middle
+of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
+a ``stopper,'' right after the token list. This control sequence is
+artificially defined to be \.{\\outer}.
+
+\Y\B\4\X164:Initialize table entries (done by \.{INITEX} only)\X${}\mathrel+\E{}$\6
+$\\{text}(\\{end\_write})\K\X1791:\.{"endwrite"}\X;{}$\5
+${}\\{eq\_level}(\\{end\_write})\K\\{level\_one};{}$\5
+${}\\{eq\_type}(\\{end\_write})\K\\{outer\_call};{}$\5
+${}\\{equiv}(\\{end\_write})\K\\{null}{}$;\par
+\fi
+
+\M{1370}\B\X1368:Declare procedures needed in \\{hlist\_out}, \\{vlist\_out}\X${}\mathrel+\E{}$\6
+\&{void} \\{write\_out}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{uint8\_t} \\{old\_setting};\C{holds print \\{selector}}\6
+\&{int} \\{old\_mode};\C{saved \\{mode}}\6
+\&{small\_number} \|j;\C{write stream number}\6
+\&{pointer} \|q${},{}$ \|r;\C{temporary variables for list manipulation}\7
+\X1371:Expand macros in the token list and make \\{link}(\\{def\_ref}) point to the result\X;\6
+${}\\{old\_setting}\K\\{selector};{}$\5
+${}\|j\K\\{write\_stream}(\|p);{}$\6
+\&{if} (\\{write\_open}[\|j])\1\5
+${}\\{selector}\K\|j;{}$\2\6
+\&{else}\5
+${}\{{}$\5
+\C{write to the terminal if file isn't open}\1\6
+\&{if} ${}((\|j\E\T{17})\W(\\{selector}\E\\{term\_and\_log})){}$\1\5
+${}\\{selector}\K\\{log\_only};{}$\2\6
+\\{print\_nl}(\.{""});\6
+\4${}\}{}$\2\6
+\\{token\_show}(\\{def\_ref});\5
+\\{print\_ln}(\,);\5
+\\{flush\_list}(\\{def\_ref});\5
+${}\\{selector}\K\\{old\_setting};{}$\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1371}The final line of this routine is slightly subtle; at least, the author
+didn't think about it until getting burnt! There is a used-up token list
+on the stack, namely the one that contained \\{end\_write\_token}. (We
+insert this artificial `\.{\\endwrite}' to prevent runaways, as explained
+above.) If it were not removed, and if there were numerous writes on a
+single page, the stack would overflow.
+
+\Y\B\4\D$\\{end\_write\_token}$ \5
+$\\{cs\_token\_flag}+{}$\\{end\_write}\par
+\Y\B\4\X1371:Expand macros in the token list and make \\{link}(\\{def\_ref}) point to the result\X${}\E{}$\6
+$\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|q)\K\\{right\_brace\_token}+\.{'\}'}{}$;\6
+${}\|r\K\\{get\_avail}(\,);{}$\5
+${}\\{link}(\|q)\K\|r;{}$\5
+${}\\{info}(\|r)\K\\{end\_write\_token};{}$\5
+\\{ins\_list}(\|q);\6
+${}\\{begin\_token\_list}(\\{write\_tokens}(\|p),\39\\{write\_text}){}$;\6
+${}\|q\K\\{get\_avail}(\,);{}$\5
+${}\\{info}(\|q)\K\\{left\_brace\_token}+\.{'\{'};{}$\5
+\\{ins\_list}(\|q);\C{now we're ready to scan `\.\{$\langle\,$token list$\,\rangle$\.{\} \\endwrite}'}\6
+${}\\{old\_mode}\K\\{mode};{}$\5
+${}\\{mode}\K\T{0}{}$;\C{disable \.{\\prevdepth}, \.{\\spacefactor}, \.{\\lastskip}, \.{\\prevgraf}}\6
+${}\\{cur\_cs}\K\\{write\_loc};{}$\5
+${}\|q\K\\{scan\_toks}(\\{false},\39\\{true}){}$;\C{expand macros, etc.}\6
+\\{get\_token}(\,);\5
+\&{if} ${}(\\{cur\_tok}\I\\{end\_write\_token}){}$\1\5
+\X1372:Recover from an unbalanced write command\X;\2\6
+${}\\{mode}\K\\{old\_mode};$ \\{end\_token\_list}(\,)\C{conserve stack space}\par
+\U1370.\fi
+
+\M{1372}\B\X1372:Recover from an unbalanced write command\X${}\E{}$\6
+${}\{{}$\5
+\1\\{print\_err}(\.{"Unbalanced\ write\ co}\)\.{mmand"});\5
+\\{help2}(\.{"On\ this\ page\ there'}\)\.{s\ a\ \\\\write\ with\ few}\)\.{er\ real\ \{'s\ than\ \}'s}\)\.{."})\6
+(\.{"I\ can't\ handle\ that}\)\.{\ very\ well;\ good\ luc}\)\.{k."});\6
+\&{error} (\,)\1\5
+;\2\6
+\&{do}\5
+${}\{{}$\1\6
+\\{get\_token}(\,);\6
+\4${}\}{}$\5
+\2\5
+\&{while} ${}(\R(\\{cur\_tok}\E\\{end\_write\_token}));{}$\6
+\4${}\}{}$\2\par
+\U1371.\fi
+
+\M{1373}The \\{out\_what} procedure takes care of outputting whatsit nodes for
+\\{vlist\_out} and \\{hlist\_out}\kern-.3pt.
+
+\Y\B\4\X1368:Declare procedures needed in \\{hlist\_out}, \\{vlist\_out}\X${}\mathrel+\E{}$\6
+\&{void} \\{out\_what}(\&{pointer} \|p)\1\1\2\2\6
+${}\{{}$\5
+\1\&{small\_number} \|j;\C{write stream number}\7
+\&{switch} (\\{subtype}(\|p))\5
+${}\{{}$\1\6
+\4\&{case} \\{open\_node}:\5
+\&{case} \\{write\_node}:\5
+\&{case} \\{close\_node}:\5
+\X1374:Do some work that has been queued up for \.{\\write}\X\5
+\&{break};\6
+\4\&{case} \\{special\_node}:\5
+\\{special\_out}(\|p);\5
+\&{break};\6
+\4\&{case} \\{language\_node}:\5
+\\{do\_nothing};\5
+\&{break};\6
+\4\&{default}:\5
+\\{confusion}(\X1792:\.{"ext4"}\X);\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1374}We don't implement \.{\\write} inside of leaders. (The reason is that
+the number of times a leader box appears might be different in different
+implementations, due to machine-dependent rounding in the glue calculations.)
+
+\Y\B\4\X1374:Do some work that has been queued up for \.{\\write}\X${}\E{}$\6
+\&{if} ${}(\R\\{doing\_leaders}){}$\5
+${}\{{}$\5
+\1${}\|j\K\\{write\_stream}(\|p);{}$\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{write\_node}){}$\1\5
+\\{write\_out}(\|p);\2\6
+\&{else}\5
+${}\{{}$\5
+\1\&{if} (\\{write\_open}[\|j])\1\5
+${}\\{a\_close}({\AND}\\{write\_file}[\|j]);{}$\2\6
+\&{if} ${}(\\{subtype}(\|p)\E\\{close\_node}){}$\1\5
+${}\\{write\_open}[\|j]\K\\{false};{}$\2\6
+\&{else} \&{if} ${}(\|j<\T{16}){}$\5
+${}\{{}$\5
+\1${}\\{cur\_name}\K\\{open\_name}(\|p);{}$\5
+${}\\{cur\_area}\K\\{open\_area}(\|p);{}$\5
+${}\\{cur\_ext}\K\\{open\_ext}(\|p);{}$\6
+\&{if} ${}(\\{cur\_ext}\E\\{empty\_string}){}$\1\5
+${}\\{cur\_ext}\K\X1637:\.{".tex"}\X;{}$\2\6
+\\{pack\_cur\_name};\6
+\&{while} ${}(\R\\{a\_open\_out}({\AND}\\{write\_file}[\|j])){}$\1\5
+${}\\{prompt\_file\_name}(\.{"output\ file\ name"},\39\X1637:\.{".tex"}\X);{}$\2\6
+${}\\{write\_open}[\|j]\K\\{true};{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U1373.\fi
+
+\M{1375}The presence of `\.{\\immediate}' causes the \\{do\_extension} procedure
+to descend to one level of recursion. Nothing happens unless \.{\\immediate}
+is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
+
+\Y\B\4\X1375:Implement \.{\\immediate}\X${}\E{}$\6
+${}\{{}$\5
+\1\\{get\_x\_token}(\,);\6
+\&{if} ${}((\\{cur\_cmd}\E\\{extension})\W(\\{cur\_chr}\Z\\{close\_node})){}$\5
+${}\{{}$\5
+\1${}\|p\K\\{tail};{}$\5
+\\{do\_extension}(\,);\C{append a whatsit node}\6
+\\{out\_what}(\\{tail});\C{do the action immediately}\6
+\\{flush\_node\_list}(\\{tail});\5
+${}\\{tail}\K\|p;{}$\5
+${}\\{link}(\|p)\K\\{null};{}$\6
+\4${}\}{}$\2\6
+\&{else}\1\5
+\\{back\_input}(\,);\2\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1376}The \.{\\language} extension is somewhat different.
+We need a subroutine that comes into play when a character of
+a non-\\{clang} language is being appended to the current paragraph.
+
+\Y\B\4\X1043:Declare action procedures for use by \\{main\_control}\X${}\mathrel+\E{}$\6
+\&{void} \\{fix\_language}(\&{void})\1\1\2\2\6
+${}\{{}$\5
+\1\&{ASCII\_code} \|l;\C{the new current language}\7
+\&{if} ${}(\\{language}\Z\T{0}){}$\1\5
+${}\|l\K\T{0};{}$\2\6
+\&{else} \&{if} ${}(\\{language}>\T{255}){}$\1\5
+${}\|l\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\|l\K\\{language};{}$\2\6
+\&{if} ${}(\|l\I\\{clang}){}$\5
+${}\{{}$\5
+\1${}\\{new\_whatsit}(\\{language\_node},\39\\{small\_node\_size});{}$\5
+${}\\{what\_lang}(\\{tail})\K\|l;{}$\5
+${}\\{clang}\K\|l{}$;\6
+${}\\{what\_lhm}(\\{tail})\K\\{norm\_min}(\\{left\_hyphen\_min});{}$\5
+${}\\{what\_rhm}(\\{tail})\K\\{norm\_min}(\\{right\_hyphen\_min});{}$\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\fi
+
+\M{1377}\B\X1377:Implement \.{\\setlanguage}\X${}\E{}$\6
+\&{if} ${}(\\{abs}(\\{mode})\I\\{hmode}){}$\1\5
+\\{report\_illegal\_case}(\,);\2\6
+\&{else}\5
+${}\{{}$\5
+\1${}\\{new\_whatsit}(\\{language\_node},\39\\{small\_node\_size});{}$\5
+\\{scan\_int}(\,);\6
+\&{if} ${}(\\{cur\_val}\Z\T{0}){}$\1\5
+${}\\{clang}\K\T{0};{}$\2\6
+\&{else} \&{if} ${}(\\{cur\_val}>\T{255}){}$\1\5
+${}\\{clang}\K\T{0};{}$\2\6
+\&{else}\1\5
+${}\\{clang}\K\\{cur\_val};{}$\2\6
+${}\\{what\_lang}(\\{tail})\K\\{clang};{}$\5
+${}\\{what\_lhm}(\\{tail})\K\\{norm\_min}(\\{left\_hyphen\_min});{}$\5
+${}\\{what\_rhm}(\\{tail})\K\\{norm\_min}(\\{right\_hyphen\_min});{}$\6
+\4${}\}{}$\2\par
+\U1348.\fi
+
+\M{1378}\B\X1378:Finish the extensions\X${}\E{}$\6
+\&{for} ${}(\|k\K\T{0};{}$ ${}\|k\Z\T{15};{}$ ${}\|k\PP)$ \&{if} (\\{write\_open}[\|k]) $\\{a\_close}({\AND}\\{write\_file}[\|k]{}$)\par
+\U1333.\fi
+
+\N{1}{1379}System-dependent changes.
+This section should be replaced, if necessary, by any special
+modifications of the program
+that are necessary to make \TeX\ work at a particular installation.
+It is usually best to design your change file so that all changes to
+previous sections preserve the section numbering; then everybody's version
+will be consistent with the published program. More extensive changes,
+which introduce new sections, can be inserted here; then only the index
+itself will get a new section number.
+
+\fi
+
+\M{1380}Appendix: Replacement of the string pool file.
+\Y\B\4\D$\\{str\_0\_255}$ \5
+\.{"\^\^@\^\^A\^\^B\^\^C\^\^D\^\^E\^}\)\.{\^F\^\^G\^\^H\^\^I\^\^J\^\^K\^\^L}\)\.{\^\^M\^\^N\^\^O"}\6
+\.{"\^\^P\^\^Q\^\^R\^\^S\^\^T\^\^U\^}\)\.{\^V\^\^W\^\^X\^\^Y\^\^Z\^\^[\^\^\\}\)\.{\\\^\^]\^\^\^\^\^\_"}\6
+\.{"\ !\\"\#\$\%\&'()*+,-./"}\6
+\.{"0123456789:;<=>?"}\6
+\.{"@ABCDEFGHIJKLMNO"}\6
+\.{"PQRSTUVWXYZ[\\\\]\^\_"}\6
+\.{"`abcdefghijklmno"}\6
+\.{"pqrstuvwxyz\{|\}\~\^\^?"}\6
+\.{"\^\^80\^\^81\^\^82\^\^83\^\^8}\)\.{4\^\^85\^\^86\^\^87\^\^88\^\^8}\)\.{9\^\^8a\^\^8b\^\^8c\^\^8d\^\^8}\)\.{e\^\^8f"}\6
+\.{"\^\^90\^\^91\^\^92\^\^93\^\^9}\)\.{4\^\^95\^\^96\^\^97\^\^98\^\^9}\)\.{9\^\^9a\^\^9b\^\^9c\^\^9d\^\^9}\)\.{e\^\^9f"}\6
+\.{"\^\^a0\^\^a1\^\^a2\^\^a3\^\^a}\)\.{4\^\^a5\^\^a6\^\^a7\^\^a8\^\^a}\)\.{9\^\^aa\^\^ab\^\^ac\^\^ad\^\^a}\)\.{e\^\^af"}\6
+\.{"\^\^b0\^\^b1\^\^b2\^\^b3\^\^b}\)\.{4\^\^b5\^\^b6\^\^b7\^\^b8\^\^b}\)\.{9\^\^ba\^\^bb\^\^bc\^\^bd\^\^b}\)\.{e\^\^bf"}\6
+\.{"\^\^c0\^\^c1\^\^c2\^\^c3\^\^c}\)\.{4\^\^c5\^\^c6\^\^c7\^\^c8\^\^c}\)\.{9\^\^ca\^\^cb\^\^cc\^\^cd\^\^c}\)\.{e\^\^cf"}\6
+\.{"\^\^d0\^\^d1\^\^d2\^\^d3\^\^d}\)\.{4\^\^d5\^\^d6\^\^d7\^\^d8\^\^d}\)\.{9\^\^da\^\^db\^\^dc\^\^dd\^\^d}\)\.{e\^\^df"}\6
+\.{"\^\^e0\^\^e1\^\^e2\^\^e3\^\^e}\)\.{4\^\^e5\^\^e6\^\^e7\^\^e8\^\^e}\)\.{9\^\^ea\^\^eb\^\^ec\^\^ed\^\^e}\)\.{e\^\^ef"}\6
+\.{"\^\^f0\^\^f1\^\^f2\^\^f3\^\^f}\)\.{4\^\^f5\^\^f6\^\^f7\^\^f8\^\^f}\)\.{9\^\^fa\^\^fb\^\^fc\^\^fd\^\^f}\)\.{e\^\^ff"}\par
+\B\4\D$\\{str\_start\_0\_255}$ \5
+$\T{0},\39\T{3},\39\T{6},\39\T{9},\39\T{12},\39\T{15},\39\T{18},\39\T{21},\39\T{24},\39\T{27},\39\T{30},\39\T{33},\39\T{36},\39\T{39},\39\T{42},\39\T{45},{}$\6
+\T{48}${},\39\T{51},\39\T{54},\39\T{57},\39\T{60},\39\T{63},\39\T{66},\39\T{69},\39\T{72},\39\T{75},\39\T{78},\39\T{81},\39\T{84},\39\T{87},\39\T{90},\39\T{93},{}$\6
+\T{96}${},\39\T{97},\39\T{98},\39\T{99},\39\T{100},\39\T{101},\39\T{102},\39\T{103},\39\T{104},\39\T{105},\39\T{106},\39\T{107},\39\T{108},\39\T{109},\39\T{110},\39\T{111},{}$\6
+\T{112}${},\39\T{113},\39\T{114},\39\T{115},\39\T{116},\39\T{117},\39\T{118},\39\T{119},\39\T{120},\39\T{121},\39\T{122},\39\T{123},\39\T{124},\39\T{125},\39\T{126},\39\T{127},{}$\6
+\T{128}${},\39\T{129},\39\T{130},\39\T{131},\39\T{132},\39\T{133},\39\T{134},\39\T{135},\39\T{136},\39\T{137},\39\T{138},\39\T{139},\39\T{140},\39\T{141},\39\T{142},\39\T{143},{}$\6
+\T{144}${},\39\T{145},\39\T{146},\39\T{147},\39\T{148},\39\T{149},\39\T{150},\39\T{151},\39\T{152},\39\T{153},\39\T{154},\39\T{155},\39\T{156},\39\T{157},\39\T{158},\39\T{159},{}$\6
+\T{160}${},\39\T{161},\39\T{162},\39\T{163},\39\T{164},\39\T{165},\39\T{166},\39\T{167},\39\T{168},\39\T{169},\39\T{170},\39\T{171},\39\T{172},\39\T{173},\39\T{174},\39\T{175},{}$\6
+\T{176}${},\39\T{177},\39\T{178},\39\T{179},\39\T{180},\39\T{181},\39\T{182},\39\T{183},\39\T{184},\39\T{185},\39\T{186},\39\T{187},\39\T{188},\39\T{189},\39\T{190},\39\T{191},{}$\6
+\T{194}${},\39\T{198},\39\T{202},\39\T{206},\39\T{210},\39\T{214},\39\T{218},\39\T{222},\39\T{226},\39\T{230},\39\T{234},\39\T{238},\39\T{242},\39\T{246},\39\T{250},\39\T{254},{}$\6
+\T{258}${},\39\T{262},\39\T{266},\39\T{270},\39\T{274},\39\T{278},\39\T{282},\39\T{286},\39\T{290},\39\T{294},\39\T{298},\39\T{302},\39\T{306},\39\T{310},\39\T{314},\39\T{318},{}$\6
+\T{322}${},\39\T{326},\39\T{330},\39\T{334},\39\T{338},\39\T{342},\39\T{346},\39\T{350},\39\T{354},\39\T{358},\39\T{362},\39\T{366},\39\T{370},\39\T{374},\39\T{378},\39\T{382},{}$\6
+\T{386}${},\39\T{390},\39\T{394},\39\T{398},\39\T{402},\39\T{406},\39\T{410},\39\T{414},\39\T{418},\39\T{422},\39\T{426},\39\T{430},\39\T{434},\39\T{438},\39\T{442},\39\T{446},{}$\6
+\T{450}${},\39\T{454},\39\T{458},\39\T{462},\39\T{466},\39\T{470},\39\T{474},\39\T{478},\39\T{482},\39\T{486},\39\T{490},\39\T{494},\39\T{498},\39\T{502},\39\T{506},\39\T{510},{}$\6
+\T{514}${},\39\T{518},\39\T{522},\39\T{526},\39\T{530},\39\T{534},\39\T{538},\39\T{542},\39\T{546},\39\T{550},\39\T{554},\39\T{558},\39\T{562},\39\T{566},\39\T{570},\39\T{574},{}$\6
+\T{578}${},\39\T{582},\39\T{586},\39\T{590},\39\T{594},\39\T{598},\39\T{602},\39\T{606},\39\T{610},\39\T{614},\39\T{618},\39\T{622},\39\T{626},\39\T{630},\39\T{634},\39\T{638},{}$\6
+\T{642}${},\39\T{646},\39\T{650},\39\T{654},\39\T{658},\39\T{662},\39\T{666},\39\T{670},\39\T{674},\39\T{678},\39\T{682},\39\T{686},\39\T{690},\39\T{694},\39\T{698},\39\T{702}$ $,{}$\par
+\fi
+
+\M{1381}
+\Y\B\4\D$\\{str\_256}$ \5
+\.{"???"}\par
+\Y\B\4\X1381:\.{"???"}\X${}\E{}$\5
+\T{256}\par
+\U59.\fi
+
+\M{1382}
+\Y\B\4\D$\\{str\_257}$ \5
+\.{"m2d5c2l5x2v5i"}\par
+\Y\B\4\X1382:\.{"m2d5c2l5x2v5i"}\X${}\E{}$\5
+\T{257}\par
+\U69.\fi
+
+\M{1383}
+\Y\B\4\D$\\{str\_258}$ \5
+\.{"batchmode"}\par
+\Y\B\4\X1383:\.{"batchmode"}\X${}\E{}$\5
+\T{258}\par
+\Us86, 1262\ETs1263.\fi
+
+\M{1384}
+\Y\B\4\D$\\{str\_259}$ \5
+\.{"nonstopmode"}\par
+\Y\B\4\X1384:\.{"nonstopmode"}\X${}\E{}$\5
+\T{259}\par
+\Us86, 1262\ETs1263.\fi
+
+\M{1385}
+\Y\B\4\D$\\{str\_260}$ \5
+\.{"scrollmode"}\par
+\Y\B\4\X1385:\.{"scrollmode"}\X${}\E{}$\5
+\T{260}\par
+\Us86, 1262\ETs1263.\fi
+
+\M{1386}
+\Y\B\4\D$\\{str\_261}$ \5
+\.{"CLOBBERED."}\par
+\Y\B\4\X1386:\.{"CLOBBERED."}\X${}\E{}$\5
+\T{261}\par
+\Us176\ET293.\fi
+
+\M{1387}
+\Y\B\4\D$\\{str\_262}$ \5
+\.{"fil"}\par
+\Y\B\4\X1387:\.{"fil"}\X${}\E{}$\5
+\T{262}\par
+\U454.\fi
+
+\M{1388}
+\Y\B\4\D$\\{str\_263}$ \5
+\.{"unset"}\par
+\Y\B\4\X1388:\.{"unset"}\X${}\E{}$\5
+\T{263}\par
+\U184.\fi
+
+\M{1389}
+\Y\B\4\D$\\{str\_264}$ \5
+\.{"rule("}\par
+\Y\B\4\X1389:\.{"rule("}\X${}\E{}$\5
+\T{264}\par
+\U187.\fi
+
+\M{1390}
+\Y\B\4\D$\\{str\_265}$ \5
+\.{"insert"}\par
+\Y\B\4\X1390:\.{"insert"}\X${}\E{}$\5
+\T{265}\par
+\Us188, 265, 266, 986\ETs1099.\fi
+
+\M{1391}
+\Y\B\4\D$\\{str\_266}$ \5
+\.{"glue"}\par
+\Y\B\4\X1391:\.{"glue"}\X${}\E{}$\5
+\T{266}\par
+\U189.\fi
+
+\M{1392}
+\Y\B\4\D$\\{str\_267}$ \5
+\.{"nonscript"}\par
+\Y\B\4\X1392:\.{"nonscript"}\X${}\E{}$\5
+\T{267}\par
+\Us189, 265\ETs266.\fi
+
+\M{1393}
+\Y\B\4\D$\\{str\_268}$ \5
+\.{"mskip"}\par
+\Y\B\4\X1393:\.{"mskip"}\X${}\E{}$\5
+\T{268}\par
+\Us189, 1058\ETs1059.\fi
+
+\M{1394}
+\Y\B\4\D$\\{str\_269}$ \5
+\.{"mu"}\par
+\Y\B\4\X1394:\.{"mu"}\X${}\E{}$\5
+\T{269}\par
+\Us189, 229, 456\ETs465.\fi
+
+\M{1395}
+\Y\B\4\D$\\{str\_270}$ \5
+\.{""}\par
+\B\4\D$\\{empty\_string}$ \5
+\T{270}\par
+\fi
+
+\M{1396}
+\Y\B\4\D$\\{str\_271}$ \5
+\.{"kern"}\par
+\Y\B\4\X1396:\.{"kern"}\X${}\E{}$\5
+\T{271}\par
+\Us191, 856, 1058\ETs1059.\fi
+
+\M{1397}
+\Y\B\4\D$\\{str\_272}$ \5
+\.{"mkern"}\par
+\Y\B\4\X1397:\.{"mkern"}\X${}\E{}$\5
+\T{272}\par
+\Us191, 1058\ETs1059.\fi
+
+\M{1398}
+\Y\B\4\D$\\{str\_273}$ \5
+\.{"math"}\par
+\Y\B\4\X1398:\.{"math"}\X${}\E{}$\5
+\T{273}\par
+\Us192\ET856.\fi
+
+\M{1399}
+\Y\B\4\D$\\{str\_274}$ \5
+\.{"penalty\ "}\par
+\Y\B\4\X1399:\.{"penalty\ "}\X${}\E{}$\5
+\T{274}\par
+\U194.\fi
+
+\M{1400}
+\Y\B\4\D$\\{str\_275}$ \5
+\.{"discretionary"}\par
+\Y\B\4\X1400:\.{"discretionary"}\X${}\E{}$\5
+\T{275}\par
+\Us195, 856, 1114, 1115\ETs1120.\fi
+
+\M{1401}
+\Y\B\4\D$\\{str\_276}$ \5
+\.{"mark"}\par
+\Y\B\4\X1401:\.{"mark"}\X${}\E{}$\5
+\T{276}\par
+\Us196, 265, 266\ETs323.\fi
+
+\M{1402}
+\Y\B\4\D$\\{str\_277}$ \5
+\.{"vadjust"}\par
+\Y\B\4\X1402:\.{"vadjust"}\X${}\E{}$\5
+\T{277}\par
+\Us197, 265\ETs266.\fi
+
+\M{1403}
+\Y\B\4\D$\\{str\_278}$ \5
+\.{"flushing"}\par
+\Y\B\4\X1403:\.{"flushing"}\X${}\E{}$\5
+\T{278}\par
+\U202.\fi
+
+\M{1404}
+\Y\B\4\D$\\{str\_279}$ \5
+\.{"copying"}\par
+\Y\B\4\X1404:\.{"copying"}\X${}\E{}$\5
+\T{279}\par
+\U206.\fi
+
+\M{1405}
+\Y\B\4\D$\\{str\_280}$ \5
+\.{"lineskip"}\par
+\Y\B\4\X1405:\.{"lineskip"}\X${}\E{}$\5
+\T{280}\par
+\Us225\ET226.\fi
+
+\M{1406}
+\Y\B\4\D$\\{str\_281}$ \5
+\.{"baselineskip"}\par
+\Y\B\4\X1406:\.{"baselineskip"}\X${}\E{}$\5
+\T{281}\par
+\Us225\ET226.\fi
+
+\M{1407}
+\Y\B\4\D$\\{str\_282}$ \5
+\.{"parskip"}\par
+\Y\B\4\X1407:\.{"parskip"}\X${}\E{}$\5
+\T{282}\par
+\Us225\ET226.\fi
+
+\M{1408}
+\Y\B\4\D$\\{str\_283}$ \5
+\.{"abovedisplayskip"}\par
+\Y\B\4\X1408:\.{"abovedisplayskip"}\X${}\E{}$\5
+\T{283}\par
+\Us225\ET226.\fi
+
+\M{1409}
+\Y\B\4\D$\\{str\_284}$ \5
+\.{"belowdisplayskip"}\par
+\Y\B\4\X1409:\.{"belowdisplayskip"}\X${}\E{}$\5
+\T{284}\par
+\Us225\ET226.\fi
+
+\M{1410}
+\Y\B\4\D$\\{str\_285}$ \5
+\.{"abovedisplayshortsk}\)\.{ip"}\par
+\Y\B\4\X1410:\.{"abovedisplayshortsk}\)\.{ip"}\X${}\E{}$\5
+\T{285}\par
+\Us225\ET226.\fi
+
+\M{1411}
+\Y\B\4\D$\\{str\_286}$ \5
+\.{"belowdisplayshortsk}\)\.{ip"}\par
+\Y\B\4\X1411:\.{"belowdisplayshortsk}\)\.{ip"}\X${}\E{}$\5
+\T{286}\par
+\Us225\ET226.\fi
+
+\M{1412}
+\Y\B\4\D$\\{str\_287}$ \5
+\.{"leftskip"}\par
+\Y\B\4\X1412:\.{"leftskip"}\X${}\E{}$\5
+\T{287}\par
+\Us225\ET226.\fi
+
+\M{1413}
+\Y\B\4\D$\\{str\_288}$ \5
+\.{"rightskip"}\par
+\Y\B\4\X1413:\.{"rightskip"}\X${}\E{}$\5
+\T{288}\par
+\Us225\ET226.\fi
+
+\M{1414}
+\Y\B\4\D$\\{str\_289}$ \5
+\.{"topskip"}\par
+\Y\B\4\X1414:\.{"topskip"}\X${}\E{}$\5
+\T{289}\par
+\Us225\ET226.\fi
+
+\M{1415}
+\Y\B\4\D$\\{str\_290}$ \5
+\.{"splittopskip"}\par
+\Y\B\4\X1415:\.{"splittopskip"}\X${}\E{}$\5
+\T{290}\par
+\Us225\ET226.\fi
+
+\M{1416}
+\Y\B\4\D$\\{str\_291}$ \5
+\.{"tabskip"}\par
+\Y\B\4\X1416:\.{"tabskip"}\X${}\E{}$\5
+\T{291}\par
+\Us225\ET226.\fi
+
+\M{1417}
+\Y\B\4\D$\\{str\_292}$ \5
+\.{"spaceskip"}\par
+\Y\B\4\X1417:\.{"spaceskip"}\X${}\E{}$\5
+\T{292}\par
+\Us225\ET226.\fi
+
+\M{1418}
+\Y\B\4\D$\\{str\_293}$ \5
+\.{"xspaceskip"}\par
+\Y\B\4\X1418:\.{"xspaceskip"}\X${}\E{}$\5
+\T{293}\par
+\Us225\ET226.\fi
+
+\M{1419}
+\Y\B\4\D$\\{str\_294}$ \5
+\.{"parfillskip"}\par
+\Y\B\4\X1419:\.{"parfillskip"}\X${}\E{}$\5
+\T{294}\par
+\Us225\ET226.\fi
+
+\M{1420}
+\Y\B\4\D$\\{str\_295}$ \5
+\.{"thinmuskip"}\par
+\Y\B\4\X1420:\.{"thinmuskip"}\X${}\E{}$\5
+\T{295}\par
+\Us225\ET226.\fi
+
+\M{1421}
+\Y\B\4\D$\\{str\_296}$ \5
+\.{"medmuskip"}\par
+\Y\B\4\X1421:\.{"medmuskip"}\X${}\E{}$\5
+\T{296}\par
+\Us225\ET226.\fi
+
+\M{1422}
+\Y\B\4\D$\\{str\_297}$ \5
+\.{"thickmuskip"}\par
+\Y\B\4\X1422:\.{"thickmuskip"}\X${}\E{}$\5
+\T{297}\par
+\Us225\ET226.\fi
+
+\M{1423}
+\Y\B\4\D$\\{str\_298}$ \5
+\.{"skip"}\par
+\Y\B\4\X1423:\.{"skip"}\X${}\E{}$\5
+\T{298}\par
+\Us227, 229, 411, 412\ETs1009.\fi
+
+\M{1424}
+\Y\B\4\D$\\{str\_299}$ \5
+\.{"muskip"}\par
+\Y\B\4\X1424:\.{"muskip"}\X${}\E{}$\5
+\T{299}\par
+\Us227, 229, 411\ETs412.\fi
+
+\M{1425}
+\Y\B\4\D$\\{str\_300}$ \5
+\.{"pt"}\par
+\Y\B\4\X1425:\.{"pt"}\X${}\E{}$\5
+\T{300}\par
+\Us229, 453\ETs465.\fi
+
+\M{1426}
+\Y\B\4\D$\\{str\_301}$ \5
+\.{"output"}\par
+\Y\B\4\X1426:\.{"output"}\X${}\E{}$\5
+\T{301}\par
+\Us230\ET231.\fi
+
+\M{1427}
+\Y\B\4\D$\\{str\_302}$ \5
+\.{"everypar"}\par
+\Y\B\4\X1427:\.{"everypar"}\X${}\E{}$\5
+\T{302}\par
+\Us230\ET231.\fi
+
+\M{1428}
+\Y\B\4\D$\\{str\_303}$ \5
+\.{"everymath"}\par
+\Y\B\4\X1428:\.{"everymath"}\X${}\E{}$\5
+\T{303}\par
+\Us230\ET231.\fi
+
+\M{1429}
+\Y\B\4\D$\\{str\_304}$ \5
+\.{"everydisplay"}\par
+\Y\B\4\X1429:\.{"everydisplay"}\X${}\E{}$\5
+\T{304}\par
+\Us230\ET231.\fi
+
+\M{1430}
+\Y\B\4\D$\\{str\_305}$ \5
+\.{"everyhbox"}\par
+\Y\B\4\X1430:\.{"everyhbox"}\X${}\E{}$\5
+\T{305}\par
+\Us230\ET231.\fi
+
+\M{1431}
+\Y\B\4\D$\\{str\_306}$ \5
+\.{"everyvbox"}\par
+\Y\B\4\X1431:\.{"everyvbox"}\X${}\E{}$\5
+\T{306}\par
+\Us230\ET231.\fi
+
+\M{1432}
+\Y\B\4\D$\\{str\_307}$ \5
+\.{"everyjob"}\par
+\Y\B\4\X1432:\.{"everyjob"}\X${}\E{}$\5
+\T{307}\par
+\Us230\ET231.\fi
+
+\M{1433}
+\Y\B\4\D$\\{str\_308}$ \5
+\.{"everycr"}\par
+\Y\B\4\X1433:\.{"everycr"}\X${}\E{}$\5
+\T{308}\par
+\Us230\ET231.\fi
+
+\M{1434}
+\Y\B\4\D$\\{str\_309}$ \5
+\.{"errhelp"}\par
+\Y\B\4\X1434:\.{"errhelp"}\X${}\E{}$\5
+\T{309}\par
+\Us230\ET231.\fi
+
+\M{1435}
+\Y\B\4\D$\\{str\_310}$ \5
+\.{"toks"}\par
+\Y\B\4\X1435:\.{"toks"}\X${}\E{}$\5
+\T{310}\par
+\Us231, 233, 265\ETs266.\fi
+
+\M{1436}
+\Y\B\4\D$\\{str\_311}$ \5
+\.{"parshape"}\par
+\Y\B\4\X1436:\.{"parshape"}\X${}\E{}$\5
+\T{311}\par
+\Us233, 265\ETs266.\fi
+
+\M{1437}
+\Y\B\4\D$\\{str\_312}$ \5
+\.{"box"}\par
+\Y\B\4\X1437:\.{"box"}\X${}\E{}$\5
+\T{312}\par
+\Us233, 1015, 1028, 1071\ETs1072.\fi
+
+\M{1438}
+\Y\B\4\D$\\{str\_313}$ \5
+\.{"textfont"}\par
+\Y\B\4\X1438:\.{"textfont"}\X${}\E{}$\5
+\T{313}\par
+\Us234, 699\ETs1230.\fi
+
+\M{1439}
+\Y\B\4\D$\\{str\_314}$ \5
+\.{"scriptfont"}\par
+\Y\B\4\X1439:\.{"scriptfont"}\X${}\E{}$\5
+\T{314}\par
+\Us234, 699\ETs1230.\fi
+
+\M{1440}
+\Y\B\4\D$\\{str\_315}$ \5
+\.{"scriptscriptfont"}\par
+\Y\B\4\X1440:\.{"scriptscriptfont"}\X${}\E{}$\5
+\T{315}\par
+\Us234, 699\ETs1230.\fi
+
+\M{1441}
+\Y\B\4\D$\\{str\_316}$ \5
+\.{"catcode"}\par
+\Y\B\4\X1441:\.{"catcode"}\X${}\E{}$\5
+\T{316}\par
+\Us235, 1230\ETs1231.\fi
+
+\M{1442}
+\Y\B\4\D$\\{str\_317}$ \5
+\.{"lccode"}\par
+\Y\B\4\X1442:\.{"lccode"}\X${}\E{}$\5
+\T{317}\par
+\Us235, 1230\ETs1231.\fi
+
+\M{1443}
+\Y\B\4\D$\\{str\_318}$ \5
+\.{"uccode"}\par
+\Y\B\4\X1443:\.{"uccode"}\X${}\E{}$\5
+\T{318}\par
+\Us235, 1230\ETs1231.\fi
+
+\M{1444}
+\Y\B\4\D$\\{str\_319}$ \5
+\.{"sfcode"}\par
+\Y\B\4\X1444:\.{"sfcode"}\X${}\E{}$\5
+\T{319}\par
+\Us235, 1230\ETs1231.\fi
+
+\M{1445}
+\Y\B\4\D$\\{str\_320}$ \5
+\.{"mathcode"}\par
+\Y\B\4\X1445:\.{"mathcode"}\X${}\E{}$\5
+\T{320}\par
+\Us235, 1230\ETs1231.\fi
+
+\M{1446}
+\Y\B\4\D$\\{str\_321}$ \5
+\.{"pretolerance"}\par
+\Y\B\4\X1446:\.{"pretolerance"}\X${}\E{}$\5
+\T{321}\par
+\Us237\ET238.\fi
+
+\M{1447}
+\Y\B\4\D$\\{str\_322}$ \5
+\.{"tolerance"}\par
+\Y\B\4\X1447:\.{"tolerance"}\X${}\E{}$\5
+\T{322}\par
+\Us237\ET238.\fi
+
+\M{1448}
+\Y\B\4\D$\\{str\_323}$ \5
+\.{"linepenalty"}\par
+\Y\B\4\X1448:\.{"linepenalty"}\X${}\E{}$\5
+\T{323}\par
+\Us237\ET238.\fi
+
+\M{1449}
+\Y\B\4\D$\\{str\_324}$ \5
+\.{"hyphenpenalty"}\par
+\Y\B\4\X1449:\.{"hyphenpenalty"}\X${}\E{}$\5
+\T{324}\par
+\Us237\ET238.\fi
+
+\M{1450}
+\Y\B\4\D$\\{str\_325}$ \5
+\.{"exhyphenpenalty"}\par
+\Y\B\4\X1450:\.{"exhyphenpenalty"}\X${}\E{}$\5
+\T{325}\par
+\Us237\ET238.\fi
+
+\M{1451}
+\Y\B\4\D$\\{str\_326}$ \5
+\.{"clubpenalty"}\par
+\Y\B\4\X1451:\.{"clubpenalty"}\X${}\E{}$\5
+\T{326}\par
+\Us237\ET238.\fi
+
+\M{1452}
+\Y\B\4\D$\\{str\_327}$ \5
+\.{"widowpenalty"}\par
+\Y\B\4\X1452:\.{"widowpenalty"}\X${}\E{}$\5
+\T{327}\par
+\Us237\ET238.\fi
+
+\M{1453}
+\Y\B\4\D$\\{str\_328}$ \5
+\.{"displaywidowpenalty}\)\.{"}\par
+\Y\B\4\X1453:\.{"displaywidowpenalty}\)\.{"}\X${}\E{}$\5
+\T{328}\par
+\Us237\ET238.\fi
+
+\M{1454}
+\Y\B\4\D$\\{str\_329}$ \5
+\.{"brokenpenalty"}\par
+\Y\B\4\X1454:\.{"brokenpenalty"}\X${}\E{}$\5
+\T{329}\par
+\Us237\ET238.\fi
+
+\M{1455}
+\Y\B\4\D$\\{str\_330}$ \5
+\.{"binoppenalty"}\par
+\Y\B\4\X1455:\.{"binoppenalty"}\X${}\E{}$\5
+\T{330}\par
+\Us237\ET238.\fi
+
+\M{1456}
+\Y\B\4\D$\\{str\_331}$ \5
+\.{"relpenalty"}\par
+\Y\B\4\X1456:\.{"relpenalty"}\X${}\E{}$\5
+\T{331}\par
+\Us237\ET238.\fi
+
+\M{1457}
+\Y\B\4\D$\\{str\_332}$ \5
+\.{"predisplaypenalty"}\par
+\Y\B\4\X1457:\.{"predisplaypenalty"}\X${}\E{}$\5
+\T{332}\par
+\Us237\ET238.\fi
+
+\M{1458}
+\Y\B\4\D$\\{str\_333}$ \5
+\.{"postdisplaypenalty"}\par
+\Y\B\4\X1458:\.{"postdisplaypenalty"}\X${}\E{}$\5
+\T{333}\par
+\Us237\ET238.\fi
+
+\M{1459}
+\Y\B\4\D$\\{str\_334}$ \5
+\.{"interlinepenalty"}\par
+\Y\B\4\X1459:\.{"interlinepenalty"}\X${}\E{}$\5
+\T{334}\par
+\Us237\ET238.\fi
+
+\M{1460}
+\Y\B\4\D$\\{str\_335}$ \5
+\.{"doublehyphendemerit}\)\.{s"}\par
+\Y\B\4\X1460:\.{"doublehyphendemerit}\)\.{s"}\X${}\E{}$\5
+\T{335}\par
+\Us237\ET238.\fi
+
+\M{1461}
+\Y\B\4\D$\\{str\_336}$ \5
+\.{"finalhyphendemerits}\)\.{"}\par
+\Y\B\4\X1461:\.{"finalhyphendemerits}\)\.{"}\X${}\E{}$\5
+\T{336}\par
+\Us237\ET238.\fi
+
+\M{1462}
+\Y\B\4\D$\\{str\_337}$ \5
+\.{"adjdemerits"}\par
+\Y\B\4\X1462:\.{"adjdemerits"}\X${}\E{}$\5
+\T{337}\par
+\Us237\ET238.\fi
+
+\M{1463}
+\Y\B\4\D$\\{str\_338}$ \5
+\.{"mag"}\par
+\Y\B\4\X1463:\.{"mag"}\X${}\E{}$\5
+\T{338}\par
+\Us237\ET238.\fi
+
+\M{1464}
+\Y\B\4\D$\\{str\_339}$ \5
+\.{"delimiterfactor"}\par
+\Y\B\4\X1464:\.{"delimiterfactor"}\X${}\E{}$\5
+\T{339}\par
+\Us237\ET238.\fi
+
+\M{1465}
+\Y\B\4\D$\\{str\_340}$ \5
+\.{"looseness"}\par
+\Y\B\4\X1465:\.{"looseness"}\X${}\E{}$\5
+\T{340}\par
+\Us237\ET238.\fi
+
+\M{1466}
+\Y\B\4\D$\\{str\_341}$ \5
+\.{"time"}\par
+\Y\B\4\X1466:\.{"time"}\X${}\E{}$\5
+\T{341}\par
+\Us237\ET238.\fi
+
+\M{1467}
+\Y\B\4\D$\\{str\_342}$ \5
+\.{"day"}\par
+\Y\B\4\X1467:\.{"day"}\X${}\E{}$\5
+\T{342}\par
+\Us237\ET238.\fi
+
+\M{1468}
+\Y\B\4\D$\\{str\_343}$ \5
+\.{"month"}\par
+\Y\B\4\X1468:\.{"month"}\X${}\E{}$\5
+\T{343}\par
+\Us237\ET238.\fi
+
+\M{1469}
+\Y\B\4\D$\\{str\_344}$ \5
+\.{"year"}\par
+\Y\B\4\X1469:\.{"year"}\X${}\E{}$\5
+\T{344}\par
+\Us237\ET238.\fi
+
+\M{1470}
+\Y\B\4\D$\\{str\_345}$ \5
+\.{"showboxbreadth"}\par
+\Y\B\4\X1470:\.{"showboxbreadth"}\X${}\E{}$\5
+\T{345}\par
+\Us237\ET238.\fi
+
+\M{1471}
+\Y\B\4\D$\\{str\_346}$ \5
+\.{"showboxdepth"}\par
+\Y\B\4\X1471:\.{"showboxdepth"}\X${}\E{}$\5
+\T{346}\par
+\Us237\ET238.\fi
+
+\M{1472}
+\Y\B\4\D$\\{str\_347}$ \5
+\.{"hbadness"}\par
+\Y\B\4\X1472:\.{"hbadness"}\X${}\E{}$\5
+\T{347}\par
+\Us237\ET238.\fi
+
+\M{1473}
+\Y\B\4\D$\\{str\_348}$ \5
+\.{"vbadness"}\par
+\Y\B\4\X1473:\.{"vbadness"}\X${}\E{}$\5
+\T{348}\par
+\Us237\ET238.\fi
+
+\M{1474}
+\Y\B\4\D$\\{str\_349}$ \5
+\.{"pausing"}\par
+\Y\B\4\X1474:\.{"pausing"}\X${}\E{}$\5
+\T{349}\par
+\Us237\ET238.\fi
+
+\M{1475}
+\Y\B\4\D$\\{str\_350}$ \5
+\.{"tracingonline"}\par
+\Y\B\4\X1475:\.{"tracingonline"}\X${}\E{}$\5
+\T{350}\par
+\Us237\ET238.\fi
+
+\M{1476}
+\Y\B\4\D$\\{str\_351}$ \5
+\.{"tracingmacros"}\par
+\Y\B\4\X1476:\.{"tracingmacros"}\X${}\E{}$\5
+\T{351}\par
+\Us237\ET238.\fi
+
+\M{1477}
+\Y\B\4\D$\\{str\_352}$ \5
+\.{"tracingstats"}\par
+\Y\B\4\X1477:\.{"tracingstats"}\X${}\E{}$\5
+\T{352}\par
+\Us237\ET238.\fi
+
+\M{1478}
+\Y\B\4\D$\\{str\_353}$ \5
+\.{"tracingparagraphs"}\par
+\Y\B\4\X1478:\.{"tracingparagraphs"}\X${}\E{}$\5
+\T{353}\par
+\Us237\ET238.\fi
+
+\M{1479}
+\Y\B\4\D$\\{str\_354}$ \5
+\.{"tracingpages"}\par
+\Y\B\4\X1479:\.{"tracingpages"}\X${}\E{}$\5
+\T{354}\par
+\Us237\ET238.\fi
+
+\M{1480}
+\Y\B\4\D$\\{str\_355}$ \5
+\.{"tracingoutput"}\par
+\Y\B\4\X1480:\.{"tracingoutput"}\X${}\E{}$\5
+\T{355}\par
+\Us237\ET238.\fi
+
+\M{1481}
+\Y\B\4\D$\\{str\_356}$ \5
+\.{"tracinglostchars"}\par
+\Y\B\4\X1481:\.{"tracinglostchars"}\X${}\E{}$\5
+\T{356}\par
+\Us237\ET238.\fi
+
+\M{1482}
+\Y\B\4\D$\\{str\_357}$ \5
+\.{"tracingcommands"}\par
+\Y\B\4\X1482:\.{"tracingcommands"}\X${}\E{}$\5
+\T{357}\par
+\Us237\ET238.\fi
+
+\M{1483}
+\Y\B\4\D$\\{str\_358}$ \5
+\.{"tracingrestores"}\par
+\Y\B\4\X1483:\.{"tracingrestores"}\X${}\E{}$\5
+\T{358}\par
+\Us237\ET238.\fi
+
+\M{1484}
+\Y\B\4\D$\\{str\_359}$ \5
+\.{"uchyph"}\par
+\Y\B\4\X1484:\.{"uchyph"}\X${}\E{}$\5
+\T{359}\par
+\Us237\ET238.\fi
+
+\M{1485}
+\Y\B\4\D$\\{str\_360}$ \5
+\.{"outputpenalty"}\par
+\Y\B\4\X1485:\.{"outputpenalty"}\X${}\E{}$\5
+\T{360}\par
+\Us237\ET238.\fi
+
+\M{1486}
+\Y\B\4\D$\\{str\_361}$ \5
+\.{"maxdeadcycles"}\par
+\Y\B\4\X1486:\.{"maxdeadcycles"}\X${}\E{}$\5
+\T{361}\par
+\Us237\ET238.\fi
+
+\M{1487}
+\Y\B\4\D$\\{str\_362}$ \5
+\.{"hangafter"}\par
+\Y\B\4\X1487:\.{"hangafter"}\X${}\E{}$\5
+\T{362}\par
+\Us237\ET238.\fi
+
+\M{1488}
+\Y\B\4\D$\\{str\_363}$ \5
+\.{"floatingpenalty"}\par
+\Y\B\4\X1488:\.{"floatingpenalty"}\X${}\E{}$\5
+\T{363}\par
+\Us237\ET238.\fi
+
+\M{1489}
+\Y\B\4\D$\\{str\_364}$ \5
+\.{"globaldefs"}\par
+\Y\B\4\X1489:\.{"globaldefs"}\X${}\E{}$\5
+\T{364}\par
+\Us237\ET238.\fi
+
+\M{1490}
+\Y\B\4\D$\\{str\_365}$ \5
+\.{"fam"}\par
+\Y\B\4\X1490:\.{"fam"}\X${}\E{}$\5
+\T{365}\par
+\Us237, 238\ETs691.\fi
+
+\M{1491}
+\Y\B\4\D$\\{str\_366}$ \5
+\.{"escapechar"}\par
+\Y\B\4\X1491:\.{"escapechar"}\X${}\E{}$\5
+\T{366}\par
+\Us237\ET238.\fi
+
+\M{1492}
+\Y\B\4\D$\\{str\_367}$ \5
+\.{"defaulthyphenchar"}\par
+\Y\B\4\X1492:\.{"defaulthyphenchar"}\X${}\E{}$\5
+\T{367}\par
+\Us237\ET238.\fi
+
+\M{1493}
+\Y\B\4\D$\\{str\_368}$ \5
+\.{"defaultskewchar"}\par
+\Y\B\4\X1493:\.{"defaultskewchar"}\X${}\E{}$\5
+\T{368}\par
+\Us237\ET238.\fi
+
+\M{1494}
+\Y\B\4\D$\\{str\_369}$ \5
+\.{"endlinechar"}\par
+\Y\B\4\X1494:\.{"endlinechar"}\X${}\E{}$\5
+\T{369}\par
+\Us237\ET238.\fi
+
+\M{1495}
+\Y\B\4\D$\\{str\_370}$ \5
+\.{"newlinechar"}\par
+\Y\B\4\X1495:\.{"newlinechar"}\X${}\E{}$\5
+\T{370}\par
+\Us237\ET238.\fi
+
+\M{1496}
+\Y\B\4\D$\\{str\_371}$ \5
+\.{"language"}\par
+\Y\B\4\X1496:\.{"language"}\X${}\E{}$\5
+\T{371}\par
+\Us237\ET238.\fi
+
+\M{1497}
+\Y\B\4\D$\\{str\_372}$ \5
+\.{"lefthyphenmin"}\par
+\Y\B\4\X1497:\.{"lefthyphenmin"}\X${}\E{}$\5
+\T{372}\par
+\Us237\ET238.\fi
+
+\M{1498}
+\Y\B\4\D$\\{str\_373}$ \5
+\.{"righthyphenmin"}\par
+\Y\B\4\X1498:\.{"righthyphenmin"}\X${}\E{}$\5
+\T{373}\par
+\Us237\ET238.\fi
+
+\M{1499}
+\Y\B\4\D$\\{str\_374}$ \5
+\.{"holdinginserts"}\par
+\Y\B\4\X1499:\.{"holdinginserts"}\X${}\E{}$\5
+\T{374}\par
+\Us237\ET238.\fi
+
+\M{1500}
+\Y\B\4\D$\\{str\_375}$ \5
+\.{"errorcontextlines"}\par
+\Y\B\4\X1500:\.{"errorcontextlines"}\X${}\E{}$\5
+\T{375}\par
+\Us237\ET238.\fi
+
+\M{1501}
+\Y\B\4\D$\\{str\_376}$ \5
+\.{"count"}\par
+\Y\B\4\X1501:\.{"count"}\X${}\E{}$\5
+\T{376}\par
+\Us239, 242, 411\ETs412.\fi
+
+\M{1502}
+\Y\B\4\D$\\{str\_377}$ \5
+\.{"delcode"}\par
+\Y\B\4\X1502:\.{"delcode"}\X${}\E{}$\5
+\T{377}\par
+\Us242, 1230\ETs1231.\fi
+
+\M{1503}
+\Y\B\4\D$\\{str\_378}$ \5
+\.{"parindent"}\par
+\Y\B\4\X1503:\.{"parindent"}\X${}\E{}$\5
+\T{378}\par
+\Us247\ET248.\fi
+
+\M{1504}
+\Y\B\4\D$\\{str\_379}$ \5
+\.{"mathsurround"}\par
+\Y\B\4\X1504:\.{"mathsurround"}\X${}\E{}$\5
+\T{379}\par
+\Us247\ET248.\fi
+
+\M{1505}
+\Y\B\4\D$\\{str\_380}$ \5
+\.{"lineskiplimit"}\par
+\Y\B\4\X1505:\.{"lineskiplimit"}\X${}\E{}$\5
+\T{380}\par
+\Us247\ET248.\fi
+
+\M{1506}
+\Y\B\4\D$\\{str\_381}$ \5
+\.{"hsize"}\par
+\Y\B\4\X1506:\.{"hsize"}\X${}\E{}$\5
+\T{381}\par
+\Us247\ET248.\fi
+
+\M{1507}
+\Y\B\4\D$\\{str\_382}$ \5
+\.{"vsize"}\par
+\Y\B\4\X1507:\.{"vsize"}\X${}\E{}$\5
+\T{382}\par
+\Us247\ET248.\fi
+
+\M{1508}
+\Y\B\4\D$\\{str\_383}$ \5
+\.{"maxdepth"}\par
+\Y\B\4\X1508:\.{"maxdepth"}\X${}\E{}$\5
+\T{383}\par
+\Us247\ET248.\fi
+
+\M{1509}
+\Y\B\4\D$\\{str\_384}$ \5
+\.{"splitmaxdepth"}\par
+\Y\B\4\X1509:\.{"splitmaxdepth"}\X${}\E{}$\5
+\T{384}\par
+\Us247\ET248.\fi
+
+\M{1510}
+\Y\B\4\D$\\{str\_385}$ \5
+\.{"boxmaxdepth"}\par
+\Y\B\4\X1510:\.{"boxmaxdepth"}\X${}\E{}$\5
+\T{385}\par
+\Us247\ET248.\fi
+
+\M{1511}
+\Y\B\4\D$\\{str\_386}$ \5
+\.{"hfuzz"}\par
+\Y\B\4\X1511:\.{"hfuzz"}\X${}\E{}$\5
+\T{386}\par
+\Us247\ET248.\fi
+
+\M{1512}
+\Y\B\4\D$\\{str\_387}$ \5
+\.{"vfuzz"}\par
+\Y\B\4\X1512:\.{"vfuzz"}\X${}\E{}$\5
+\T{387}\par
+\Us247\ET248.\fi
+
+\M{1513}
+\Y\B\4\D$\\{str\_388}$ \5
+\.{"delimitershortfall"}\par
+\Y\B\4\X1513:\.{"delimitershortfall"}\X${}\E{}$\5
+\T{388}\par
+\Us247\ET248.\fi
+
+\M{1514}
+\Y\B\4\D$\\{str\_389}$ \5
+\.{"nulldelimiterspace"}\par
+\Y\B\4\X1514:\.{"nulldelimiterspace"}\X${}\E{}$\5
+\T{389}\par
+\Us247\ET248.\fi
+
+\M{1515}
+\Y\B\4\D$\\{str\_390}$ \5
+\.{"scriptspace"}\par
+\Y\B\4\X1515:\.{"scriptspace"}\X${}\E{}$\5
+\T{390}\par
+\Us247\ET248.\fi
+
+\M{1516}
+\Y\B\4\D$\\{str\_391}$ \5
+\.{"predisplaysize"}\par
+\Y\B\4\X1516:\.{"predisplaysize"}\X${}\E{}$\5
+\T{391}\par
+\Us247\ET248.\fi
+
+\M{1517}
+\Y\B\4\D$\\{str\_392}$ \5
+\.{"displaywidth"}\par
+\Y\B\4\X1517:\.{"displaywidth"}\X${}\E{}$\5
+\T{392}\par
+\Us247\ET248.\fi
+
+\M{1518}
+\Y\B\4\D$\\{str\_393}$ \5
+\.{"displayindent"}\par
+\Y\B\4\X1518:\.{"displayindent"}\X${}\E{}$\5
+\T{393}\par
+\Us247\ET248.\fi
+
+\M{1519}
+\Y\B\4\D$\\{str\_394}$ \5
+\.{"overfullrule"}\par
+\Y\B\4\X1519:\.{"overfullrule"}\X${}\E{}$\5
+\T{394}\par
+\Us247\ET248.\fi
+
+\M{1520}
+\Y\B\4\D$\\{str\_395}$ \5
+\.{"hangindent"}\par
+\Y\B\4\X1520:\.{"hangindent"}\X${}\E{}$\5
+\T{395}\par
+\Us247\ET248.\fi
+
+\M{1521}
+\Y\B\4\D$\\{str\_396}$ \5
+\.{"hoffset"}\par
+\Y\B\4\X1521:\.{"hoffset"}\X${}\E{}$\5
+\T{396}\par
+\Us247\ET248.\fi
+
+\M{1522}
+\Y\B\4\D$\\{str\_397}$ \5
+\.{"voffset"}\par
+\Y\B\4\X1522:\.{"voffset"}\X${}\E{}$\5
+\T{397}\par
+\Us247\ET248.\fi
+
+\M{1523}
+\Y\B\4\D$\\{str\_398}$ \5
+\.{"emergencystretch"}\par
+\Y\B\4\X1523:\.{"emergencystretch"}\X${}\E{}$\5
+\T{398}\par
+\Us247\ET248.\fi
+
+\M{1524}
+\Y\B\4\D$\\{str\_399}$ \5
+\.{"dimen"}\par
+\Y\B\4\X1524:\.{"dimen"}\X${}\E{}$\5
+\T{399}\par
+\Us249, 251, 411\ETs412.\fi
+
+\M{1525}
+\Y\B\4\D$\\{str\_400}$ \5
+\.{"notexpanded:"}\par
+\Y\B\4\X1525:\.{"notexpanded:"}\X${}\E{}$\5
+\T{400}\par
+\U258.\fi
+
+\M{1526}
+\Y\B\4\D$\\{str\_401}$ \5
+\.{"csname"}\par
+\Y\B\4\X1526:\.{"csname"}\X${}\E{}$\5
+\T{401}\par
+\Us262, 263, 265\ETs266.\fi
+
+\M{1527}
+\Y\B\4\D$\\{str\_402}$ \5
+\.{"endcsname"}\par
+\Y\B\4\X1527:\.{"endcsname"}\X${}\E{}$\5
+\T{402}\par
+\Us262, 263, 265, 266, 373\ETs1135.\fi
+
+\M{1528}
+\Y\B\4\D$\\{str\_403}$ \5
+\.{"IMPOSSIBLE."}\par
+\Y\B\4\X1528:\.{"IMPOSSIBLE."}\X${}\E{}$\5
+\T{403}\par
+\U262.\fi
+
+\M{1529}
+\Y\B\4\D$\\{str\_404}$ \5
+\.{"NONEXISTENT."}\par
+\Y\B\4\X1529:\.{"NONEXISTENT."}\X${}\E{}$\5
+\T{404}\par
+\U262.\fi
+
+\M{1530}
+\Y\B\4\D$\\{str\_405}$ \5
+\.{"accent"}\par
+\Y\B\4\X1530:\.{"accent"}\X${}\E{}$\5
+\T{405}\par
+\Us265, 266\ETs696.\fi
+
+\M{1531}
+\Y\B\4\D$\\{str\_406}$ \5
+\.{"advance"}\par
+\Y\B\4\X1531:\.{"advance"}\X${}\E{}$\5
+\T{406}\par
+\Us265\ET266.\fi
+
+\M{1532}
+\Y\B\4\D$\\{str\_407}$ \5
+\.{"afterassignment"}\par
+\Y\B\4\X1532:\.{"afterassignment"}\X${}\E{}$\5
+\T{407}\par
+\Us265\ET266.\fi
+
+\M{1533}
+\Y\B\4\D$\\{str\_408}$ \5
+\.{"aftergroup"}\par
+\Y\B\4\X1533:\.{"aftergroup"}\X${}\E{}$\5
+\T{408}\par
+\Us265\ET266.\fi
+
+\M{1534}
+\Y\B\4\D$\\{str\_409}$ \5
+\.{"begingroup"}\par
+\Y\B\4\X1534:\.{"begingroup"}\X${}\E{}$\5
+\T{409}\par
+\Us265\ET266.\fi
+
+\M{1535}
+\Y\B\4\D$\\{str\_410}$ \5
+\.{"char"}\par
+\Y\B\4\X1535:\.{"char"}\X${}\E{}$\5
+\T{410}\par
+\Us265, 266\ETs1223.\fi
+
+\M{1536}
+\Y\B\4\D$\\{str\_411}$ \5
+\.{"delimiter"}\par
+\Y\B\4\X1536:\.{"delimiter"}\X${}\E{}$\5
+\T{411}\par
+\Us265\ET266.\fi
+
+\M{1537}
+\Y\B\4\D$\\{str\_412}$ \5
+\.{"divide"}\par
+\Y\B\4\X1537:\.{"divide"}\X${}\E{}$\5
+\T{412}\par
+\Us265\ET266.\fi
+
+\M{1538}
+\Y\B\4\D$\\{str\_413}$ \5
+\.{"endgroup"}\par
+\Y\B\4\X1538:\.{"endgroup"}\X${}\E{}$\5
+\T{413}\par
+\Us265, 266, 1065\ETs1069.\fi
+
+\M{1539}
+\Y\B\4\D$\\{str\_414}$ \5
+\.{"expandafter"}\par
+\Y\B\4\X1539:\.{"expandafter"}\X${}\E{}$\5
+\T{414}\par
+\Us265\ET266.\fi
+
+\M{1540}
+\Y\B\4\D$\\{str\_415}$ \5
+\.{"font"}\par
+\Y\B\4\X1540:\.{"font"}\X${}\E{}$\5
+\T{415}\par
+\Us265\ET266.\fi
+
+\M{1541}
+\Y\B\4\D$\\{str\_416}$ \5
+\.{"fontdimen"}\par
+\Y\B\4\X1541:\.{"fontdimen"}\X${}\E{}$\5
+\T{416}\par
+\Us265\ET266.\fi
+
+\M{1542}
+\Y\B\4\D$\\{str\_417}$ \5
+\.{"halign"}\par
+\Y\B\4\X1542:\.{"halign"}\X${}\E{}$\5
+\T{417}\par
+\Us265, 266\ETs776.\fi
+
+\M{1543}
+\Y\B\4\D$\\{str\_418}$ \5
+\.{"hrule"}\par
+\Y\B\4\X1543:\.{"hrule"}\X${}\E{}$\5
+\T{418}\par
+\Us265, 266\ETs1095.\fi
+
+\M{1544}
+\Y\B\4\D$\\{str\_419}$ \5
+\.{"ignorespaces"}\par
+\Y\B\4\X1544:\.{"ignorespaces"}\X${}\E{}$\5
+\T{419}\par
+\Us265\ET266.\fi
+
+\M{1545}
+\Y\B\4\D$\\{str\_420}$ \5
+\.{"mathaccent"}\par
+\Y\B\4\X1545:\.{"mathaccent"}\X${}\E{}$\5
+\T{420}\par
+\Us265, 266\ETs1166.\fi
+
+\M{1546}
+\Y\B\4\D$\\{str\_421}$ \5
+\.{"mathchar"}\par
+\Y\B\4\X1546:\.{"mathchar"}\X${}\E{}$\5
+\T{421}\par
+\Us265, 266\ETs1223.\fi
+
+\M{1547}
+\Y\B\4\D$\\{str\_422}$ \5
+\.{"mathchoice"}\par
+\Y\B\4\X1547:\.{"mathchoice"}\X${}\E{}$\5
+\T{422}\par
+\Us265, 266\ETs695.\fi
+
+\M{1548}
+\Y\B\4\D$\\{str\_423}$ \5
+\.{"multiply"}\par
+\Y\B\4\X1548:\.{"multiply"}\X${}\E{}$\5
+\T{423}\par
+\Us265\ET266.\fi
+
+\M{1549}
+\Y\B\4\D$\\{str\_424}$ \5
+\.{"noalign"}\par
+\Y\B\4\X1549:\.{"noalign"}\X${}\E{}$\5
+\T{424}\par
+\Us265, 266\ETs1129.\fi
+
+\M{1550}
+\Y\B\4\D$\\{str\_425}$ \5
+\.{"noboundary"}\par
+\Y\B\4\X1550:\.{"noboundary"}\X${}\E{}$\5
+\T{425}\par
+\Us265\ET266.\fi
+
+\M{1551}
+\Y\B\4\D$\\{str\_426}$ \5
+\.{"noexpand"}\par
+\Y\B\4\X1551:\.{"noexpand"}\X${}\E{}$\5
+\T{426}\par
+\Us265\ET266.\fi
+
+\M{1552}
+\Y\B\4\D$\\{str\_427}$ \5
+\.{"omit"}\par
+\Y\B\4\X1552:\.{"omit"}\X${}\E{}$\5
+\T{427}\par
+\Us265, 266\ETs1129.\fi
+
+\M{1553}
+\Y\B\4\D$\\{str\_428}$ \5
+\.{"penalty"}\par
+\Y\B\4\X1553:\.{"penalty"}\X${}\E{}$\5
+\T{428}\par
+\Us265, 266\ETs856.\fi
+
+\M{1554}
+\Y\B\4\D$\\{str\_429}$ \5
+\.{"prevgraf"}\par
+\Y\B\4\X1554:\.{"prevgraf"}\X${}\E{}$\5
+\T{429}\par
+\Us265, 266\ETs1244.\fi
+
+\M{1555}
+\Y\B\4\D$\\{str\_430}$ \5
+\.{"radical"}\par
+\Y\B\4\X1555:\.{"radical"}\X${}\E{}$\5
+\T{430}\par
+\Q267.
+\Us265, 266\ETs696.\fi
+
+\M{1556}
+\Y\B\4\D$\\{str\_431}$ \5
+\.{"read"}\par
+\Y\B\4\X1556:\.{"read"}\X${}\E{}$\5
+\T{431}\par
+\Us265, 266\ETs486.\fi
+
+\M{1557}
+\Y\B\4\D$\\{str\_432}$ \5
+\.{"relax"}\par
+\Y\B\4\X1557:\.{"relax"}\X${}\E{}$\5
+\T{432}\par
+\Us265\ET266.\fi
+
+\M{1558}
+\Y\B\4\D$\\{str\_433}$ \5
+\.{"setbox"}\par
+\Y\B\4\X1558:\.{"setbox"}\X${}\E{}$\5
+\T{433}\par
+\Us265, 266\ETs1241.\fi
+
+\M{1559}
+\Y\B\4\D$\\{str\_434}$ \5
+\.{"the"}\par
+\Y\B\4\X1559:\.{"the"}\X${}\E{}$\5
+\T{434}\par
+\Us265, 266\ETs428.\fi
+
+\M{1560}
+\Y\B\4\D$\\{str\_435}$ \5
+\.{"valign"}\par
+\Y\B\4\X1560:\.{"valign"}\X${}\E{}$\5
+\T{435}\par
+\Us265\ET266.\fi
+
+\M{1561}
+\Y\B\4\D$\\{str\_436}$ \5
+\.{"vcenter"}\par
+\Y\B\4\X1561:\.{"vcenter"}\X${}\E{}$\5
+\T{436}\par
+\Us265, 266, 696\ETs736.\fi
+
+\M{1562}
+\Y\B\4\D$\\{str\_437}$ \5
+\.{"vrule"}\par
+\Y\B\4\X1562:\.{"vrule"}\X${}\E{}$\5
+\T{437}\par
+\Us265\ET266.\fi
+
+\M{1563}
+\Y\B\4\D$\\{str\_438}$ \5
+\.{"curlevel"}\par
+\Y\B\4\X1563:\.{"curlevel"}\X${}\E{}$\5
+\T{438}\par
+\U281.\fi
+
+\M{1564}
+\Y\B\4\D$\\{str\_439}$ \5
+\.{"retaining"}\par
+\Y\B\4\X1564:\.{"retaining"}\X${}\E{}$\5
+\T{439}\par
+\U283.\fi
+
+\M{1565}
+\Y\B\4\D$\\{str\_440}$ \5
+\.{"restoring"}\par
+\Y\B\4\X1565:\.{"restoring"}\X${}\E{}$\5
+\T{440}\par
+\U283.\fi
+
+\M{1566}
+\Y\B\4\D$\\{str\_441}$ \5
+\.{"ETC."}\par
+\Y\B\4\X1566:\.{"ETC."}\X${}\E{}$\5
+\T{441}\par
+\U292.\fi
+
+\M{1567}
+\Y\B\4\D$\\{str\_442}$ \5
+\.{"BAD."}\par
+\Y\B\4\X1567:\.{"BAD."}\X${}\E{}$\5
+\T{442}\par
+\Us293\ET294.\fi
+
+\M{1568}
+\Y\B\4\D$\\{str\_443}$ \5
+\.{"write"}\par
+\Y\B\4\X1568:\.{"write"}\X${}\E{}$\5
+\T{443}\par
+\Us323, 1344, 1346\ETs1356.\fi
+
+\M{1569}
+\Y\B\4\D$\\{str\_444}$ \5
+\.{"par"}\par
+\Y\B\4\X1569:\.{"par"}\X${}\E{}$\5
+\T{444}\par
+\Us334, 335\ETs856.\fi
+
+\M{1570}
+\Y\B\4\D$\\{str\_445}$ \5
+\.{"input"}\par
+\Y\B\4\X1570:\.{"input"}\X${}\E{}$\5
+\T{445}\par
+\Us376\ET377.\fi
+
+\M{1571}
+\Y\B\4\D$\\{str\_446}$ \5
+\.{"endinput"}\par
+\Y\B\4\X1571:\.{"endinput"}\X${}\E{}$\5
+\T{446}\par
+\Us376\ET377.\fi
+
+\M{1572}
+\Y\B\4\D$\\{str\_447}$ \5
+\.{"topmark"}\par
+\Y\B\4\X1572:\.{"topmark"}\X${}\E{}$\5
+\T{447}\par
+\Us384\ET385.\fi
+
+\M{1573}
+\Y\B\4\D$\\{str\_448}$ \5
+\.{"firstmark"}\par
+\Y\B\4\X1573:\.{"firstmark"}\X${}\E{}$\5
+\T{448}\par
+\Us384\ET385.\fi
+
+\M{1574}
+\Y\B\4\D$\\{str\_449}$ \5
+\.{"botmark"}\par
+\Y\B\4\X1574:\.{"botmark"}\X${}\E{}$\5
+\T{449}\par
+\Us384\ET385.\fi
+
+\M{1575}
+\Y\B\4\D$\\{str\_450}$ \5
+\.{"splitfirstmark"}\par
+\Y\B\4\X1575:\.{"splitfirstmark"}\X${}\E{}$\5
+\T{450}\par
+\Us384\ET385.\fi
+
+\M{1576}
+\Y\B\4\D$\\{str\_451}$ \5
+\.{"splitbotmark"}\par
+\Y\B\4\X1576:\.{"splitbotmark"}\X${}\E{}$\5
+\T{451}\par
+\Us384\ET385.\fi
+
+\M{1577}
+\Y\B\4\D$\\{str\_452}$ \5
+\.{"spacefactor"}\par
+\Y\B\4\X1577:\.{"spacefactor"}\X${}\E{}$\5
+\T{452}\par
+\Us416\ET417.\fi
+
+\M{1578}
+\Y\B\4\D$\\{str\_453}$ \5
+\.{"prevdepth"}\par
+\Y\B\4\X1578:\.{"prevdepth"}\X${}\E{}$\5
+\T{453}\par
+\Us416\ET417.\fi
+
+\M{1579}
+\Y\B\4\D$\\{str\_454}$ \5
+\.{"deadcycles"}\par
+\Y\B\4\X1579:\.{"deadcycles"}\X${}\E{}$\5
+\T{454}\par
+\Us416\ET417.\fi
+
+\M{1580}
+\Y\B\4\D$\\{str\_455}$ \5
+\.{"insertpenalties"}\par
+\Y\B\4\X1580:\.{"insertpenalties"}\X${}\E{}$\5
+\T{455}\par
+\Us416\ET417.\fi
+
+\M{1581}
+\Y\B\4\D$\\{str\_456}$ \5
+\.{"wd"}\par
+\Y\B\4\X1581:\.{"wd"}\X${}\E{}$\5
+\T{456}\par
+\Us416\ET417.\fi
+
+\M{1582}
+\Y\B\4\D$\\{str\_457}$ \5
+\.{"ht"}\par
+\Y\B\4\X1582:\.{"ht"}\X${}\E{}$\5
+\T{457}\par
+\Us416\ET417.\fi
+
+\M{1583}
+\Y\B\4\D$\\{str\_458}$ \5
+\.{"dp"}\par
+\Y\B\4\X1583:\.{"dp"}\X${}\E{}$\5
+\T{458}\par
+\Us416\ET417.\fi
+
+\M{1584}
+\Y\B\4\D$\\{str\_459}$ \5
+\.{"lastpenalty"}\par
+\Y\B\4\X1584:\.{"lastpenalty"}\X${}\E{}$\5
+\T{459}\par
+\Us416\ET417.\fi
+
+\M{1585}
+\Y\B\4\D$\\{str\_460}$ \5
+\.{"lastkern"}\par
+\Y\B\4\X1585:\.{"lastkern"}\X${}\E{}$\5
+\T{460}\par
+\Us416\ET417.\fi
+
+\M{1586}
+\Y\B\4\D$\\{str\_461}$ \5
+\.{"lastskip"}\par
+\Y\B\4\X1586:\.{"lastskip"}\X${}\E{}$\5
+\T{461}\par
+\Us416\ET417.\fi
+
+\M{1587}
+\Y\B\4\D$\\{str\_462}$ \5
+\.{"inputlineno"}\par
+\Y\B\4\X1587:\.{"inputlineno"}\X${}\E{}$\5
+\T{462}\par
+\Us416\ET417.\fi
+
+\M{1588}
+\Y\B\4\D$\\{str\_463}$ \5
+\.{"badness"}\par
+\Y\B\4\X1588:\.{"badness"}\X${}\E{}$\5
+\T{463}\par
+\Us416\ET417.\fi
+
+\M{1589}
+\Y\B\4\D$\\{str\_464}$ \5
+\.{"true"}\par
+\Y\B\4\X1589:\.{"true"}\X${}\E{}$\5
+\T{464}\par
+\U453.\fi
+
+\M{1590}
+\Y\B\4\D$\\{str\_465}$ \5
+\.{"em"}\par
+\Y\B\4\X1590:\.{"em"}\X${}\E{}$\5
+\T{465}\par
+\U455.\fi
+
+\M{1591}
+\Y\B\4\D$\\{str\_466}$ \5
+\.{"ex"}\par
+\Y\B\4\X1591:\.{"ex"}\X${}\E{}$\5
+\T{466}\par
+\U455.\fi
+
+\M{1592}
+\Y\B\4\D$\\{str\_467}$ \5
+\.{"in"}\par
+\Y\B\4\X1592:\.{"in"}\X${}\E{}$\5
+\T{467}\par
+\U458.\fi
+
+\M{1593}
+\Y\B\4\D$\\{str\_468}$ \5
+\.{"pc"}\par
+\Y\B\4\X1593:\.{"pc"}\X${}\E{}$\5
+\T{468}\par
+\U458.\fi
+
+\M{1594}
+\Y\B\4\D$\\{str\_469}$ \5
+\.{"cm"}\par
+\Y\B\4\X1594:\.{"cm"}\X${}\E{}$\5
+\T{469}\par
+\U458.\fi
+
+\M{1595}
+\Y\B\4\D$\\{str\_470}$ \5
+\.{"mm"}\par
+\Y\B\4\X1595:\.{"mm"}\X${}\E{}$\5
+\T{470}\par
+\U458.\fi
+
+\M{1596}
+\Y\B\4\D$\\{str\_471}$ \5
+\.{"bp"}\par
+\Y\B\4\X1596:\.{"bp"}\X${}\E{}$\5
+\T{471}\par
+\U458.\fi
+
+\M{1597}
+\Y\B\4\D$\\{str\_472}$ \5
+\.{"dd"}\par
+\Y\B\4\X1597:\.{"dd"}\X${}\E{}$\5
+\T{472}\par
+\U458.\fi
+
+\M{1598}
+\Y\B\4\D$\\{str\_473}$ \5
+\.{"cc"}\par
+\Y\B\4\X1598:\.{"cc"}\X${}\E{}$\5
+\T{473}\par
+\U458.\fi
+
+\M{1599}
+\Y\B\4\D$\\{str\_474}$ \5
+\.{"sp"}\par
+\Y\B\4\X1599:\.{"sp"}\X${}\E{}$\5
+\T{474}\par
+\U458.\fi
+
+\M{1600}
+\Y\B\4\D$\\{str\_475}$ \5
+\.{"plus"}\par
+\Y\B\4\X1600:\.{"plus"}\X${}\E{}$\5
+\T{475}\par
+\U462.\fi
+
+\M{1601}
+\Y\B\4\D$\\{str\_476}$ \5
+\.{"minus"}\par
+\Y\B\4\X1601:\.{"minus"}\X${}\E{}$\5
+\T{476}\par
+\U462.\fi
+
+\M{1602}
+\Y\B\4\D$\\{str\_477}$ \5
+\.{"width"}\par
+\Y\B\4\X1602:\.{"width"}\X${}\E{}$\5
+\T{477}\par
+\U463.\fi
+
+\M{1603}
+\Y\B\4\D$\\{str\_478}$ \5
+\.{"height"}\par
+\Y\B\4\X1603:\.{"height"}\X${}\E{}$\5
+\T{478}\par
+\U463.\fi
+
+\M{1604}
+\Y\B\4\D$\\{str\_479}$ \5
+\.{"depth"}\par
+\Y\B\4\X1604:\.{"depth"}\X${}\E{}$\5
+\T{479}\par
+\U463.\fi
+
+\M{1605}
+\Y\B\4\D$\\{str\_480}$ \5
+\.{"number"}\par
+\Y\B\4\X1605:\.{"number"}\X${}\E{}$\5
+\T{480}\par
+\Us468\ET469.\fi
+
+\M{1606}
+\Y\B\4\D$\\{str\_481}$ \5
+\.{"romannumeral"}\par
+\Y\B\4\X1606:\.{"romannumeral"}\X${}\E{}$\5
+\T{481}\par
+\Us468\ET469.\fi
+
+\M{1607}
+\Y\B\4\D$\\{str\_482}$ \5
+\.{"string"}\par
+\Y\B\4\X1607:\.{"string"}\X${}\E{}$\5
+\T{482}\par
+\Us468\ET469.\fi
+
+\M{1608}
+\Y\B\4\D$\\{str\_483}$ \5
+\.{"meaning"}\par
+\Y\B\4\X1608:\.{"meaning"}\X${}\E{}$\5
+\T{483}\par
+\Us468\ET469.\fi
+
+\M{1609}
+\Y\B\4\D$\\{str\_484}$ \5
+\.{"fontname"}\par
+\Y\B\4\X1609:\.{"fontname"}\X${}\E{}$\5
+\T{484}\par
+\Us468\ET469.\fi
+
+\M{1610}
+\Y\B\4\D$\\{str\_485}$ \5
+\.{"jobname"}\par
+\Y\B\4\X1610:\.{"jobname"}\X${}\E{}$\5
+\T{485}\par
+\Us468\ET469.\fi
+
+\M{1611}
+\Y\B\4\D$\\{str\_486}$ \5
+\.{"if"}\par
+\Y\B\4\X1611:\.{"if"}\X${}\E{}$\5
+\T{486}\par
+\Us487, 488\ETs497.\fi
+
+\M{1612}
+\Y\B\4\D$\\{str\_487}$ \5
+\.{"ifcat"}\par
+\Y\B\4\X1612:\.{"ifcat"}\X${}\E{}$\5
+\T{487}\par
+\Us487\ET488.\fi
+
+\M{1613}
+\Y\B\4\D$\\{str\_488}$ \5
+\.{"ifnum"}\par
+\Y\B\4\X1613:\.{"ifnum"}\X${}\E{}$\5
+\T{488}\par
+\Us487\ET488.\fi
+
+\M{1614}
+\Y\B\4\D$\\{str\_489}$ \5
+\.{"ifdim"}\par
+\Y\B\4\X1614:\.{"ifdim"}\X${}\E{}$\5
+\T{489}\par
+\Us487\ET488.\fi
+
+\M{1615}
+\Y\B\4\D$\\{str\_490}$ \5
+\.{"ifodd"}\par
+\Y\B\4\X1615:\.{"ifodd"}\X${}\E{}$\5
+\T{490}\par
+\Us487\ET488.\fi
+
+\M{1616}
+\Y\B\4\D$\\{str\_491}$ \5
+\.{"ifvmode"}\par
+\Y\B\4\X1616:\.{"ifvmode"}\X${}\E{}$\5
+\T{491}\par
+\Us487\ET488.\fi
+
+\M{1617}
+\Y\B\4\D$\\{str\_492}$ \5
+\.{"ifhmode"}\par
+\Y\B\4\X1617:\.{"ifhmode"}\X${}\E{}$\5
+\T{492}\par
+\Us487\ET488.\fi
+
+\M{1618}
+\Y\B\4\D$\\{str\_493}$ \5
+\.{"ifmmode"}\par
+\Y\B\4\X1618:\.{"ifmmode"}\X${}\E{}$\5
+\T{493}\par
+\Us487\ET488.\fi
+
+\M{1619}
+\Y\B\4\D$\\{str\_494}$ \5
+\.{"ifinner"}\par
+\Y\B\4\X1619:\.{"ifinner"}\X${}\E{}$\5
+\T{494}\par
+\Us487\ET488.\fi
+
+\M{1620}
+\Y\B\4\D$\\{str\_495}$ \5
+\.{"ifvoid"}\par
+\Y\B\4\X1620:\.{"ifvoid"}\X${}\E{}$\5
+\T{495}\par
+\Us487\ET488.\fi
+
+\M{1621}
+\Y\B\4\D$\\{str\_496}$ \5
+\.{"ifhbox"}\par
+\Y\B\4\X1621:\.{"ifhbox"}\X${}\E{}$\5
+\T{496}\par
+\Us487\ET488.\fi
+
+\M{1622}
+\Y\B\4\D$\\{str\_497}$ \5
+\.{"ifvbox"}\par
+\Y\B\4\X1622:\.{"ifvbox"}\X${}\E{}$\5
+\T{497}\par
+\Us487\ET488.\fi
+
+\M{1623}
+\Y\B\4\D$\\{str\_498}$ \5
+\.{"ifx"}\par
+\Y\B\4\X1623:\.{"ifx"}\X${}\E{}$\5
+\T{498}\par
+\Us487\ET488.\fi
+
+\M{1624}
+\Y\B\4\D$\\{str\_499}$ \5
+\.{"ifeof"}\par
+\Y\B\4\X1624:\.{"ifeof"}\X${}\E{}$\5
+\T{499}\par
+\Us487\ET488.\fi
+
+\M{1625}
+\Y\B\4\D$\\{str\_500}$ \5
+\.{"iftrue"}\par
+\Y\B\4\X1625:\.{"iftrue"}\X${}\E{}$\5
+\T{500}\par
+\Us487\ET488.\fi
+
+\M{1626}
+\Y\B\4\D$\\{str\_501}$ \5
+\.{"iffalse"}\par
+\Y\B\4\X1626:\.{"iffalse"}\X${}\E{}$\5
+\T{501}\par
+\Us487\ET488.\fi
+
+\M{1627}
+\Y\B\4\D$\\{str\_502}$ \5
+\.{"ifcase"}\par
+\Y\B\4\X1627:\.{"ifcase"}\X${}\E{}$\5
+\T{502}\par
+\Us487\ET488.\fi
+
+\M{1628}
+\Y\B\4\D$\\{str\_503}$ \5
+\.{"fi"}\par
+\Y\B\4\X1628:\.{"fi"}\X${}\E{}$\5
+\T{503}\par
+\Us491\ET492.\fi
+
+\M{1629}
+\Y\B\4\D$\\{str\_504}$ \5
+\.{"or"}\par
+\Y\B\4\X1629:\.{"or"}\X${}\E{}$\5
+\T{504}\par
+\Us491, 492\ETs500.\fi
+
+\M{1630}
+\Y\B\4\D$\\{str\_505}$ \5
+\.{"else"}\par
+\Y\B\4\X1630:\.{"else"}\X${}\E{}$\5
+\T{505}\par
+\Us491\ET492.\fi
+
+\M{1631}
+\Y\B\4\D$\\{str\_506}$ \5
+\.{"TeXinputs/"}\par
+\B\4\D$\\{TEX\_area}$ \5
+\T{506}\par
+\fi
+
+\M{1632}
+\Y\B\4\D$\\{str\_507}$ \5
+\.{"TeXfonts/"}\par
+\B\4\D$\\{TEX\_font\_area}$ \5
+\T{507}\par
+\fi
+
+\M{1633}
+\Y\B\4\D$\\{str\_508}$ \5
+\.{".fmt"}\par
+\B\4\D$\\{format\_extension}$ \5
+\T{508}\par
+\fi
+
+\M{1634}
+\Y\B\4\D$\\{str\_509}$ \5
+\.{".log"}\par
+\Y\B\4\X1634:\.{".log"}\X${}\E{}$\5
+\T{509}\par
+\Q528.
+\Us534\ET535.\fi
+
+\M{1635}
+\Y\B\4\D$\\{str\_510}$ \5
+\.{".dvi"}\par
+\Y\B\4\X1635:\.{".dvi"}\X${}\E{}$\5
+\T{510}\par
+\Q528.
+\U531.\fi
+
+\M{1636}
+\Y\B\4\D$\\{str\_511}$ \5
+\.{"input\ file\ name"}\par
+\Y\B\4\X1636:\.{"input\ file\ name"}\X${}\E{}$\5
+\T{511}\par
+\fi
+
+\M{1637}
+\Y\B\4\D$\\{str\_512}$ \5
+\.{".tex"}\par
+\Y\B\4\X1637:\.{".tex"}\X${}\E{}$\5
+\T{512}\par
+\Us529, 537, 1275\ETs1374.\fi
+
+\M{1638}
+\Y\B\4\D$\\{str\_513}$ \5
+\.{"texput"}\par
+\Y\B\4\X1638:\.{"texput"}\X${}\E{}$\5
+\T{513}\par
+\U534.\fi
+
+\M{1639}
+\Y\B\4\D$\\{str\_514}$ \5
+\.{"nullfont"}\par
+\Y\B\4\X1639:\.{"nullfont"}\X${}\E{}$\5
+\T{514}\par
+\Us552\ET553.\fi
+
+\M{1640}
+\Y\B\4\D$\\{str\_515}$ \5
+\.{".tfm"}\par
+\Y\B\4\X1640:\.{".tfm"}\X${}\E{}$\5
+\T{515}\par
+\U563.\fi
+
+\M{1641}
+\Y\B\4\D$\\{str\_516}$ \5
+\.{"vlistout"}\par
+\Y\B\4\X1641:\.{"vlistout"}\X${}\E{}$\5
+\T{516}\par
+\U630.\fi
+
+\M{1642}
+\Y\B\4\D$\\{str\_517}$ \5
+\.{"to"}\par
+\Y\B\4\X1642:\.{"to"}\X${}\E{}$\5
+\T{517}\par
+\Us645, 1082\ETs1225.\fi
+
+\M{1643}
+\Y\B\4\D$\\{str\_518}$ \5
+\.{"spread"}\par
+\Y\B\4\X1643:\.{"spread"}\X${}\E{}$\5
+\T{518}\par
+\U645.\fi
+
+\M{1644}
+\Y\B\4\D$\\{str\_519}$ \5
+\.{"vpack"}\par
+\Y\B\4\X1644:\.{"vpack"}\X${}\E{}$\5
+\T{519}\par
+\U669.\fi
+
+\M{1645}
+\Y\B\4\D$\\{str\_520}$ \5
+\.{"displaystyle"}\par
+\Y\B\4\X1645:\.{"displaystyle"}\X${}\E{}$\5
+\T{520}\par
+\Us694\ET1169.\fi
+
+\M{1646}
+\Y\B\4\D$\\{str\_521}$ \5
+\.{"textstyle"}\par
+\Y\B\4\X1646:\.{"textstyle"}\X${}\E{}$\5
+\T{521}\par
+\Us694\ET1169.\fi
+
+\M{1647}
+\Y\B\4\D$\\{str\_522}$ \5
+\.{"scriptstyle"}\par
+\Y\B\4\X1647:\.{"scriptstyle"}\X${}\E{}$\5
+\T{522}\par
+\Us694\ET1169.\fi
+
+\M{1648}
+\Y\B\4\D$\\{str\_523}$ \5
+\.{"scriptscriptstyle"}\par
+\Y\B\4\X1648:\.{"scriptscriptstyle"}\X${}\E{}$\5
+\T{523}\par
+\Us694\ET1169.\fi
+
+\M{1649}
+\Y\B\4\D$\\{str\_524}$ \5
+\.{"mathord"}\par
+\Y\B\4\X1649:\.{"mathord"}\X${}\E{}$\5
+\T{524}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1650}
+\Y\B\4\D$\\{str\_525}$ \5
+\.{"mathop"}\par
+\Y\B\4\X1650:\.{"mathop"}\X${}\E{}$\5
+\T{525}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1651}
+\Y\B\4\D$\\{str\_526}$ \5
+\.{"mathbin"}\par
+\Y\B\4\X1651:\.{"mathbin"}\X${}\E{}$\5
+\T{526}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1652}
+\Y\B\4\D$\\{str\_527}$ \5
+\.{"mathrel"}\par
+\Y\B\4\X1652:\.{"mathrel"}\X${}\E{}$\5
+\T{527}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1653}
+\Y\B\4\D$\\{str\_528}$ \5
+\.{"mathopen"}\par
+\Y\B\4\X1653:\.{"mathopen"}\X${}\E{}$\5
+\T{528}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1654}
+\Y\B\4\D$\\{str\_529}$ \5
+\.{"mathclose"}\par
+\Y\B\4\X1654:\.{"mathclose"}\X${}\E{}$\5
+\T{529}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1655}
+\Y\B\4\D$\\{str\_530}$ \5
+\.{"mathpunct"}\par
+\Y\B\4\X1655:\.{"mathpunct"}\X${}\E{}$\5
+\T{530}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1656}
+\Y\B\4\D$\\{str\_531}$ \5
+\.{"mathinner"}\par
+\Y\B\4\X1656:\.{"mathinner"}\X${}\E{}$\5
+\T{531}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1657}
+\Y\B\4\D$\\{str\_532}$ \5
+\.{"overline"}\par
+\Y\B\4\X1657:\.{"overline"}\X${}\E{}$\5
+\T{532}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1658}
+\Y\B\4\D$\\{str\_533}$ \5
+\.{"underline"}\par
+\Y\B\4\X1658:\.{"underline"}\X${}\E{}$\5
+\T{533}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1659}
+\Y\B\4\D$\\{str\_534}$ \5
+\.{"left"}\par
+\Y\B\4\X1659:\.{"left"}\X${}\E{}$\5
+\T{534}\par
+\Us696, 1188\ETs1189.\fi
+
+\M{1660}
+\Y\B\4\D$\\{str\_535}$ \5
+\.{"right"}\par
+\Y\B\4\X1660:\.{"right"}\X${}\E{}$\5
+\T{535}\par
+\Us696, 1069, 1185, 1188, 1189\ETs1192.\fi
+
+\M{1661}
+\Y\B\4\D$\\{str\_536}$ \5
+\.{"limits"}\par
+\Y\B\4\X1661:\.{"limits"}\X${}\E{}$\5
+\T{536}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1662}
+\Y\B\4\D$\\{str\_537}$ \5
+\.{"nolimits"}\par
+\Y\B\4\X1662:\.{"nolimits"}\X${}\E{}$\5
+\T{537}\par
+\Us696, 1156\ETs1157.\fi
+
+\M{1663}
+\Y\B\4\D$\\{str\_538}$ \5
+\.{"fraction,\ thickness}\)\.{\ "}\par
+\Y\B\4\X1663:\.{"fraction,\ thickness}\)\.{\ "}\X${}\E{}$\5
+\T{538}\par
+\U697.\fi
+
+\M{1664}
+\Y\B\4\D$\\{str\_539}$ \5
+\.{"mlist1"}\par
+\Y\B\4\X1664:\.{"mlist1"}\X${}\E{}$\5
+\T{539}\par
+\U728.\fi
+
+\M{1665}
+\Y\B\4\D$\\{str\_540}$ \5
+\.{"mlist2"}\par
+\Y\B\4\X1665:\.{"mlist2"}\X${}\E{}$\5
+\T{540}\par
+\U754.\fi
+
+\M{1666}
+\Y\B\4\D$\\{str\_541}$ \5
+\.{"mlist3"}\par
+\Y\B\4\X1666:\.{"mlist3"}\X${}\E{}$\5
+\T{541}\par
+\U761.\fi
+
+\M{1667}
+\Y\B\4\D$\\{str\_542}$ \5
+\.{"0234000122*4000133*}\)\.{*3**344*0400400*0000}\)\.{00234000111*11111123}\)\.{41011"}\par
+\B\4\D$\\{math\_spacing}$ \5
+\T{542}\par
+\fi
+
+\M{1668}
+\Y\B\4\D$\\{str\_543}$ \5
+\.{"mlist4"}\par
+\Y\B\4\X1668:\.{"mlist4"}\X${}\E{}$\5
+\T{543}\par
+\U766.\fi
+
+\M{1669}
+\Y\B\4\D$\\{str\_544}$ \5
+\.{"span"}\par
+\Y\B\4\X1669:\.{"span"}\X${}\E{}$\5
+\T{544}\par
+\Us780\ET781.\fi
+
+\M{1670}
+\Y\B\4\D$\\{str\_545}$ \5
+\.{"cr"}\par
+\Y\B\4\X1670:\.{"cr"}\X${}\E{}$\5
+\T{545}\par
+\Us780, 781, 792\ETs1132.\fi
+
+\M{1671}
+\Y\B\4\D$\\{str\_546}$ \5
+\.{"crcr"}\par
+\Y\B\4\X1671:\.{"crcr"}\X${}\E{}$\5
+\T{546}\par
+\Us780\ET781.\fi
+
+\M{1672}
+\Y\B\4\D$\\{str\_547}$ \5
+\.{"endtemplate"}\par
+\Y\B\4\X1672:\.{"endtemplate"}\X${}\E{}$\5
+\T{547}\par
+\U780.\fi
+
+\M{1673}
+\Y\B\4\D$\\{str\_548}$ \5
+\.{"endv"}\par
+\Y\B\4\X1673:\.{"endv"}\X${}\E{}$\5
+\T{548}\par
+\U791.\fi
+
+\M{1674}
+\Y\B\4\D$\\{str\_549}$ \5
+\.{"256\ spans"}\par
+\Y\B\4\X1674:\.{"256\ spans"}\X${}\E{}$\5
+\T{549}\par
+\U798.\fi
+
+\M{1675}
+\Y\B\4\D$\\{str\_550}$ \5
+\.{"align1"}\par
+\Y\B\4\X1675:\.{"align1"}\X${}\E{}$\5
+\T{550}\par
+\U800.\fi
+
+\M{1676}
+\Y\B\4\D$\\{str\_551}$ \5
+\.{"align0"}\par
+\Y\B\4\X1676:\.{"align0"}\X${}\E{}$\5
+\T{551}\par
+\U800.\fi
+
+\M{1677}
+\Y\B\4\D$\\{str\_552}$ \5
+\.{"disc1"}\par
+\Y\B\4\X1677:\.{"disc1"}\X${}\E{}$\5
+\T{552}\par
+\U841.\fi
+
+\M{1678}
+\Y\B\4\D$\\{str\_553}$ \5
+\.{"disc2"}\par
+\Y\B\4\X1678:\.{"disc2"}\X${}\E{}$\5
+\T{553}\par
+\U842.\fi
+
+\M{1679}
+\Y\B\4\D$\\{str\_554}$ \5
+\.{"paragraph"}\par
+\Y\B\4\X1679:\.{"paragraph"}\X${}\E{}$\5
+\T{554}\par
+\U866.\fi
+
+\M{1680}
+\Y\B\4\D$\\{str\_555}$ \5
+\.{"disc3"}\par
+\Y\B\4\X1680:\.{"disc3"}\X${}\E{}$\5
+\T{555}\par
+\U870.\fi
+
+\M{1681}
+\Y\B\4\D$\\{str\_556}$ \5
+\.{"disc4"}\par
+\Y\B\4\X1681:\.{"disc4"}\X${}\E{}$\5
+\T{556}\par
+\U871.\fi
+
+\M{1682}
+\Y\B\4\D$\\{str\_557}$ \5
+\.{"line\ breaking"}\par
+\Y\B\4\X1682:\.{"line\ breaking"}\X${}\E{}$\5
+\T{557}\par
+\U877.\fi
+
+\M{1683}
+\Y\B\4\D$\\{str\_558}$ \5
+\.{"hyphenation"}\par
+\Y\B\4\X1683:\.{"hyphenation"}\X${}\E{}$\5
+\T{558}\par
+\Us936, 1250\ETs1251.\fi
+
+\M{1684}
+\Y\B\4\D$\\{str\_559}$ \5
+\.{"patterns"}\par
+\Y\B\4\X1684:\.{"patterns"}\X${}\E{}$\5
+\T{559}\par
+\Us960, 961, 1250\ETs1251.\fi
+
+\M{1685}
+\Y\B\4\D$\\{str\_560}$ \5
+\.{"pruning"}\par
+\Y\B\4\X1685:\.{"pruning"}\X${}\E{}$\5
+\T{560}\par
+\U968.\fi
+
+\M{1686}
+\Y\B\4\D$\\{str\_561}$ \5
+\.{"vertbreak"}\par
+\Y\B\4\X1686:\.{"vertbreak"}\X${}\E{}$\5
+\T{561}\par
+\U973.\fi
+
+\M{1687}
+\Y\B\4\D$\\{str\_562}$ \5
+\.{"vsplit"}\par
+\Y\B\4\X1687:\.{"vsplit"}\X${}\E{}$\5
+\T{562}\par
+\Us978, 1071\ETs1072.\fi
+
+\M{1688}
+\Y\B\4\D$\\{str\_563}$ \5
+\.{"vbox"}\par
+\Y\B\4\X1688:\.{"vbox"}\X${}\E{}$\5
+\T{563}\par
+\Us978, 1071\ETs1072.\fi
+
+\M{1689}
+\Y\B\4\D$\\{str\_564}$ \5
+\.{"pagegoal"}\par
+\Y\B\4\X1689:\.{"pagegoal"}\X${}\E{}$\5
+\T{564}\par
+\Us983\ET984.\fi
+
+\M{1690}
+\Y\B\4\D$\\{str\_565}$ \5
+\.{"pagetotal"}\par
+\Y\B\4\X1690:\.{"pagetotal"}\X${}\E{}$\5
+\T{565}\par
+\Us983\ET984.\fi
+
+\M{1691}
+\Y\B\4\D$\\{str\_566}$ \5
+\.{"pagestretch"}\par
+\Y\B\4\X1691:\.{"pagestretch"}\X${}\E{}$\5
+\T{566}\par
+\Us983\ET984.\fi
+
+\M{1692}
+\Y\B\4\D$\\{str\_567}$ \5
+\.{"pagefilstretch"}\par
+\Y\B\4\X1692:\.{"pagefilstretch"}\X${}\E{}$\5
+\T{567}\par
+\Us983\ET984.\fi
+
+\M{1693}
+\Y\B\4\D$\\{str\_568}$ \5
+\.{"pagefillstretch"}\par
+\Y\B\4\X1693:\.{"pagefillstretch"}\X${}\E{}$\5
+\T{568}\par
+\Us983\ET984.\fi
+
+\M{1694}
+\Y\B\4\D$\\{str\_569}$ \5
+\.{"pagefilllstretch"}\par
+\Y\B\4\X1694:\.{"pagefilllstretch"}\X${}\E{}$\5
+\T{569}\par
+\Us983\ET984.\fi
+
+\M{1695}
+\Y\B\4\D$\\{str\_570}$ \5
+\.{"pageshrink"}\par
+\Y\B\4\X1695:\.{"pageshrink"}\X${}\E{}$\5
+\T{570}\par
+\Us983\ET984.\fi
+
+\M{1696}
+\Y\B\4\D$\\{str\_571}$ \5
+\.{"pagedepth"}\par
+\Y\B\4\X1696:\.{"pagedepth"}\X${}\E{}$\5
+\T{571}\par
+\Us983\ET984.\fi
+
+\M{1697}
+\Y\B\4\D$\\{str\_572}$ \5
+\.{"page"}\par
+\Y\B\4\X1697:\.{"page"}\X${}\E{}$\5
+\T{572}\par
+\U1000.\fi
+
+\M{1698}
+\Y\B\4\D$\\{str\_573}$ \5
+\.{"end"}\par
+\Y\B\4\X1698:\.{"end"}\X${}\E{}$\5
+\T{573}\par
+\Us1052\ET1053.\fi
+
+\M{1699}
+\Y\B\4\D$\\{str\_574}$ \5
+\.{"dump"}\par
+\Y\B\4\X1699:\.{"dump"}\X${}\E{}$\5
+\T{574}\par
+\Us1052\ET1053.\fi
+
+\M{1700}
+\Y\B\4\D$\\{str\_575}$ \5
+\.{"hskip"}\par
+\Y\B\4\X1700:\.{"hskip"}\X${}\E{}$\5
+\T{575}\par
+\Us1058\ET1059.\fi
+
+\M{1701}
+\Y\B\4\D$\\{str\_576}$ \5
+\.{"hfil"}\par
+\Y\B\4\X1701:\.{"hfil"}\X${}\E{}$\5
+\T{576}\par
+\Us1058\ET1059.\fi
+
+\M{1702}
+\Y\B\4\D$\\{str\_577}$ \5
+\.{"hfill"}\par
+\Y\B\4\X1702:\.{"hfill"}\X${}\E{}$\5
+\T{577}\par
+\Us1058\ET1059.\fi
+
+\M{1703}
+\Y\B\4\D$\\{str\_578}$ \5
+\.{"hss"}\par
+\Y\B\4\X1703:\.{"hss"}\X${}\E{}$\5
+\T{578}\par
+\Us1058\ET1059.\fi
+
+\M{1704}
+\Y\B\4\D$\\{str\_579}$ \5
+\.{"hfilneg"}\par
+\Y\B\4\X1704:\.{"hfilneg"}\X${}\E{}$\5
+\T{579}\par
+\Us1058\ET1059.\fi
+
+\M{1705}
+\Y\B\4\D$\\{str\_580}$ \5
+\.{"vskip"}\par
+\Y\B\4\X1705:\.{"vskip"}\X${}\E{}$\5
+\T{580}\par
+\Us1058\ET1059.\fi
+
+\M{1706}
+\Y\B\4\D$\\{str\_581}$ \5
+\.{"vfil"}\par
+\Y\B\4\X1706:\.{"vfil"}\X${}\E{}$\5
+\T{581}\par
+\Us1058\ET1059.\fi
+
+\M{1707}
+\Y\B\4\D$\\{str\_582}$ \5
+\.{"vfill"}\par
+\Y\B\4\X1707:\.{"vfill"}\X${}\E{}$\5
+\T{582}\par
+\Us1058\ET1059.\fi
+
+\M{1708}
+\Y\B\4\D$\\{str\_583}$ \5
+\.{"vss"}\par
+\Y\B\4\X1708:\.{"vss"}\X${}\E{}$\5
+\T{583}\par
+\Us1058\ET1059.\fi
+
+\M{1709}
+\Y\B\4\D$\\{str\_584}$ \5
+\.{"vfilneg"}\par
+\Y\B\4\X1709:\.{"vfilneg"}\X${}\E{}$\5
+\T{584}\par
+\Us1058\ET1059.\fi
+
+\M{1710}
+\Y\B\4\D$\\{str\_585}$ \5
+\.{"right."}\par
+\Y\B\4\X1710:\.{"right."}\X${}\E{}$\5
+\T{585}\par
+\U1065.\fi
+
+\M{1711}
+\Y\B\4\D$\\{str\_586}$ \5
+\.{"rightbrace"}\par
+\Y\B\4\X1711:\.{"rightbrace"}\X${}\E{}$\5
+\T{586}\par
+\U1068.\fi
+
+\M{1712}
+\Y\B\4\D$\\{str\_587}$ \5
+\.{"moveleft"}\par
+\Y\B\4\X1712:\.{"moveleft"}\X${}\E{}$\5
+\T{587}\par
+\Us1071\ET1072.\fi
+
+\M{1713}
+\Y\B\4\D$\\{str\_588}$ \5
+\.{"moveright"}\par
+\Y\B\4\X1713:\.{"moveright"}\X${}\E{}$\5
+\T{588}\par
+\Us1071\ET1072.\fi
+
+\M{1714}
+\Y\B\4\D$\\{str\_589}$ \5
+\.{"raise"}\par
+\Y\B\4\X1714:\.{"raise"}\X${}\E{}$\5
+\T{589}\par
+\Us1071\ET1072.\fi
+
+\M{1715}
+\Y\B\4\D$\\{str\_590}$ \5
+\.{"lower"}\par
+\Y\B\4\X1715:\.{"lower"}\X${}\E{}$\5
+\T{590}\par
+\Us1071\ET1072.\fi
+
+\M{1716}
+\Y\B\4\D$\\{str\_591}$ \5
+\.{"copy"}\par
+\Y\B\4\X1716:\.{"copy"}\X${}\E{}$\5
+\T{591}\par
+\Us1071\ET1072.\fi
+
+\M{1717}
+\Y\B\4\D$\\{str\_592}$ \5
+\.{"lastbox"}\par
+\Y\B\4\X1717:\.{"lastbox"}\X${}\E{}$\5
+\T{592}\par
+\Us1071\ET1072.\fi
+
+\M{1718}
+\Y\B\4\D$\\{str\_593}$ \5
+\.{"vtop"}\par
+\Y\B\4\X1718:\.{"vtop"}\X${}\E{}$\5
+\T{593}\par
+\Us1071\ET1072.\fi
+
+\M{1719}
+\Y\B\4\D$\\{str\_594}$ \5
+\.{"hbox"}\par
+\Y\B\4\X1719:\.{"hbox"}\X${}\E{}$\5
+\T{594}\par
+\Us1071\ET1072.\fi
+
+\M{1720}
+\Y\B\4\D$\\{str\_595}$ \5
+\.{"shipout"}\par
+\Y\B\4\X1720:\.{"shipout"}\X${}\E{}$\5
+\T{595}\par
+\Us1071\ET1072.\fi
+
+\M{1721}
+\Y\B\4\D$\\{str\_596}$ \5
+\.{"leaders"}\par
+\Y\B\4\X1721:\.{"leaders"}\X${}\E{}$\5
+\T{596}\par
+\Us1071\ET1072.\fi
+
+\M{1722}
+\Y\B\4\D$\\{str\_597}$ \5
+\.{"cleaders"}\par
+\Y\B\4\X1722:\.{"cleaders"}\X${}\E{}$\5
+\T{597}\par
+\Us1071\ET1072.\fi
+
+\M{1723}
+\Y\B\4\D$\\{str\_598}$ \5
+\.{"xleaders"}\par
+\Y\B\4\X1723:\.{"xleaders"}\X${}\E{}$\5
+\T{598}\par
+\Us1071\ET1072.\fi
+
+\M{1724}
+\Y\B\4\D$\\{str\_599}$ \5
+\.{"indent"}\par
+\Y\B\4\X1724:\.{"indent"}\X${}\E{}$\5
+\T{599}\par
+\Us1088\ET1089.\fi
+
+\M{1725}
+\Y\B\4\D$\\{str\_600}$ \5
+\.{"noindent"}\par
+\Y\B\4\X1725:\.{"noindent"}\X${}\E{}$\5
+\T{600}\par
+\Us1088\ET1089.\fi
+
+\M{1726}
+\Y\B\4\D$\\{str\_601}$ \5
+\.{"unpenalty"}\par
+\Y\B\4\X1726:\.{"unpenalty"}\X${}\E{}$\5
+\T{601}\par
+\Us1107\ET1108.\fi
+
+\M{1727}
+\Y\B\4\D$\\{str\_602}$ \5
+\.{"unkern"}\par
+\Y\B\4\X1727:\.{"unkern"}\X${}\E{}$\5
+\T{602}\par
+\Us1107\ET1108.\fi
+
+\M{1728}
+\Y\B\4\D$\\{str\_603}$ \5
+\.{"unskip"}\par
+\Y\B\4\X1728:\.{"unskip"}\X${}\E{}$\5
+\T{603}\par
+\Us1107\ET1108.\fi
+
+\M{1729}
+\Y\B\4\D$\\{str\_604}$ \5
+\.{"unhbox"}\par
+\Y\B\4\X1729:\.{"unhbox"}\X${}\E{}$\5
+\T{604}\par
+\Us1107\ET1108.\fi
+
+\M{1730}
+\Y\B\4\D$\\{str\_605}$ \5
+\.{"unhcopy"}\par
+\Y\B\4\X1730:\.{"unhcopy"}\X${}\E{}$\5
+\T{605}\par
+\Us1107\ET1108.\fi
+
+\M{1731}
+\Y\B\4\D$\\{str\_606}$ \5
+\.{"unvbox"}\par
+\Y\B\4\X1731:\.{"unvbox"}\X${}\E{}$\5
+\T{606}\par
+\Us1107\ET1108.\fi
+
+\M{1732}
+\Y\B\4\D$\\{str\_607}$ \5
+\.{"unvcopy"}\par
+\Y\B\4\X1732:\.{"unvcopy"}\X${}\E{}$\5
+\T{607}\par
+\Us1107\ET1108.\fi
+
+\M{1733}
+\Y\B\4\D$\\{str\_608}$ \5
+\.{"eqno"}\par
+\Y\B\4\X1733:\.{"eqno"}\X${}\E{}$\5
+\T{608}\par
+\Us1141\ET1143.\fi
+
+\M{1734}
+\Y\B\4\D$\\{str\_609}$ \5
+\.{"leqno"}\par
+\Y\B\4\X1734:\.{"leqno"}\X${}\E{}$\5
+\T{609}\par
+\Us1141\ET1143.\fi
+
+\M{1735}
+\Y\B\4\D$\\{str\_610}$ \5
+\.{"displaylimits"}\par
+\Y\B\4\X1735:\.{"displaylimits"}\X${}\E{}$\5
+\T{610}\par
+\Us1156\ET1157.\fi
+
+\M{1736}
+\Y\B\4\D$\\{str\_611}$ \5
+\.{"above"}\par
+\Y\B\4\X1736:\.{"above"}\X${}\E{}$\5
+\T{611}\par
+\Us1178\ET1179.\fi
+
+\M{1737}
+\Y\B\4\D$\\{str\_612}$ \5
+\.{"over"}\par
+\Y\B\4\X1737:\.{"over"}\X${}\E{}$\5
+\T{612}\par
+\Us1178\ET1179.\fi
+
+\M{1738}
+\Y\B\4\D$\\{str\_613}$ \5
+\.{"atop"}\par
+\Y\B\4\X1738:\.{"atop"}\X${}\E{}$\5
+\T{613}\par
+\Us1178\ET1179.\fi
+
+\M{1739}
+\Y\B\4\D$\\{str\_614}$ \5
+\.{"abovewithdelims"}\par
+\Y\B\4\X1739:\.{"abovewithdelims"}\X${}\E{}$\5
+\T{614}\par
+\Us1178\ET1179.\fi
+
+\M{1740}
+\Y\B\4\D$\\{str\_615}$ \5
+\.{"overwithdelims"}\par
+\Y\B\4\X1740:\.{"overwithdelims"}\X${}\E{}$\5
+\T{615}\par
+\Us1178\ET1179.\fi
+
+\M{1741}
+\Y\B\4\D$\\{str\_616}$ \5
+\.{"atopwithdelims"}\par
+\Y\B\4\X1741:\.{"atopwithdelims"}\X${}\E{}$\5
+\T{616}\par
+\Us1178\ET1179.\fi
+
+\M{1742}
+\Y\B\4\D$\\{str\_617}$ \5
+\.{"display"}\par
+\Y\B\4\X1742:\.{"display"}\X${}\E{}$\5
+\T{617}\par
+\U1200.\fi
+
+\M{1743}
+\Y\B\4\D$\\{str\_618}$ \5
+\.{"long"}\par
+\Y\B\4\X1743:\.{"long"}\X${}\E{}$\5
+\T{618}\par
+\Us1208, 1209, 1213\ETs1295.\fi
+
+\M{1744}
+\Y\B\4\D$\\{str\_619}$ \5
+\.{"outer"}\par
+\Y\B\4\X1744:\.{"outer"}\X${}\E{}$\5
+\T{619}\par
+\Us1208, 1209\ETs1213.\fi
+
+\M{1745}
+\Y\B\4\D$\\{str\_620}$ \5
+\.{"global"}\par
+\Y\B\4\X1745:\.{"global"}\X${}\E{}$\5
+\T{620}\par
+\Us1208\ET1209.\fi
+
+\M{1746}
+\Y\B\4\D$\\{str\_621}$ \5
+\.{"def"}\par
+\Y\B\4\X1746:\.{"def"}\X${}\E{}$\5
+\T{621}\par
+\Us1208\ET1209.\fi
+
+\M{1747}
+\Y\B\4\D$\\{str\_622}$ \5
+\.{"gdef"}\par
+\Y\B\4\X1747:\.{"gdef"}\X${}\E{}$\5
+\T{622}\par
+\Us1208\ET1209.\fi
+
+\M{1748}
+\Y\B\4\D$\\{str\_623}$ \5
+\.{"edef"}\par
+\Y\B\4\X1748:\.{"edef"}\X${}\E{}$\5
+\T{623}\par
+\Us1208\ET1209.\fi
+
+\M{1749}
+\Y\B\4\D$\\{str\_624}$ \5
+\.{"xdef"}\par
+\Y\B\4\X1749:\.{"xdef"}\X${}\E{}$\5
+\T{624}\par
+\Us1208\ET1209.\fi
+
+\M{1750}
+\Y\B\4\D$\\{str\_625}$ \5
+\.{"prefix"}\par
+\Y\B\4\X1750:\.{"prefix"}\X${}\E{}$\5
+\T{625}\par
+\U1211.\fi
+
+\M{1751}
+\Y\B\4\D$\\{str\_626}$ \5
+\.{"inaccessible"}\par
+\Y\B\4\X1751:\.{"inaccessible"}\X${}\E{}$\5
+\T{626}\par
+\U1216.\fi
+
+\M{1752}
+\Y\B\4\D$\\{str\_627}$ \5
+\.{"let"}\par
+\Y\B\4\X1752:\.{"let"}\X${}\E{}$\5
+\T{627}\par
+\Us1219\ET1220.\fi
+
+\M{1753}
+\Y\B\4\D$\\{str\_628}$ \5
+\.{"futurelet"}\par
+\Y\B\4\X1753:\.{"futurelet"}\X${}\E{}$\5
+\T{628}\par
+\Us1219\ET1220.\fi
+
+\M{1754}
+\Y\B\4\D$\\{str\_629}$ \5
+\.{"chardef"}\par
+\Y\B\4\X1754:\.{"chardef"}\X${}\E{}$\5
+\T{629}\par
+\Us1222\ET1223.\fi
+
+\M{1755}
+\Y\B\4\D$\\{str\_630}$ \5
+\.{"mathchardef"}\par
+\Y\B\4\X1755:\.{"mathchardef"}\X${}\E{}$\5
+\T{630}\par
+\Us1222\ET1223.\fi
+
+\M{1756}
+\Y\B\4\D$\\{str\_631}$ \5
+\.{"countdef"}\par
+\Y\B\4\X1756:\.{"countdef"}\X${}\E{}$\5
+\T{631}\par
+\Us1222\ET1223.\fi
+
+\M{1757}
+\Y\B\4\D$\\{str\_632}$ \5
+\.{"dimendef"}\par
+\Y\B\4\X1757:\.{"dimendef"}\X${}\E{}$\5
+\T{632}\par
+\Us1222\ET1223.\fi
+
+\M{1758}
+\Y\B\4\D$\\{str\_633}$ \5
+\.{"skipdef"}\par
+\Y\B\4\X1758:\.{"skipdef"}\X${}\E{}$\5
+\T{633}\par
+\Us1222\ET1223.\fi
+
+\M{1759}
+\Y\B\4\D$\\{str\_634}$ \5
+\.{"muskipdef"}\par
+\Y\B\4\X1759:\.{"muskipdef"}\X${}\E{}$\5
+\T{634}\par
+\Us1222\ET1223.\fi
+
+\M{1760}
+\Y\B\4\D$\\{str\_635}$ \5
+\.{"toksdef"}\par
+\Y\B\4\X1760:\.{"toksdef"}\X${}\E{}$\5
+\T{635}\par
+\Us1222\ET1223.\fi
+
+\M{1761}
+\Y\B\4\D$\\{str\_636}$ \5
+\.{"by"}\par
+\Y\B\4\X1761:\.{"by"}\X${}\E{}$\5
+\T{636}\par
+\U1236.\fi
+
+\M{1762}
+\Y\B\4\D$\\{str\_637}$ \5
+\.{"hyphenchar"}\par
+\Y\B\4\X1762:\.{"hyphenchar"}\X${}\E{}$\5
+\T{637}\par
+\Us1254\ET1255.\fi
+
+\M{1763}
+\Y\B\4\D$\\{str\_638}$ \5
+\.{"skewchar"}\par
+\Y\B\4\X1763:\.{"skewchar"}\X${}\E{}$\5
+\T{638}\par
+\Us1254\ET1255.\fi
+
+\M{1764}
+\Y\B\4\D$\\{str\_639}$ \5
+\.{"FONT"}\par
+\Y\B\4\X1764:\.{"FONT"}\X${}\E{}$\5
+\T{639}\par
+\U1257.\fi
+
+\M{1765}
+\Y\B\4\D$\\{str\_640}$ \5
+\.{"at"}\par
+\Y\B\4\X1765:\.{"at"}\X${}\E{}$\5
+\T{640}\par
+\U1258.\fi
+
+\M{1766}
+\Y\B\4\D$\\{str\_641}$ \5
+\.{"scaled"}\par
+\Y\B\4\X1766:\.{"scaled"}\X${}\E{}$\5
+\T{641}\par
+\U1258.\fi
+
+\M{1767}
+\Y\B\4\D$\\{str\_642}$ \5
+\.{"errorstopmode"}\par
+\Y\B\4\X1767:\.{"errorstopmode"}\X${}\E{}$\5
+\T{642}\par
+\Us1262\ET1263.\fi
+
+\M{1768}
+\Y\B\4\D$\\{str\_643}$ \5
+\.{"openin"}\par
+\Y\B\4\X1768:\.{"openin"}\X${}\E{}$\5
+\T{643}\par
+\Us1272\ET1273.\fi
+
+\M{1769}
+\Y\B\4\D$\\{str\_644}$ \5
+\.{"closein"}\par
+\Y\B\4\X1769:\.{"closein"}\X${}\E{}$\5
+\T{644}\par
+\Us1272\ET1273.\fi
+
+\M{1770}
+\Y\B\4\D$\\{str\_645}$ \5
+\.{"message"}\par
+\Y\B\4\X1770:\.{"message"}\X${}\E{}$\5
+\T{645}\par
+\Us1277\ET1278.\fi
+
+\M{1771}
+\Y\B\4\D$\\{str\_646}$ \5
+\.{"errmessage"}\par
+\Y\B\4\X1771:\.{"errmessage"}\X${}\E{}$\5
+\T{646}\par
+\Us1277\ET1278.\fi
+
+\M{1772}
+\Y\B\4\D$\\{str\_647}$ \5
+\.{"lowercase"}\par
+\Y\B\4\X1772:\.{"lowercase"}\X${}\E{}$\5
+\T{647}\par
+\Us1286\ET1287.\fi
+
+\M{1773}
+\Y\B\4\D$\\{str\_648}$ \5
+\.{"uppercase"}\par
+\Y\B\4\X1773:\.{"uppercase"}\X${}\E{}$\5
+\T{648}\par
+\Us1286\ET1287.\fi
+
+\M{1774}
+\Y\B\4\D$\\{str\_649}$ \5
+\.{"show"}\par
+\Y\B\4\X1774:\.{"show"}\X${}\E{}$\5
+\T{649}\par
+\Us1291\ET1292.\fi
+
+\M{1775}
+\Y\B\4\D$\\{str\_650}$ \5
+\.{"showbox"}\par
+\Y\B\4\X1775:\.{"showbox"}\X${}\E{}$\5
+\T{650}\par
+\Us1291\ET1292.\fi
+
+\M{1776}
+\Y\B\4\D$\\{str\_651}$ \5
+\.{"showthe"}\par
+\Y\B\4\X1776:\.{"showthe"}\X${}\E{}$\5
+\T{651}\par
+\Us1291\ET1292.\fi
+
+\M{1777}
+\Y\B\4\D$\\{str\_652}$ \5
+\.{"showlists"}\par
+\Y\B\4\X1777:\.{"showlists"}\X${}\E{}$\5
+\T{652}\par
+\Us1291\ET1292.\fi
+
+\M{1778}
+\Y\B\4\D$\\{str\_653}$ \5
+\.{"long\ macro"}\par
+\Y\B\4\X1778:\.{"long\ macro"}\X${}\E{}$\5
+\T{653}\par
+\U1295.\fi
+
+\M{1779}
+\Y\B\4\D$\\{str\_654}$ \5
+\.{"outer\ macro"}\par
+\Y\B\4\X1779:\.{"outer\ macro"}\X${}\E{}$\5
+\T{654}\par
+\U1295.\fi
+
+\M{1780}
+\Y\B\4\D$\\{str\_655}$ \5
+\.{"outer\ endtemplate"}\par
+\Y\B\4\X1780:\.{"outer\ endtemplate"}\X${}\E{}$\5
+\T{655}\par
+\U1295.\fi
+
+\M{1781}
+\Y\B\4\D$\\{str\_656}$ \5
+\.{"\ (INITEX)"}\par
+\Y\B\4\X1781:\.{"\ (INITEX)"}\X${}\E{}$\5
+\T{656}\par
+\U1301.\fi
+
+\M{1782}
+\Y\B\4\D$\\{str\_657}$ \5
+\.{"end\ occurred\ "}\par
+\Y\B\4\X1782:\.{"end\ occurred\ "}\X${}\E{}$\5
+\T{657}\par
+\U1335.\fi
+
+\M{1783}
+\Y\B\4\D$\\{str\_658}$ \5
+\.{"openout"}\par
+\Y\B\4\X1783:\.{"openout"}\X${}\E{}$\5
+\T{658}\par
+\Us1344, 1346\ETs1356.\fi
+
+\M{1784}
+\Y\B\4\D$\\{str\_659}$ \5
+\.{"closeout"}\par
+\Y\B\4\X1784:\.{"closeout"}\X${}\E{}$\5
+\T{659}\par
+\Us1344, 1346\ETs1356.\fi
+
+\M{1785}
+\Y\B\4\D$\\{str\_660}$ \5
+\.{"special"}\par
+\Y\B\4\X1785:\.{"special"}\X${}\E{}$\5
+\T{660}\par
+\Us1344, 1346\ETs1356.\fi
+
+\M{1786}
+\Y\B\4\D$\\{str\_661}$ \5
+\.{"immediate"}\par
+\Y\B\4\X1786:\.{"immediate"}\X${}\E{}$\5
+\T{661}\par
+\Us1344\ET1346.\fi
+
+\M{1787}
+\Y\B\4\D$\\{str\_662}$ \5
+\.{"setlanguage"}\par
+\Y\B\4\X1787:\.{"setlanguage"}\X${}\E{}$\5
+\T{662}\par
+\Us1344, 1346\ETs1356.\fi
+
+\M{1788}
+\Y\B\4\D$\\{str\_663}$ \5
+\.{"ext1"}\par
+\Y\B\4\X1788:\.{"ext1"}\X${}\E{}$\5
+\T{663}\par
+\U1348.\fi
+
+\M{1789}
+\Y\B\4\D$\\{str\_664}$ \5
+\.{"ext2"}\par
+\Y\B\4\X1789:\.{"ext2"}\X${}\E{}$\5
+\T{664}\par
+\U1357.\fi
+
+\M{1790}
+\Y\B\4\D$\\{str\_665}$ \5
+\.{"ext3"}\par
+\Y\B\4\X1790:\.{"ext3"}\X${}\E{}$\5
+\T{665}\par
+\U1358.\fi
+
+\M{1791}
+\Y\B\4\D$\\{str\_666}$ \5
+\.{"endwrite"}\par
+\Y\B\4\X1791:\.{"endwrite"}\X${}\E{}$\5
+\T{666}\par
+\U1369.\fi
+
+\M{1792}
+\Y\B\4\D$\\{str\_667}$ \5
+\.{"ext4"}\par
+\Y\B\4\X1792:\.{"ext4"}\X${}\E{}$\5
+\T{667}\par
+\U1373.\fi
+
+\M{1793}All the above strings together make up the string pool.
+\Y\B\4\X1793:\\{str\_pool} initialization\X${}\E{}$\6
+\\{str\_0\_255}\\{str\_256}\\{str\_257}\\{str\_258}\\{str\_259}\\{str\_260}\\{str\_261}\\{str\_262}\\{str\_263}\6
+\\{str\_264}\\{str\_265}\\{str\_266}\\{str\_267}\\{str\_268}\\{str\_269}\\{str\_270}\\{str\_271}\6
+\\{str\_272}\\{str\_273}\\{str\_274}\\{str\_275}\\{str\_276}\\{str\_277}\\{str\_278}\\{str\_279}\6
+\\{str\_280}\\{str\_281}\\{str\_282}\\{str\_283}\\{str\_284}\\{str\_285}\\{str\_286}\\{str\_287}\6
+\\{str\_288}\\{str\_289}\\{str\_290}\\{str\_291}\\{str\_292}\\{str\_293}\\{str\_294}\\{str\_295}\6
+\\{str\_296}\\{str\_297}\\{str\_298}\\{str\_299}\\{str\_300}\\{str\_301}\\{str\_302}\\{str\_303}\6
+\\{str\_304}\\{str\_305}\\{str\_306}\\{str\_307}\\{str\_308}\\{str\_309}\\{str\_310}\\{str\_311}\6
+\\{str\_312}\\{str\_313}\\{str\_314}\\{str\_315}\\{str\_316}\\{str\_317}\\{str\_318}\\{str\_319}\6
+\\{str\_320}\\{str\_321}\\{str\_322}\\{str\_323}\\{str\_324}\\{str\_325}\\{str\_326}\\{str\_327}\6
+\\{str\_328}\\{str\_329}\\{str\_330}\\{str\_331}\\{str\_332}\\{str\_333}\\{str\_334}\\{str\_335}\6
+\\{str\_336}\\{str\_337}\\{str\_338}\\{str\_339}\\{str\_340}\\{str\_341}\\{str\_342}\\{str\_343}\6
+\\{str\_344}\\{str\_345}\\{str\_346}\\{str\_347}\\{str\_348}\\{str\_349}\\{str\_350}\\{str\_351}\6
+\\{str\_352}\\{str\_353}\\{str\_354}\\{str\_355}\\{str\_356}\\{str\_357}\\{str\_358}\\{str\_359}\6
+\\{str\_360}\\{str\_361}\\{str\_362}\\{str\_363}\\{str\_364}\\{str\_365}\\{str\_366}\\{str\_367}\6
+\\{str\_368}\\{str\_369}\\{str\_370}\\{str\_371}\\{str\_372}\\{str\_373}\\{str\_374}\\{str\_375}\6
+\\{str\_376}\\{str\_377}\\{str\_378}\\{str\_379}\\{str\_380}\\{str\_381}\\{str\_382}\\{str\_383}\6
+\\{str\_384}\\{str\_385}\\{str\_386}\\{str\_387}\\{str\_388}\\{str\_389}\\{str\_390}\\{str\_391}\6
+\\{str\_392}\\{str\_393}\\{str\_394}\\{str\_395}\\{str\_396}\\{str\_397}\\{str\_398}\\{str\_399}\6
+\\{str\_400}\\{str\_401}\\{str\_402}\\{str\_403}\\{str\_404}\\{str\_405}\\{str\_406}\\{str\_407}\6
+\\{str\_408}\\{str\_409}\\{str\_410}\\{str\_411}\\{str\_412}\\{str\_413}\\{str\_414}\\{str\_415}\6
+\\{str\_416}\\{str\_417}\\{str\_418}\\{str\_419}\\{str\_420}\\{str\_421}\\{str\_422}\\{str\_423}\6
+\\{str\_424}\\{str\_425}\\{str\_426}\\{str\_427}\\{str\_428}\\{str\_429}\\{str\_430}\\{str\_431}\6
+\\{str\_432}\\{str\_433}\\{str\_434}\\{str\_435}\\{str\_436}\\{str\_437}\\{str\_438}\\{str\_439}\6
+\\{str\_440}\\{str\_441}\\{str\_442}\\{str\_443}\\{str\_444}\\{str\_445}\\{str\_446}\\{str\_447}\6
+\\{str\_448}\\{str\_449}\\{str\_450}\\{str\_451}\\{str\_452}\\{str\_453}\\{str\_454}\\{str\_455}\6
+\\{str\_456}\\{str\_457}\\{str\_458}\\{str\_459}\\{str\_460}\\{str\_461}\\{str\_462}\\{str\_463}\6
+\\{str\_464}\\{str\_465}\\{str\_466}\\{str\_467}\\{str\_468}\\{str\_469}\\{str\_470}\\{str\_471}\6
+\\{str\_472}\\{str\_473}\\{str\_474}\\{str\_475}\\{str\_476}\\{str\_477}\\{str\_478}\\{str\_479}\6
+\\{str\_480}\\{str\_481}\\{str\_482}\\{str\_483}\\{str\_484}\\{str\_485}\\{str\_486}\\{str\_487}\6
+\\{str\_488}\\{str\_489}\\{str\_490}\\{str\_491}\\{str\_492}\\{str\_493}\\{str\_494}\\{str\_495}\6
+\\{str\_496}\\{str\_497}\\{str\_498}\\{str\_499}\\{str\_500}\\{str\_501}\\{str\_502}\\{str\_503}\6
+\\{str\_504}\\{str\_505}\\{str\_506}\\{str\_507}\\{str\_508}\\{str\_509}\\{str\_510}\\{str\_511}\6
+\\{str\_512}\\{str\_513}\\{str\_514}\\{str\_515}\\{str\_516}\\{str\_517}\\{str\_518}\\{str\_519}\6
+\\{str\_520}\\{str\_521}\\{str\_522}\\{str\_523}\\{str\_524}\\{str\_525}\\{str\_526}\\{str\_527}\6
+\\{str\_528}\\{str\_529}\\{str\_530}\\{str\_531}\\{str\_532}\\{str\_533}\\{str\_534}\\{str\_535}\6
+\\{str\_536}\\{str\_537}\\{str\_538}\\{str\_539}\\{str\_540}\\{str\_541}\\{str\_542}\\{str\_543}\6
+\\{str\_544}\\{str\_545}\\{str\_546}\\{str\_547}\\{str\_548}\\{str\_549}\\{str\_550}\\{str\_551}\6
+\\{str\_552}\\{str\_553}\\{str\_554}\\{str\_555}\\{str\_556}\\{str\_557}\\{str\_558}\\{str\_559}\6
+\\{str\_560}\\{str\_561}\\{str\_562}\\{str\_563}\\{str\_564}\\{str\_565}\\{str\_566}\\{str\_567}\6
+\\{str\_568}\\{str\_569}\\{str\_570}\\{str\_571}\\{str\_572}\\{str\_573}\\{str\_574}\\{str\_575}\6
+\\{str\_576}\\{str\_577}\\{str\_578}\\{str\_579}\\{str\_580}\\{str\_581}\\{str\_582}\\{str\_583}\6
+\\{str\_584}\\{str\_585}\\{str\_586}\\{str\_587}\\{str\_588}\\{str\_589}\\{str\_590}\\{str\_591}\6
+\\{str\_592}\\{str\_593}\\{str\_594}\\{str\_595}\\{str\_596}\\{str\_597}\\{str\_598}\\{str\_599}\6
+\\{str\_600}\\{str\_601}\\{str\_602}\\{str\_603}\\{str\_604}\\{str\_605}\\{str\_606}\\{str\_607}\6
+\\{str\_608}\\{str\_609}\\{str\_610}\\{str\_611}\\{str\_612}\\{str\_613}\\{str\_614}\\{str\_615}\6
+\\{str\_616}\\{str\_617}\\{str\_618}\\{str\_619}\\{str\_620}\\{str\_621}\\{str\_622}\\{str\_623}\6
+\\{str\_624}\\{str\_625}\\{str\_626}\\{str\_627}\\{str\_628}\\{str\_629}\\{str\_630}\\{str\_631}\6
+\\{str\_632}\\{str\_633}\\{str\_634}\\{str\_635}\\{str\_636}\\{str\_637}\\{str\_638}\\{str\_639}\6
+\\{str\_640}\\{str\_641}\\{str\_642}\\{str\_643}\\{str\_644}\\{str\_645}\\{str\_646}\\{str\_647}\6
+\\{str\_648}\\{str\_649}\\{str\_650}\\{str\_651}\\{str\_652}\\{str\_653}\\{str\_654}\\{str\_655}\6
+\\{str\_656}\\{str\_657}\\{str\_658}\\{str\_659}\\{str\_660}\\{str\_661}\\{str\_662}\\{str\_663}\6
+\\{str\_664}\\{str\_665}\\{str\_666}\\{str\_667}\par
+\U39.\fi
+
+\M{1794}\B\X1794:\\{str\_start} initialization\X${}\E{}$\6
+$\\{str\_start\_0\_255}\\{str\_start\_256},\39\\{str\_start\_257},\39\\{str\_start\_258},\39\\{str\_start\_259},\39\\{str\_start\_260},\39\\{str\_start\_261},\39\\{str\_start\_262},\39\\{str\_start\_263},\39\\{str\_start\_264},\39\\{str\_start\_265},\39%
+\\{str\_start\_266},\39\\{str\_start\_267},\39\\{str\_start\_268},\39\\{str\_start\_269},\39\\{str\_start\_270},\39\\{str\_start\_271},\39\\{str\_start\_272},\39\\{str\_start\_273},\39\\{str\_start\_274},\39\\{str\_start\_275},\39\\{str\_start\_276},\39%
+\\{str\_start\_277},\39\\{str\_start\_278},\39\\{str\_start\_279},\39\\{str\_start\_280},\39\\{str\_start\_281},\39\\{str\_start\_282},\39\\{str\_start\_283},\39\\{str\_start\_284},\39\\{str\_start\_285},\39\\{str\_start\_286},\39\\{str\_start\_287},\39%
+\\{str\_start\_288},\39\\{str\_start\_289},\39\\{str\_start\_290},\39\\{str\_start\_291},\39\\{str\_start\_292},\39\\{str\_start\_293},\39\\{str\_start\_294},\39\\{str\_start\_295},\39\\{str\_start\_296},\39\\{str\_start\_297},\39\\{str\_start\_298},\39%
+\\{str\_start\_299},\39\\{str\_start\_300},\39\\{str\_start\_301},\39\\{str\_start\_302},\39\\{str\_start\_303},\39\\{str\_start\_304},\39\\{str\_start\_305},\39\\{str\_start\_306},\39\\{str\_start\_307},\39\\{str\_start\_308},\39\\{str\_start\_309},\39%
+\\{str\_start\_310},\39\\{str\_start\_311},\39\\{str\_start\_312},\39\\{str\_start\_313},\39\\{str\_start\_314},\39\\{str\_start\_315},\39\\{str\_start\_316},\39\\{str\_start\_317},\39\\{str\_start\_318},\39\\{str\_start\_319},\39\\{str\_start\_320},\39%
+\\{str\_start\_321},\39\\{str\_start\_322},\39\\{str\_start\_323},\39\\{str\_start\_324},\39\\{str\_start\_325},\39\\{str\_start\_326},\39\\{str\_start\_327},\39\\{str\_start\_328},\39\\{str\_start\_329},\39\\{str\_start\_330},\39\\{str\_start\_331},\39%
+\\{str\_start\_332},\39\\{str\_start\_333},\39\\{str\_start\_334},\39\\{str\_start\_335},\39\\{str\_start\_336},\39\\{str\_start\_337},\39\\{str\_start\_338},\39\\{str\_start\_339},\39\\{str\_start\_340},\39\\{str\_start\_341},\39\\{str\_start\_342},\39%
+\\{str\_start\_343},\39\\{str\_start\_344},\39\\{str\_start\_345},\39\\{str\_start\_346},\39\\{str\_start\_347},\39\\{str\_start\_348},\39\\{str\_start\_349},\39\\{str\_start\_350},\39\\{str\_start\_351},\39\\{str\_start\_352},\39\\{str\_start\_353},\39%
+\\{str\_start\_354},\39\\{str\_start\_355},\39\\{str\_start\_356},\39\\{str\_start\_357},\39\\{str\_start\_358},\39\\{str\_start\_359},\39\\{str\_start\_360},\39\\{str\_start\_361},\39\\{str\_start\_362},\39\\{str\_start\_363},\39\\{str\_start\_364},\39%
+\\{str\_start\_365},\39\\{str\_start\_366},\39\\{str\_start\_367},\39\\{str\_start\_368},\39\\{str\_start\_369},\39\\{str\_start\_370},\39\\{str\_start\_371},\39\\{str\_start\_372},\39\\{str\_start\_373},\39\\{str\_start\_374},\39\\{str\_start\_375},\39%
+\\{str\_start\_376},\39\\{str\_start\_377},\39\\{str\_start\_378},\39\\{str\_start\_379},\39\\{str\_start\_380},\39\\{str\_start\_381},\39\\{str\_start\_382},\39\\{str\_start\_383},\39\\{str\_start\_384},\39\\{str\_start\_385},\39\\{str\_start\_386},\39%
+\\{str\_start\_387},\39\\{str\_start\_388},\39\\{str\_start\_389},\39\\{str\_start\_390},\39\\{str\_start\_391},\39\\{str\_start\_392},\39\\{str\_start\_393},\39\\{str\_start\_394},\39\\{str\_start\_395},\39\\{str\_start\_396},\39\\{str\_start\_397},\39%
+\\{str\_start\_398},\39\\{str\_start\_399},\39\\{str\_start\_400},\39\\{str\_start\_401},\39\\{str\_start\_402},\39\\{str\_start\_403},\39\\{str\_start\_404},\39\\{str\_start\_405},\39\\{str\_start\_406},\39\\{str\_start\_407},\39\\{str\_start\_408},\39%
+\\{str\_start\_409},\39\\{str\_start\_410},\39\\{str\_start\_411},\39\\{str\_start\_412},\39\\{str\_start\_413},\39\\{str\_start\_414},\39\\{str\_start\_415},\39\\{str\_start\_416},\39\\{str\_start\_417},\39\\{str\_start\_418},\39\\{str\_start\_419},\39%
+\\{str\_start\_420},\39\\{str\_start\_421},\39\\{str\_start\_422},\39\\{str\_start\_423},\39\\{str\_start\_424},\39\\{str\_start\_425},\39\\{str\_start\_426},\39\\{str\_start\_427},\39\\{str\_start\_428},\39\\{str\_start\_429},\39\\{str\_start\_430},\39%
+\\{str\_start\_431},\39\\{str\_start\_432},\39\\{str\_start\_433},\39\\{str\_start\_434},\39\\{str\_start\_435},\39\\{str\_start\_436},\39\\{str\_start\_437},\39\\{str\_start\_438},\39\\{str\_start\_439},\39\\{str\_start\_440},\39\\{str\_start\_441},\39%
+\\{str\_start\_442},\39\\{str\_start\_443},\39\\{str\_start\_444},\39\\{str\_start\_445},\39\\{str\_start\_446},\39\\{str\_start\_447},\39\\{str\_start\_448},\39\\{str\_start\_449},\39\\{str\_start\_450},\39\\{str\_start\_451},\39\\{str\_start\_452},\39%
+\\{str\_start\_453},\39\\{str\_start\_454},\39\\{str\_start\_455},\39\\{str\_start\_456},\39\\{str\_start\_457},\39\\{str\_start\_458},\39\\{str\_start\_459},\39\\{str\_start\_460},\39\\{str\_start\_461},\39\\{str\_start\_462},\39\\{str\_start\_463},\39%
+\\{str\_start\_464},\39\\{str\_start\_465},\39\\{str\_start\_466},\39\\{str\_start\_467},\39\\{str\_start\_468},\39\\{str\_start\_469},\39\\{str\_start\_470},\39\\{str\_start\_471},\39\\{str\_start\_472},\39\\{str\_start\_473},\39\\{str\_start\_474},\39%
+\\{str\_start\_475},\39\\{str\_start\_476},\39\\{str\_start\_477},\39\\{str\_start\_478},\39\\{str\_start\_479},\39\\{str\_start\_480},\39\\{str\_start\_481},\39\\{str\_start\_482},\39\\{str\_start\_483},\39\\{str\_start\_484},\39\\{str\_start\_485},\39%
+\\{str\_start\_486},\39\\{str\_start\_487},\39\\{str\_start\_488},\39\\{str\_start\_489},\39\\{str\_start\_490},\39\\{str\_start\_491},\39\\{str\_start\_492},\39\\{str\_start\_493},\39\\{str\_start\_494},\39\\{str\_start\_495},\39\\{str\_start\_496},\39%
+\\{str\_start\_497},\39\\{str\_start\_498},\39\\{str\_start\_499},\39\\{str\_start\_500},\39\\{str\_start\_501},\39\\{str\_start\_502},\39\\{str\_start\_503},\39\\{str\_start\_504},\39\\{str\_start\_505},\39\\{str\_start\_506},\39\\{str\_start\_507},\39%
+\\{str\_start\_508},\39\\{str\_start\_509},\39\\{str\_start\_510},\39\\{str\_start\_511},\39\\{str\_start\_512},\39\\{str\_start\_513},\39\\{str\_start\_514},\39\\{str\_start\_515},\39\\{str\_start\_516},\39\\{str\_start\_517},\39\\{str\_start\_518},\39%
+\\{str\_start\_519},\39\\{str\_start\_520},\39\\{str\_start\_521},\39\\{str\_start\_522},\39\\{str\_start\_523},\39\\{str\_start\_524},\39\\{str\_start\_525},\39\\{str\_start\_526},\39\\{str\_start\_527},\39\\{str\_start\_528},\39\\{str\_start\_529},\39%
+\\{str\_start\_530},\39\\{str\_start\_531},\39\\{str\_start\_532},\39\\{str\_start\_533},\39\\{str\_start\_534},\39\\{str\_start\_535},\39\\{str\_start\_536},\39\\{str\_start\_537},\39\\{str\_start\_538},\39\\{str\_start\_539},\39\\{str\_start\_540},\39%
+\\{str\_start\_541},\39\\{str\_start\_542},\39\\{str\_start\_543},\39\\{str\_start\_544},\39\\{str\_start\_545},\39\\{str\_start\_546},\39\\{str\_start\_547},\39\\{str\_start\_548},\39\\{str\_start\_549},\39\\{str\_start\_550},\39\\{str\_start\_551},\39%
+\\{str\_start\_552},\39\\{str\_start\_553},\39\\{str\_start\_554},\39\\{str\_start\_555},\39\\{str\_start\_556},\39\\{str\_start\_557},\39\\{str\_start\_558},\39\\{str\_start\_559},\39\\{str\_start\_560},\39\\{str\_start\_561},\39\\{str\_start\_562},\39%
+\\{str\_start\_563},\39\\{str\_start\_564},\39\\{str\_start\_565},\39\\{str\_start\_566},\39\\{str\_start\_567},\39\\{str\_start\_568},\39\\{str\_start\_569},\39\\{str\_start\_570},\39\\{str\_start\_571},\39\\{str\_start\_572},\39\\{str\_start\_573},\39%
+\\{str\_start\_574},\39\\{str\_start\_575},\39\\{str\_start\_576},\39\\{str\_start\_577},\39\\{str\_start\_578},\39\\{str\_start\_579},\39\\{str\_start\_580},\39\\{str\_start\_581},\39\\{str\_start\_582},\39\\{str\_start\_583},\39\\{str\_start\_584},\39%
+\\{str\_start\_585},\39\\{str\_start\_586},\39\\{str\_start\_587},\39\\{str\_start\_588},\39\\{str\_start\_589},\39\\{str\_start\_590},\39\\{str\_start\_591},\39\\{str\_start\_592},\39\\{str\_start\_593},\39\\{str\_start\_594},\39\\{str\_start\_595},\39%
+\\{str\_start\_596},\39\\{str\_start\_597},\39\\{str\_start\_598},\39\\{str\_start\_599},\39\\{str\_start\_600},\39\\{str\_start\_601},\39\\{str\_start\_602},\39\\{str\_start\_603},\39\\{str\_start\_604},\39\\{str\_start\_605},\39\\{str\_start\_606},\39%
+\\{str\_start\_607},\39\\{str\_start\_608},\39\\{str\_start\_609},\39\\{str\_start\_610},\39\\{str\_start\_611},\39\\{str\_start\_612},\39\\{str\_start\_613},\39\\{str\_start\_614},\39\\{str\_start\_615},\39\\{str\_start\_616},\39\\{str\_start\_617},\39%
+\\{str\_start\_618},\39\\{str\_start\_619},\39\\{str\_start\_620},\39\\{str\_start\_621},\39\\{str\_start\_622},\39\\{str\_start\_623},\39\\{str\_start\_624},\39\\{str\_start\_625},\39\\{str\_start\_626},\39\\{str\_start\_627},\39\\{str\_start\_628},\39%
+\\{str\_start\_629},\39\\{str\_start\_630},\39\\{str\_start\_631},\39\\{str\_start\_632},\39\\{str\_start\_633},\39\\{str\_start\_634},\39\\{str\_start\_635},\39\\{str\_start\_636},\39\\{str\_start\_637},\39\\{str\_start\_638},\39\\{str\_start\_639},\39%
+\\{str\_start\_640},\39\\{str\_start\_641},\39\\{str\_start\_642},\39\\{str\_start\_643},\39\\{str\_start\_644},\39\\{str\_start\_645},\39\\{str\_start\_646},\39\\{str\_start\_647},\39\\{str\_start\_648},\39\\{str\_start\_649},\39\\{str\_start\_650},\39%
+\\{str\_start\_651},\39\\{str\_start\_652},\39\\{str\_start\_653},\39\\{str\_start\_654},\39\\{str\_start\_655},\39\\{str\_start\_656},\39\\{str\_start\_657},\39\\{str\_start\_658},\39\\{str\_start\_659},\39\\{str\_start\_660},\39\\{str\_start\_661},\39%
+\\{str\_start\_662},\39\\{str\_start\_663},\39\\{str\_start\_664},\39\\{str\_start\_665},\39\\{str\_start\_666},\39\\{str\_start\_667},\39{}$\\{str\_start\_668}\par
+\U39.\fi
+
+\M{1795}We still need to define the start locations of the strings.
+\Y\B\4\X1795:prepare for string pool initialization\X${}\E{}$\6
+\&{typedef} \&{enum} ${}\{{}$\1\6
+${}\\{str\_start\_256}\K{}$\&{sizeof} (\\{str\_0\_255})${}-\T{1},\39\\{str\_start\_257}\K\\{str\_start\_256}+{}$\&{sizeof} (\\{str\_256})${}-\T{1},{}$\6
+\\{str\_start\_258}${}\K\\{str\_start\_257}+{}$\&{sizeof} (\\{str\_257})${}-\T{1},{}$\6
+\\{str\_start\_259}${}\K\\{str\_start\_258}+{}$\&{sizeof} (\\{str\_258})${}-\T{1},{}$\6
+\\{str\_start\_260}${}\K\\{str\_start\_259}+{}$\&{sizeof} (\\{str\_259})${}-\T{1},{}$\6
+\\{str\_start\_261}${}\K\\{str\_start\_260}+{}$\&{sizeof} (\\{str\_260})${}-\T{1},{}$\6
+\\{str\_start\_262}${}\K\\{str\_start\_261}+{}$\&{sizeof} (\\{str\_261})${}-\T{1},{}$\6
+\\{str\_start\_263}${}\K\\{str\_start\_262}+{}$\&{sizeof} (\\{str\_262})${}-\T{1},{}$\6
+\\{str\_start\_264}${}\K\\{str\_start\_263}+{}$\&{sizeof} (\\{str\_263})${}-\T{1},{}$\6
+\\{str\_start\_265}${}\K\\{str\_start\_264}+{}$\&{sizeof} (\\{str\_264})${}-\T{1},{}$\6
+\\{str\_start\_266}${}\K\\{str\_start\_265}+{}$\&{sizeof} (\\{str\_265})${}-\T{1},{}$\6
+\\{str\_start\_267}${}\K\\{str\_start\_266}+{}$\&{sizeof} (\\{str\_266})${}-\T{1},{}$\6
+\\{str\_start\_268}${}\K\\{str\_start\_267}+{}$\&{sizeof} (\\{str\_267})${}-\T{1},{}$\6
+\\{str\_start\_269}${}\K\\{str\_start\_268}+{}$\&{sizeof} (\\{str\_268})${}-\T{1},{}$\6
+\\{str\_start\_270}${}\K\\{str\_start\_269}+{}$\&{sizeof} (\\{str\_269})${}-\T{1},{}$\6
+\\{str\_start\_271}${}\K\\{str\_start\_270}+{}$\&{sizeof} (\\{str\_270})${}-\T{1},{}$\6
+\\{str\_start\_272}${}\K\\{str\_start\_271}+{}$\&{sizeof} (\\{str\_271})${}-\T{1},{}$\6
+\\{str\_start\_273}${}\K\\{str\_start\_272}+{}$\&{sizeof} (\\{str\_272})${}-\T{1},{}$\6
+\\{str\_start\_274}${}\K\\{str\_start\_273}+{}$\&{sizeof} (\\{str\_273})${}-\T{1},{}$\6
+\\{str\_start\_275}${}\K\\{str\_start\_274}+{}$\&{sizeof} (\\{str\_274})${}-\T{1},{}$\6
+\\{str\_start\_276}${}\K\\{str\_start\_275}+{}$\&{sizeof} (\\{str\_275})${}-\T{1},{}$\6
+\\{str\_start\_277}${}\K\\{str\_start\_276}+{}$\&{sizeof} (\\{str\_276})${}-\T{1},{}$\6
+\\{str\_start\_278}${}\K\\{str\_start\_277}+{}$\&{sizeof} (\\{str\_277})${}-\T{1},{}$\6
+\\{str\_start\_279}${}\K\\{str\_start\_278}+{}$\&{sizeof} (\\{str\_278})${}-\T{1},{}$\6
+\\{str\_start\_280}${}\K\\{str\_start\_279}+{}$\&{sizeof} (\\{str\_279})${}-\T{1},{}$\6
+\\{str\_start\_281}${}\K\\{str\_start\_280}+{}$\&{sizeof} (\\{str\_280})${}-\T{1},{}$\6
+\\{str\_start\_282}${}\K\\{str\_start\_281}+{}$\&{sizeof} (\\{str\_281})${}-\T{1},{}$\6
+\\{str\_start\_283}${}\K\\{str\_start\_282}+{}$\&{sizeof} (\\{str\_282})${}-\T{1},{}$\6
+\\{str\_start\_284}${}\K\\{str\_start\_283}+{}$\&{sizeof} (\\{str\_283})${}-\T{1},{}$\6
+\\{str\_start\_285}${}\K\\{str\_start\_284}+{}$\&{sizeof} (\\{str\_284})${}-\T{1},{}$\6
+\\{str\_start\_286}${}\K\\{str\_start\_285}+{}$\&{sizeof} (\\{str\_285})${}-\T{1},{}$\6
+\\{str\_start\_287}${}\K\\{str\_start\_286}+{}$\&{sizeof} (\\{str\_286})${}-\T{1},{}$\6
+\\{str\_start\_288}${}\K\\{str\_start\_287}+{}$\&{sizeof} (\\{str\_287})${}-\T{1},{}$\6
+\\{str\_start\_289}${}\K\\{str\_start\_288}+{}$\&{sizeof} (\\{str\_288})${}-\T{1},{}$\6
+\\{str\_start\_290}${}\K\\{str\_start\_289}+{}$\&{sizeof} (\\{str\_289})${}-\T{1},{}$\6
+\\{str\_start\_291}${}\K\\{str\_start\_290}+{}$\&{sizeof} (\\{str\_290})${}-\T{1},{}$\6
+\\{str\_start\_292}${}\K\\{str\_start\_291}+{}$\&{sizeof} (\\{str\_291})${}-\T{1},{}$\6
+\\{str\_start\_293}${}\K\\{str\_start\_292}+{}$\&{sizeof} (\\{str\_292})${}-\T{1},{}$\6
+\\{str\_start\_294}${}\K\\{str\_start\_293}+{}$\&{sizeof} (\\{str\_293})${}-\T{1},{}$\6
+\\{str\_start\_295}${}\K\\{str\_start\_294}+{}$\&{sizeof} (\\{str\_294})${}-\T{1},{}$\6
+\\{str\_start\_296}${}\K\\{str\_start\_295}+{}$\&{sizeof} (\\{str\_295})${}-\T{1},{}$\6
+\\{str\_start\_297}${}\K\\{str\_start\_296}+{}$\&{sizeof} (\\{str\_296})${}-\T{1},{}$\6
+\\{str\_start\_298}${}\K\\{str\_start\_297}+{}$\&{sizeof} (\\{str\_297})${}-\T{1},{}$\6
+\\{str\_start\_299}${}\K\\{str\_start\_298}+{}$\&{sizeof} (\\{str\_298})${}-\T{1},{}$\6
+\\{str\_start\_300}${}\K\\{str\_start\_299}+{}$\&{sizeof} (\\{str\_299})${}-\T{1},{}$\6
+\\{str\_start\_301}${}\K\\{str\_start\_300}+{}$\&{sizeof} (\\{str\_300})${}-\T{1},{}$\6
+\\{str\_start\_302}${}\K\\{str\_start\_301}+{}$\&{sizeof} (\\{str\_301})${}-\T{1},{}$\6
+\\{str\_start\_303}${}\K\\{str\_start\_302}+{}$\&{sizeof} (\\{str\_302})${}-\T{1},{}$\6
+\\{str\_start\_304}${}\K\\{str\_start\_303}+{}$\&{sizeof} (\\{str\_303})${}-\T{1},{}$\6
+\\{str\_start\_305}${}\K\\{str\_start\_304}+{}$\&{sizeof} (\\{str\_304})${}-\T{1},{}$\6
+\\{str\_start\_306}${}\K\\{str\_start\_305}+{}$\&{sizeof} (\\{str\_305})${}-\T{1},{}$\6
+\\{str\_start\_307}${}\K\\{str\_start\_306}+{}$\&{sizeof} (\\{str\_306})${}-\T{1},{}$\6
+\\{str\_start\_308}${}\K\\{str\_start\_307}+{}$\&{sizeof} (\\{str\_307})${}-\T{1},{}$\6
+\\{str\_start\_309}${}\K\\{str\_start\_308}+{}$\&{sizeof} (\\{str\_308})${}-\T{1},{}$\6
+\\{str\_start\_310}${}\K\\{str\_start\_309}+{}$\&{sizeof} (\\{str\_309})${}-\T{1},{}$\6
+\\{str\_start\_311}${}\K\\{str\_start\_310}+{}$\&{sizeof} (\\{str\_310})${}-\T{1},{}$\6
+\\{str\_start\_312}${}\K\\{str\_start\_311}+{}$\&{sizeof} (\\{str\_311})${}-\T{1},{}$\6
+\\{str\_start\_313}${}\K\\{str\_start\_312}+{}$\&{sizeof} (\\{str\_312})${}-\T{1},{}$\6
+\\{str\_start\_314}${}\K\\{str\_start\_313}+{}$\&{sizeof} (\\{str\_313})${}-\T{1},{}$\6
+\\{str\_start\_315}${}\K\\{str\_start\_314}+{}$\&{sizeof} (\\{str\_314})${}-\T{1},{}$\6
+\\{str\_start\_316}${}\K\\{str\_start\_315}+{}$\&{sizeof} (\\{str\_315})${}-\T{1},{}$\6
+\\{str\_start\_317}${}\K\\{str\_start\_316}+{}$\&{sizeof} (\\{str\_316})${}-\T{1},{}$\6
+\\{str\_start\_318}${}\K\\{str\_start\_317}+{}$\&{sizeof} (\\{str\_317})${}-\T{1},{}$\6
+\\{str\_start\_319}${}\K\\{str\_start\_318}+{}$\&{sizeof} (\\{str\_318})${}-\T{1},{}$\6
+\\{str\_start\_320}${}\K\\{str\_start\_319}+{}$\&{sizeof} (\\{str\_319})${}-\T{1},{}$\6
+\\{str\_start\_321}${}\K\\{str\_start\_320}+{}$\&{sizeof} (\\{str\_320})${}-\T{1},{}$\6
+\\{str\_start\_322}${}\K\\{str\_start\_321}+{}$\&{sizeof} (\\{str\_321})${}-\T{1},{}$\6
+\\{str\_start\_323}${}\K\\{str\_start\_322}+{}$\&{sizeof} (\\{str\_322})${}-\T{1},{}$\6
+\\{str\_start\_324}${}\K\\{str\_start\_323}+{}$\&{sizeof} (\\{str\_323})${}-\T{1},{}$\6
+\\{str\_start\_325}${}\K\\{str\_start\_324}+{}$\&{sizeof} (\\{str\_324})${}-\T{1},{}$\6
+\\{str\_start\_326}${}\K\\{str\_start\_325}+{}$\&{sizeof} (\\{str\_325})${}-\T{1},{}$\6
+\\{str\_start\_327}${}\K\\{str\_start\_326}+{}$\&{sizeof} (\\{str\_326})${}-\T{1},{}$\6
+\\{str\_start\_328}${}\K\\{str\_start\_327}+{}$\&{sizeof} (\\{str\_327})${}-\T{1},{}$\6
+\\{str\_start\_329}${}\K\\{str\_start\_328}+{}$\&{sizeof} (\\{str\_328})${}-\T{1},{}$\6
+\\{str\_start\_330}${}\K\\{str\_start\_329}+{}$\&{sizeof} (\\{str\_329})${}-\T{1},{}$\6
+\\{str\_start\_331}${}\K\\{str\_start\_330}+{}$\&{sizeof} (\\{str\_330})${}-\T{1},{}$\6
+\\{str\_start\_332}${}\K\\{str\_start\_331}+{}$\&{sizeof} (\\{str\_331})${}-\T{1},{}$\6
+\\{str\_start\_333}${}\K\\{str\_start\_332}+{}$\&{sizeof} (\\{str\_332})${}-\T{1},{}$\6
+\\{str\_start\_334}${}\K\\{str\_start\_333}+{}$\&{sizeof} (\\{str\_333})${}-\T{1},{}$\6
+\\{str\_start\_335}${}\K\\{str\_start\_334}+{}$\&{sizeof} (\\{str\_334})${}-\T{1},{}$\6
+\\{str\_start\_336}${}\K\\{str\_start\_335}+{}$\&{sizeof} (\\{str\_335})${}-\T{1},{}$\6
+\\{str\_start\_337}${}\K\\{str\_start\_336}+{}$\&{sizeof} (\\{str\_336})${}-\T{1},{}$\6
+\\{str\_start\_338}${}\K\\{str\_start\_337}+{}$\&{sizeof} (\\{str\_337})${}-\T{1},{}$\6
+\\{str\_start\_339}${}\K\\{str\_start\_338}+{}$\&{sizeof} (\\{str\_338})${}-\T{1},{}$\6
+\\{str\_start\_340}${}\K\\{str\_start\_339}+{}$\&{sizeof} (\\{str\_339})${}-\T{1},{}$\6
+\\{str\_start\_341}${}\K\\{str\_start\_340}+{}$\&{sizeof} (\\{str\_340})${}-\T{1},{}$\6
+\\{str\_start\_342}${}\K\\{str\_start\_341}+{}$\&{sizeof} (\\{str\_341})${}-\T{1},{}$\6
+\\{str\_start\_343}${}\K\\{str\_start\_342}+{}$\&{sizeof} (\\{str\_342})${}-\T{1},{}$\6
+\\{str\_start\_344}${}\K\\{str\_start\_343}+{}$\&{sizeof} (\\{str\_343})${}-\T{1},{}$\6
+\\{str\_start\_345}${}\K\\{str\_start\_344}+{}$\&{sizeof} (\\{str\_344})${}-\T{1},{}$\6
+\\{str\_start\_346}${}\K\\{str\_start\_345}+{}$\&{sizeof} (\\{str\_345})${}-\T{1},{}$\6
+\\{str\_start\_347}${}\K\\{str\_start\_346}+{}$\&{sizeof} (\\{str\_346})${}-\T{1},{}$\6
+\\{str\_start\_348}${}\K\\{str\_start\_347}+{}$\&{sizeof} (\\{str\_347})${}-\T{1},{}$\6
+\\{str\_start\_349}${}\K\\{str\_start\_348}+{}$\&{sizeof} (\\{str\_348})${}-\T{1},{}$\6
+\\{str\_start\_350}${}\K\\{str\_start\_349}+{}$\&{sizeof} (\\{str\_349})${}-\T{1},{}$\6
+\\{str\_start\_351}${}\K\\{str\_start\_350}+{}$\&{sizeof} (\\{str\_350})${}-\T{1},{}$\6
+\\{str\_start\_352}${}\K\\{str\_start\_351}+{}$\&{sizeof} (\\{str\_351})${}-\T{1},{}$\6
+\\{str\_start\_353}${}\K\\{str\_start\_352}+{}$\&{sizeof} (\\{str\_352})${}-\T{1},{}$\6
+\\{str\_start\_354}${}\K\\{str\_start\_353}+{}$\&{sizeof} (\\{str\_353})${}-\T{1},{}$\6
+\\{str\_start\_355}${}\K\\{str\_start\_354}+{}$\&{sizeof} (\\{str\_354})${}-\T{1},{}$\6
+\\{str\_start\_356}${}\K\\{str\_start\_355}+{}$\&{sizeof} (\\{str\_355})${}-\T{1},{}$\6
+\\{str\_start\_357}${}\K\\{str\_start\_356}+{}$\&{sizeof} (\\{str\_356})${}-\T{1},{}$\6
+\\{str\_start\_358}${}\K\\{str\_start\_357}+{}$\&{sizeof} (\\{str\_357})${}-\T{1},{}$\6
+\\{str\_start\_359}${}\K\\{str\_start\_358}+{}$\&{sizeof} (\\{str\_358})${}-\T{1},{}$\6
+\\{str\_start\_360}${}\K\\{str\_start\_359}+{}$\&{sizeof} (\\{str\_359})${}-\T{1},{}$\6
+\\{str\_start\_361}${}\K\\{str\_start\_360}+{}$\&{sizeof} (\\{str\_360})${}-\T{1},{}$\6
+\\{str\_start\_362}${}\K\\{str\_start\_361}+{}$\&{sizeof} (\\{str\_361})${}-\T{1},{}$\6
+\\{str\_start\_363}${}\K\\{str\_start\_362}+{}$\&{sizeof} (\\{str\_362})${}-\T{1},{}$\6
+\\{str\_start\_364}${}\K\\{str\_start\_363}+{}$\&{sizeof} (\\{str\_363})${}-\T{1},{}$\6
+\\{str\_start\_365}${}\K\\{str\_start\_364}+{}$\&{sizeof} (\\{str\_364})${}-\T{1},{}$\6
+\\{str\_start\_366}${}\K\\{str\_start\_365}+{}$\&{sizeof} (\\{str\_365})${}-\T{1},{}$\6
+\\{str\_start\_367}${}\K\\{str\_start\_366}+{}$\&{sizeof} (\\{str\_366})${}-\T{1},{}$\6
+\\{str\_start\_368}${}\K\\{str\_start\_367}+{}$\&{sizeof} (\\{str\_367})${}-\T{1},{}$\6
+\\{str\_start\_369}${}\K\\{str\_start\_368}+{}$\&{sizeof} (\\{str\_368})${}-\T{1},{}$\6
+\\{str\_start\_370}${}\K\\{str\_start\_369}+{}$\&{sizeof} (\\{str\_369})${}-\T{1},{}$\6
+\\{str\_start\_371}${}\K\\{str\_start\_370}+{}$\&{sizeof} (\\{str\_370})${}-\T{1},{}$\6
+\\{str\_start\_372}${}\K\\{str\_start\_371}+{}$\&{sizeof} (\\{str\_371})${}-\T{1},{}$\6
+\\{str\_start\_373}${}\K\\{str\_start\_372}+{}$\&{sizeof} (\\{str\_372})${}-\T{1},{}$\6
+\\{str\_start\_374}${}\K\\{str\_start\_373}+{}$\&{sizeof} (\\{str\_373})${}-\T{1},{}$\6
+\\{str\_start\_375}${}\K\\{str\_start\_374}+{}$\&{sizeof} (\\{str\_374})${}-\T{1},{}$\6
+\\{str\_start\_376}${}\K\\{str\_start\_375}+{}$\&{sizeof} (\\{str\_375})${}-\T{1},{}$\6
+\\{str\_start\_377}${}\K\\{str\_start\_376}+{}$\&{sizeof} (\\{str\_376})${}-\T{1},{}$\6
+\\{str\_start\_378}${}\K\\{str\_start\_377}+{}$\&{sizeof} (\\{str\_377})${}-\T{1},{}$\6
+\\{str\_start\_379}${}\K\\{str\_start\_378}+{}$\&{sizeof} (\\{str\_378})${}-\T{1},{}$\6
+\\{str\_start\_380}${}\K\\{str\_start\_379}+{}$\&{sizeof} (\\{str\_379})${}-\T{1},{}$\6
+\\{str\_start\_381}${}\K\\{str\_start\_380}+{}$\&{sizeof} (\\{str\_380})${}-\T{1},{}$\6
+\\{str\_start\_382}${}\K\\{str\_start\_381}+{}$\&{sizeof} (\\{str\_381})${}-\T{1},{}$\6
+\\{str\_start\_383}${}\K\\{str\_start\_382}+{}$\&{sizeof} (\\{str\_382})${}-\T{1},{}$\6
+\\{str\_start\_384}${}\K\\{str\_start\_383}+{}$\&{sizeof} (\\{str\_383})${}-\T{1},{}$\6
+\\{str\_start\_385}${}\K\\{str\_start\_384}+{}$\&{sizeof} (\\{str\_384})${}-\T{1},{}$\6
+\\{str\_start\_386}${}\K\\{str\_start\_385}+{}$\&{sizeof} (\\{str\_385})${}-\T{1},{}$\6
+\\{str\_start\_387}${}\K\\{str\_start\_386}+{}$\&{sizeof} (\\{str\_386})${}-\T{1},{}$\6
+\\{str\_start\_388}${}\K\\{str\_start\_387}+{}$\&{sizeof} (\\{str\_387})${}-\T{1},{}$\6
+\\{str\_start\_389}${}\K\\{str\_start\_388}+{}$\&{sizeof} (\\{str\_388})${}-\T{1},{}$\6
+\\{str\_start\_390}${}\K\\{str\_start\_389}+{}$\&{sizeof} (\\{str\_389})${}-\T{1},{}$\6
+\\{str\_start\_391}${}\K\\{str\_start\_390}+{}$\&{sizeof} (\\{str\_390})${}-\T{1},{}$\6
+\\{str\_start\_392}${}\K\\{str\_start\_391}+{}$\&{sizeof} (\\{str\_391})${}-\T{1},{}$\6
+\\{str\_start\_393}${}\K\\{str\_start\_392}+{}$\&{sizeof} (\\{str\_392})${}-\T{1},{}$\6
+\\{str\_start\_394}${}\K\\{str\_start\_393}+{}$\&{sizeof} (\\{str\_393})${}-\T{1},{}$\6
+\\{str\_start\_395}${}\K\\{str\_start\_394}+{}$\&{sizeof} (\\{str\_394})${}-\T{1},{}$\6
+\\{str\_start\_396}${}\K\\{str\_start\_395}+{}$\&{sizeof} (\\{str\_395})${}-\T{1},{}$\6
+\\{str\_start\_397}${}\K\\{str\_start\_396}+{}$\&{sizeof} (\\{str\_396})${}-\T{1},{}$\6
+\\{str\_start\_398}${}\K\\{str\_start\_397}+{}$\&{sizeof} (\\{str\_397})${}-\T{1},{}$\6
+\\{str\_start\_399}${}\K\\{str\_start\_398}+{}$\&{sizeof} (\\{str\_398})${}-\T{1},{}$\6
+\\{str\_start\_400}${}\K\\{str\_start\_399}+{}$\&{sizeof} (\\{str\_399})${}-\T{1},{}$\6
+\\{str\_start\_401}${}\K\\{str\_start\_400}+{}$\&{sizeof} (\\{str\_400})${}-\T{1},{}$\6
+\\{str\_start\_402}${}\K\\{str\_start\_401}+{}$\&{sizeof} (\\{str\_401})${}-\T{1},{}$\6
+\\{str\_start\_403}${}\K\\{str\_start\_402}+{}$\&{sizeof} (\\{str\_402})${}-\T{1},{}$\6
+\\{str\_start\_404}${}\K\\{str\_start\_403}+{}$\&{sizeof} (\\{str\_403})${}-\T{1},{}$\6
+\\{str\_start\_405}${}\K\\{str\_start\_404}+{}$\&{sizeof} (\\{str\_404})${}-\T{1},{}$\6
+\\{str\_start\_406}${}\K\\{str\_start\_405}+{}$\&{sizeof} (\\{str\_405})${}-\T{1},{}$\6
+\\{str\_start\_407}${}\K\\{str\_start\_406}+{}$\&{sizeof} (\\{str\_406})${}-\T{1},{}$\6
+\\{str\_start\_408}${}\K\\{str\_start\_407}+{}$\&{sizeof} (\\{str\_407})${}-\T{1},{}$\6
+\\{str\_start\_409}${}\K\\{str\_start\_408}+{}$\&{sizeof} (\\{str\_408})${}-\T{1},{}$\6
+\\{str\_start\_410}${}\K\\{str\_start\_409}+{}$\&{sizeof} (\\{str\_409})${}-\T{1},{}$\6
+\\{str\_start\_411}${}\K\\{str\_start\_410}+{}$\&{sizeof} (\\{str\_410})${}-\T{1},{}$\6
+\\{str\_start\_412}${}\K\\{str\_start\_411}+{}$\&{sizeof} (\\{str\_411})${}-\T{1},{}$\6
+\\{str\_start\_413}${}\K\\{str\_start\_412}+{}$\&{sizeof} (\\{str\_412})${}-\T{1},{}$\6
+\\{str\_start\_414}${}\K\\{str\_start\_413}+{}$\&{sizeof} (\\{str\_413})${}-\T{1},{}$\6
+\\{str\_start\_415}${}\K\\{str\_start\_414}+{}$\&{sizeof} (\\{str\_414})${}-\T{1},{}$\6
+\\{str\_start\_416}${}\K\\{str\_start\_415}+{}$\&{sizeof} (\\{str\_415})${}-\T{1},{}$\6
+\\{str\_start\_417}${}\K\\{str\_start\_416}+{}$\&{sizeof} (\\{str\_416})${}-\T{1},{}$\6
+\\{str\_start\_418}${}\K\\{str\_start\_417}+{}$\&{sizeof} (\\{str\_417})${}-\T{1},{}$\6
+\\{str\_start\_419}${}\K\\{str\_start\_418}+{}$\&{sizeof} (\\{str\_418})${}-\T{1},{}$\6
+\\{str\_start\_420}${}\K\\{str\_start\_419}+{}$\&{sizeof} (\\{str\_419})${}-\T{1},{}$\6
+\\{str\_start\_421}${}\K\\{str\_start\_420}+{}$\&{sizeof} (\\{str\_420})${}-\T{1},{}$\6
+\\{str\_start\_422}${}\K\\{str\_start\_421}+{}$\&{sizeof} (\\{str\_421})${}-\T{1},{}$\6
+\\{str\_start\_423}${}\K\\{str\_start\_422}+{}$\&{sizeof} (\\{str\_422})${}-\T{1},{}$\6
+\\{str\_start\_424}${}\K\\{str\_start\_423}+{}$\&{sizeof} (\\{str\_423})${}-\T{1},{}$\6
+\\{str\_start\_425}${}\K\\{str\_start\_424}+{}$\&{sizeof} (\\{str\_424})${}-\T{1},{}$\6
+\\{str\_start\_426}${}\K\\{str\_start\_425}+{}$\&{sizeof} (\\{str\_425})${}-\T{1},{}$\6
+\\{str\_start\_427}${}\K\\{str\_start\_426}+{}$\&{sizeof} (\\{str\_426})${}-\T{1},{}$\6
+\\{str\_start\_428}${}\K\\{str\_start\_427}+{}$\&{sizeof} (\\{str\_427})${}-\T{1},{}$\6
+\\{str\_start\_429}${}\K\\{str\_start\_428}+{}$\&{sizeof} (\\{str\_428})${}-\T{1},{}$\6
+\\{str\_start\_430}${}\K\\{str\_start\_429}+{}$\&{sizeof} (\\{str\_429})${}-\T{1},{}$\6
+\\{str\_start\_431}${}\K\\{str\_start\_430}+{}$\&{sizeof} (\\{str\_430})${}-\T{1},{}$\6
+\\{str\_start\_432}${}\K\\{str\_start\_431}+{}$\&{sizeof} (\\{str\_431})${}-\T{1},{}$\6
+\\{str\_start\_433}${}\K\\{str\_start\_432}+{}$\&{sizeof} (\\{str\_432})${}-\T{1},{}$\6
+\\{str\_start\_434}${}\K\\{str\_start\_433}+{}$\&{sizeof} (\\{str\_433})${}-\T{1},{}$\6
+\\{str\_start\_435}${}\K\\{str\_start\_434}+{}$\&{sizeof} (\\{str\_434})${}-\T{1},{}$\6
+\\{str\_start\_436}${}\K\\{str\_start\_435}+{}$\&{sizeof} (\\{str\_435})${}-\T{1},{}$\6
+\\{str\_start\_437}${}\K\\{str\_start\_436}+{}$\&{sizeof} (\\{str\_436})${}-\T{1},{}$\6
+\\{str\_start\_438}${}\K\\{str\_start\_437}+{}$\&{sizeof} (\\{str\_437})${}-\T{1},{}$\6
+\\{str\_start\_439}${}\K\\{str\_start\_438}+{}$\&{sizeof} (\\{str\_438})${}-\T{1},{}$\6
+\\{str\_start\_440}${}\K\\{str\_start\_439}+{}$\&{sizeof} (\\{str\_439})${}-\T{1},{}$\6
+\\{str\_start\_441}${}\K\\{str\_start\_440}+{}$\&{sizeof} (\\{str\_440})${}-\T{1},{}$\6
+\\{str\_start\_442}${}\K\\{str\_start\_441}+{}$\&{sizeof} (\\{str\_441})${}-\T{1},{}$\6
+\\{str\_start\_443}${}\K\\{str\_start\_442}+{}$\&{sizeof} (\\{str\_442})${}-\T{1},{}$\6
+\\{str\_start\_444}${}\K\\{str\_start\_443}+{}$\&{sizeof} (\\{str\_443})${}-\T{1},{}$\6
+\\{str\_start\_445}${}\K\\{str\_start\_444}+{}$\&{sizeof} (\\{str\_444})${}-\T{1},{}$\6
+\\{str\_start\_446}${}\K\\{str\_start\_445}+{}$\&{sizeof} (\\{str\_445})${}-\T{1},{}$\6
+\\{str\_start\_447}${}\K\\{str\_start\_446}+{}$\&{sizeof} (\\{str\_446})${}-\T{1},{}$\6
+\\{str\_start\_448}${}\K\\{str\_start\_447}+{}$\&{sizeof} (\\{str\_447})${}-\T{1},{}$\6
+\\{str\_start\_449}${}\K\\{str\_start\_448}+{}$\&{sizeof} (\\{str\_448})${}-\T{1},{}$\6
+\\{str\_start\_450}${}\K\\{str\_start\_449}+{}$\&{sizeof} (\\{str\_449})${}-\T{1},{}$\6
+\\{str\_start\_451}${}\K\\{str\_start\_450}+{}$\&{sizeof} (\\{str\_450})${}-\T{1},{}$\6
+\\{str\_start\_452}${}\K\\{str\_start\_451}+{}$\&{sizeof} (\\{str\_451})${}-\T{1},{}$\6
+\\{str\_start\_453}${}\K\\{str\_start\_452}+{}$\&{sizeof} (\\{str\_452})${}-\T{1},{}$\6
+\\{str\_start\_454}${}\K\\{str\_start\_453}+{}$\&{sizeof} (\\{str\_453})${}-\T{1},{}$\6
+\\{str\_start\_455}${}\K\\{str\_start\_454}+{}$\&{sizeof} (\\{str\_454})${}-\T{1},{}$\6
+\\{str\_start\_456}${}\K\\{str\_start\_455}+{}$\&{sizeof} (\\{str\_455})${}-\T{1},{}$\6
+\\{str\_start\_457}${}\K\\{str\_start\_456}+{}$\&{sizeof} (\\{str\_456})${}-\T{1},{}$\6
+\\{str\_start\_458}${}\K\\{str\_start\_457}+{}$\&{sizeof} (\\{str\_457})${}-\T{1},{}$\6
+\\{str\_start\_459}${}\K\\{str\_start\_458}+{}$\&{sizeof} (\\{str\_458})${}-\T{1},{}$\6
+\\{str\_start\_460}${}\K\\{str\_start\_459}+{}$\&{sizeof} (\\{str\_459})${}-\T{1},{}$\6
+\\{str\_start\_461}${}\K\\{str\_start\_460}+{}$\&{sizeof} (\\{str\_460})${}-\T{1},{}$\6
+\\{str\_start\_462}${}\K\\{str\_start\_461}+{}$\&{sizeof} (\\{str\_461})${}-\T{1},{}$\6
+\\{str\_start\_463}${}\K\\{str\_start\_462}+{}$\&{sizeof} (\\{str\_462})${}-\T{1},{}$\6
+\\{str\_start\_464}${}\K\\{str\_start\_463}+{}$\&{sizeof} (\\{str\_463})${}-\T{1},{}$\6
+\\{str\_start\_465}${}\K\\{str\_start\_464}+{}$\&{sizeof} (\\{str\_464})${}-\T{1},{}$\6
+\\{str\_start\_466}${}\K\\{str\_start\_465}+{}$\&{sizeof} (\\{str\_465})${}-\T{1},{}$\6
+\\{str\_start\_467}${}\K\\{str\_start\_466}+{}$\&{sizeof} (\\{str\_466})${}-\T{1},{}$\6
+\\{str\_start\_468}${}\K\\{str\_start\_467}+{}$\&{sizeof} (\\{str\_467})${}-\T{1},{}$\6
+\\{str\_start\_469}${}\K\\{str\_start\_468}+{}$\&{sizeof} (\\{str\_468})${}-\T{1},{}$\6
+\\{str\_start\_470}${}\K\\{str\_start\_469}+{}$\&{sizeof} (\\{str\_469})${}-\T{1},{}$\6
+\\{str\_start\_471}${}\K\\{str\_start\_470}+{}$\&{sizeof} (\\{str\_470})${}-\T{1},{}$\6
+\\{str\_start\_472}${}\K\\{str\_start\_471}+{}$\&{sizeof} (\\{str\_471})${}-\T{1},{}$\6
+\\{str\_start\_473}${}\K\\{str\_start\_472}+{}$\&{sizeof} (\\{str\_472})${}-\T{1},{}$\6
+\\{str\_start\_474}${}\K\\{str\_start\_473}+{}$\&{sizeof} (\\{str\_473})${}-\T{1},{}$\6
+\\{str\_start\_475}${}\K\\{str\_start\_474}+{}$\&{sizeof} (\\{str\_474})${}-\T{1},{}$\6
+\\{str\_start\_476}${}\K\\{str\_start\_475}+{}$\&{sizeof} (\\{str\_475})${}-\T{1},{}$\6
+\\{str\_start\_477}${}\K\\{str\_start\_476}+{}$\&{sizeof} (\\{str\_476})${}-\T{1},{}$\6
+\\{str\_start\_478}${}\K\\{str\_start\_477}+{}$\&{sizeof} (\\{str\_477})${}-\T{1},{}$\6
+\\{str\_start\_479}${}\K\\{str\_start\_478}+{}$\&{sizeof} (\\{str\_478})${}-\T{1},{}$\6
+\\{str\_start\_480}${}\K\\{str\_start\_479}+{}$\&{sizeof} (\\{str\_479})${}-\T{1},{}$\6
+\\{str\_start\_481}${}\K\\{str\_start\_480}+{}$\&{sizeof} (\\{str\_480})${}-\T{1},{}$\6
+\\{str\_start\_482}${}\K\\{str\_start\_481}+{}$\&{sizeof} (\\{str\_481})${}-\T{1},{}$\6
+\\{str\_start\_483}${}\K\\{str\_start\_482}+{}$\&{sizeof} (\\{str\_482})${}-\T{1},{}$\6
+\\{str\_start\_484}${}\K\\{str\_start\_483}+{}$\&{sizeof} (\\{str\_483})${}-\T{1},{}$\6
+\\{str\_start\_485}${}\K\\{str\_start\_484}+{}$\&{sizeof} (\\{str\_484})${}-\T{1},{}$\6
+\\{str\_start\_486}${}\K\\{str\_start\_485}+{}$\&{sizeof} (\\{str\_485})${}-\T{1},{}$\6
+\\{str\_start\_487}${}\K\\{str\_start\_486}+{}$\&{sizeof} (\\{str\_486})${}-\T{1},{}$\6
+\\{str\_start\_488}${}\K\\{str\_start\_487}+{}$\&{sizeof} (\\{str\_487})${}-\T{1},{}$\6
+\\{str\_start\_489}${}\K\\{str\_start\_488}+{}$\&{sizeof} (\\{str\_488})${}-\T{1},{}$\6
+\\{str\_start\_490}${}\K\\{str\_start\_489}+{}$\&{sizeof} (\\{str\_489})${}-\T{1},{}$\6
+\\{str\_start\_491}${}\K\\{str\_start\_490}+{}$\&{sizeof} (\\{str\_490})${}-\T{1},{}$\6
+\\{str\_start\_492}${}\K\\{str\_start\_491}+{}$\&{sizeof} (\\{str\_491})${}-\T{1},{}$\6
+\\{str\_start\_493}${}\K\\{str\_start\_492}+{}$\&{sizeof} (\\{str\_492})${}-\T{1},{}$\6
+\\{str\_start\_494}${}\K\\{str\_start\_493}+{}$\&{sizeof} (\\{str\_493})${}-\T{1},{}$\6
+\\{str\_start\_495}${}\K\\{str\_start\_494}+{}$\&{sizeof} (\\{str\_494})${}-\T{1},{}$\6
+\\{str\_start\_496}${}\K\\{str\_start\_495}+{}$\&{sizeof} (\\{str\_495})${}-\T{1},{}$\6
+\\{str\_start\_497}${}\K\\{str\_start\_496}+{}$\&{sizeof} (\\{str\_496})${}-\T{1},{}$\6
+\\{str\_start\_498}${}\K\\{str\_start\_497}+{}$\&{sizeof} (\\{str\_497})${}-\T{1},{}$\6
+\\{str\_start\_499}${}\K\\{str\_start\_498}+{}$\&{sizeof} (\\{str\_498})${}-\T{1},{}$\6
+\\{str\_start\_500}${}\K\\{str\_start\_499}+{}$\&{sizeof} (\\{str\_499})${}-\T{1},{}$\6
+\\{str\_start\_501}${}\K\\{str\_start\_500}+{}$\&{sizeof} (\\{str\_500})${}-\T{1},{}$\6
+\\{str\_start\_502}${}\K\\{str\_start\_501}+{}$\&{sizeof} (\\{str\_501})${}-\T{1},{}$\6
+\\{str\_start\_503}${}\K\\{str\_start\_502}+{}$\&{sizeof} (\\{str\_502})${}-\T{1},{}$\6
+\\{str\_start\_504}${}\K\\{str\_start\_503}+{}$\&{sizeof} (\\{str\_503})${}-\T{1},{}$\6
+\\{str\_start\_505}${}\K\\{str\_start\_504}+{}$\&{sizeof} (\\{str\_504})${}-\T{1},{}$\6
+\\{str\_start\_506}${}\K\\{str\_start\_505}+{}$\&{sizeof} (\\{str\_505})${}-\T{1},{}$\6
+\\{str\_start\_507}${}\K\\{str\_start\_506}+{}$\&{sizeof} (\\{str\_506})${}-\T{1},{}$\6
+\\{str\_start\_508}${}\K\\{str\_start\_507}+{}$\&{sizeof} (\\{str\_507})${}-\T{1},{}$\6
+\\{str\_start\_509}${}\K\\{str\_start\_508}+{}$\&{sizeof} (\\{str\_508})${}-\T{1},{}$\6
+\\{str\_start\_510}${}\K\\{str\_start\_509}+{}$\&{sizeof} (\\{str\_509})${}-\T{1},{}$\6
+\\{str\_start\_511}${}\K\\{str\_start\_510}+{}$\&{sizeof} (\\{str\_510})${}-\T{1},{}$\6
+\\{str\_start\_512}${}\K\\{str\_start\_511}+{}$\&{sizeof} (\\{str\_511})${}-\T{1},{}$\6
+\\{str\_start\_513}${}\K\\{str\_start\_512}+{}$\&{sizeof} (\\{str\_512})${}-\T{1},{}$\6
+\\{str\_start\_514}${}\K\\{str\_start\_513}+{}$\&{sizeof} (\\{str\_513})${}-\T{1},{}$\6
+\\{str\_start\_515}${}\K\\{str\_start\_514}+{}$\&{sizeof} (\\{str\_514})${}-\T{1},{}$\6
+\\{str\_start\_516}${}\K\\{str\_start\_515}+{}$\&{sizeof} (\\{str\_515})${}-\T{1},{}$\6
+\\{str\_start\_517}${}\K\\{str\_start\_516}+{}$\&{sizeof} (\\{str\_516})${}-\T{1},{}$\6
+\\{str\_start\_518}${}\K\\{str\_start\_517}+{}$\&{sizeof} (\\{str\_517})${}-\T{1},{}$\6
+\\{str\_start\_519}${}\K\\{str\_start\_518}+{}$\&{sizeof} (\\{str\_518})${}-\T{1},{}$\6
+\\{str\_start\_520}${}\K\\{str\_start\_519}+{}$\&{sizeof} (\\{str\_519})${}-\T{1},{}$\6
+\\{str\_start\_521}${}\K\\{str\_start\_520}+{}$\&{sizeof} (\\{str\_520})${}-\T{1},{}$\6
+\\{str\_start\_522}${}\K\\{str\_start\_521}+{}$\&{sizeof} (\\{str\_521})${}-\T{1},{}$\6
+\\{str\_start\_523}${}\K\\{str\_start\_522}+{}$\&{sizeof} (\\{str\_522})${}-\T{1},{}$\6
+\\{str\_start\_524}${}\K\\{str\_start\_523}+{}$\&{sizeof} (\\{str\_523})${}-\T{1},{}$\6
+\\{str\_start\_525}${}\K\\{str\_start\_524}+{}$\&{sizeof} (\\{str\_524})${}-\T{1},{}$\6
+\\{str\_start\_526}${}\K\\{str\_start\_525}+{}$\&{sizeof} (\\{str\_525})${}-\T{1},{}$\6
+\\{str\_start\_527}${}\K\\{str\_start\_526}+{}$\&{sizeof} (\\{str\_526})${}-\T{1},{}$\6
+\\{str\_start\_528}${}\K\\{str\_start\_527}+{}$\&{sizeof} (\\{str\_527})${}-\T{1},{}$\6
+\\{str\_start\_529}${}\K\\{str\_start\_528}+{}$\&{sizeof} (\\{str\_528})${}-\T{1},{}$\6
+\\{str\_start\_530}${}\K\\{str\_start\_529}+{}$\&{sizeof} (\\{str\_529})${}-\T{1},{}$\6
+\\{str\_start\_531}${}\K\\{str\_start\_530}+{}$\&{sizeof} (\\{str\_530})${}-\T{1},{}$\6
+\\{str\_start\_532}${}\K\\{str\_start\_531}+{}$\&{sizeof} (\\{str\_531})${}-\T{1},{}$\6
+\\{str\_start\_533}${}\K\\{str\_start\_532}+{}$\&{sizeof} (\\{str\_532})${}-\T{1},{}$\6
+\\{str\_start\_534}${}\K\\{str\_start\_533}+{}$\&{sizeof} (\\{str\_533})${}-\T{1},{}$\6
+\\{str\_start\_535}${}\K\\{str\_start\_534}+{}$\&{sizeof} (\\{str\_534})${}-\T{1},{}$\6
+\\{str\_start\_536}${}\K\\{str\_start\_535}+{}$\&{sizeof} (\\{str\_535})${}-\T{1},{}$\6
+\\{str\_start\_537}${}\K\\{str\_start\_536}+{}$\&{sizeof} (\\{str\_536})${}-\T{1},{}$\6
+\\{str\_start\_538}${}\K\\{str\_start\_537}+{}$\&{sizeof} (\\{str\_537})${}-\T{1},{}$\6
+\\{str\_start\_539}${}\K\\{str\_start\_538}+{}$\&{sizeof} (\\{str\_538})${}-\T{1},{}$\6
+\\{str\_start\_540}${}\K\\{str\_start\_539}+{}$\&{sizeof} (\\{str\_539})${}-\T{1},{}$\6
+\\{str\_start\_541}${}\K\\{str\_start\_540}+{}$\&{sizeof} (\\{str\_540})${}-\T{1},{}$\6
+\\{str\_start\_542}${}\K\\{str\_start\_541}+{}$\&{sizeof} (\\{str\_541})${}-\T{1},{}$\6
+\\{str\_start\_543}${}\K\\{str\_start\_542}+{}$\&{sizeof} (\\{str\_542})${}-\T{1},{}$\6
+\\{str\_start\_544}${}\K\\{str\_start\_543}+{}$\&{sizeof} (\\{str\_543})${}-\T{1},{}$\6
+\\{str\_start\_545}${}\K\\{str\_start\_544}+{}$\&{sizeof} (\\{str\_544})${}-\T{1},{}$\6
+\\{str\_start\_546}${}\K\\{str\_start\_545}+{}$\&{sizeof} (\\{str\_545})${}-\T{1},{}$\6
+\\{str\_start\_547}${}\K\\{str\_start\_546}+{}$\&{sizeof} (\\{str\_546})${}-\T{1},{}$\6
+\\{str\_start\_548}${}\K\\{str\_start\_547}+{}$\&{sizeof} (\\{str\_547})${}-\T{1},{}$\6
+\\{str\_start\_549}${}\K\\{str\_start\_548}+{}$\&{sizeof} (\\{str\_548})${}-\T{1},{}$\6
+\\{str\_start\_550}${}\K\\{str\_start\_549}+{}$\&{sizeof} (\\{str\_549})${}-\T{1},{}$\6
+\\{str\_start\_551}${}\K\\{str\_start\_550}+{}$\&{sizeof} (\\{str\_550})${}-\T{1},{}$\6
+\\{str\_start\_552}${}\K\\{str\_start\_551}+{}$\&{sizeof} (\\{str\_551})${}-\T{1},{}$\6
+\\{str\_start\_553}${}\K\\{str\_start\_552}+{}$\&{sizeof} (\\{str\_552})${}-\T{1},{}$\6
+\\{str\_start\_554}${}\K\\{str\_start\_553}+{}$\&{sizeof} (\\{str\_553})${}-\T{1},{}$\6
+\\{str\_start\_555}${}\K\\{str\_start\_554}+{}$\&{sizeof} (\\{str\_554})${}-\T{1},{}$\6
+\\{str\_start\_556}${}\K\\{str\_start\_555}+{}$\&{sizeof} (\\{str\_555})${}-\T{1},{}$\6
+\\{str\_start\_557}${}\K\\{str\_start\_556}+{}$\&{sizeof} (\\{str\_556})${}-\T{1},{}$\6
+\\{str\_start\_558}${}\K\\{str\_start\_557}+{}$\&{sizeof} (\\{str\_557})${}-\T{1},{}$\6
+\\{str\_start\_559}${}\K\\{str\_start\_558}+{}$\&{sizeof} (\\{str\_558})${}-\T{1},{}$\6
+\\{str\_start\_560}${}\K\\{str\_start\_559}+{}$\&{sizeof} (\\{str\_559})${}-\T{1},{}$\6
+\\{str\_start\_561}${}\K\\{str\_start\_560}+{}$\&{sizeof} (\\{str\_560})${}-\T{1},{}$\6
+\\{str\_start\_562}${}\K\\{str\_start\_561}+{}$\&{sizeof} (\\{str\_561})${}-\T{1},{}$\6
+\\{str\_start\_563}${}\K\\{str\_start\_562}+{}$\&{sizeof} (\\{str\_562})${}-\T{1},{}$\6
+\\{str\_start\_564}${}\K\\{str\_start\_563}+{}$\&{sizeof} (\\{str\_563})${}-\T{1},{}$\6
+\\{str\_start\_565}${}\K\\{str\_start\_564}+{}$\&{sizeof} (\\{str\_564})${}-\T{1},{}$\6
+\\{str\_start\_566}${}\K\\{str\_start\_565}+{}$\&{sizeof} (\\{str\_565})${}-\T{1},{}$\6
+\\{str\_start\_567}${}\K\\{str\_start\_566}+{}$\&{sizeof} (\\{str\_566})${}-\T{1},{}$\6
+\\{str\_start\_568}${}\K\\{str\_start\_567}+{}$\&{sizeof} (\\{str\_567})${}-\T{1},{}$\6
+\\{str\_start\_569}${}\K\\{str\_start\_568}+{}$\&{sizeof} (\\{str\_568})${}-\T{1},{}$\6
+\\{str\_start\_570}${}\K\\{str\_start\_569}+{}$\&{sizeof} (\\{str\_569})${}-\T{1},{}$\6
+\\{str\_start\_571}${}\K\\{str\_start\_570}+{}$\&{sizeof} (\\{str\_570})${}-\T{1},{}$\6
+\\{str\_start\_572}${}\K\\{str\_start\_571}+{}$\&{sizeof} (\\{str\_571})${}-\T{1},{}$\6
+\\{str\_start\_573}${}\K\\{str\_start\_572}+{}$\&{sizeof} (\\{str\_572})${}-\T{1},{}$\6
+\\{str\_start\_574}${}\K\\{str\_start\_573}+{}$\&{sizeof} (\\{str\_573})${}-\T{1},{}$\6
+\\{str\_start\_575}${}\K\\{str\_start\_574}+{}$\&{sizeof} (\\{str\_574})${}-\T{1},{}$\6
+\\{str\_start\_576}${}\K\\{str\_start\_575}+{}$\&{sizeof} (\\{str\_575})${}-\T{1},{}$\6
+\\{str\_start\_577}${}\K\\{str\_start\_576}+{}$\&{sizeof} (\\{str\_576})${}-\T{1},{}$\6
+\\{str\_start\_578}${}\K\\{str\_start\_577}+{}$\&{sizeof} (\\{str\_577})${}-\T{1},{}$\6
+\\{str\_start\_579}${}\K\\{str\_start\_578}+{}$\&{sizeof} (\\{str\_578})${}-\T{1},{}$\6
+\\{str\_start\_580}${}\K\\{str\_start\_579}+{}$\&{sizeof} (\\{str\_579})${}-\T{1},{}$\6
+\\{str\_start\_581}${}\K\\{str\_start\_580}+{}$\&{sizeof} (\\{str\_580})${}-\T{1},{}$\6
+\\{str\_start\_582}${}\K\\{str\_start\_581}+{}$\&{sizeof} (\\{str\_581})${}-\T{1},{}$\6
+\\{str\_start\_583}${}\K\\{str\_start\_582}+{}$\&{sizeof} (\\{str\_582})${}-\T{1},{}$\6
+\\{str\_start\_584}${}\K\\{str\_start\_583}+{}$\&{sizeof} (\\{str\_583})${}-\T{1},{}$\6
+\\{str\_start\_585}${}\K\\{str\_start\_584}+{}$\&{sizeof} (\\{str\_584})${}-\T{1},{}$\6
+\\{str\_start\_586}${}\K\\{str\_start\_585}+{}$\&{sizeof} (\\{str\_585})${}-\T{1},{}$\6
+\\{str\_start\_587}${}\K\\{str\_start\_586}+{}$\&{sizeof} (\\{str\_586})${}-\T{1},{}$\6
+\\{str\_start\_588}${}\K\\{str\_start\_587}+{}$\&{sizeof} (\\{str\_587})${}-\T{1},{}$\6
+\\{str\_start\_589}${}\K\\{str\_start\_588}+{}$\&{sizeof} (\\{str\_588})${}-\T{1},{}$\6
+\\{str\_start\_590}${}\K\\{str\_start\_589}+{}$\&{sizeof} (\\{str\_589})${}-\T{1},{}$\6
+\\{str\_start\_591}${}\K\\{str\_start\_590}+{}$\&{sizeof} (\\{str\_590})${}-\T{1},{}$\6
+\\{str\_start\_592}${}\K\\{str\_start\_591}+{}$\&{sizeof} (\\{str\_591})${}-\T{1},{}$\6
+\\{str\_start\_593}${}\K\\{str\_start\_592}+{}$\&{sizeof} (\\{str\_592})${}-\T{1},{}$\6
+\\{str\_start\_594}${}\K\\{str\_start\_593}+{}$\&{sizeof} (\\{str\_593})${}-\T{1},{}$\6
+\\{str\_start\_595}${}\K\\{str\_start\_594}+{}$\&{sizeof} (\\{str\_594})${}-\T{1},{}$\6
+\\{str\_start\_596}${}\K\\{str\_start\_595}+{}$\&{sizeof} (\\{str\_595})${}-\T{1},{}$\6
+\\{str\_start\_597}${}\K\\{str\_start\_596}+{}$\&{sizeof} (\\{str\_596})${}-\T{1},{}$\6
+\\{str\_start\_598}${}\K\\{str\_start\_597}+{}$\&{sizeof} (\\{str\_597})${}-\T{1},{}$\6
+\\{str\_start\_599}${}\K\\{str\_start\_598}+{}$\&{sizeof} (\\{str\_598})${}-\T{1},{}$\6
+\\{str\_start\_600}${}\K\\{str\_start\_599}+{}$\&{sizeof} (\\{str\_599})${}-\T{1},{}$\6
+\\{str\_start\_601}${}\K\\{str\_start\_600}+{}$\&{sizeof} (\\{str\_600})${}-\T{1},{}$\6
+\\{str\_start\_602}${}\K\\{str\_start\_601}+{}$\&{sizeof} (\\{str\_601})${}-\T{1},{}$\6
+\\{str\_start\_603}${}\K\\{str\_start\_602}+{}$\&{sizeof} (\\{str\_602})${}-\T{1},{}$\6
+\\{str\_start\_604}${}\K\\{str\_start\_603}+{}$\&{sizeof} (\\{str\_603})${}-\T{1},{}$\6
+\\{str\_start\_605}${}\K\\{str\_start\_604}+{}$\&{sizeof} (\\{str\_604})${}-\T{1},{}$\6
+\\{str\_start\_606}${}\K\\{str\_start\_605}+{}$\&{sizeof} (\\{str\_605})${}-\T{1},{}$\6
+\\{str\_start\_607}${}\K\\{str\_start\_606}+{}$\&{sizeof} (\\{str\_606})${}-\T{1},{}$\6
+\\{str\_start\_608}${}\K\\{str\_start\_607}+{}$\&{sizeof} (\\{str\_607})${}-\T{1},{}$\6
+\\{str\_start\_609}${}\K\\{str\_start\_608}+{}$\&{sizeof} (\\{str\_608})${}-\T{1},{}$\6
+\\{str\_start\_610}${}\K\\{str\_start\_609}+{}$\&{sizeof} (\\{str\_609})${}-\T{1},{}$\6
+\\{str\_start\_611}${}\K\\{str\_start\_610}+{}$\&{sizeof} (\\{str\_610})${}-\T{1},{}$\6
+\\{str\_start\_612}${}\K\\{str\_start\_611}+{}$\&{sizeof} (\\{str\_611})${}-\T{1},{}$\6
+\\{str\_start\_613}${}\K\\{str\_start\_612}+{}$\&{sizeof} (\\{str\_612})${}-\T{1},{}$\6
+\\{str\_start\_614}${}\K\\{str\_start\_613}+{}$\&{sizeof} (\\{str\_613})${}-\T{1},{}$\6
+\\{str\_start\_615}${}\K\\{str\_start\_614}+{}$\&{sizeof} (\\{str\_614})${}-\T{1},{}$\6
+\\{str\_start\_616}${}\K\\{str\_start\_615}+{}$\&{sizeof} (\\{str\_615})${}-\T{1},{}$\6
+\\{str\_start\_617}${}\K\\{str\_start\_616}+{}$\&{sizeof} (\\{str\_616})${}-\T{1},{}$\6
+\\{str\_start\_618}${}\K\\{str\_start\_617}+{}$\&{sizeof} (\\{str\_617})${}-\T{1},{}$\6
+\\{str\_start\_619}${}\K\\{str\_start\_618}+{}$\&{sizeof} (\\{str\_618})${}-\T{1},{}$\6
+\\{str\_start\_620}${}\K\\{str\_start\_619}+{}$\&{sizeof} (\\{str\_619})${}-\T{1},{}$\6
+\\{str\_start\_621}${}\K\\{str\_start\_620}+{}$\&{sizeof} (\\{str\_620})${}-\T{1},{}$\6
+\\{str\_start\_622}${}\K\\{str\_start\_621}+{}$\&{sizeof} (\\{str\_621})${}-\T{1},{}$\6
+\\{str\_start\_623}${}\K\\{str\_start\_622}+{}$\&{sizeof} (\\{str\_622})${}-\T{1},{}$\6
+\\{str\_start\_624}${}\K\\{str\_start\_623}+{}$\&{sizeof} (\\{str\_623})${}-\T{1},{}$\6
+\\{str\_start\_625}${}\K\\{str\_start\_624}+{}$\&{sizeof} (\\{str\_624})${}-\T{1},{}$\6
+\\{str\_start\_626}${}\K\\{str\_start\_625}+{}$\&{sizeof} (\\{str\_625})${}-\T{1},{}$\6
+\\{str\_start\_627}${}\K\\{str\_start\_626}+{}$\&{sizeof} (\\{str\_626})${}-\T{1},{}$\6
+\\{str\_start\_628}${}\K\\{str\_start\_627}+{}$\&{sizeof} (\\{str\_627})${}-\T{1},{}$\6
+\\{str\_start\_629}${}\K\\{str\_start\_628}+{}$\&{sizeof} (\\{str\_628})${}-\T{1},{}$\6
+\\{str\_start\_630}${}\K\\{str\_start\_629}+{}$\&{sizeof} (\\{str\_629})${}-\T{1},{}$\6
+\\{str\_start\_631}${}\K\\{str\_start\_630}+{}$\&{sizeof} (\\{str\_630})${}-\T{1},{}$\6
+\\{str\_start\_632}${}\K\\{str\_start\_631}+{}$\&{sizeof} (\\{str\_631})${}-\T{1},{}$\6
+\\{str\_start\_633}${}\K\\{str\_start\_632}+{}$\&{sizeof} (\\{str\_632})${}-\T{1},{}$\6
+\\{str\_start\_634}${}\K\\{str\_start\_633}+{}$\&{sizeof} (\\{str\_633})${}-\T{1},{}$\6
+\\{str\_start\_635}${}\K\\{str\_start\_634}+{}$\&{sizeof} (\\{str\_634})${}-\T{1},{}$\6
+\\{str\_start\_636}${}\K\\{str\_start\_635}+{}$\&{sizeof} (\\{str\_635})${}-\T{1},{}$\6
+\\{str\_start\_637}${}\K\\{str\_start\_636}+{}$\&{sizeof} (\\{str\_636})${}-\T{1},{}$\6
+\\{str\_start\_638}${}\K\\{str\_start\_637}+{}$\&{sizeof} (\\{str\_637})${}-\T{1},{}$\6
+\\{str\_start\_639}${}\K\\{str\_start\_638}+{}$\&{sizeof} (\\{str\_638})${}-\T{1},{}$\6
+\\{str\_start\_640}${}\K\\{str\_start\_639}+{}$\&{sizeof} (\\{str\_639})${}-\T{1},{}$\6
+\\{str\_start\_641}${}\K\\{str\_start\_640}+{}$\&{sizeof} (\\{str\_640})${}-\T{1},{}$\6
+\\{str\_start\_642}${}\K\\{str\_start\_641}+{}$\&{sizeof} (\\{str\_641})${}-\T{1},{}$\6
+\\{str\_start\_643}${}\K\\{str\_start\_642}+{}$\&{sizeof} (\\{str\_642})${}-\T{1},{}$\6
+\\{str\_start\_644}${}\K\\{str\_start\_643}+{}$\&{sizeof} (\\{str\_643})${}-\T{1},{}$\6
+\\{str\_start\_645}${}\K\\{str\_start\_644}+{}$\&{sizeof} (\\{str\_644})${}-\T{1},{}$\6
+\\{str\_start\_646}${}\K\\{str\_start\_645}+{}$\&{sizeof} (\\{str\_645})${}-\T{1},{}$\6
+\\{str\_start\_647}${}\K\\{str\_start\_646}+{}$\&{sizeof} (\\{str\_646})${}-\T{1},{}$\6
+\\{str\_start\_648}${}\K\\{str\_start\_647}+{}$\&{sizeof} (\\{str\_647})${}-\T{1},{}$\6
+\\{str\_start\_649}${}\K\\{str\_start\_648}+{}$\&{sizeof} (\\{str\_648})${}-\T{1},{}$\6
+\\{str\_start\_650}${}\K\\{str\_start\_649}+{}$\&{sizeof} (\\{str\_649})${}-\T{1},{}$\6
+\\{str\_start\_651}${}\K\\{str\_start\_650}+{}$\&{sizeof} (\\{str\_650})${}-\T{1},{}$\6
+\\{str\_start\_652}${}\K\\{str\_start\_651}+{}$\&{sizeof} (\\{str\_651})${}-\T{1},{}$\6
+\\{str\_start\_653}${}\K\\{str\_start\_652}+{}$\&{sizeof} (\\{str\_652})${}-\T{1},{}$\6
+\\{str\_start\_654}${}\K\\{str\_start\_653}+{}$\&{sizeof} (\\{str\_653})${}-\T{1},{}$\6
+\\{str\_start\_655}${}\K\\{str\_start\_654}+{}$\&{sizeof} (\\{str\_654})${}-\T{1},{}$\6
+\\{str\_start\_656}${}\K\\{str\_start\_655}+{}$\&{sizeof} (\\{str\_655})${}-\T{1},{}$\6
+\\{str\_start\_657}${}\K\\{str\_start\_656}+{}$\&{sizeof} (\\{str\_656})${}-\T{1},{}$\6
+\\{str\_start\_658}${}\K\\{str\_start\_657}+{}$\&{sizeof} (\\{str\_657})${}-\T{1},{}$\6
+\\{str\_start\_659}${}\K\\{str\_start\_658}+{}$\&{sizeof} (\\{str\_658})${}-\T{1},{}$\6
+\\{str\_start\_660}${}\K\\{str\_start\_659}+{}$\&{sizeof} (\\{str\_659})${}-\T{1},{}$\6
+\\{str\_start\_661}${}\K\\{str\_start\_660}+{}$\&{sizeof} (\\{str\_660})${}-\T{1},{}$\6
+\\{str\_start\_662}${}\K\\{str\_start\_661}+{}$\&{sizeof} (\\{str\_661})${}-\T{1},{}$\6
+\\{str\_start\_663}${}\K\\{str\_start\_662}+{}$\&{sizeof} (\\{str\_662})${}-\T{1},{}$\6
+\\{str\_start\_664}${}\K\\{str\_start\_663}+{}$\&{sizeof} (\\{str\_663})${}-\T{1},{}$\6
+\\{str\_start\_665}${}\K\\{str\_start\_664}+{}$\&{sizeof} (\\{str\_664})${}-\T{1},{}$\6
+\\{str\_start\_666}${}\K\\{str\_start\_665}+{}$\&{sizeof} (\\{str\_665})${}-\T{1},{}$\6
+\\{str\_start\_667}${}\K\\{str\_start\_666}+{}$\&{sizeof} (\\{str\_666})${}-\T{1},{}$\6
+\\{str\_start\_668}${}\K\\{str\_start\_667}+{}$\&{sizeof} (\\{str\_667})${}-\T{1},{}$\6
+\\{str\_start\_end}\2\6
+${}\}{}$ \&{str\_starts};\par
+\U39.\fi
+
+\M{1796}\B\X1796:\\{pool\_ptr} initialization\X${}\E{}$\6
+\\{str\_start\_668}\par
+\U39.\fi
+
+\M{1797}\B\X1797:\\{str\_ptr} initialization\X${}\E{}$\6
+\T{668}\par
+\U39.\fi
+
+\N{1}{1798}Index.
+Here is where you can find all uses of each identifier in the program,
+with underlined entries pointing to where the identifier was defined.
+If the identifier is only one letter long, however, you get to see only
+the underlined entries. {\sl All references are to section numbers instead of
+page numbers.}
+
+This index also lists error messages and other aspects of the program
+that you might want to look up some day. For example, the entry
+for ``system dependencies'' lists all sections that should receive
+special attention from people who are installing \TeX\ in a new
+operating environment. A list of various things that can't happen appears
+under ``this can't happen''. Approximately 40 sections are listed under
+``inner loop''; these account for about 60\pct! of \TeX's running time,
+exclusive of input and output.
+\fi
+
+\inx
+\fin
+\con