diff options
author | Karl Berry <karl@freefriends.org> | 2005-12-29 00:34:36 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2005-12-29 00:34:36 +0000 |
commit | 41ceff5a615ab4e3d46b1c94bd26d9dcf9d6c1f8 (patch) | |
tree | c710ef0b82f65ae0f818e6ea8f10c2f40f2decf3 /Master/texmf-doc/doc/english/impatient/macros.tex | |
parent | 2293d6885b754133151c14be7e01ad81baf0afbf (diff) |
doc/english/i-l
git-svn-id: svn://tug.org/texlive/trunk@21 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-doc/doc/english/impatient/macros.tex')
-rw-r--r-- | Master/texmf-doc/doc/english/impatient/macros.tex | 2295 |
1 files changed, 2295 insertions, 0 deletions
diff --git a/Master/texmf-doc/doc/english/impatient/macros.tex b/Master/texmf-doc/doc/english/impatient/macros.tex new file mode 100644 index 00000000000..e3a84adac70 --- /dev/null +++ b/Master/texmf-doc/doc/english/impatient/macros.tex @@ -0,0 +1,2295 @@ +% This is part of the book TeX for the Impatient. +% Copyright (C) 2003 Paul W. Abrahams, Kathryn A. Hargreaves, Karl Berry. +% See file fdl.tex for copying conditions. +% +% Macros for typesetting TeX for the Impatient. +% +% These macros are being distributed without any warranty whatsoever. +% The level of commentary is that which we, the authors, found necessary +% for our own purposes. +% +% ========================================================================== +% +% The macros use the term `chapter' for what in the book is called +% a `section', `section' for the book's `subsection', etc. For purposes of +% defining macros it's convenient to think of the book as divided into +% chapters, but because of the nonsequential nature of the book we don't +% want to tell the readers that they are reading chapters. + + +% An embedded file should end with \byebye. +% +\begingroup +\ifx \macsin\relax + % In frontm.tex, we do \input macros several times, and we still want + % the \byebye at the end to end the job. + % So we \input inside a group in frontm, and make the assignment to + % \endinput local. + \aftergroup\let\aftergroup\byebye\aftergroup\endinput + \aftergroup\endinput % Don't read this file again. +\else + \global\let\byebye = \end + \global\let\macsin = \relax +\fi +\endgroup + +% This must come before config.tex. +\input eplain + +% Define configuration switches and then read their values. +% +\newif\ifcenterpage \centerpagetrue +\newif\ifcompletebook +\newif\iffinal % true for the 2000dpi copy +\newif\ifmsdos +\newif\ifedgetabs \edgetabstrue +\newif\ifdvi \dvitrue % true if we want a .dvi file + +%\xrefwarningfalse + +% The config file contains settings for flags, e.g., +% \completebookfalse +% It can be empty as long as it exists. +\input config +\ifcompletebook \else\rewritetocfilefalse \fi +\edef\tempfile{\ifmsdos g:temp \else x \fi} +\ifx\setmodes\undefined\else\setmodes\fi % modify from command line input + +% Certain defaults are forced by certain others. +% +\iffinal \centerpagetrue \edgetabstrue\fi + +% Initial definitions. (These should come before \input fonts.) +% +\catcode`\@ = \letter % For the macro file only. + +% We don't want register allocation information in the log, +% so we redefine the relevant macro from plain.tex. + +\def\alloc@#1#2#3#4#5{\global\advance\count1#1 by 1 + \ch@ck#1#4#2% + \allocationnumber=\count1#1 \global#3#5=\allocationnumber +} + +% The fonts. This should come before defining the new character control +% sequences that follow. +% +\input fonts + +\hyphenation{script-script base-line-skip no-base-line-skip line-skip + line-skip-limit max-dead-cycles output-penalty no-inter-line-skip + show-box-depth show-box-breadth if-hmode if-vmode if-mmode + back-spaces back-space par-indent tracing-on-line} + +{ + \catcode`\| = 0 + \catcode`\\ = \other + |global|let|bsc = \ % \bsc is a true backslash character. +} + +\let\\ = \bsc + +\def\bslash{$\backslash$} % backslash suitable for printing +\let\shriek = ! +\let\vbar = | +{ + \catcode `\[ = 1 \catcode `\] = 2 + \catcode `\{ = \other \catcode `\} = \other + \global\let\lbracechar = { + \global\let\rbracechar = } +] +\def\blbrace{{\bt \{}} +\def\brbrace{{\bt \}}} + +{ + \catcode`\ =\other% Notice no spaces at beginning of next line. +\gdef\otherspace{ } +} + +\let\mathlbrace = \{ \let\mathrbrace = \} +{ + \catcode `\[ = 1 \catcode `\] = 2 + \catcode `\{ = \other \catcode `\} = \other + \gdef\{[\ifmmode\mathlbrace\else [\bt {]\fi] + \gdef\}[\ifmmode\mathrbrace\else [\bt }]\fi] +] + + +% These are for debugging (less drastically than \tracingall or \loggingall). +% +\def\tron{\tracingmacros=2 \tracingcommands=2 \tracingonline=1} +\def\troff{\tracingmacros=0 \tracingcommands=0} + +% \pagebreak should always cause a break, even if the resulting +% page is empty. +% +\def\pagebreak{\null\vfill\eject} + +% \linebreak causes a line break in chapter headings, but outside of that +% context we don't want it to do anything. +% +\let\linebreak = \relax + + +% Parameters. +% +\parskip = 0pt plus 0.3pt +\newdimen\codefuzz \codefuzz = 10pt % for \csdisplay, \example +\hbadness = 4000 +\vbadness = 8000 +\hfuzz = 0.1pt % as in plain TeX +\vfuzz = 0.1pt % as in plain TeX +\exhyphenpenalty = 0 % we don't mind these +\widowpenalty = 10000 % these are very bad +\clubpenalty = 10000 % these are very bad too + +% Page margins. +% +% Note that the \newdimens can't be within an \if or a \def +% because \newdimen is an \outer macro (thanks to DEK). +% +\newdimen\insidemargin \newdimen\outsidemargin +\newdimen\topmargin \newdimen\bottommargin +\newdimen\headmargin +\newdimen\totalwidth \newdimen\totalheight +\newdimen\oddoffset \newdimen\evenoffset +\newif\ifnoheadline + +% \totalwidth and \totalheight are the actual trim size of the book. +% \insidemargin, \outsidemargin, \topmargin, and \bottommargin are margins +% with respect to the pages of the book, not the draft 8 1/2 x 11 pages. +% + +% This makes it so that we only have to cut twice on a page. +% 8.5" = 51.19125pc exactly. +% \totalwidth should = \outsidemargin + \insidemargin + \hsize. +% +\totalwidth = 7.375in % 44.4159375pc = 7 3/8". +\outsidemargin = 8pc +\insidemargin = 10pc +\hsize = \totalwidth +\advance \hsize by -\outsidemargin +\advance \hsize by -\insidemargin +% \hsize should now be 26.4159375pc + +% Now that we know \hsize, we can set \parfillskip to eliminate (most) +% widows. +% +\parfillskip = .75\hsize plus .06\hsize minus .75\hsize + + +% \oddoffset and \evenoffset are the \hoffset values needed to +% align the left edge of the virtual page with the left edge of the +% draft paper (not the left edge of the book pages). +% +% The -1in below comes from the default margin, which the DVI driver must +% set at 1in. Odd pages are on the left, even on the right. +% +% First, align the left edge of the virtual page with the left edge of the +% draft page. +% +\oddoffset = -1in +\advance\oddoffset by \insidemargin +% +\evenoffset = -1in +\advance\evenoffset by \outsidemargin + +% For centered pages, move the virtual page right by half the trim width. +% +\ifcenterpage + \dimen0 = 8.5in + \advance\dimen0 by -\totalwidth + \divide\dimen0 by 2 + \advance\oddoffset by \dimen0 + \advance\evenoffset by \dimen0 + +% For uncentered even-numbered pages, align the right edge of the virtual +% page with the right edge of the draft paper so that we can remove the trim +% of two-sided pages with a single cut. +% +\else + \advance\evenoffset by 8.5in + \advance\evenoffset by -\totalwidth +\fi + +\hoffset = \oddoffset % First page is numbered one. + +% Now for the vertical, which is simpler, since it doesn't vary from +% page to page. +% 11" = 66.2475pc exactly. +% \totalheight should = \topmargin + \bottommargin + \vsize. +% +\totalheight = 9.25in % 9 1/4" = 55.708125pc +\topmargin = 6pc % Distance from top of page to baseline of text line 1 +\bottommargin = 6pc % Distance from last line to bottom of page. +\topskip = 2pc % Distance from top of \box255 to baseline of text line 1 +% \vsize Distance from top of \box255 to last line of text. +% \headmargin Distance from top of \box255 to top of page +% We'll place the headline just above \box255 + +\headmargin = \topmargin \advance \headmargin by -\topskip + +\vsize = \totalheight +\advance \vsize by -\headmargin +\advance \vsize by -\bottommargin +% \vsize should now be 46.708125pc + +\voffset = -1in % align top of logical page with top of physical page +\advance \voffset by \headmargin +\ifcenterpage + \dimen0 = 11in + \advance\dimen0 by -\totalheight + \divide\dimen0 by 2 + \advance\voffset by \dimen0 +\fi + +\topskip = 2pc % Distance from headline to first line of text. + + +% Other formatting parameters. +% +% The basic increments we'll use in the layout. +% +\def\setskip#1 = #2 {% + \dimen0 = #2\baselineskip + \csname #1skipamount\endcsname = + \dimen0 plus .33\dimen0 minus .25\dimen0 + \ignorespaces +} +\newskip\greaterskipamount +\newskip\greatskipamount +\newskip\biggerskipamount +\newskip\medbigskipamount +\newskip\medsmallskipamount +\newskip\tinyskipamount + +\setskip greater = 2.5 +\setskip great = 2.0 +\setskip bigger = 1.5 +\setskip big = 1.0 +\setskip medbig = .75 +\setskip med = .5 +\setskip medsmall = .375 +\setskip small = .25 +\setskip tiny = .125 + +\parindent = 1em +\newdimen\normalindent \normalindent = \parindent + +\footnotemarkseparation = .16666em + +\abovelistskip = \smallskipamount +\interitemskip = \tinyskipamount +\belowlistskip = \smallskipamount +\listleftindent = \parindent + +% Displays involve text and math. We don't want as much flexibility in +% the glue as plain.tex sets. +% +\abovedisplayskip = \medsmallskipamount +\abovedisplayshortskip = 0pt plus 2pt +\belowdisplayskip = \medsmallskipamount +\belowdisplayshortskip = \belowdisplayskip + +\newskip\intercapsuleskip \intercapsuleskip = .75\tinyskipamount plus 0.4pt +\newdimen\capsulehangindent \capsulehangindent = 2pc + +\newskip\aboveconceptskip \aboveconceptskip = \bigskipamount + + +\newskip\abovesectionskip \abovesectionskip = \greaterskipamount +% No stretch or shrink below heads, according to A-W. +\newskip\belowsectionskip \belowsectionskip = 1\biggerskipamount + +\newskip\abovesubsectionskip \abovesubsectionskip = \greatskipamount +\newskip\belowsubsectionskip \belowsubsectionskip = 1\bigskipamount + +\newskip\abovedescriptionskip \abovedescriptionskip = \biggerskipamount +\newskip\belowdescriptionskip \belowdescriptionskip = \medskipamount + +\newskip\explainskip \explainskip = \tinyskipamount +\newskip\exampleskip \exampleskip = \smallskipamount + +\def\interexampleskip{\vskip\medsmallskipamount} +\def\tinyskip{\vskip\tinyskipamount} + +% Space in which a symbol is shown in a columnated list of commands. +\newdimen\symbolspace \symbolspace = 14pt + +% \colsindent is the indentation before material arranged in columns and +% displayed, as in the list of Greek letters. +\newskip\colsindent \colsindent = \parindent + +% The indentation for page lists in the index that don't fit on one line. +\newdimen\indexpageindent \indexpageindent = 1pc + +% The indentation for subsidiary entries in the index. (Should be less +% than \indexpageindent.) +\newdimen\indexlevelindent \indexlevelindent = .5pc + +\newskip\codebaselineskip \codebaselineskip = \baselineskip + +% Fill the previous page with blank space before a command. +% +\def\cmdbreak{\par\nobreak\vfil\penalty 1000\vfilneg\par} + +% Penalties. +% +\newcount\conceptpenalty \conceptpenalty = -1500 +\newcount\intercmdnamepenalty \intercmdnamepenalty = 300 +\newcount\@intercmdnamepenalty \@intercmdnamepenalty = \intercmdnamepenalty + + + +% The output routine. +% +\output = {% + \onepageout + % + % Odd pages are right-hand pages. + % + % Note \pageno has been incremented when we get here -- it now refers + % to the page number of the page about to be typeset, not the page + % that we just shipped out. + % + \ifodd\pageno % \onepageout advances \pageno. + \global\hoffset = \oddoffset + \global\intercmdnamepenalty = 10000 + \else + \global\hoffset = \evenoffset + \global\intercmdnamepenalty = \@intercmdnamepenalty + \fi +} + +\ifdvi\else\output={% + \setbox0=\box255\deadcycles=0 + \advancepageno + \global\advance \truepage by 1 + \ifnum\outputpenalty>-20000\else \dosupereject \fi + } +\fi + +\def\onepageout{% + \shipout\vbox{% + \offinterlineskip % The page should have vertically abutting boxes. + \ifodd\pageno + \cropmargin = \insidemargin + \else + \cropmargin = \outsidemargin + \fi + \addcropmarks % Does not affect the position. + \ifcenterpage \addtruepage \fi + % + \ifedgetabs \ifodd\pageno \ifnoheadline\else + \edgetabs % Does not affect the position. + \fi\fi\fi + % + \vbox to 0pt{\vskip-\headmargin \vskip-3.5pc + \rightline{\sevenrm\timestamp}\vss}% + % + \smash{\line{\the\headline}}% Simplified \makeheadline. + \pagebody + \vskip 2\normalbaselineskip + % The footline is needed on one page (for an example). + \line{\the\footline}% + }% + % Now the rest from \plainoutput: + \advancepageno + \global\advance\truepage by 1 + \ifnum\outputpenalty>-20000\else \dosupereject \fi +} + +\footline = {\hfil} + +% The headline always includes the name of the current chapter. This +% goes on the inside. If more information, such as the concept we're +% explaining, is included, it goes on the outside. +% +\headline = {% + % Produce the timestamp + \ifnoheadline + \hfil + \global\noheadlinefalse + \else + \let\\ = \ignorespaces + \ifodd \pageno % Right-hand page. + {\tenit \firstmark}\hfil {\tenbf \folio}% + \else % Left-hand page. + {\tenbf \folio}% + \hfil + {\tenit + \chaptername + \ifnum\pageno>0\ifback\else + \quad $\backslash$\quad\S\the\chapterno + \fi\fi + }% + \fi + \fi +} + +% Sizes for cropmarks: +% +\newdimen\cropthick \cropthick = 0.4pt +\newdimen\crophsize \crophsize = 1pc +\newdimen\cropvsize \cropvsize = 1pc +\newdimen\cropoffset \cropoffset = .0625in + +% Each of the following macros generates a quarter of a cropmark as +% a zero-size box at the center point of the cropmark. +% We want the cropmarks to be centered with respect to their thicknesses. + +\def\vcropdown {\hbox to 0pt{% + \kern -.5\cropthick + \vbox to 0pt{% + \vskip \cropoffset + \hrule width\cropthick depth\cropvsize height0pt + \vss}% + \kern -.5\cropthick}% +} + +\def\vcropup {\hbox to 0pt{% + \kern -.5\cropthick + \vbox to 0pt{% + \vss + \hrule width\cropthick depth\cropvsize height0pt + \vskip \cropoffset}% + \kern -.5\cropthick}% +} + +\def\hcropright{\rlap{\kern\cropoffset\smash{% + \vrule width\crophsize depth .5\cropthick height .5\cropthick}}} + +\def\hcropleft{\llap{\smash{% + \vrule width\crophsize depth .5\cropthick height .5\cropthick}% + \kern\cropoffset}} + +% \cropmargin will be set to the left margin on the current page. +% +\newdimen\cropmargin +\def\cropline#1{\moveleft\cropmargin\hbox to \totalwidth{#1}} + +% \addcropmarks adds the cropmarks to a page while leaving everything else +% alone. It assumes we're positioned at the top of the page. + +\def\addcropmarks{% + \vbox to 0pt{% + \offinterlineskip % contextually redundant but precautionary + \vskip -\headmargin % to get to logical top of page + \ifcenterpage + \cropline{\hcropleft\vcropup \hfil \vcropup\hcropright} + \else + \cropline{\hfil \vcropdown}% + \fi + \vskip\totalheight + \ifcenterpage + \cropline{\hcropleft\vcropdown \hfil \vcropdown\hcropright}% + \else + \cropline{\hcropright\hfil\hcropleft\vcropup\vcropdown\hcropright}% + \fi + \vss +}} + +% \addtruepage adds a small page number near the upper right cropmark. +% +\newcount\truepage \truepage = 1 +\def\addtruepage{% + \vbox to 0pt{\vskip -\headmargin\vskip -2pc + \moveleft\cropmargin\hbox to \totalwidth{% + \twelvebf + \quad\TeX\ for the Impatient\hss + N\raise 3.3pt\hbox{o} \the\truepage\quad}% + \vss}% +} + + +% The mark information is output by \markinfo. +% +% We can use a different mark, e.g., a shorter heading, by calling +% \changemark. +% +\newtoks\shortmark \shortmark = {} +\newif\ifchangemark + +\def\markinfo#1{% + \ifchangemark + \mark{\the\shortmark}\changemarkfalse + \else + \mark{#1}% + \fi +} + +\def\changemark#1{\shortmark = {#1}\changemarktrue} + + +% ``Tabs'' down the side of the book. +% Say \nextedgetab to move the thing down to the next. +% Say \edgetabsfalse to turn them off. +% +\newcount\numtabs \numtabs = 7 +\newdimen\edgetabjump \edgetabjump = 0pt +\def\nextedgetab{% + \advance\edgetabjump by \edgetabdepth +} + +\def\settabdepth#1{% + \edgetabdepth = #1 + \setbox\tabbox = \vbox to \edgetabdepth{% + \leaders + \vbox{\vskip \edgespacing + \hrule width\edgetabwidth height0pt depth\edgethick}% + \vfil} +} + +\newskip\bigtab \newskip\smalltab +\newskip\edgetabdepth +\newbox\tabbox + +\bigtab = \totalheight \divide\bigtab by \numtabs +\smalltab = .4\bigtab % five smalls make two bigs + +\newdimen\edgetabin \edgetabin = .25in +\newdimen\edgetabbleed \edgetabbleed = .25in +\newdimen\edgetabwidth + \edgetabwidth = \edgetabin + \advance \edgetabwidth by \edgetabbleed +\newdimen\edgethick \edgethick = .3pt % line thickness +\newdimen\edgespacing \edgespacing = .9pt % line spacing + + +\def\edgetabs{\vbox to 0pt{% + \vskip-\headmargin + \vskip\edgetabjump + \hbox{% + \hskip \hsize + \hskip\outsidemargin + \hskip-\edgetabin + \copy\tabbox + }% + \vss +}} + + +% We can simplify \pagecontents (which is called by \pagebody) somewhat, +% since we don't have \topinserts. +% +\def\pagecontents{% + \unvbox255 % The main page contents. + % + \ifvoid\footins\else % Footnotes are present. + \vskip\skip\footins + \footnoterule + \unvbox\footins + \fi +} + + +% The command chapters had a mini-index at the bottom of right-hand +% pages. These definitions are the way to put entries into it. +% +% \minref generates a reference for the mini-index, and prints the +% reference on the page, also. +% +\def\minref#1{% + #1% Print it on the page. + % That's it, now. +} + +% Mini-index entry without printing the argument on the page. +% Just ignore the argument now. +% +\def\minrefs#1{% + \ignorespaces +} + +% This is used for producing the concept mini-index. +% +\def\minrefsdelim#1\endmark{\minrefs{#1}} + +% One last insertion-oriented thing: +% we always want numbered footnotes, as defined in eplain. +% We'll do them in 8-point type. +% +\let\@plainfootnote = \footnote +\let\footnote = \numberedfootnote +\everyfootnote = {\footnotefonts} + + +% The \margin macro produces a marginal note at the same level as its call. +% It should only be used in a paragraph or in the main vertical list. +% It is nullified when we're printing the final copy. +% +\def\margin#1{% + \ifhmode + \vadjust{\printmarginnote{#1}}% + \else + \dimen0 = \prevdepth + \prevdepth = -1000pt + \printmarginnote{#1}% + \prevdepth = \dimen0 + \fi + \ignorespaces +} + +\def\printmarginnote#1{% + \hbox to 0pt{% + \hskip 1.1\hsize + \vbox to 0pt{% + \everypar = {}% Don't inherit hanging indentation. + \hsize = 1in \rightskip = 0pt plus 1fil \noindent \sevenrm + \let\tt = \eighttt + \parfillskip = 0pt plus 1fil + \baselineskip = 8pt #1% + \vss + }% + \hss + }% +} + +%\iffinal +\iftrue + \def\margin#1{\ignorespaces} +\fi + + +% Stuff to preserve page breaks inserted for the 2nd printing. +% This macro takes one ``argument''. +% +\def\secondprinting{\afterassignment\finishsecondprinting \toks0 = } +\def\finishsecondprinting{\the\toks0} + + + +% Parts of the book. +% +% +% Chapters. +% +\let\chaptername = \empty +\newcount\chapterno + +\def\chaprule{\vrule depth3\baselineskip height1.5pc width1pt} + +% Chapter openings should not have headlines. +% The text of each chapter starts on a right-hand page in the final +% book. The facing page has an illustration. This means that if the +% previous chapter ended on a left-hand (i.e., even) page, we have to +% eject an extra blank page. +% +\outer\def\chapter#1 \par{% + \ifcompletebook % Don't do the blank pages for proof copies. + \blankpage % the illustration page + % The first real chapter starts on page 1. + \ifnum\pageno < 0 \pageno = 1 \fi + \fi + % + \def\chaptername{#1}% + \advance\chapterno by 1 + % + \setbox0 = \hbox{\chapternumeralfont + \kern1pt + \expandafter\kernchapno\the\chapterno\empty + \kern3pt}% + \vglue 0pt % But we get a \topskip of 2pc now. + \nointerlineskip + \leftline{% + \ifback\else + \vtop{% + \copy0 + \vskip6pt + \hrule width\wd0 height2.2pc + }% + \kern 16pt + \fi + \chapterfonts % to get \baselineskip now + \chaprule + \kern 6pt + \vtop{% + \def\linebreak{\hfil\break}% + \noindent \chaptername}% + }% + \vskip 6pc plus.5pc minus.5pc + \noheadlinetrue + \toks0=\expandafter{\chaptername} + \edef\writechaptertoc{% + \noexpand\writenumberedtocentry{chapter}{\the\toks0}{\the\chapterno}% + }% + \writechaptertoc + % + % Use chaptername as first A-head (or only one). + \mark{\chaptername}% + \footnotenumber = 0 % Number footnotes from 1 in each chapter. + \beginit{CHAPTER}% + \noindent + \ignorespaces +} + +\def\endchapter{% + \mark{\chaptername}% Use chapter name on last blank recto page + \vfil\eject % be sure everything's out before testing for recto + \ifodd\pageno + \message{Chapter ends on a verso page.}% + \blankpage + \fi + \endit{CHAPTER}% +} +% +% \blankpage creates a blank page with no headline. +% In the final book, it just advances the page number. +% For the web edition, the blank pages serve no purpose except to keep +% the indexing correct. I didn't want to rerun the index. +% +\def\blankpage{% + \iffinal + \advancepageno + \global \advance \truepage by 1 + \else + \noheadlinetrue\pagebreak + \fi +} + +% This hokey little macro kerns between the numerals in the chapter +% number. We want to kern more between `11' then otherwise; also, we +% want to remove the extra space before the chapter number, and after +% `11'. +% +\def\kernchapno#1#2{% + \ifx\empty#2\else \kern-3pt \fi + #1% + \ifx\empty#2\else + \if1#2% + \kern-.1em + \else + \kern-.05em + \fi + \fi + #2% + \if 1#2\kern-.1em\fi +} + +% Sections. +% +\newif\ifheading % Avoid breaking after a heading. + +% get section numbers for the fdl only, since it has internal references. +\let\fdlkludge=\empty + +% The heading flag is turned on by headings and turned off +% at the start of a description. +% +\outer\def\section#1 \par{% + \par % be sure we're in vertical mode + \saveskip = \lastskip % will be 0 if no skip + \cmdbreak + \combineskips\abovesectionskip + \dimen0 = 2.5\baselineskip \advance\dimen0 by -\topskip + \vskip -\dimen0 + \vglue \dimen0 + % + {\sectionfonts \leftline{\fdlkludge #1}}% + % + \markinfo{#1}% + \writetocentry{section}{#1}% + \nobreak + % Don't go into horizontal mode within the command descriptions. + % + \vskip\belowsectionskip + \ifcommands \else \noindent \fi + \headingtrue + \everypar = {\headingfalse \global\everypar = {}}% + % only gets executed for \par in horizontal mode + \ignorespaces +} + + +% Subsections. We don't want a break at the glue if we were preceded by +% a \nobreak. +% +\def\subsection#1 \par{% + \par % be sure we're in vertical mode + \saveskip = \lastskip % will be 0 if no skip + \ifheading % Did we just have \section? + \nobreak + \fi + \combineskips\abovesubsectionskip + \dimen0 = 2.5\baselineskip \advance\dimen0 by -\topskip + \vskip -\dimen0 + \vglue \dimen0 + % + {\subsectionfonts + \leftline{\vrule width.5em height1.2ex depth.2ex \enspace #1}}% + \writetocentry{subsection}{#1}% + \nobreak + % Don't go into horizontal mode within the command descriptions. + \vskip\belowsubsectionskip + \ifcommands \else \noindent \fi + \headingtrue + \everypar = {\headingfalse \global\everypar = {}}% + % only gets executed for \par in horizontal mode + \ignorespaces +} + +% \combineskips combines the current skip (#1) with the previous skip +% (which must be in \saveskip), and effectively skips by the larger of +% the two. +% +\newskip\saveskip +\def\combineskips#1{\ifdim\saveskip<#1\vskip-\saveskip \vskip#1\fi} + + + +% List macros. +% + +% We want to use different names than eplain. +% +\let\ulist = \unorderedlist +\let\endulist = \endunorderedlist +% +\let\olist = \numberedlist +\let\endolist = \endnumberedlist + +\let\compact = \listcompact + +% The \noindent here keeps us from getting indentation on the first line. +% It also makes the display into a `short' display, FYI. +% The \belowdisplayskip and \abovedisplayskip glue are inserted by the +% display. +% +\long\def\display#1{% + \ifvmode \noindent \fi + $$\vtop{\everypar = {}\hsize = \displaywidth + \parfillskip = 0pt plus 1fil % don't worry about widows + \noindent #1\par\global\savedepth = \prevdepth}$$% + \endgraf + \prevdepth = \savedepth +} + +% \vdisplay is like \display, except it's for vertical mode material. Use it +% to avoid an unwanted initial lineskip. +% +\long\def\vdisplay#1{% + \ifvmode \noindent \fi + $$\vtop{\everypar = {}\hsize = \displaywidth + \parfillskip = 0pt plus 1fil % don't worry about widows + #1\par\global\savedepth = \prevdepth}$$% + \endgraf + \prevdepth = \savedepth +} + + + +% Indexing. +% Derived from Knuth's manmac macros. +% +\newwrite\index + +\immediate\openout\index = \jobname.idx +\newif\ifsilent + +% We need ^ to be active temporarily, while we define it. +% +{ \catcode`\^ = \active +% +\gdef^{% + \ifmmode + \let \nextaction = \sp + \else + \let \nextaction = \beginindexref + \begingroup + \catcode `| = \other \catcode `^ = \other + \fi + \nextaction +}} + +\def\beginindexref{\futurelet\next\checksilence} + +{% And for here, we need ^ to be deactivated +\catcode `^ = \other + +\gdef\checksilence{% + \if ^\next + \silenttrue \let\nextaction = \secondhat + \else + \silentfalse \let\nextaction = \checkbar + \fi + \nextaction +} + +% Eat the `^' that we saw would be the next token. +% +\gdef\secondhat^{\checkbar} + +} % end scope where ^ is \other + +\def\checkbar{\futurelet\next\iswitch} + +% Here we start reading the text of the actual index entry; +% we've determined whether it's silent or not. +% +% We handle the following cases: +% ^{alpha} and ^^{alpha} +% ^|alpha| and ^^|alpha| +% ^|\alpha| and ^^|\alpha| +% +% When this is called, \next is either `|' or `{'. +% +\def\iswitch{% + \ifx |\next + \let \nextaction = \checkbackslash + \else + \let \nextaction = \normalidx + \fi + \nextaction +} + +\def\checkbackslash|{% + % within |...| we allow anything (but another |) + \deactivate \catcode `\ = \other + \futurelet\next\litidx +} + +% The thing after the ^ is a |. We have further checking to do -- is +% the next character a \? +% +{ % reverse \ and / +\catcode`\/ = 0 +\catcode`\\ = \other +/gdef/litidx{% + /if \/next + /expandafter/litidxA + /else + /expandafter/litidxB + /fi +} + +% The thing being indexed starts with a \. +% +/gdef/litidxA \#1|{% + /ctsidxref{#1}% + /litidxswitch{/\#1}% +} + +% The thing being indexed is just a word. +% +/gdef/litidxB #1|{% + /ttidxref{#1}% + /litidxswitch{#1}% +} +}% end reversal of \ and / + +% The thing after the ^ is not a |. +% +\def\normalidx#1{% + \ifsilent + \aftergroup\ignorespaces + \else + #1% + \fi + \idxref{#1}% + \endgroup % group started by \iswitch. +} + +\def\litidxswitch#1{% + \ifsilent + \aftergroup\ignorespaces + \else + {\tt #1}% + \fi + \endgroup % group started by \iswitch. +} + + + +% Indexing macros for external use. + +% \idxref generates an index entry for #1. If #1 contains any control +% sequences, they are treated literally. +% +\def\idxref#1{\indexwrite{#1}N\ignorespaces} + + +% For creating an index entry for control space. +{\catcode `\ =\other +\gdef\blankidxref{\ctsidxref{ }} +} + +% I removed this macro from eplain because \csname works as well, but +% since the macros below are already written to use it ... +\def\@tokstostring#1{\@ttsA#1 \@ttsmarkA}% +\let\tokstostring=\@tokstostring +\def\@ttsA#1 #2\@ttsmarkA{% + \@ifempty{#1}\else + \@ttsB #1\@ttsmarkB + \@ifempty{#2}\else + \@spacesub\@ttsA#2\@ttsmarkA + \fi + \fi +}% +\def\@ttsB#1{% + \ifx #1\@ttsmarkB\else + \string #1% + \expandafter\@ttsB + \fi +}% +\def\@ttsmarkB{\@ttsmarkB}% should never be expanded +% +\def\@spacesub{+}% +\let\spacesub = \@spacesub +% +\def\@ifempty#1{\@@ifempty #1\@emptymarkA\@emptymarkB}% +\def\@@ifempty#1#2\@emptymarkB{\ifx #1\@emptymarkA}% +\def\@emptymarkA{\@emptymarkA}% Again, so \ifx won't complain. + +% #1 is the index term, #2 is the reference as in +% Diacritical mark, see accent. + +\def\idxsee#1#2{% + \begingroup + \def\spacesub{\otherspace}% + \edef\nextaction{\write\index{\tokstostring{#1}::N::*\tokstostring{#2}}}% + \nextaction + \ignorespaces +\endgroup} + + +% \ttidxref generates an index entry for #1 in the program font. +% If #1 contains any control sequences, they are treated literally. +% +\def\ttidxref#1{\indexwrite{#1}T\ignorespaces} + + +% \ctsidxref generates an index entry for a control sequence. #1 +% should not have a preceding backslash, so that the proper call for +% indexing \alpha is \ctsidxref{alpha}. +% +\def\ctsidxref #1{\indexwrite{#1}C\ignorespaces} + +% \indexchar is needed to generate index entries for three especially +% difficult single characters: {, }, and \. They are blank-delimited. +% +\def\indexchar{\begingroup \deactivate \indexcharA} +\def\indexcharA#1 {\indexwrite{#1}T\endgroup} + +% \pix indicates that the next index entry is a principal one. +% +\newif\ifpix +\def\pix{\global\pixtrue} + +% \bix and \eix indicate that the next index entry begins or ends a +% range of pages. +% +\newif\ifbix \def\bix{\bixtrue} +\newif\ifeix \def\eix{\eixtrue} + +% #1 is the text of the entry, #2 is N (normal), T (typewriter) or +% C (control sequence) or `cs' for now. +% +\def\indexwrite#1#2{\begingroup + \def\spacesub{\otherspace}% + \edef\tts{\tokstostring{#1}}% + \edef\nextaction{\write\index{\tts::#2::\noexpand\number\noexpand\pageno + \ifpix P\fi\ifbix B\fi\ifeix E\fi}}% + \nextaction + \global\pixfalse \global\bixfalse \global\eixfalse +\endgroup} + +{\catcode `\^ = \other \gdef\twocarets{^^}} + + +% For generating index entries with weird characters, we need to deactivate +% them: { } blank \ and substitute [ ] ! for { } \ . \recat does this. +% It should be enclosed in a group (which must end in `]'). +\def\recat{% + \aftergroup\ignorespaces + \catcode `\! = 0 \catcode `[ = 1 \catcode `] = 2 + \catcode `\ = \other \deactivate +} + + + +% Macros for the front matter. +% +% Space at the top of the frontmatter pages. +% +\def\sinkage{\vglue 7pc \relax} + +% And at the top of the backmatter pages. +% +\def\backsinkage{\vglue 2pc \relax} + +% \frontchapter doesn't care if we're on an even page or an odd page. +% +\def\frontchapter#1 \par{% + \def\chaptername{#1}% + \leftline{% + \chapterfonts + \chaprule + \kern 6pt + \vtop{% + \def\linebreak{\hfil\break}% + \noindent \chaptername}% + }% + \vskip 4pc + \noheadlinetrue + % Use chaptername as first A-head (or only one) + \mark{\chaptername}% + \noheadlinetrue + \noindent \ignorespaces +} + + +% We are called from inside a group, so we can redefine the \toc... macros. +% +\def\shortcontents{{% + \firsttoctrue + \backfalse + \shorttocfonts + \let\tocchapterentry = \shorttocchapter + \let\tocsectionentry = \gobblethree + \let\tocsubsectionentry = \gobblethree + \halign{\hfil\strut##&\strut ##\hfil\cr + \readtocfile + \crcr}}% + \pagebreak + \global\backfalse +} + +% #1 is the chapter name, #2 the chapter number, #3 the page number. +% +\def\shorttocchapter#1#2#3{% + \ifback\else#2\quad $\backslash$\quad\fi\qquad + \raise3pt\hbox{\vrule height2pt width4pt depth2pt}$\,\,$#3\cr +} + +% Yes, we read the entire contents (several pages) as one alignment. +% +\def\contents{{% + \firsttoctrue + \backfalse + \tocfonts + \interlinepenalty = 100 + \halign{\hfil\strut##&\strut ##\hfil\cr + \readtocfile + \crcr}}% + \pagebreak + % We want to end the contents on a recto page, even if it's blank + \ifodd\pageno\pagebreak\fi % leaves us on an even page. + \global\backfalse +} + +\newif\iffirsttoc + +\def\tocchapterentry#1#2#3{% + \iffirsttoc + \global\firsttocfalse + \else + \noalign{\penalty-1000 \bigskip\smallskip}% + \fi + % + \ifback\else\bf#2\quad $\backslash$\quad\fi + &\bf#1\qquad\raise3pt\hbox{\vrule height2pt width4pt depth2pt}% + $\,\,$#3\cr + \noalign{\nobreak\vskip2pt}% +} + +\def\tocsectionentry#1#2#3{% + \noalign{\penalty-500 \vskip\medsmallskipamount}% + &\it #1\quad \openbox$\,\,$\rm #3\cr +} + +\def\tocsubsectionentry#1#2#3{% + &\qquad #1\quad $\cdot\,$#3\cr +} + +\def\openbox{\ht0 = 1.75pt \dp0 = 1.75pt \wd0 = 3.5pt + \raise 2.75pt \makeblankbox{.2pt}{.2pt}% +} + +\newif\ifback +% \ifback is true when we're doing the table of contents and are about +% to do the back matter. It is also true just before we do the back matter +% chapters (really, only the index). +% +\def\backmatter{\write\tocfile{\noexpand\setback}\backtrue} +\def\setback{\noalign{\bigskip\global\backtrue}} + + + +% Macros for the examples chapter. +% +% \doexamples is called with the name of the examples file +% Each example is ended by ::: (including the last one) +% A line starting with ~ is executed in the output (without the ~) +% but dropped from the input. +% +% Within the input, ! is an escape character, but {} are not recognized. +% This provides a limited control sequence capability, which is sufficient +% for delimited macros and therefore for cross-references (see \xrefdelim). +% !! stands for !. +% +\def\endmark{:::} + +\newif\ifnotatend \newif\ifnotatendfile \newif\iftildeline +\newread\exfileA \newread\exfileB \newwrite\exfileC +\newcount\examplenumber + +\def\doexamples#1{% + % Here we assume that two read-only openings of the same file are OK. + \immediate\openin\exfileA = #1 + \immediate\openin\exfileB = #1 + \loop + \advance\examplenumber by 1 + \reader + \ifx\holder\empty \notatendfilefalse \else \notatendfiletrue \fi + \ifnotatendfile + \dooneexample + \repeat +} + + +% We want control sequences to be executed as the input of each example +% is formatted, but we don't want to execute them for the output of each +% example until we generate that output with an \input command. +% Therefore, we treat ! differently for \holder, which produces example +% input, and \holderA, which produces example output. +% +% We can't say \global\immediate\read, but \immediate is implied with \read. +% +\def\reader{{\deactivate + \catcode`\! = \other % To execute control sequences on \input. + \catcode`\^^M = 9 \global\read\exfileA to \holder + % + \catcode`\! = 0 % To execute control sequences right away. + \obeyspaces \global\read\exfileB to \holderA + }% +} + +\def\dooneexample{{% + % We want to mention \! in one of the examples: + \edef\examplenum{\numbername\examplenumber}% + + \immediate\openout\exfileC = \tempfile + + \catcode`\| = \other % No literal code in these examples. + \chardef\! = `\! % !! means a literal ! character. + + + % Collect the input page, as it is to be printed, in a box + % At the same time, write out each line to \exfileC + % We make the box 0pt tall to avoid problems with overfull pages. + \setbox\xmpinput = \vbox to 0pt{% + % + \baselineskip = \codebaselineskip + \loop + \ifx\endmark\holder \notatendfalse \else\notatendtrue \fi + \ifnotatend + \expandafter\tildecheck\holder \empty \marker + \iftildeline\else + \leftline{\tt\frenchspacing \holderA \thinspace}% + \immediate\write\exfileC{\holder}% + \fi + \reader + \repeat + \vss % reduce height to 0pt + }% end \vtop + + \immediate\closeout\exfileC + + {% + \maxdepth = \maxdimen % allow long input + \vfill\eject + \catcode`\! = 0 + \restoreplainTeX + {% + \let\eject = \relax \input\tempfile + % Every example ends with \bye, but \bye is disabled in the main text. + \vfill\par\penalty-10000 + \global\footline = {\hfil}% + }% + \box\xmpinput + }% +}} + +{ + \catcode `\~ = \other % So the \ifx works. + \gdef\tildecheck#1#2\marker{% + \ifx #1~% + \immediate\write\exfileC {#2}\tildelinetrue + \else + \tildelinefalse + \fi + } +} + +% This definition is more or less repeated verbatim in the first example +% in xmptext.tex. +% +\def\xmpheader #1/#2{% + {\exampletitlefonts \leftline{Example #1:\quad \bi#2}}% + \vglue .5\baselineskip + \count255 = \pageno + \xdef\examplepage{\number\count255}% + \markinfo{Example #1: #2} + \ifrewritetocfile + \write\tocfile{\string\tocsectionentry{#2}{}{\examplepage}}% + \fi +} +% Let's number examples automatically; it makes it easier to move them +% around and add new ones. + +\def\xmpnum{\number\examplenumber} + +\newbox\xmpinput + + +% \negthin lets us put `\!' in examples. + +\def\negthin{\ifmmode \mskip-\thinmuskip \else \char`\\ \char`\! \fi} + +\def\xmpheaddef{see \xref{xmphead}} + +\def\restoreplainTeX{% + % Restore plain TeX's parameters (except for \hsize and \hoffset). + \parindent = 20pt + \parskip = 0pt plus 1pt + \parfillskip = 0pt plus 1fil + \hfuzz = 0.1pt + \hbadness = 1000 + \abovedisplayskip=12pt plus 3pt minus 9pt + \abovedisplayshortskip=0pt plus 3pt + \belowdisplayskip=12pt plus 3pt minus 9pt + \belowdisplayshortskip=7pt plus 3pt minus 4pt + \everymath = {}% + \everydisplay = {}% + \centereddisplays + \let\vfootnote = \@plainvfootnote + \let\footnote = \@plainfootnote + \let\tenrm = \oldtenrm + \textfont0 = \tenrm + \rm + \ignorespaces +}% + + + +% Macros for the concepts chapter. +% +% +% Start off the chapter. +% +\def\beginconcepts{\openout\conceptfile = \jobname.ccs } +\def\endconcepts{\closeout\conceptfile} + +\newwrite\conceptfile + +% \concept produces a concept heading and also generates a crossreference +% suitable for the mini-index. It even works for concepts with several words +% or containing control sequences like `\ascii'. +% +\def\concept#1 \par{% + \par + %k \cmdbreak + \penalty\conceptpenalty\vskip\aboveconceptskip + %k \vskip 0pt plus 1pt % allow a little more stretch + \noindent + % generate the index entry + \ifconceptindex \else \global\indextoks = {\idxref{#1}}\fi + \conceptindexfalse + \pix\bix\the\indextoks + % + {\bt \let\it=\bti \unskip\null #1.\hskip1em plus.2em minus.2em }% + \markinfo{#1}% + \xrdef{#1}% + \write\conceptfile{\string\doconcept{#1}{\number\pageno}}% + \beginit{CONCEPT}% + \nobreak + \ignorespaces +} + +\def\endconcept{% + \par % always go to vertical mode here + \eix\the\indextoks + \endit{CONCEPT}% + \ignorespaces +} + +\def\doconcept#1#2{\hbox{#1\quad #2}} + +% Sometimes we want to index a concept under some other name than the +% concept name, e.g., indexing `delimiter' as `delimiters'. The +% \conceptindex macro lets us do this. +% +\newif\ifconceptindex +\newtoks\indextoks +\def\conceptindex#1{% + \conceptindextrue + \global\indextoks = {\idxref{#1}}% + \ignorespaces +} + + +% Commands for cross-referencing within the concepts chapter. +% Each refterm has the form {a} or {a:b}, where b is the term to +% actually reference (e.g., \refterm{\PlainTeX:\plainTeX}). +% +\def\refterm#1{% + \reftermA #1:\endmark % Parse the stuff. + \expandafter\minrefsdelim\termtoref\endmark + \relax % Cancel the \ignorespaces. +}% +\def\reftermA#1:{\reftermfirst{#1}\futurelet\next\reftermB} +\def\reftermB#1\endmark{\ifx\endmark \next \else \reftermsecond#1\fi} + +\def\reftermfirst#1{#1\def\termtoref{#1}} +\def\reftermsecond#1:{\def\termtoref{#1}}% + +% The defining sentence for a concept. +% +\def\defterm#1{{\it #1\/}} + + +% This macro prints the single page that will go on the back cover. +% +\def\printconceptpage{% + % Make sure this is considered an odd page. + \ifodd\pageno\else\blankpage\fi + \noheadlinetrue + \advance\hsize by 2pc + \vglue2pc % Plus a \topskip of 2pc. + {\sectionfonts \leftline{List of concepts}}% + \vskip\belowsectionskip + {\conceptpagefonts + \parindent=0pt + \makecolumns 94/3: + \input \jobname.ccs + \vfil + % Put the `logo' at the bottom of the page. + \rightline{\thisbook}% + }% + \eject +} + + + +% Macros for the commands chapters. +% +% \ifcommands is true when we're within \begindescriptions ... + +\newif\ifcommands + + +% \begindescriptions should be called to start the actual control sequences. +% +\outer\def\begindescriptions{\beginit{DESCRIPTIONS}% + % The following definitions are local to this chapter. + % + \let\example = \commandexample + \let\endexample = \endcommandexample + \interlinepenalty = 50 + % + \commandstrue + \ignorespaces +} + +% The \endgroup that \enddescriptions does must come after the page +% break, so the last page of descriptions will get a mini-index. +% +\def\enddescriptions{% + \vskip -\lastskip % undo the skip created by \enddesc + \endit{DESCRIPTIONS}% + \ignorespaces +} + + +% Begin or end the description of a control sequence or group thereof. +% +\def\begindesc{% + \par % force vertical mode + \saveskip = \lastskip % will be 0 if no skip + \ifheading % Did we just have \section or \subsection? + \nobreak + \else + \cmdbreak + \fi + \combineskips\abovedescriptionskip + \headingfalse + \beginit{DESCRIPTION}% + \beginit{COMMANDS}% + % Each command name is set as a paragraph (for reasons I don't + % remember, \leftline doesn't work because of the way the manuscript + % was typed), and so \clubpenalty will be the penalty at the + % interline glue (see p.96). + \clubpenalty = \intercmdnamepenalty + \parfillskip = 0pt plus 1fil + \ignorespaces +} + +\def\enddesc{% + \nobreak % if we need a break, we'll get it from the next group opener + \vskip\belowdescriptionskip + \endit{DESCRIPTION}% + \ignorespaces +} + +% Begin the explanation of a control sequence. Don't break at the +% space above the explanation, or the interline glue before the first line. +% +\def\explain{% + \par + \endit{COMMANDS}% + \nobreak \vskip\explainskip + \interlinepenalty = 50 + \nobreak \noindent + \ignorespaces +} + +% Here is how \example looks in the text: +% \example +% ... +% | +% \produces +% ... +% \endexample +% +% repeated an indefinite number of times. +% +% We want to set the code of an example in a box so as to prevent it from +% being broken across pages. By using \vtop we assure that the code is the +% right distance from the `Example:' line. In order to keep the `produces:' +% the right distance from the last code line, we save the depth of that code +% line and then fool TeX into thinking that the \vtop has that depth by +% assigning it to \prevdepth. If we didn't do this, the last line of the code +% would be too close to the `produces:' (as indeed it was in earlier versions +% of the book. +% +\newdimen\savedepth + +{\makeactive| +\gdef\commandexample{% a.k.a. \example, inside \begindescriptions. + \cmdbreak\vskip\exampleskip + \leftline{\it Example:}% + \nobreak % At the interline glue. + \beginit{EXAMPLE}% + \parfillskip = 0pt plus 1fil + \hbox\bgroup\hskip\parindent\vtop\bgroup + \begincs + \let | = \endcode + \advance\hsize by -\parindent + \parindent = 0pt + \bgroup\obeywhitespace +}}% + +\def\endcode{% + \egroup % end \obeywhitespace group + \par\global\savedepth=\prevdepth + \egroup % end inner \vbox + \egroup % end outer \hbox + \prevdepth = \savedepth + \ignorespaces +} + +% \dproduces should be used when the following material is a math +% display. +% +\newif\ifexampledisplay +\def\dproduces{\global\exampledisplaytrue \produces} + +\newif\ifproduces + +% \produces puts its material into a vbox so it won't be broken. +% The material starts in VERTICAL MODE! It uses the plainTeX conventions +% except that \parindent is 0pt. + +\def\produces{% + \producestrue + \ifodd\pageno \par \nobreak \else \cmdbreak\fi + \vskip\tinyskipamount + \noindent {\it produces\ifexamplelog\ in the log\examplelogfalse\fi :}% + \vadjust{\nobreak}% At the interline glue. + \ifexampledisplay + \centereddisplays + \else + \par\nobreak + \advance\hsize by -\parindent + \savedepth = \prevdepth + \nointerlineskip + \hbox\bgroup\hskip\normalindent + \vtop\bgroup \restoreplainTeX \parindent = 0pt + \prevdepth = \savedepth + \fi +}% + +% we need another ``produces'' form for when a command puts things in +% the log. In this case, the produces text also ends with a |. +% +\newif\ifexamplelog +{\makeactive| +\gdef\logproduces{\examplelogtrue\produces + \begincs + \def |{\endcode\producesfalse}% + % Every line is set as a paragraph, so we get one \parindent for free. + % But we also did \advance\leftskip in \produces, so now we have two. + % We only want one. + \advance\leftskip by -\parindent + \bgroup\obeywhitespace +}}% + +\def\nextexample{\endexample\interexampleskip\example} + +\def\endcommandexample{% + \par % force vertical mode, set previous paragraph + \ifproduces \ifexampledisplay \global\exampledisplayfalse \else + \global\savedepth = \prevdepth + \egroup % Matches the \vtop in either the \produces or the \example. + \egroup % Matches the \hbox in \producesbox. + \global\producesfalse + \par + \prevdepth = \savedepth + \fi\fi + \endit{EXAMPLE}% + \ignorespaces +} + +\def\see{% + \ifodd\pageno\nobreak\fi % don't put at the top of a verso page + \vskip -\lastskip % should be \belowdescriptionskip + \bigskip + \noindent + {\tenbi \spaceskip = 3.33pt plus 2pt minus 1.1pt + \parfillskip = 0pt plus 1fil + See also: %k \hskip 1em plus .5em minus .25em + }% + \ignorespaces +}% + + +\newif\ifxref \xreftrue + +% \aux acts as a prefix to a \cts command, specifying that a +% cross-reference should not be generated. +% +\def\aux{\xreffalse} + +% So does \easy, which prints a hand, pointing at the control sequence. +% (The hand font doesn't define an em.) +% +\newif\ifeasy +\let\easy = \easytrue +\def\testeasy{\ifeasy\llap{\hand\ \kern 6pt}\easyfalse\fi} + +% \cts typesets the beginning of a control sequence description, and +% generates an index entry and cross-reference definition for it. The +% control sequence name must be delimited by a blank, since there may be +% parameters that follow. The control sequence name can contain special +% characters; they are deactivated. The initial \ must be omitted. +% +\def\cts{\begingroup \deactivate \ctsA} +\def\ctsA#1 {\endgroup \ctsB{#1}} +\def\ctsB#1#2{% + \ctsbasic{\\#1}{#2}% + \ifxref \ctsxrdef{#1}\else \xreftrue \fi + \pix\ctsidxref{#1}% +} + +% \ctsx is like \cts, but separates the control sequence name and the +% text by more space. (`x' for `extra') +% +\def\ctsx{\begingroup \deactivate \ctsxA} +\def\ctsxA#1 {\endgroup \ctsxB{#1}} +\def\ctsxB#1#2{% + \ctsbasic{\\#1}{\quad #2}% + \ifxref \ctsxrdef{#1}\else \xreftrue \fi + \pix\ctsidxref{#1}% +} + + +% \ctscol is like \cts, but doesn't start a new paragraph. It's used in +% in columns of cs's and their explanations. +% +\def\ctscol#1 #2{% + {\bt \\#1}\quad #2% + \ifxref \ctsxrdef{#1}\else \xreftrue \fi + \pix\ctsidxref{#1}% +} + +% \ctsbasic does the actual printing of a cs name. It's needed on its +% own for `\ '. It does not generate any index or cross-reference +% entries. #1 is the command name, #2 some (possibly empty) text to go +% next to it. +% +\def\ctsbasic#1#2{% + \par + \nobreak % At the \parskip glue the \noindent will produce. + \noindent\testeasy {{\bt #1}\space #2}% +} + +% \ctsxrdef generates a control sequence cross-reference definition. +% For example, `\ctsxrdef{@star}' generates a cross-reference definition +% for `\@star'. +% +\def\ctsxrdef#1{\expandafter\xrdef\csname#1\endcsname} + +% \ctsact prints an active character #1 and generates an index entry +% for it. #1 is blank-delimited. \ctsact does not generate a +% cross-reference definition. +% +\def\ctsact{\begingroup \deactivate \ctsactA} +\def\ctsactA#1 {\endgroup + \ctsbasic{#1}{}% + \pix\ttidxref{#1}} + +% \ctspecial prints a control sequence #1 and generates an index +% entry for it. #1 is blank-delimited. \ctspecial does not +% automatically generate a cross-reference definition, and so it's used +% for things like \newbox and \%. +% +\def\ctspecial{\begingroup \deactivate \ctspecialA} +\def\ctspecialA#1 {\endgroup + \ctsbasic{\\#1}{}% + \pix\ctsidxref{#1}% +} + +% \ctspecialx is like \ctspecial, but leaves more space after its +% argument. We want ` and ' to come from cmtt, instead of Optima, so we +% call \mapquotes before reading the argument. This only affects the \` +% and \' descriptions. +% +\def\ctspecialx{\begingroup \deactivate \mapquotes \ctspecialxA} +\def\ctspecialxA#1 {\endgroup + \ctsbasic{\\#1}{}\quad + \pix\ctsidxref{#1}% +} + +% \ctsdisplay has a blank-delimited argument consisting of a control +% sequence such as alpha. It produces $\alpha$ followed by \alpha. +% +\def\ctsdisplay#1 {\basicdisplay {$\csname #1\endcsname$}{\\#1}% + \ifxref\ctsxrdef{#1}\else\xreftrue\fi \pix\ctsidxref {#1}} + +% \ctsdoubledisplay has a blank-delimited argument consisting of a +% control sequence such as bigvee. It produces $\bigvee$ and +% $\big\bigvee$ followed by \bigvee. +% +\def\ctsdoubledisplay#1 { + {% + \symbolspace = 42pt + \basicdisplay{$\csname #1\endcsname\quad + \displaystyle\csname #1\endcsname$\ddstrut}% + {\\#1}% + }% + \ifxref\ctsxrdef{#1}\else\xreftrue\fi + \pix\ctsidxref{#1}% +} +\def\ddstrut{\vrule width0pt height15pt depth11pt} + +% \ctsydisplay displays a control symbol. #1 is a single character, +% which may be active. #2 is the cross-reference label, +% blank-delimited. +% +\def\ctsydisplay{\begingroup \deactivate\catcode`\|=\other \ctsydisplayA} +\def\ctsydisplayA#1 #2 {\endgroup + \basicdisplay{$\csname\string#1\endcsname$}{\\#1}% + \ifxref \ctsxrdef{#2}\else \xreftrue \fi + \pix\ctsidxref{#1}% +} + +% \actdisplay displays an active character. #1 is the character, and +% #2 is the cross-reference label, blank-delimited. +% +\def\actdisplay{\begingroup\catcode `\|=\other\actdisplayA} +\def\actdisplayA#1 #2 {\endgroup + \basicdisplay{$#1$}{\string#1}% + \ifxref \xrdef{#2}\else \xreftrue \fi + \pix\ttidxref{#1}% +} + +% \basicdisplay does the actual typesetting of a control sequence name. +% for inside displays. +% +\def\basicdisplay#1#2{\testeasy\hbox to \symbolspace{#1\hfil}{\bt #2}} + +% Printing parameter and table entry headings. +% +\def\param#1{\printparam{#1}{parameter}} +\def\tblentry#1{\printparam{#1}{table entry}} +\def\printparam#1#2{\hskip1.5em [\kern3pt \<#1> #2\kern2pt]} + +% Required braces. +% +\def\rqbraces#1{\{\hskip2pt#1\hskip2pt\}} + +% Printing rulers. +% +\def\1{\vrule height 0pt depth 2pt} +\def\2{\vrule height 0pt depth 4pt} +\def\3{\vrule height 0pt depth 6pt} +\def\4{\vrule height 0pt depth 8pt} +\def\ruler#1#2#3{{$\vcenter{\hrule\hbox{\4#1}}\,\,\rm#2\,{#3}$}} +\def\doruler{\par \noindent\ruler} +\def\tick#1{\hbox to .125in{\hfil#1}} +\def\8{\tick\1\tick\2\tick\1\tick\3\tick\1\tick\2\tick\1\tick\4} + +% Macros for the capsule summary chapter. +% +\def\begincapsum{\beginit{CAPSULE SUMMARY}% + \let\bt = \tentt + \bigskip +} + +\def\endcapsum{\endit{CAPSULE SUMMARY}} + +\newbox\@primitivebox \setbox\@primitivebox = \hbox{\tt *} +\newif\ifcs + +\def\capline{\begingroup \deactivate\catcode `\| = \other \caplineA} +\def\caplineA#1 {\endgroup + \begingroup + \catcode `@ = \letter % for constructing labels + \caplineB{#1}% +} + +% Parameters of \caplineB: +% #1 name of control sequence +% #2 description +% #3 * or empty +% #4 xref or xref1:xref2 or empty + +\def\caplineB#1#2#3#4{% + \ifempty {#4}\temptrue\else\tempfalse\fi + % \iftemp needed to avoid \if ... \else ... \fi nesting problems + \ifcs + \toks0 = {\caplineout{\\#1}{#2}{#3}}% + \iftemp + \toks1 = \expandafter{\csname #1\endcsname}% + \else + \toks1 = {#4}% + \fi + \edef\nextaction{\the\toks0 {\the\toks1}}% + \nextaction + \ctsidxref {#1}% + \else + % The \space makes one-character entries line up nicely. + \caplineout{\space #1}{#2}{#3}{#4}% + \ttidxref {#1}% + \fi + \endgroup +} + +\newif\iftemp + + +% In a few cases we have two cross-references for a single control +% sequence. +% +\newif\ifcstwo + +\def\capac{\cstwofalse\csfalse\capline} +\def\capactwo{\cstwotrue\csfalse\capline} +\def\capcs{\cstwofalse\cstrue\capline} +\def\capcstwo{\cstwotrue\cstrue\capline} + +% \caplineout produces an output line (or several lines) for the capsule +% summary. #1 is the command text, #2 is the description, #3 is either * or +% empty, and #4 is the cross-reference label. +% +\def\caplineout#1#2#3#4{% + \setbox0 = \ifempty {#3}\box\voidb@x \else \copy\@primitivebox\fi + \vskip\intercapsuleskip + % If we use \vbox here, a multi-line summary at the top of a page + % will cause \topskip to disappear. + % + \vtop{\noindent \hangindent = \capsulehangindent + \spaceskip = 3.33pt plus 2pt minus 1.5pt + \rightskip = 0pt plus 4em % a little more stretch + \parfillskip = 0pt plus 1fil + \llap{\box0}{\bt #1}% Bold typewriter for the cs name. + \quad \hskip 0pt plus 1pt minus 1pt + #2\unskip\ + (\ifcstwo \tworefs #4:\else \xref{#4}\fi)% + }% + \par +} + +\def\tworefs#1:#2:{\xref{#1}, \xref{#2}} + + + +% Macros for printing the index. +% +% Set up to print it. +% +\def\beginindex{% + \doublecolumns + \beginit{THE INDEX} + \markinfo{\chaptername}% + \indexfonts + \parindent = 0pt + \def\pp##1{{\it ##1}} % Principal entry. + \def\c{,\thinspace\allowbreak}% + \def\ic{,\quad} + \def\see##1{.\quad{\it See} ##1 } + \def\seealso##1{\hfil\break{\it See also} ##1 } + \let\r = \romannumeral + + \raggedright +} + +\def\endindex{\endit{THE INDEX}\singlecolumn} + + +% #1 is the level of this index entry minus 1 (i.e., 0 for a main +% entry), #2 is the index term, #3 is the kind of term +% (T for ttfont, C for control sequence, N for normal), and +% #4 is the list of pages. The page list can have \pp (principal +% entry)in it, and each page is separated by \c. +% +\def\indexentry#1#2#3#4{% + \beginit{INDEX ENTRY}% + \leftskip = #1\indexpageindent + \par + \leavevmode + \hangindent = \indexlevelindent + \ifx #3T% + {\tt #2}% Typewriter. + \else \ifx #3C% + {\tt \llap{\\}#2}% Control sequence. + \else + % in normal entries, \b and \e enclose a group. ({ and } don't work.) + {\let \b = \bgroup \let \e = \egroup #2}% + \fi\fi + #4% The list of pages. + \par + \endit{INDEX ENTRY}% +} + +% Nah, let's forget printing the initial. +% +\def\indexgroup#1{% + \bigskip +} + + + +% Code formatting. +% +% +% Turn off normally special characters. +% +\def\deactivate{% + \catcode`\\ = \other \catcode`\{ = \other \catcode`\} = \other + \catcode`\$ = \other \catcode`\& = \other \catcode`\# = \other + \catcode`\% = \other \catcode`\~ = \other \catcode`\^ = \other + \catcode`\_ = \other +} + +% It is convenient to have |...| mean print the ... verbatim, except for !. +% (But | should just be a vertical bar in math mode.) This should be +% used only for inline code; returns inside |...| become spaces. +% +\catcode`\| = \active +\def|{% + \ifmmode + \vert + \else + \begingroup + \obeyspaces + \begincs + \let| = \endgroup + \fi +} + +% \csdisplay is similar, but it inserts glue before and after. +% It also is ended by |, so we have to redefine that. +% +\def\csdisplay{% + \par + \nobreak % don't break above displays + \vskip\abovedisplayskip + \begingroup + \interlinepenalty = 10000 + \obeywhitespace + \begincs + \def|{\endgroup\vskip\belowdisplayskip \noindent\ignorespaces}% +} + +% \begincs does the setup for verbatim printing. It does not confine +% its effects to a group. +% +\def\begincs{% + \hfuzz = \codefuzz + \parfillskip = 0pt plus 1fil + \parskip = 0pt % don't stretch interparagraph space within code displays + \catcode`\! = 0 + \let\! = \exclam + \let\| = \verticalbar + \let\$ = $% + \let\. = \empty % Use !. to end a control sequence to be executed. + \def\-{\discretionary{-}{}{}}% but allow explicit discretionary hyphens + \tt \deactivate +} + + +\chardef\exclam = `\! +\chardef\verticalbar = `\| + +% In math mode we want vertical bars and exclamation points to be +% regular characters again. +% +\everymath = {\setmathchars} +\everydisplay = {\setmathchars} +\leftdisplays + +\def\setmathchars{% + \catcode`\| = \other \catcode`\! = \other + \let\{ = \lbrace \let\} = \rbrace +} + + + + +% Some miscellanous macros. +% +\def\anatomy{anatomy of \TeX} +\def\ascii{{\ninerm ASCII}} +\def\asciichar#1{$\langle \rm #1\rangle$} +\def\bblfile{{\tt .bbl} file} +\def\bibfile{{\tt .bib} file} +\def\bstfile{{\tt .bst} file} +\def\didotpt{did\^ot point} +\def\dvifile{{\tt .dvi} file} +\def\em{\thinspace {\rm em}} +\def\emph#1{{\it #1}\itcorr} % Emphasize. +\def\ftp{{\tt ftp}} +\def\gffile{{\tt .gf} file} +\def\hand{{\handfont A}} +\def\ifatest{{\tt \\if} test} +\chardef\inches = "7D +\def\knuth#1{#1 of \texbook} +\let\Metafont = \MF +\def\Mperiod.{$M$\kern-1.6pt.} +\def\Mprimecomma,{$M'$\kern-3.5pt,} +\def\Mprimeperiod.{$M'$\kern-2.5pt.} +\def\mud{\thinspace {\rm mu}} % can't use \mu; it'a a Greek letter! +\def\newTeX{new \TeX} +\def\p{p.\thinspace} +\def\pkfile{{\tt .pk} file} +\def\plainTeX{plain \TeX} +\def\PlainTeX{Plain \TeX} +\def\pp{p\p} +\def\pt{\thinspace {\rm pt}} +\def\pxlfile{{\tt .pxl} file} +\def\tequiv{\unskip $\>\equiv\>$} % equivalence in text +\def\texbook{{\sl The \TeX book}\itcorr} +\let\tex@ = \TeX +\def\TeX{\tex@\null} +\def\TeXMeX{\TeX\ M\kern-.11em\lower .5ex\hbox{E}\kern-.125em X\null}% +\def\tfmfile{{\tt .tfm} file} +\def\thisbook{{\sl \TeX\ for the Impatient\/}} +\let\ths = \thinspace +\def\tminus{\unskip\allowbreak $\>-\>$\allowbreak} % minus in text +\def\tplus{\unskip\allowbreak $\>+\>$\allowbreak} % plus in text +\def\TUG{\TeX{} Users Group} +\def\Vcomma,{$V$\kern-2pt,} +\def\visiblespace{{\tentt \char'040}} +\def\Vperiod.{$V$\kern-2pt.} +\let\vs=\visiblespace +\def\xrefpg#1{page~\xrefn{#1}} + +% \tighten attempts to shorten the number of lines occupied by a paragraph. +\def\tighten{\looseness=-1 + \spaceskip = .9\fontdimen2\font plus \fontdimen3\font + minus 1.1\fontdimen4\font +} + +% \itcorr can be used at the end of a macro that puts its argument in +% italics in order to produce an italic correction just when it's needed. +% It won't look inside a following macro call, however. + +\def\itcorr{\futurelet\next\itcorrA} +\def\itcorrA{\ifx.\next\else\ifx,\next\else\/\fi\fi} + + +% Arrange N items in three columns. +% A right brace is needed at the end of the list to match the \bgroup. +% +\def\threecolumns{\nobreak\vskip\abovedisplayskip\dothreecolumns} + +\def\dothreecolumns#1 {\bgroup + \parindent = 0pt + \makecolumns #1/3: +} + +% We don't want to make < an active character because then it cannot be used +% in \ifnum tests. So, \<foo> denotes a nonterminal `foo'. +% +\def\<#1>{$\langle${\rm\it \kern-.2pt #1\kern.65pt}$\rangle$} + +\let\beginit = \environment +\let\endit = \endenvironment + +\def\eatpar#1\par{} + +% \needspace breaks out the page if there's less than #1 left on it. + +\def\needspace#1{% + \saveskip = \lastskip + \par % force vertical mode + \vfil + \penalty 1000 + \vskip #1 + \penalty9999 + \par % exercise the page builder + \vskip -#1 plus -1fil + \vskip -\saveskip \vskip \saveskip % to restore \lastskip +} + + + + +% Expanded cross-referencing for various parts of the books. +% + +% Sometimes it is clearer to refer to a cross-reference as a control +% sequence. +% +\def\ctsref{\begingroup \catcode`\@ = \letter \@ctsref} +\def\@ctsref#1{(\xref{#1})\endgroup} + +\def\xrefdelim[#1]{page~\xrefn{#1}} % this form doesn't need braces + +% This command comes at the beginning of chapters, after the \chapter +% command and before the text. Hence the \par in the template +% and the \noindent +% +\def\chapterdef#1#2\par{% + \@writeaux{% + \string\gdef\expandafter\string + \csname#1_C\endcsname{\the\chapterno}}% + \noindent +} + +\def\chapternum#1{% + \def\csn{#1_C}% + \expandafter\ifx\csname\csn\endcsname \relax + \expandafter\def\csname\csn\endcsname{`#1'}% + \ifxrefwarning + \message{Undefined chapter `#1'.}% + \fi + \fi + \csname\csn\endcsname +} + +\def\chapterref#1{Section~\chapternum{#1}} + +\def\headcit#1#2{``{\rm #1}'' (\xref{#2})} + +\def\conceptcit#1{\headcit{#1}{#1}} + +\def\seeconcept#1{(see ``{\rm #1}'', \xref{#1})} + + + + +% Special types of pictures. +% +% Glue pictures: +% +\newdimen\glueboxwidth +\newdimen\boxdepth \boxdepth = 3.5pc +\newskip\underlabel \underlabel= .1\boxdepth % space under `width n'. +\def\squeezeglue{\glueboxwidth = .725\glueboxwidth} + +\def\labelledbox#1 #2 #3{\vtop{% + \hrule + \hbox{% + \vrule + \hbox to #1{\hfil \vbox to #2{\vfil#3\vskip\underlabel}\hfil}% + \vrule + }% + \hrule +}}% + +% Make a picture of a box. +% +\def\picbox#1 {% + \glueboxwidth = #1pc \squeezeglue + \vtop{% + \hbox to \glueboxwidth{\strut \hfil {\it box}\hfil}% + \labelledbox % Have to have spaces after the arguments. + {\glueboxwidth} + {\boxdepth} + {\halign{\hfil##\hfil\cr width #1\cr}}% + }% +} + +% And of glue. +% +\def\gluebox#1 #2 #3 #4 {\vtop{% + \glueboxwidth = #4pc \squeezeglue + \hbox to \glueboxwidth{\strut \hfil {\it glue}\hfil}% + \nointerlineskip + \kern2pt % to move the brace down a bit + \hbox{$\overbrace{\hbox{\hskip\glueboxwidth}}$}% + \kern-3pt % The \overbrace puts in 3pt below itself. + \nointerlineskip + \vbox to \boxdepth{% + \hsize = \glueboxwidth + \vskip 2pt + \advance\baselineskip by -2pt + \centerline{\strut size #1}% + \centerline{stretch #2}% + \centerline{shrink #3}% + \centerline{width #4}% + \vss + }% + \kern 1.5pt % I don't know why this is needed. + \nointerlineskip + \hbox{$\underbrace{\hbox{\hskip\glueboxwidth}}$}% +}} + +\def\gluepicture#1 #2{{\ninerm + \medskip + \vtop{% + \setbox0 = \hbox{#2}% The glue and box pictures. + \glueboxwidth = \wd0 + \leftline{\box0}% + \kern 6pt + \hbox to \glueboxwidth{\leftarrowfill{ width #1 }\rightarrowfill}% + }% + \medskip +}} + +% Box pictures. +% +% Set up a `reference point' and the macro for a labelled height, for use +% in forming pictures of boxes. +% +\newbox\refpoint + +\setbox\refpoint = \vbox to 0pt{% + \kern-2.6pt + \hbox to 0pt{\kern-2.2pt $\bullet$\hss} + \vss +}% + +\def\labelledheight#1#2{% +\vtop to #1{\offinterlineskip + \setbox0=\hbox{#2}\skip0=\wd0 + \hbox to \skip0{\hss\tenex\char"78\hss}\kern-4pt + {\cleaders\hbox to \skip0{\hss\tenex\char"3F\hss}\vfil}% + \vskip1pt\box0\vskip1pt + {\cleaders\hbox to \skip0{\hss\tenex\char"3F\hss}\vfil}% + \kern -6pt\boxmaxdepth 0pt\hbox to \skip0{\hss\tenex\char"79\hss}}} + + + +% Paul's updates -- no longer needed; we have converged. +% +%\input paulmacs + +% Read the cross-reference definitions. +% +\readauxfile + +\catcode`\@ = \other % Make @ an `other' character again. +\catcode`\^ = \active % Make ^'s do indexing outside of math mode. |