196263Sobrien% texinfo.tex -- TeX macros to handle Texinfo files.
296263Sobrien%
396263Sobrien% Load plain if necessary, i.e., if running under initex.
496263Sobrien\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
596263Sobrien%
6169689Skan\def\texinfoversion{2005-06-10.07}
796263Sobrien%
8117395Skan% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
9169689Skan% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
10169689Skan% Foundation, Inc.
1196263Sobrien%
1296263Sobrien% This texinfo.tex file is free software; you can redistribute it and/or
1396263Sobrien% modify it under the terms of the GNU General Public License as
1496263Sobrien% published by the Free Software Foundation; either version 2, or (at
1596263Sobrien% your option) any later version.
1696263Sobrien%
1796263Sobrien% This texinfo.tex file is distributed in the hope that it will be
1896263Sobrien% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1996263Sobrien% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2096263Sobrien% General Public License for more details.
2196263Sobrien%
2296263Sobrien% You should have received a copy of the GNU General Public License
2396263Sobrien% along with this texinfo.tex file; see the file COPYING.  If not, write
24169689Skan% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25169689Skan% Boston, MA 02110-1301, USA.
2696263Sobrien%
27132718Skan% As a special exception, when this file is read by TeX when processing
28132718Skan% a Texinfo source document, you may use the result without
29132718Skan% restriction.  (This has been our intent since Texinfo was invented.)
30169689Skan%
3196263Sobrien% Please try the latest version of texinfo.tex before submitting bug
3296263Sobrien% reports; you can get the latest version from:
33132718Skan%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
3496263Sobrien%   ftp://tug.org/tex/texinfo.tex
35132718Skan%     (and all CTAN mirrors, see http://www.ctan.org).
36132718Skan% The texinfo.tex in any given distribution could well be out
3796263Sobrien% of date, so if that's what you're using, please check.
38119256Skan%
3996263Sobrien% Send bug reports to bug-texinfo@gnu.org.  Please include including a
4096263Sobrien% complete document in each bug report with which we can reproduce the
4196263Sobrien% problem.  Patches are, of course, greatly appreciated.
4296263Sobrien%
4396263Sobrien% To process a Texinfo manual with TeX, it's most reliable to use the
4496263Sobrien% texi2dvi shell script that comes with the distribution.  For a simple
4596263Sobrien% manual foo.texi, however, you can get away with this:
4696263Sobrien%   tex foo.texi
4796263Sobrien%   texindex foo.??
4896263Sobrien%   tex foo.texi
4996263Sobrien%   tex foo.texi
50117395Skan%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
5196263Sobrien% The extra TeX runs get the cross-reference information correct.
5296263Sobrien% Sometimes one run after texindex suffices, and sometimes you need more
5396263Sobrien% than two; texi2dvi does it as many times as necessary.
5496263Sobrien%
55119256Skan% It is possible to adapt texinfo.tex for other languages, to some
56119256Skan% extent.  You can get the existing language-specific files from the
57119256Skan% full Texinfo distribution.
58169689Skan%
59132718Skan% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
6096263Sobrien
61132718Skan
6296263Sobrien\message{Loading texinfo [version \texinfoversion]:}
6396263Sobrien
6496263Sobrien% If in a .fmt file, print the version number
6596263Sobrien% and turn on active characters that we couldn't do earlier because
6696263Sobrien% they might have appeared in the input file name.
6796263Sobrien\everyjob{\message{[Texinfo version \texinfoversion]}%
6896263Sobrien  \catcode`+=\active \catcode`\_=\active}
6996263Sobrien
70117395Skan\message{Basics,}
71117395Skan\chardef\other=12
72117395Skan
73119256Skan% We never want plain's \outer definition of \+ in Texinfo.
74117395Skan% For @tex, we can use \tabalign.
75117395Skan\let\+ = \relax
76117395Skan
77119256Skan% Save some plain tex macros whose names we will redefine.
7896263Sobrien\let\ptexb=\b
7996263Sobrien\let\ptexbullet=\bullet
8096263Sobrien\let\ptexc=\c
8196263Sobrien\let\ptexcomma=\,
8296263Sobrien\let\ptexdot=\.
8396263Sobrien\let\ptexdots=\dots
8496263Sobrien\let\ptexend=\end
8596263Sobrien\let\ptexequiv=\equiv
8696263Sobrien\let\ptexexclam=\!
87132718Skan\let\ptexfootnote=\footnote
88117395Skan\let\ptexgtr=>
89117395Skan\let\ptexhat=^
9096263Sobrien\let\ptexi=\i
91119256Skan\let\ptexindent=\indent
92132718Skan\let\ptexinsert=\insert
9396263Sobrien\let\ptexlbrace=\{
94117395Skan\let\ptexless=<
95169689Skan\let\ptexnewwrite\newwrite
96169689Skan\let\ptexnoindent=\noindent
97117395Skan\let\ptexplus=+
9896263Sobrien\let\ptexrbrace=\}
99119256Skan\let\ptexslash=\/
10096263Sobrien\let\ptexstar=\*
10196263Sobrien\let\ptext=\t
10296263Sobrien
10396263Sobrien% If this character appears in an error message or help string, it
10496263Sobrien% starts a new line in the output.
10596263Sobrien\newlinechar = `^^J
10696263Sobrien
107132718Skan% Use TeX 3.0's \inputlineno to get the line number, for better error
108132718Skan% messages, but if we're using an old version of TeX, don't do anything.
109132718Skan%
110132718Skan\ifx\inputlineno\thisisundefined
111132718Skan  \let\linenumber = \empty % Pre-3.0.
112132718Skan\else
113132718Skan  \def\linenumber{l.\the\inputlineno:\space}
114132718Skan\fi
115132718Skan
11696263Sobrien% Set up fixed words for English if not already set.
11796263Sobrien\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
11896263Sobrien\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
11996263Sobrien\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
12096263Sobrien\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
12196263Sobrien\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
12296263Sobrien\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
12396263Sobrien\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
12496263Sobrien\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
12596263Sobrien\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
12696263Sobrien\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
12796263Sobrien\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
12896263Sobrien\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
12996263Sobrien\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
13096263Sobrien\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
13196263Sobrien\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
13296263Sobrien\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
13396263Sobrien\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
13496263Sobrien\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
13596263Sobrien\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
13696263Sobrien%
13796263Sobrien\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
13896263Sobrien\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
13996263Sobrien\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
14096263Sobrien\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
14196263Sobrien\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
14296263Sobrien\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
14396263Sobrien\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
14496263Sobrien\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
14596263Sobrien\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
14696263Sobrien\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
14796263Sobrien\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
14896263Sobrien\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
14996263Sobrien%
15096263Sobrien\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
15196263Sobrien\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
15296263Sobrien\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
15396263Sobrien\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
15496263Sobrien\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
15596263Sobrien
156119256Skan% In some macros, we cannot use the `\? notation---the left quote is
157119256Skan% in some cases the escape char.
158169689Skan\chardef\backChar  = `\\
159119256Skan\chardef\colonChar = `\:
160119256Skan\chardef\commaChar = `\,
161119256Skan\chardef\dotChar   = `\.
162119256Skan\chardef\exclamChar= `\!
163169689Skan\chardef\plusChar  = `\+
164119256Skan\chardef\questChar = `\?
165119256Skan\chardef\semiChar  = `\;
166119256Skan\chardef\underChar = `\_
167119256Skan
168132718Skan\chardef\spaceChar = `\ %
169132718Skan\chardef\spacecat = 10
170132718Skan\def\spaceisspace{\catcode\spaceChar=\spacecat}
171132718Skan
172169689Skan{% for help with debugging.
173169689Skan % example usage: \expandafter\show\activebackslash
174169689Skan \catcode`\! = 0 \catcode`\\ = \active
175169689Skan !global!def!activebackslash{\}
176169689Skan}
177169689Skan
17896263Sobrien% Ignore a token.
17996263Sobrien%
18096263Sobrien\def\gobble#1{}
18196263Sobrien
182132718Skan% The following is used inside several \edef's.
183132718Skan\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
184117395Skan
185117395Skan% Hyphenation fixes.
186169689Skan\hyphenation{
187169689Skan  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
188169689Skan  ap-pen-dix bit-map bit-maps
189169689Skan  data-base data-bases eshell fall-ing half-way long-est man-u-script
190169689Skan  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
191169689Skan  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
192169689Skan  spell-ing spell-ings
193169689Skan  stand-alone strong-est time-stamp time-stamps which-ever white-space
194169689Skan  wide-spread wrap-around
195169689Skan}
19696263Sobrien
19796263Sobrien% Margin to add to right of even pages, to left of odd pages.
198117395Skan\newdimen\bindingoffset
199117395Skan\newdimen\normaloffset
20096263Sobrien\newdimen\pagewidth \newdimen\pageheight
20196263Sobrien
202132718Skan% For a final copy, take out the rectangles
203132718Skan% that mark overfull boxes (in case you have decided
204132718Skan% that the text looks ok even though it passes the margin).
205132718Skan%
206132718Skan\def\finalout{\overfullrule=0pt}
207132718Skan
208132718Skan% @| inserts a changebar to the left of the current line.  It should
209132718Skan% surround any changed text.  This approach does *not* work if the
210132718Skan% change spans more than two lines of output.  To handle that, we would
211132718Skan% have adopt a much more difficult approach (putting marks into the main
212132718Skan% vertical list for the beginning and end of each change).
213132718Skan%
214132718Skan\def\|{%
215132718Skan  % \vadjust can only be used in horizontal mode.
216132718Skan  \leavevmode
217132718Skan  %
218132718Skan  % Append this vertical mode material after the current line in the output.
219132718Skan  \vadjust{%
220132718Skan    % We want to insert a rule with the height and depth of the current
221132718Skan    % leading; that is exactly what \strutbox is supposed to record.
222132718Skan    \vskip-\baselineskip
223132718Skan    %
224132718Skan    % \vadjust-items are inserted at the left edge of the type.  So
225132718Skan    % the \llap here moves out into the left-hand margin.
226132718Skan    \llap{%
227132718Skan      %
228132718Skan      % For a thicker or thinner bar, change the `1pt'.
229132718Skan      \vrule height\baselineskip width1pt
230132718Skan      %
231132718Skan      % This is the space between the bar and the text.
232132718Skan      \hskip 12pt
233132718Skan    }%
234132718Skan  }%
235132718Skan}
236132718Skan
23796263Sobrien% Sometimes it is convenient to have everything in the transcript file
23896263Sobrien% and nothing on the terminal.  We don't just call \tracingall here,
239117395Skan% since that produces some useless output on the terminal.  We also make
240117395Skan% some effort to order the tracing commands to reduce output in the log
241117395Skan% file; cf. trace.sty in LaTeX.
24296263Sobrien%
24396263Sobrien\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
244117395Skan\def\loggingall{%
245117395Skan  \tracingstats2
246117395Skan  \tracingpages1
247117395Skan  \tracinglostchars2  % 2 gives us more in etex
248117395Skan  \tracingparagraphs1
249117395Skan  \tracingoutput1
250117395Skan  \tracingmacros2
251117395Skan  \tracingrestores1
252117395Skan  \showboxbreadth\maxdimen \showboxdepth\maxdimen
253117395Skan  \ifx\eTeXversion\undefined\else % etex gives us more logging
254117395Skan    \tracingscantokens1
255117395Skan    \tracingifs1
256117395Skan    \tracinggroups1
257117395Skan    \tracingnesting2
258117395Skan    \tracingassigns1
259117395Skan  \fi
260117395Skan  \tracingcommands3  % 3 gives us more in etex
261132718Skan  \errorcontextlines16
26296263Sobrien}%
26396263Sobrien
26496263Sobrien% add check for \lastpenalty to plain's definitions.  If the last thing
26596263Sobrien% we did was a \nobreak, we don't want to insert more space.
266119256Skan%
26796263Sobrien\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
26896263Sobrien  \removelastskip\penalty-50\smallskip\fi\fi}
26996263Sobrien\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
27096263Sobrien  \removelastskip\penalty-100\medskip\fi\fi}
27196263Sobrien\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
27296263Sobrien  \removelastskip\penalty-200\bigskip\fi\fi}
27396263Sobrien
27496263Sobrien% For @cropmarks command.
27596263Sobrien% Do @cropmarks to get crop marks.
27696263Sobrien%
27796263Sobrien\newif\ifcropmarks
27896263Sobrien\let\cropmarks = \cropmarkstrue
27996263Sobrien%
28096263Sobrien% Dimensions to add cropmarks at corners.
28196263Sobrien% Added by P. A. MacKay, 12 Nov. 1986
28296263Sobrien%
28396263Sobrien\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
28496263Sobrien\newdimen\cornerlong  \cornerlong=1pc
28596263Sobrien\newdimen\cornerthick \cornerthick=.3pt
28696263Sobrien\newdimen\topandbottommargin \topandbottommargin=.75in
28796263Sobrien
28896263Sobrien% Main output routine.
28996263Sobrien\chardef\PAGE = 255
29096263Sobrien\output = {\onepageout{\pagecontents\PAGE}}
29196263Sobrien
29296263Sobrien\newbox\headlinebox
29396263Sobrien\newbox\footlinebox
29496263Sobrien
29596263Sobrien% \onepageout takes a vbox as an argument.  Note that \pagecontents
29696263Sobrien% does insertions, but you have to call it yourself.
29796263Sobrien\def\onepageout#1{%
29896263Sobrien  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
29996263Sobrien  %
30096263Sobrien  \ifodd\pageno  \advance\hoffset by \bindingoffset
30196263Sobrien  \else \advance\hoffset by -\bindingoffset\fi
30296263Sobrien  %
30396263Sobrien  % Do this outside of the \shipout so @code etc. will be expanded in
30496263Sobrien  % the headline as they should be, not taken literally (outputting ''code).
30596263Sobrien  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
30696263Sobrien  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
30796263Sobrien  %
30896263Sobrien  {%
30996263Sobrien    % Have to do this stuff outside the \shipout because we want it to
31096263Sobrien    % take effect in \write's, yet the group defined by the \vbox ends
31196263Sobrien    % before the \shipout runs.
31296263Sobrien    %
31396263Sobrien    \escapechar = `\\     % use backslash in output files.
31496263Sobrien    \indexdummies         % don't expand commands in the output.
31596263Sobrien    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
31696263Sobrien                   % the page break happens to be in the middle of an example.
31796263Sobrien    \shipout\vbox{%
31896263Sobrien      % Do this early so pdf references go to the beginning of the page.
319132718Skan      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
32096263Sobrien      %
32196263Sobrien      \ifcropmarks \vbox to \outervsize\bgroup
32296263Sobrien        \hsize = \outerhsize
32396263Sobrien        \vskip-\topandbottommargin
32496263Sobrien        \vtop to0pt{%
32596263Sobrien          \line{\ewtop\hfil\ewtop}%
32696263Sobrien          \nointerlineskip
32796263Sobrien          \line{%
32896263Sobrien            \vbox{\moveleft\cornerthick\nstop}%
32996263Sobrien            \hfill
33096263Sobrien            \vbox{\moveright\cornerthick\nstop}%
33196263Sobrien          }%
33296263Sobrien          \vss}%
33396263Sobrien        \vskip\topandbottommargin
33496263Sobrien        \line\bgroup
33596263Sobrien          \hfil % center the page within the outer (page) hsize.
33696263Sobrien          \ifodd\pageno\hskip\bindingoffset\fi
33796263Sobrien          \vbox\bgroup
33896263Sobrien      \fi
33996263Sobrien      %
34096263Sobrien      \unvbox\headlinebox
34196263Sobrien      \pagebody{#1}%
34296263Sobrien      \ifdim\ht\footlinebox > 0pt
34396263Sobrien        % Only leave this space if the footline is nonempty.
34496263Sobrien        % (We lessened \vsize for it in \oddfootingxxx.)
34596263Sobrien        % The \baselineskip=24pt in plain's \makefootline has no effect.
34696263Sobrien        \vskip 2\baselineskip
34796263Sobrien        \unvbox\footlinebox
34896263Sobrien      \fi
34996263Sobrien      %
35096263Sobrien      \ifcropmarks
35196263Sobrien          \egroup % end of \vbox\bgroup
35296263Sobrien        \hfil\egroup % end of (centering) \line\bgroup
35396263Sobrien        \vskip\topandbottommargin plus1fill minus1fill
35496263Sobrien        \boxmaxdepth = \cornerthick
35596263Sobrien        \vbox to0pt{\vss
35696263Sobrien          \line{%
35796263Sobrien            \vbox{\moveleft\cornerthick\nsbot}%
35896263Sobrien            \hfill
35996263Sobrien            \vbox{\moveright\cornerthick\nsbot}%
36096263Sobrien          }%
36196263Sobrien          \nointerlineskip
36296263Sobrien          \line{\ewbot\hfil\ewbot}%
36396263Sobrien        }%
36496263Sobrien      \egroup % \vbox from first cropmarks clause
36596263Sobrien      \fi
36696263Sobrien    }% end of \shipout\vbox
367119256Skan  }% end of group with \normalturnoffactive
36896263Sobrien  \advancepageno
36996263Sobrien  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
37096263Sobrien}
37196263Sobrien
37296263Sobrien\newinsert\margin \dimen\margin=\maxdimen
37396263Sobrien
37496263Sobrien\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
37596263Sobrien{\catcode`\@ =11
37696263Sobrien\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
37796263Sobrien% marginal hacks, juha@viisa.uucp (Juha Takala)
37896263Sobrien\ifvoid\margin\else % marginal info is present
37996263Sobrien  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
38096263Sobrien\dimen@=\dp#1 \unvbox#1
38196263Sobrien\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
38296263Sobrien\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
38396263Sobrien}
38496263Sobrien
38596263Sobrien% Here are the rules for the cropmarks.  Note that they are
38696263Sobrien% offset so that the space between them is truly \outerhsize or \outervsize
38796263Sobrien% (P. A. MacKay, 12 November, 1986)
38896263Sobrien%
38996263Sobrien\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
39096263Sobrien\def\nstop{\vbox
39196263Sobrien  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
39296263Sobrien\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
39396263Sobrien\def\nsbot{\vbox
39496263Sobrien  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
39596263Sobrien
39696263Sobrien% Parse an argument, then pass it to #1.  The argument is the rest of
39796263Sobrien% the input line (except we remove a trailing comment).  #1 should be a
39896263Sobrien% macro which expects an ordinary undelimited TeX argument.
39996263Sobrien%
400132718Skan\def\parsearg{\parseargusing{}}
401132718Skan\def\parseargusing#1#2{%
402132718Skan  \def\next{#2}%
40396263Sobrien  \begingroup
40496263Sobrien    \obeylines
405132718Skan    \spaceisspace
406132718Skan    #1%
407132718Skan    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
40896263Sobrien}
40996263Sobrien
41096263Sobrien{\obeylines %
41196263Sobrien  \gdef\parseargline#1^^M{%
41296263Sobrien    \endgroup % End of the group started in \parsearg.
413132718Skan    \argremovecomment #1\comment\ArgTerm%
41496263Sobrien  }%
41596263Sobrien}
41696263Sobrien
417132718Skan% First remove any @comment, then any @c comment.
418132718Skan\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
419132718Skan\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
42096263Sobrien
421132718Skan% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
422132718Skan%
423132718Skan% \argremovec might leave us with trailing space, e.g.,
42496263Sobrien%    @end itemize  @c foo
425132718Skan% This space token undergoes the same procedure and is eventually removed
426132718Skan% by \finishparsearg.
42796263Sobrien%
428132718Skan\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
429132718Skan\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
430132718Skan\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
431132718Skan  \def\temp{#3}%
432132718Skan  \ifx\temp\empty
433132718Skan    % We cannot use \next here, as it holds the macro to run;
434132718Skan    % thus we reuse \temp.
435132718Skan    \let\temp\finishparsearg
436132718Skan  \else
437132718Skan    \let\temp\argcheckspaces
438132718Skan  \fi
439132718Skan  % Put the space token in:
440132718Skan  \temp#1 #3\ArgTerm
441132718Skan}
442132718Skan
443132718Skan% If a _delimited_ argument is enclosed in braces, they get stripped; so
444132718Skan% to get _exactly_ the rest of the line, we had to prevent such situation.
445132718Skan% We prepended an \empty token at the very beginning and we expand it now,
446132718Skan% just before passing the control to \next.
447132718Skan% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
448132718Skan% either the null string, or it ends with \^^M---thus there is no danger
449132718Skan% that a pair of braces would be stripped.
45096263Sobrien%
451132718Skan% But first, we have to remove the trailing space token.
452132718Skan%
453132718Skan\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
454132718Skan
455132718Skan% \parseargdef\foo{...}
456132718Skan%	is roughly equivalent to
457132718Skan% \def\foo{\parsearg\Xfoo}
458132718Skan% \def\Xfoo#1{...}
459132718Skan%
460132718Skan% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
461132718Skan% favourite TeX trick.  --kasal, 16nov03
462132718Skan
463132718Skan\def\parseargdef#1{%
464132718Skan  \expandafter \doparseargdef \csname\string#1\endcsname #1%
46596263Sobrien}
466132718Skan\def\doparseargdef#1#2{%
467132718Skan  \def#2{\parsearg#1}%
468132718Skan  \def#1##1%
469132718Skan}
47096263Sobrien
471132718Skan% Several utility definitions with active space:
472132718Skan{
47396263Sobrien  \obeyspaces
474132718Skan  \gdef\obeyedspace{ }
47596263Sobrien
476132718Skan  % Make each space character in the input produce a normal interword
477132718Skan  % space in the output.  Don't allow a line break at this space, as this
478132718Skan  % is used only in environments like @example, where each line of input
479132718Skan  % should produce a line of output anyway.
480132718Skan  %
481132718Skan  \gdef\sepspaces{\obeyspaces\let =\tie}
48296263Sobrien
483132718Skan  % If an index command is used in an @example environment, any spaces
484132718Skan  % therein should become regular spaces in the raw index file, not the
485132718Skan  % expansion of \tie (\leavevmode \penalty \@M \ ).
486132718Skan  \gdef\unsepspaces{\let =\space}
487132718Skan}
488132718Skan
489132718Skan
49096263Sobrien\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
49196263Sobrien
492132718Skan% Define the framework for environments in texinfo.tex.  It's used like this:
493169689Skan%
494132718Skan%   \envdef\foo{...}
495132718Skan%   \def\Efoo{...}
496169689Skan%
497132718Skan% It's the responsibility of \envdef to insert \begingroup before the
498132718Skan% actual body; @end closes the group after calling \Efoo.  \envdef also
499132718Skan% defines \thisenv, so the current environment is known; @end checks
500132718Skan% whether the environment name matches.  The \checkenv macro can also be
501132718Skan% used to check whether the current environment is the one expected.
502169689Skan%
503132718Skan% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
504132718Skan% are not treated as enviroments; they don't open a group.  (The
505132718Skan% implementation of @end takes care not to call \endgroup in this
506132718Skan% special case.)
50796263Sobrien
50896263Sobrien
509132718Skan% At runtime, environments start with this:
510132718Skan\def\startenvironment#1{\begingroup\def\thisenv{#1}}
511132718Skan% initialize
512132718Skan\let\thisenv\empty
51396263Sobrien
514132718Skan% ... but they get defined via ``\envdef\foo{...}'':
515132718Skan\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
516132718Skan\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
51796263Sobrien
518132718Skan% Check whether we're in the right environment:
519132718Skan\def\checkenv#1{%
520132718Skan  \def\temp{#1}%
521132718Skan  \ifx\thisenv\temp
52296263Sobrien  \else
523132718Skan    \badenverr
52496263Sobrien  \fi
52596263Sobrien}
52696263Sobrien
527132718Skan% Evironment mismatch, #1 expected:
528132718Skan\def\badenverr{%
52996263Sobrien  \errhelp = \EMsimple
530132718Skan  \errmessage{This command can appear only \inenvironment\temp,
531132718Skan    not \inenvironment\thisenv}%
53296263Sobrien}
533132718Skan\def\inenvironment#1{%
534132718Skan  \ifx#1\empty
535132718Skan    out of any environment%
536132718Skan  \else
537132718Skan    in environment \expandafter\string#1%
538132718Skan  \fi
539132718Skan}
54096263Sobrien
541132718Skan% @end foo executes the definition of \Efoo.
542132718Skan% But first, it executes a specialized version of \checkenv
54396263Sobrien%
544132718Skan\parseargdef\end{%
545132718Skan  \if 1\csname iscond.#1\endcsname
546132718Skan  \else
547132718Skan    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
548132718Skan    \expandafter\checkenv\csname#1\endcsname
549132718Skan    \csname E#1\endcsname
550132718Skan    \endgroup
551132718Skan  \fi
55296263Sobrien}
55396263Sobrien
554132718Skan\newhelp\EMsimple{Press RETURN to continue.}
55596263Sobrien
556132718Skan
55796263Sobrien%% Simple single-character @ commands
55896263Sobrien
55996263Sobrien% @@ prints an @
56096263Sobrien% Kludge this until the fonts are right (grr).
56196263Sobrien\def\@{{\tt\char64}}
56296263Sobrien
56396263Sobrien% This is turned off because it was never documented
56496263Sobrien% and you can use @w{...} around a quote to suppress ligatures.
56596263Sobrien%% Define @` and @' to be the same as ` and '
56696263Sobrien%% but suppressing ligatures.
56796263Sobrien%\def\`{{`}}
56896263Sobrien%\def\'{{'}}
56996263Sobrien
57096263Sobrien% Used to generate quoted braces.
57196263Sobrien\def\mylbrace {{\tt\char123}}
57296263Sobrien\def\myrbrace {{\tt\char125}}
57396263Sobrien\let\{=\mylbrace
57496263Sobrien\let\}=\myrbrace
57596263Sobrien\begingroup
576119256Skan  % Definitions to produce \{ and \} commands for indices,
577169689Skan  % and @{ and @} for the aux/toc files.
578119256Skan  \catcode`\{ = \other \catcode`\} = \other
57996263Sobrien  \catcode`\[ = 1 \catcode`\] = 2
580119256Skan  \catcode`\! = 0 \catcode`\\ = \other
581119256Skan  !gdef!lbracecmd[\{]%
582119256Skan  !gdef!rbracecmd[\}]%
583119256Skan  !gdef!lbraceatcmd[@{]%
584119256Skan  !gdef!rbraceatcmd[@}]%
585119256Skan!endgroup
58696263Sobrien
587132718Skan% @comma{} to avoid , parsing problems.
588132718Skan\let\comma = ,
589132718Skan
59096263Sobrien% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
591119256Skan% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
59296263Sobrien\let\, = \c
59396263Sobrien\let\dotaccent = \.
59496263Sobrien\def\ringaccent#1{{\accent23 #1}}
59596263Sobrien\let\tieaccent = \t
59696263Sobrien\let\ubaraccent = \b
59796263Sobrien\let\udotaccent = \d
59896263Sobrien
599132718Skan% Other special characters: @questiondown @exclamdown @ordf @ordm
600119256Skan% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
60196263Sobrien\def\questiondown{?`}
60296263Sobrien\def\exclamdown{!`}
603132718Skan\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
604132718Skan\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
60596263Sobrien
60696263Sobrien% Dotless i and dotless j, used for accents.
60796263Sobrien\def\imacro{i}
60896263Sobrien\def\jmacro{j}
60996263Sobrien\def\dotless#1{%
61096263Sobrien  \def\temp{#1}%
61196263Sobrien  \ifx\temp\imacro \ptexi
61296263Sobrien  \else\ifx\temp\jmacro \j
61396263Sobrien  \else \errmessage{@dotless can be used only with i or j}%
61496263Sobrien  \fi\fi
61596263Sobrien}
61696263Sobrien
617169689Skan% The \TeX{} logo, as in plain, but resetting the spacing so that a
618169689Skan% period following counts as ending a sentence.  (Idea found in latex.)
619169689Skan%
620169689Skan\edef\TeX{\TeX \spacefactor=1000 }
621169689Skan
622169689Skan% @LaTeX{} logo.  Not quite the same results as the definition in
623169689Skan% latex.ltx, since we use a different font for the raised A; it's most
624169689Skan% convenient for us to use an explicitly smaller font, rather than using
625169689Skan% the \scriptstyle font (since we don't reset \scriptstyle and
626169689Skan% \scriptscriptstyle).
627169689Skan%
628132718Skan\def\LaTeX{%
629132718Skan  L\kern-.36em
630132718Skan  {\setbox0=\hbox{T}%
631132718Skan   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
632132718Skan  \kern-.15em
633132718Skan  \TeX
634132718Skan}
635132718Skan
63696263Sobrien% Be sure we're in horizontal mode when doing a tie, since we make space
63796263Sobrien% equivalent to this in @example-like environments. Otherwise, a space
63896263Sobrien% at the beginning of a line will start with \penalty -- and
63996263Sobrien% since \penalty is valid in vertical mode, we'd end up putting the
64096263Sobrien% penalty on the vertical list instead of in the new paragraph.
64196263Sobrien{\catcode`@ = 11
64296263Sobrien % Avoid using \@M directly, because that causes trouble
64396263Sobrien % if the definition is written into an index file.
64496263Sobrien \global\let\tiepenalty = \@M
64596263Sobrien \gdef\tie{\leavevmode\penalty\tiepenalty\ }
64696263Sobrien}
64796263Sobrien
64896263Sobrien% @: forces normal size whitespace following.
64996263Sobrien\def\:{\spacefactor=1000 }
65096263Sobrien
65196263Sobrien% @* forces a line break.
65296263Sobrien\def\*{\hfil\break\hbox{}\ignorespaces}
65396263Sobrien
654119256Skan% @/ allows a line break.
655119256Skan\let\/=\allowbreak
656119256Skan
65796263Sobrien% @. is an end-of-sentence period.
658169689Skan\def\.{.\spacefactor=\endofsentencespacefactor\space}
65996263Sobrien
66096263Sobrien% @! is an end-of-sentence bang.
661169689Skan\def\!{!\spacefactor=\endofsentencespacefactor\space}
66296263Sobrien
66396263Sobrien% @? is an end-of-sentence query.
664169689Skan\def\?{?\spacefactor=\endofsentencespacefactor\space}
66596263Sobrien
666169689Skan% @frenchspacing on|off  says whether to put extra space after punctuation.
667169689Skan% 
668169689Skan\def\onword{on}
669169689Skan\def\offword{off}
670169689Skan%
671169689Skan\parseargdef\frenchspacing{%
672169689Skan  \def\temp{#1}%
673169689Skan  \ifx\temp\onword \plainfrenchspacing
674169689Skan  \else\ifx\temp\offword \plainnonfrenchspacing
675169689Skan  \else
676169689Skan    \errhelp = \EMsimple
677169689Skan    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
678169689Skan  \fi\fi
679169689Skan}
680169689Skan
68196263Sobrien% @w prevents a word break.  Without the \leavevmode, @w at the
68296263Sobrien% beginning of a paragraph, when TeX is still in vertical mode, would
68396263Sobrien% produce a whole line of output instead of starting the paragraph.
68496263Sobrien\def\w#1{\leavevmode\hbox{#1}}
68596263Sobrien
68696263Sobrien% @group ... @end group forces ... to be all on one page, by enclosing
68796263Sobrien% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
68896263Sobrien% to keep its height that of a normal line.  According to the rules for
68996263Sobrien% \topskip (p.114 of the TeXbook), the glue inserted is
69096263Sobrien% max (\topskip - \ht (first item), 0).  If that height is large,
69196263Sobrien% therefore, no glue is inserted, and the space between the headline and
69296263Sobrien% the text is small, which looks bad.
69396263Sobrien%
694119256Skan% Another complication is that the group might be very large.  This can
695119256Skan% cause the glue on the previous page to be unduly stretched, because it
696119256Skan% does not have much material.  In this case, it's better to add an
697119256Skan% explicit \vfill so that the extra space is at the bottom.  The
698119256Skan% threshold for doing this is if the group is more than \vfilllimit
699119256Skan% percent of a page (\vfilllimit can be changed inside of @tex).
700119256Skan%
701119256Skan\newbox\groupbox
702119256Skan\def\vfilllimit{0.7}
703119256Skan%
704132718Skan\envdef\group{%
705132718Skan  \ifnum\catcode`\^^M=\active \else
70696263Sobrien    \errhelp = \groupinvalidhelp
70796263Sobrien    \errmessage{@group invalid in context where filling is enabled}%
70896263Sobrien  \fi
709132718Skan  \startsavinginserts
71096263Sobrien  %
711119256Skan  \setbox\groupbox = \vtop\bgroup
71296263Sobrien    % Do @comment since we are called inside an environment such as
71396263Sobrien    % @example, where each end-of-line in the input causes an
71496263Sobrien    % end-of-line in the output.  We don't want the end-of-line after
71596263Sobrien    % the `@group' to put extra space in the output.  Since @group
71696263Sobrien    % should appear on a line by itself (according to the Texinfo
71796263Sobrien    % manual), we don't worry about eating any user text.
71896263Sobrien    \comment
71996263Sobrien}
72096263Sobrien%
721132718Skan% The \vtop produces a box with normal height and large depth; thus, TeX puts
722132718Skan% \baselineskip glue before it, and (when the next line of text is done)
723132718Skan% \lineskip glue after it.  Thus, space below is not quite equal to space
724132718Skan% above.  But it's pretty close.
725132718Skan\def\Egroup{%
726132718Skan    % To get correct interline space between the last line of the group
727132718Skan    % and the first line afterwards, we have to propagate \prevdepth.
728132718Skan    \endgraf % Not \par, as it may have been set to \lisppar.
729132718Skan    \global\dimen1 = \prevdepth
730132718Skan  \egroup           % End the \vtop.
731132718Skan  % \dimen0 is the vertical size of the group's box.
732132718Skan  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
733132718Skan  % \dimen2 is how much space is left on the page (more or less).
734132718Skan  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
735132718Skan  % if the group doesn't fit on the current page, and it's a big big
736132718Skan  % group, force a page break.
737132718Skan  \ifdim \dimen0 > \dimen2
738132718Skan    \ifdim \pagetotal < \vfilllimit\pageheight
739132718Skan      \page
740132718Skan    \fi
741132718Skan  \fi
742132718Skan  \box\groupbox
743132718Skan  \prevdepth = \dimen1
744132718Skan  \checkinserts
745132718Skan}
746132718Skan%
74796263Sobrien% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
74896263Sobrien% message, so this ends up printing `@group can only ...'.
74996263Sobrien%
75096263Sobrien\newhelp\groupinvalidhelp{%
75196263Sobriengroup can only be used in environments such as @example,^^J%
75296263Sobrienwhere each line of input produces a line of output.}
75396263Sobrien
75496263Sobrien% @need space-in-mils
75596263Sobrien% forces a page break if there is not space-in-mils remaining.
75696263Sobrien
75796263Sobrien\newdimen\mil  \mil=0.001in
75896263Sobrien
75996263Sobrien% Old definition--didn't work.
760132718Skan%\parseargdef\need{\par %
76196263Sobrien%% This method tries to make TeX break the page naturally
76296263Sobrien%% if the depth of the box does not fit.
76396263Sobrien%{\baselineskip=0pt%
76496263Sobrien%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
76596263Sobrien%\prevdepth=-1000pt
76696263Sobrien%}}
76796263Sobrien
768132718Skan\parseargdef\need{%
76996263Sobrien  % Ensure vertical mode, so we don't make a big box in the middle of a
77096263Sobrien  % paragraph.
77196263Sobrien  \par
77296263Sobrien  %
77396263Sobrien  % If the @need value is less than one line space, it's useless.
77496263Sobrien  \dimen0 = #1\mil
77596263Sobrien  \dimen2 = \ht\strutbox
77696263Sobrien  \advance\dimen2 by \dp\strutbox
77796263Sobrien  \ifdim\dimen0 > \dimen2
77896263Sobrien    %
77996263Sobrien    % Do a \strut just to make the height of this box be normal, so the
78096263Sobrien    % normal leading is inserted relative to the preceding line.
78196263Sobrien    % And a page break here is fine.
78296263Sobrien    \vtop to #1\mil{\strut\vfil}%
78396263Sobrien    %
78496263Sobrien    % TeX does not even consider page breaks if a penalty added to the
78596263Sobrien    % main vertical list is 10000 or more.  But in order to see if the
78696263Sobrien    % empty box we just added fits on the page, we must make it consider
78796263Sobrien    % page breaks.  On the other hand, we don't want to actually break the
78896263Sobrien    % page after the empty box.  So we use a penalty of 9999.
78996263Sobrien    %
79096263Sobrien    % There is an extremely small chance that TeX will actually break the
79196263Sobrien    % page at this \penalty, if there are no other feasible breakpoints in
79296263Sobrien    % sight.  (If the user is using lots of big @group commands, which
79396263Sobrien    % almost-but-not-quite fill up a page, TeX will have a hard time doing
79496263Sobrien    % good page breaking, for example.)  However, I could not construct an
79596263Sobrien    % example where a page broke at this \penalty; if it happens in a real
79696263Sobrien    % document, then we can reconsider our strategy.
79796263Sobrien    \penalty9999
79896263Sobrien    %
79996263Sobrien    % Back up by the size of the box, whether we did a page break or not.
80096263Sobrien    \kern -#1\mil
80196263Sobrien    %
80296263Sobrien    % Do not allow a page break right after this kern.
80396263Sobrien    \nobreak
80496263Sobrien  \fi
80596263Sobrien}
80696263Sobrien
807132718Skan% @br   forces paragraph break (and is undocumented).
80896263Sobrien
80996263Sobrien\let\br = \par
81096263Sobrien
811119256Skan% @page forces the start of a new page.
81296263Sobrien%
81396263Sobrien\def\page{\par\vfill\supereject}
81496263Sobrien
81596263Sobrien% @exdent text....
81696263Sobrien% outputs text on separate line in roman font, starting at standard page margin
81796263Sobrien
81896263Sobrien% This records the amount of indent in the innermost environment.
81996263Sobrien% That's how much \exdent should take out.
82096263Sobrien\newskip\exdentamount
82196263Sobrien
82296263Sobrien% This defn is used inside fill environments such as @defun.
823132718Skan\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
82496263Sobrien
82596263Sobrien% This defn is used inside nofill environments such as @example.
826132718Skan\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
827132718Skan  \leftline{\hskip\leftskip{\rm#1}}}}
82896263Sobrien
82996263Sobrien% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
83096263Sobrien% paragraph.  For more general purposes, use the \margin insertion
83196263Sobrien% class.  WHICH is `l' or `r'.
83296263Sobrien%
83396263Sobrien\newskip\inmarginspacing \inmarginspacing=1cm
83496263Sobrien\def\strutdepth{\dp\strutbox}
83596263Sobrien%
83696263Sobrien\def\doinmargin#1#2{\strut\vadjust{%
83796263Sobrien  \nobreak
83896263Sobrien  \kern-\strutdepth
83996263Sobrien  \vtop to \strutdepth{%
84096263Sobrien    \baselineskip=\strutdepth
84196263Sobrien    \vss
84296263Sobrien    % if you have multiple lines of stuff to put here, you'll need to
84396263Sobrien    % make the vbox yourself of the appropriate size.
84496263Sobrien    \ifx#1l%
84596263Sobrien      \llap{\ignorespaces #2\hskip\inmarginspacing}%
84696263Sobrien    \else
84796263Sobrien      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
84896263Sobrien    \fi
84996263Sobrien    \null
85096263Sobrien  }%
85196263Sobrien}}
85296263Sobrien\def\inleftmargin{\doinmargin l}
85396263Sobrien\def\inrightmargin{\doinmargin r}
85496263Sobrien%
85596263Sobrien% @inmargin{TEXT [, RIGHT-TEXT]}
85696263Sobrien% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
85796263Sobrien% else use TEXT for both).
858119256Skan%
85996263Sobrien\def\inmargin#1{\parseinmargin #1,,\finish}
86096263Sobrien\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
861119256Skan  \setbox0 = \hbox{\ignorespaces #2}%
86296263Sobrien  \ifdim\wd0 > 0pt
86396263Sobrien    \def\lefttext{#1}%  have both texts
86496263Sobrien    \def\righttext{#2}%
86596263Sobrien  \else
86696263Sobrien    \def\lefttext{#1}%  have only one text
86796263Sobrien    \def\righttext{#1}%
86896263Sobrien  \fi
86996263Sobrien  %
87096263Sobrien  \ifodd\pageno
87196263Sobrien    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
87296263Sobrien  \else
87396263Sobrien    \def\temp{\inleftmargin\lefttext}%
87496263Sobrien  \fi
87596263Sobrien  \temp
87696263Sobrien}
87796263Sobrien
87896263Sobrien% @include file    insert text of that file as input.
879132718Skan%
880132718Skan\def\include{\parseargusing\filenamecatcodes\includezzz}
881132718Skan\def\includezzz#1{%
882132718Skan  \pushthisfilestack
883132718Skan  \def\thisfile{#1}%
884132718Skan  {%
885132718Skan    \makevalueexpandable
886132718Skan    \def\temp{\input #1 }%
887132718Skan    \expandafter
888132718Skan  }\temp
889132718Skan  \popthisfilestack
890132718Skan}
891132718Skan\def\filenamecatcodes{%
892119256Skan  \catcode`\\=\other
893119256Skan  \catcode`~=\other
894119256Skan  \catcode`^=\other
895119256Skan  \catcode`_=\other
896119256Skan  \catcode`|=\other
897119256Skan  \catcode`<=\other
898119256Skan  \catcode`>=\other
899119256Skan  \catcode`+=\other
900132718Skan  \catcode`-=\other
901132718Skan}
90296263Sobrien
903132718Skan\def\pushthisfilestack{%
904132718Skan  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
905132718Skan}
906132718Skan\def\pushthisfilestackX{%
907132718Skan  \expandafter\pushthisfilestackY\thisfile\StackTerm
908132718Skan}
909132718Skan\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
910132718Skan  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
911132718Skan}
912132718Skan
913132718Skan\def\popthisfilestack{\errthisfilestackempty}
914132718Skan\def\errthisfilestackempty{\errmessage{Internal error:
915132718Skan  the stack of filenames is empty.}}
916132718Skan
91796263Sobrien\def\thisfile{}
91896263Sobrien
919119256Skan% @center line
920119256Skan% outputs that line, centered.
921119256Skan%
922132718Skan\parseargdef\center{%
923132718Skan  \ifhmode
924132718Skan    \let\next\centerH
925132718Skan  \else
926132718Skan    \let\next\centerV
927132718Skan  \fi
928132718Skan  \next{\hfil \ignorespaces#1\unskip \hfil}%
929132718Skan}
930132718Skan\def\centerH#1{%
931132718Skan  {%
932132718Skan    \hfil\break
933132718Skan    \advance\hsize by -\leftskip
934132718Skan    \advance\hsize by -\rightskip
935132718Skan    \line{#1}%
936132718Skan    \break
937132718Skan  }%
938132718Skan}
939132718Skan\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
94096263Sobrien
94196263Sobrien% @sp n   outputs n lines of vertical space
94296263Sobrien
943132718Skan\parseargdef\sp{\vskip #1\baselineskip}
94496263Sobrien
94596263Sobrien% @comment ...line which is ignored...
94696263Sobrien% @c is the same as @comment
94796263Sobrien% @ignore ... @end ignore  is another way to write a comment
94896263Sobrien
94996263Sobrien\def\comment{\begingroup \catcode`\^^M=\other%
95096263Sobrien\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
95196263Sobrien\commentxxx}
95296263Sobrien{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
95396263Sobrien
95496263Sobrien\let\c=\comment
95596263Sobrien
95696263Sobrien% @paragraphindent NCHARS
95796263Sobrien% We'll use ems for NCHARS, close enough.
958119256Skan% NCHARS can also be the word `asis' or `none'.
959119256Skan% We cannot feasibly implement @paragraphindent asis, though.
960119256Skan%
96196263Sobrien\def\asisword{asis} % no translation, these are keywords
96296263Sobrien\def\noneword{none}
96396263Sobrien%
964132718Skan\parseargdef\paragraphindent{%
96596263Sobrien  \def\temp{#1}%
96696263Sobrien  \ifx\temp\asisword
96796263Sobrien  \else
96896263Sobrien    \ifx\temp\noneword
96996263Sobrien      \defaultparindent = 0pt
97096263Sobrien    \else
97196263Sobrien      \defaultparindent = #1em
97296263Sobrien    \fi
97396263Sobrien  \fi
97496263Sobrien  \parindent = \defaultparindent
97596263Sobrien}
97696263Sobrien
97796263Sobrien% @exampleindent NCHARS
97896263Sobrien% We'll use ems for NCHARS like @paragraphindent.
97996263Sobrien% It seems @exampleindent asis isn't necessary, but
98096263Sobrien% I preserve it to make it similar to @paragraphindent.
981132718Skan\parseargdef\exampleindent{%
98296263Sobrien  \def\temp{#1}%
98396263Sobrien  \ifx\temp\asisword
98496263Sobrien  \else
98596263Sobrien    \ifx\temp\noneword
98696263Sobrien      \lispnarrowing = 0pt
98796263Sobrien    \else
98896263Sobrien      \lispnarrowing = #1em
98996263Sobrien    \fi
99096263Sobrien  \fi
99196263Sobrien}
99296263Sobrien
993119256Skan% @firstparagraphindent WORD
994119256Skan% If WORD is `none', then suppress indentation of the first paragraph
995132718Skan% after a section heading.  If WORD is `insert', then do indent at such
996119256Skan% paragraphs.
997119256Skan%
998119256Skan% The paragraph indentation is suppressed or not by calling
999132718Skan% \suppressfirstparagraphindent, which the sectioning commands do.
1000132718Skan% We switch the definition of this back and forth according to WORD.
1001132718Skan% By default, we suppress indentation.
1002119256Skan%
1003119256Skan\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
1004119256Skan\def\insertword{insert}
1005119256Skan%
1006132718Skan\parseargdef\firstparagraphindent{%
1007119256Skan  \def\temp{#1}%
1008119256Skan  \ifx\temp\noneword
1009119256Skan    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
1010119256Skan  \else\ifx\temp\insertword
1011119256Skan    \let\suppressfirstparagraphindent = \relax
1012119256Skan  \else
1013119256Skan    \errhelp = \EMsimple
1014119256Skan    \errmessage{Unknown @firstparagraphindent option `\temp'}%
1015119256Skan  \fi\fi
1016119256Skan}
1017119256Skan
1018119256Skan% Here is how we actually suppress indentation.  Redefine \everypar to
1019119256Skan% \kern backwards by \parindent, and then reset itself to empty.
1020119256Skan%
1021119256Skan% We also make \indent itself not actually do anything until the next
1022119256Skan% paragraph.
1023119256Skan%
1024119256Skan\gdef\dosuppressfirstparagraphindent{%
1025119256Skan  \gdef\indent{%
1026132718Skan    \restorefirstparagraphindent
1027132718Skan    \indent
1028119256Skan  }%
1029132718Skan  \gdef\noindent{%
1030132718Skan    \restorefirstparagraphindent
1031132718Skan    \noindent
1032132718Skan  }%
1033119256Skan  \global\everypar = {%
1034132718Skan    \kern -\parindent
1035132718Skan    \restorefirstparagraphindent
1036119256Skan  }%
1037132718Skan}
1038119256Skan
1039132718Skan\gdef\restorefirstparagraphindent{%
1040132718Skan  \global \let \indent = \ptexindent
1041132718Skan  \global \let \noindent = \ptexnoindent
1042132718Skan  \global \everypar = {}%
1043132718Skan}
1044119256Skan
1045132718Skan
104696263Sobrien% @asis just yields its argument.  Used with @table, for example.
104796263Sobrien%
104896263Sobrien\def\asis#1{#1}
104996263Sobrien
105096263Sobrien% @math outputs its argument in math mode.
1051119256Skan%
105296263Sobrien% One complication: _ usually means subscripts, but it could also mean
105396263Sobrien% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
1054132718Skan% _ active, and distinguish by seeing if the current family is \slfam,
1055132718Skan% which is what @var uses.
1056132718Skan{
1057132718Skan  \catcode\underChar = \active
1058132718Skan  \gdef\mathunderscore{%
1059132718Skan    \catcode\underChar=\active
1060132718Skan    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
1061132718Skan  }
1062132718Skan}
1063117395Skan% Another complication: we want \\ (and @\) to output a \ character.
1064117395Skan% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
1065117395Skan% this is not advertised and we don't care.  Texinfo does not
1066117395Skan% otherwise define @\.
1067119256Skan%
1068117395Skan% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
1069117395Skan\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
1070117395Skan%
1071117395Skan\def\math{%
1072117395Skan  \tex
1073132718Skan  \mathunderscore
1074117395Skan  \let\\ = \mathbackslash
1075117395Skan  \mathactive
1076132718Skan  $\finishmath
1077132718Skan}
1078132718Skan\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
107996263Sobrien
1080117395Skan% Some active characters (such as <) are spaced differently in math.
1081132718Skan% We have to reset their definitions in case the @math was an argument
1082132718Skan% to a command which sets the catcodes (such as @item or @section).
1083119256Skan%
1084117395Skan{
1085117395Skan  \catcode`^ = \active
1086117395Skan  \catcode`< = \active
1087117395Skan  \catcode`> = \active
1088117395Skan  \catcode`+ = \active
1089117395Skan  \gdef\mathactive{%
1090117395Skan    \let^ = \ptexhat
1091117395Skan    \let< = \ptexless
1092117395Skan    \let> = \ptexgtr
1093117395Skan    \let+ = \ptexplus
1094117395Skan  }
1095117395Skan}
1096117395Skan
109796263Sobrien% @bullet and @minus need the same treatment as @math, just above.
1098132718Skan\def\bullet{$\ptexbullet$}
1099132718Skan\def\minus{$-$}
110096263Sobrien
1101132718Skan% @dots{} outputs an ellipsis using the current font.
1102132718Skan% We do .5em per period so that it has the same spacing in a typewriter
1103132718Skan% font as three actual period characters.
1104132718Skan%
1105132718Skan\def\dots{%
1106132718Skan  \leavevmode
1107132718Skan  \hbox to 1.5em{%
1108132718Skan    \hskip 0pt plus 0.25fil
1109132718Skan    .\hfil.\hfil.%
1110132718Skan    \hskip 0pt plus 0.5fil
1111132718Skan  }%
1112132718Skan}
1113132718Skan
1114132718Skan% @enddots{} is an end-of-sentence ellipsis.
1115132718Skan%
1116132718Skan\def\enddots{%
1117132718Skan  \dots
1118169689Skan  \spacefactor=\endofsentencespacefactor
1119132718Skan}
1120132718Skan
1121132718Skan% @comma{} is so commas can be inserted into text without messing up
1122132718Skan% Texinfo's parsing.
1123169689Skan%
1124132718Skan\let\comma = ,
1125132718Skan
112696263Sobrien% @refill is a no-op.
112796263Sobrien\let\refill=\relax
112896263Sobrien
112996263Sobrien% If working on a large document in chapters, it is convenient to
113096263Sobrien% be able to disable indexing, cross-referencing, and contents, for test runs.
113196263Sobrien% This is done with @novalidate (before @setfilename).
113296263Sobrien%
113396263Sobrien\newif\iflinks \linkstrue % by default we want the aux files.
113496263Sobrien\let\novalidate = \linksfalse
113596263Sobrien
113696263Sobrien% @setfilename is done at the beginning of every texinfo file.
113796263Sobrien% So open here the files we need to have open while reading the input.
113896263Sobrien% This makes it possible to make a .fmt file for texinfo.
113996263Sobrien\def\setfilename{%
1140169689Skan   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
114196263Sobrien   \iflinks
1142132718Skan     \tryauxfile
1143132718Skan     % Open the new aux file.  TeX will close it automatically at exit.
1144132718Skan     \immediate\openout\auxfile=\jobname.aux
114596263Sobrien   \fi % \openindices needs to do some work in any case.
114696263Sobrien   \openindices
1147169689Skan   \let\setfilename=\comment % Ignore extra @setfilename cmds.
114896263Sobrien   %
114996263Sobrien   % If texinfo.cnf is present on the system, read it.
115096263Sobrien   % Useful for site-wide @afourpaper, etc.
115196263Sobrien   \openin 1 texinfo.cnf
1152132718Skan   \ifeof 1 \else \input texinfo.cnf \fi
1153132718Skan   \closein 1
115496263Sobrien   %
115596263Sobrien   \comment % Ignore the actual filename.
115696263Sobrien}
115796263Sobrien
115896263Sobrien% Called from \setfilename.
115996263Sobrien%
116096263Sobrien\def\openindices{%
116196263Sobrien  \newindex{cp}%
116296263Sobrien  \newcodeindex{fn}%
116396263Sobrien  \newcodeindex{vr}%
116496263Sobrien  \newcodeindex{tp}%
116596263Sobrien  \newcodeindex{ky}%
116696263Sobrien  \newcodeindex{pg}%
116796263Sobrien}
116896263Sobrien
116996263Sobrien% @bye.
117096263Sobrien\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
117196263Sobrien
117296263Sobrien
117396263Sobrien\message{pdf,}
117496263Sobrien% adobe `portable' document format
117596263Sobrien\newcount\tempnum
117696263Sobrien\newcount\lnkcount
117796263Sobrien\newtoks\filename
117896263Sobrien\newcount\filenamelength
117996263Sobrien\newcount\pgn
118096263Sobrien\newtoks\toksA
118196263Sobrien\newtoks\toksB
118296263Sobrien\newtoks\toksC
118396263Sobrien\newtoks\toksD
118496263Sobrien\newbox\boxA
118596263Sobrien\newcount\countA
118696263Sobrien\newif\ifpdf
118796263Sobrien\newif\ifpdfmakepagedest
118896263Sobrien
1189169689Skan% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
1190169689Skan% can be set).  So we test for \relax and 0 as well as \undefined,
1191169689Skan% borrowed from ifpdf.sty.
119296263Sobrien\ifx\pdfoutput\undefined
119396263Sobrien\else
1194169689Skan  \ifx\pdfoutput\relax
1195169689Skan  \else
1196169689Skan    \ifcase\pdfoutput
1197169689Skan    \else
1198169689Skan      \pdftrue
1199169689Skan    \fi
1200169689Skan  \fi
1201169689Skan\fi
1202169689Skan
1203169689Skan% PDF uses PostScript string constants for the names of xref targets, to
1204169689Skan% for display in the outlines, and in other places.  Thus, we have to
1205169689Skan% double any backslashes.  Otherwise, a name like "\node" will be
1206169689Skan% interpreted as a newline (\n), followed by o, d, e.  Not good.
1207169689Skan% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
1208169689Skan% (and related messages, the final outcome is that it is up to the TeX
1209169689Skan% user to double the backslashes and otherwise make the string valid, so
1210169689Skan% that's we do).
1211169689Skan
1212169689Skan% double active backslashes.
1213169689Skan% 
1214169689Skan{\catcode`\@=0 \catcode`\\=\active
1215169689Skan @gdef@activebackslash{@catcode`@\=@active @otherbackslash}
1216169689Skan @gdef@activebackslashdouble{%
1217169689Skan   @catcode@backChar=@active
1218169689Skan   @let\=@doublebackslash}
1219169689Skan}
1220169689Skan
1221169689Skan% To handle parens, we must adopt a different approach, since parens are
1222169689Skan% not active characters.  hyperref.dtx (which has the same problem as
1223169689Skan% us) handles it with this amazing macro to replace tokens.  I've
1224169689Skan% tinkered with it a little for texinfo, but it's definitely from there.
1225169689Skan% 
1226169689Skan% #1 is the tokens to replace.
1227169689Skan% #2 is the replacement.
1228169689Skan% #3 is the control sequence with the string.
1229169689Skan% 
1230169689Skan\def\HyPsdSubst#1#2#3{%
1231169689Skan  \def\HyPsdReplace##1#1##2\END{%
1232169689Skan    ##1%
1233169689Skan    \ifx\\##2\\%
1234169689Skan    \else
1235169689Skan      #2%
1236169689Skan      \HyReturnAfterFi{%
1237169689Skan        \HyPsdReplace##2\END
1238169689Skan      }%
1239169689Skan    \fi
1240169689Skan  }%
1241169689Skan  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
1242169689Skan}
1243169689Skan\long\def\HyReturnAfterFi#1\fi{\fi#1}
1244169689Skan
1245169689Skan% #1 is a control sequence in which to do the replacements.
1246169689Skan\def\backslashparens#1{%
1247169689Skan  \xdef#1{#1}% redefine it as its expansion; the definition is simply
1248169689Skan             % \lastnode when called from \setref -> \pdfmkdest.
1249169689Skan  \HyPsdSubst{(}{\backslashlparen}{#1}%
1250169689Skan  \HyPsdSubst{)}{\backslashrparen}{#1}%
1251169689Skan}
1252169689Skan
1253169689Skan{\catcode\exclamChar = 0 \catcode\backChar = \other
1254169689Skan !gdef!backslashlparen{\(}%
1255169689Skan !gdef!backslashrparen{\)}%
1256169689Skan}
1257169689Skan
1258169689Skan\ifpdf
125996263Sobrien  \input pdfcolor
1260132718Skan  \pdfcatalog{/PageMode /UseOutlines}%
126196263Sobrien  \def\dopdfimage#1#2#3{%
126296263Sobrien    \def\imagewidth{#2}%
126396263Sobrien    \def\imageheight{#3}%
126496263Sobrien    % without \immediate, pdftex seg faults when the same image is
126596263Sobrien    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
126696263Sobrien    \ifnum\pdftexversion < 14
126796263Sobrien      \immediate\pdfimage
126896263Sobrien    \else
126996263Sobrien      \immediate\pdfximage
127096263Sobrien    \fi
127196263Sobrien      \ifx\empty\imagewidth\else width \imagewidth \fi
127296263Sobrien      \ifx\empty\imageheight\else height \imageheight \fi
127396263Sobrien      \ifnum\pdftexversion<13
1274117395Skan         #1.pdf%
127596263Sobrien       \else
127696263Sobrien         {#1.pdf}%
127796263Sobrien       \fi
127896263Sobrien    \ifnum\pdftexversion < 14 \else
127996263Sobrien      \pdfrefximage \pdflastximage
128096263Sobrien    \fi}
1281132718Skan  \def\pdfmkdest#1{{%
1282169689Skan    % We have to set dummies so commands such as @code, and characters
1283169689Skan    % such as \, aren't expanded when present in a section title.
1284132718Skan    \atdummies
1285169689Skan    \turnoffactive
1286169689Skan    \activebackslashdouble
1287169689Skan    \def\pdfdestname{#1}%
1288169689Skan    \backslashparens\pdfdestname
1289169689Skan    \pdfdest name{\pdfdestname} xyz%
1290169689Skan  }}%
1291169689Skan  %
1292169689Skan  % used to mark target names; must be expandable.
1293169689Skan  \def\pdfmkpgn#1{#1}%
1294169689Skan  %
129596263Sobrien  \let\linkcolor = \Blue  % was Cyan, but that seems light?
129696263Sobrien  \def\endlink{\Black\pdfendlink}
129796263Sobrien  % Adding outlines to PDF; macros for calculating structure of outlines
129896263Sobrien  % come from Petr Olsak
129996263Sobrien  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
130096263Sobrien    \else \csname#1\endcsname \fi}
130196263Sobrien  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
1302132718Skan    \advance\tempnum by 1
130396263Sobrien    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
1304132718Skan  %
1305169689Skan  % #1 is the section text, which is what will be displayed in the
1306169689Skan  % outline by the pdf viewer.  #2 is the pdf expression for the number
1307169689Skan  % of subentries (or empty, for subsubsections).  #3 is the node text,
1308169689Skan  % which might be empty if this toc entry had no corresponding node.
1309169689Skan  % #4 is the page number
1310169689Skan  %
1311132718Skan  \def\dopdfoutline#1#2#3#4{%
1312132718Skan    % Generate a link to the node text if that exists; else, use the
1313132718Skan    % page number.  We could generate a destination for the section
1314132718Skan    % text in the case where a section has no node, but it doesn't
1315169689Skan    % seem worth the trouble, since most documents are normally structured.
1316132718Skan    \def\pdfoutlinedest{#3}%
1317169689Skan    \ifx\pdfoutlinedest\empty
1318169689Skan      \def\pdfoutlinedest{#4}%
1319169689Skan    \else
1320169689Skan      % Doubled backslashes in the name.
1321169689Skan      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
1322169689Skan       \backslashparens\pdfoutlinedest}%
1323169689Skan    \fi
1324132718Skan    %
1325169689Skan    % Also double the backslashes in the display string.
1326169689Skan    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
1327169689Skan     \backslashparens\pdfoutlinetext}%
1328169689Skan    %
1329169689Skan    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
1330132718Skan  }
1331132718Skan  %
1332132718Skan  \def\pdfmakeoutlines{%
1333132718Skan    \begingroup
1334119256Skan      % Thanh's hack / proper braces in bookmarks
133596263Sobrien      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
133696263Sobrien      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
133796263Sobrien      %
1338132718Skan      % Read toc silently, to get counts of subentries for \pdfoutline.
1339132718Skan      \def\numchapentry##1##2##3##4{%
1340132718Skan	\def\thischapnum{##2}%
1341169689Skan	\def\thissecnum{0}%
1342169689Skan	\def\thissubsecnum{0}%
1343132718Skan      }%
1344132718Skan      \def\numsecentry##1##2##3##4{%
1345132718Skan	\advancenumber{chap\thischapnum}%
1346132718Skan	\def\thissecnum{##2}%
1347169689Skan	\def\thissubsecnum{0}%
1348132718Skan      }%
1349132718Skan      \def\numsubsecentry##1##2##3##4{%
1350132718Skan	\advancenumber{sec\thissecnum}%
1351132718Skan	\def\thissubsecnum{##2}%
1352132718Skan      }%
1353132718Skan      \def\numsubsubsecentry##1##2##3##4{%
1354132718Skan	\advancenumber{subsec\thissubsecnum}%
1355132718Skan      }%
1356169689Skan      \def\thischapnum{0}%
1357169689Skan      \def\thissecnum{0}%
1358169689Skan      \def\thissubsecnum{0}%
1359132718Skan      %
1360132718Skan      % use \def rather than \let here because we redefine \chapentry et
1361132718Skan      % al. a second time, below.
1362132718Skan      \def\appentry{\numchapentry}%
1363132718Skan      \def\appsecentry{\numsecentry}%
1364132718Skan      \def\appsubsecentry{\numsubsecentry}%
1365132718Skan      \def\appsubsubsecentry{\numsubsubsecentry}%
1366132718Skan      \def\unnchapentry{\numchapentry}%
1367132718Skan      \def\unnsecentry{\numsecentry}%
1368132718Skan      \def\unnsubsecentry{\numsubsecentry}%
1369132718Skan      \def\unnsubsubsecentry{\numsubsubsecentry}%
1370169689Skan      \readdatafile{toc}%
1371117395Skan      %
1372132718Skan      % Read toc second time, this time actually producing the outlines.
1373132718Skan      % The `-' means take the \expnumber as the absolute number of
1374132718Skan      % subentries, which we calculated on our first read of the .toc above.
1375169689Skan      %
1376132718Skan      % We use the node names as the destinations.
1377132718Skan      \def\numchapentry##1##2##3##4{%
1378132718Skan        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
1379132718Skan      \def\numsecentry##1##2##3##4{%
1380132718Skan        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
1381132718Skan      \def\numsubsecentry##1##2##3##4{%
1382132718Skan        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
1383132718Skan      \def\numsubsubsecentry##1##2##3##4{% count is always zero
1384132718Skan        \dopdfoutline{##1}{}{##3}{##4}}%
1385132718Skan      %
1386169689Skan      % PDF outlines are displayed using system fonts, instead of
1387169689Skan      % document fonts.  Therefore we cannot use special characters,
1388169689Skan      % since the encoding is unknown.  For example, the eogonek from
1389169689Skan      % Latin 2 (0xea) gets translated to a | character.  Info from
1390169689Skan      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
1391169689Skan      %
1392169689Skan      % xx to do this right, we have to translate 8-bit characters to
1393169689Skan      % their "best" equivalent, based on the @documentencoding.  Right
1394169689Skan      % now, I guess we'll just let the pdf reader have its way.
1395117395Skan      \indexnofonts
1396169689Skan      \setupdatafile
1397169689Skan      \activebackslash
139896263Sobrien      \input \jobname.toc
1399132718Skan    \endgroup
1400132718Skan  }
1401132718Skan  %
140296263Sobrien  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
140396263Sobrien    \ifx\PP\D\let\nextsp\relax
140496263Sobrien    \else\let\nextsp\skipspaces
140596263Sobrien      \ifx\p\space\else\addtokens{\filename}{\PP}%
140696263Sobrien        \advance\filenamelength by 1
140796263Sobrien      \fi
140896263Sobrien    \fi
140996263Sobrien    \nextsp}
141096263Sobrien  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
141196263Sobrien  \ifnum\pdftexversion < 14
141296263Sobrien    \let \startlink \pdfannotlink
141396263Sobrien  \else
141496263Sobrien    \let \startlink \pdfstartlink
141596263Sobrien  \fi
141696263Sobrien  \def\pdfurl#1{%
141796263Sobrien    \begingroup
141896263Sobrien      \normalturnoffactive\def\@{@}%
1419132718Skan      \makevalueexpandable
142096263Sobrien      \leavevmode\Red
142196263Sobrien      \startlink attr{/Border [0 0 0]}%
142296263Sobrien        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
142396263Sobrien    \endgroup}
142496263Sobrien  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
142596263Sobrien  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
142696263Sobrien  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
142796263Sobrien  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
142896263Sobrien  \def\maketoks{%
1429169689Skan    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
143096263Sobrien    \ifx\first0\adn0
143196263Sobrien    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
143296263Sobrien    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
1433119256Skan    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
143496263Sobrien    \else
143596263Sobrien      \ifnum0=\countA\else\makelink\fi
143696263Sobrien      \ifx\first.\let\next=\done\else
143796263Sobrien        \let\next=\maketoks
143896263Sobrien        \addtokens{\toksB}{\the\toksD}
143996263Sobrien        \ifx\first,\addtokens{\toksB}{\space}\fi
144096263Sobrien      \fi
144196263Sobrien    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
144296263Sobrien    \next}
144396263Sobrien  \def\makelink{\addtokens{\toksB}%
144496263Sobrien    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
144596263Sobrien  \def\pdflink#1{%
144696263Sobrien    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
144796263Sobrien    \linkcolor #1\endlink}
144896263Sobrien  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
1449169689Skan\else
1450169689Skan  \let\pdfmkdest = \gobble
1451169689Skan  \let\pdfurl = \gobble
1452169689Skan  \let\endlink = \relax
1453169689Skan  \let\linkcolor = \relax
1454169689Skan  \let\pdfmakeoutlines = \relax
1455169689Skan\fi  % \ifx\pdfoutput
145696263Sobrien
145796263Sobrien
145896263Sobrien\message{fonts,}
145996263Sobrien
1460132718Skan% Change the current font style to #1, remembering it in \curfontstyle.
1461132718Skan% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
1462132718Skan% italics, not bold italics.
1463169689Skan%
1464132718Skan\def\setfontstyle#1{%
1465132718Skan  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
1466132718Skan  \csname ten#1\endcsname  % change the current font
1467132718Skan}
1468132718Skan
1469132718Skan% Select #1 fonts with the current style.
1470169689Skan%
1471132718Skan\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
1472132718Skan
1473132718Skan\def\rm{\fam=0 \setfontstyle{rm}}
1474132718Skan\def\it{\fam=\itfam \setfontstyle{it}}
1475132718Skan\def\sl{\fam=\slfam \setfontstyle{sl}}
1476169689Skan\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
1477132718Skan\def\tt{\fam=\ttfam \setfontstyle{tt}}
1478132718Skan
147996263Sobrien% Texinfo sort of supports the sans serif font style, which plain TeX does not.
1480132718Skan% So we set up a \sf.
148196263Sobrien\newfam\sffam
1482132718Skan\def\sf{\fam=\sffam \setfontstyle{sf}}
148396263Sobrien\let\li = \sf % Sometimes we call it \li, not \sf.
148496263Sobrien
1485132718Skan% We don't need math for this font style.
1486132718Skan\def\ttsl{\setfontstyle{ttsl}}
148796263Sobrien
148896263Sobrien% Default leading.
148996263Sobrien\newdimen\textleading  \textleading = 13.2pt
149096263Sobrien
149196263Sobrien% Set the baselineskip to #1, and the lineskip and strut size
149296263Sobrien% correspondingly.  There is no deep meaning behind these magic numbers
149396263Sobrien% used as factors; they just match (closely enough) what Knuth defined.
149496263Sobrien%
149596263Sobrien\def\lineskipfactor{.08333}
149696263Sobrien\def\strutheightpercent{.70833}
149796263Sobrien\def\strutdepthpercent {.29167}
149896263Sobrien%
149996263Sobrien\def\setleading#1{%
150096263Sobrien  \normalbaselineskip = #1\relax
150196263Sobrien  \normallineskip = \lineskipfactor\normalbaselineskip
150296263Sobrien  \normalbaselines
150396263Sobrien  \setbox\strutbox =\hbox{%
150496263Sobrien    \vrule width0pt height\strutheightpercent\baselineskip
150596263Sobrien                    depth \strutdepthpercent \baselineskip
150696263Sobrien  }%
150796263Sobrien}
150896263Sobrien
150996263Sobrien% Set the font macro #1 to the font named #2, adding on the
151096263Sobrien% specified font prefix (normally `cm').
151196263Sobrien% #3 is the font's design size, #4 is a scale factor
151296263Sobrien\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
151396263Sobrien
151496263Sobrien% Use cm as the default font prefix.
151596263Sobrien% To specify the font prefix, you must define \fontprefix
151696263Sobrien% before you read in texinfo.tex.
151796263Sobrien\ifx\fontprefix\undefined
151896263Sobrien\def\fontprefix{cm}
151996263Sobrien\fi
152096263Sobrien% Support font families that don't use the same naming scheme as CM.
152196263Sobrien\def\rmshape{r}
152296263Sobrien\def\rmbshape{bx}               %where the normal face is bold
152396263Sobrien\def\bfshape{b}
152496263Sobrien\def\bxshape{bx}
152596263Sobrien\def\ttshape{tt}
152696263Sobrien\def\ttbshape{tt}
152796263Sobrien\def\ttslshape{sltt}
152896263Sobrien\def\itshape{ti}
152996263Sobrien\def\itbshape{bxti}
153096263Sobrien\def\slshape{sl}
153196263Sobrien\def\slbshape{bxsl}
153296263Sobrien\def\sfshape{ss}
153396263Sobrien\def\sfbshape{ss}
153496263Sobrien\def\scshape{csc}
153596263Sobrien\def\scbshape{csc}
153696263Sobrien
1537132718Skan% Text fonts (11.2pt, magstep1).
1538169689Skan\def\textnominalsize{11pt}
1539169689Skan\edef\mainmagstep{\magstephalf}
1540169689Skan\setfont\textrm\rmshape{10}{\mainmagstep}
1541169689Skan\setfont\texttt\ttshape{10}{\mainmagstep}
154296263Sobrien\setfont\textbf\bfshape{10}{\mainmagstep}
154396263Sobrien\setfont\textit\itshape{10}{\mainmagstep}
154496263Sobrien\setfont\textsl\slshape{10}{\mainmagstep}
154596263Sobrien\setfont\textsf\sfshape{10}{\mainmagstep}
154696263Sobrien\setfont\textsc\scshape{10}{\mainmagstep}
154796263Sobrien\setfont\textttsl\ttslshape{10}{\mainmagstep}
154896263Sobrien\font\texti=cmmi10 scaled \mainmagstep
154996263Sobrien\font\textsy=cmsy10 scaled \mainmagstep
155096263Sobrien
1551132718Skan% A few fonts for @defun names and args.
1552132718Skan\setfont\defbf\bfshape{10}{\magstep1}
155396263Sobrien\setfont\deftt\ttshape{10}{\magstep1}
1554132718Skan\setfont\defttsl\ttslshape{10}{\magstep1}
1555132718Skan\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
155696263Sobrien
155796263Sobrien% Fonts for indices, footnotes, small examples (9pt).
1558169689Skan\def\smallnominalsize{9pt}
155996263Sobrien\setfont\smallrm\rmshape{9}{1000}
156096263Sobrien\setfont\smalltt\ttshape{9}{1000}
156196263Sobrien\setfont\smallbf\bfshape{10}{900}
156296263Sobrien\setfont\smallit\itshape{9}{1000}
156396263Sobrien\setfont\smallsl\slshape{9}{1000}
156496263Sobrien\setfont\smallsf\sfshape{9}{1000}
156596263Sobrien\setfont\smallsc\scshape{10}{900}
156696263Sobrien\setfont\smallttsl\ttslshape{10}{900}
156796263Sobrien\font\smalli=cmmi9
156896263Sobrien\font\smallsy=cmsy9
156996263Sobrien
157096263Sobrien% Fonts for small examples (8pt).
1571169689Skan\def\smallernominalsize{8pt}
157296263Sobrien\setfont\smallerrm\rmshape{8}{1000}
157396263Sobrien\setfont\smallertt\ttshape{8}{1000}
157496263Sobrien\setfont\smallerbf\bfshape{10}{800}
157596263Sobrien\setfont\smallerit\itshape{8}{1000}
157696263Sobrien\setfont\smallersl\slshape{8}{1000}
157796263Sobrien\setfont\smallersf\sfshape{8}{1000}
157896263Sobrien\setfont\smallersc\scshape{10}{800}
157996263Sobrien\setfont\smallerttsl\ttslshape{10}{800}
158096263Sobrien\font\smalleri=cmmi8
158196263Sobrien\font\smallersy=cmsy8
158296263Sobrien
1583132718Skan% Fonts for title page (20.4pt):
1584169689Skan\def\titlenominalsize{20pt}
158596263Sobrien\setfont\titlerm\rmbshape{12}{\magstep3}
158696263Sobrien\setfont\titleit\itbshape{10}{\magstep4}
158796263Sobrien\setfont\titlesl\slbshape{10}{\magstep4}
158896263Sobrien\setfont\titlett\ttbshape{12}{\magstep3}
158996263Sobrien\setfont\titlettsl\ttslshape{10}{\magstep4}
159096263Sobrien\setfont\titlesf\sfbshape{17}{\magstep1}
159196263Sobrien\let\titlebf=\titlerm
159296263Sobrien\setfont\titlesc\scbshape{10}{\magstep4}
159396263Sobrien\font\titlei=cmmi12 scaled \magstep3
159496263Sobrien\font\titlesy=cmsy10 scaled \magstep4
159596263Sobrien\def\authorrm{\secrm}
1596117395Skan\def\authortt{\sectt}
159796263Sobrien
159896263Sobrien% Chapter (and unnumbered) fonts (17.28pt).
1599169689Skan\def\chapnominalsize{17pt}
160096263Sobrien\setfont\chaprm\rmbshape{12}{\magstep2}
160196263Sobrien\setfont\chapit\itbshape{10}{\magstep3}
160296263Sobrien\setfont\chapsl\slbshape{10}{\magstep3}
160396263Sobrien\setfont\chaptt\ttbshape{12}{\magstep2}
160496263Sobrien\setfont\chapttsl\ttslshape{10}{\magstep3}
160596263Sobrien\setfont\chapsf\sfbshape{17}{1000}
160696263Sobrien\let\chapbf=\chaprm
160796263Sobrien\setfont\chapsc\scbshape{10}{\magstep3}
160896263Sobrien\font\chapi=cmmi12 scaled \magstep2
160996263Sobrien\font\chapsy=cmsy10 scaled \magstep3
161096263Sobrien
161196263Sobrien% Section fonts (14.4pt).
1612169689Skan\def\secnominalsize{14pt}
161396263Sobrien\setfont\secrm\rmbshape{12}{\magstep1}
161496263Sobrien\setfont\secit\itbshape{10}{\magstep2}
161596263Sobrien\setfont\secsl\slbshape{10}{\magstep2}
161696263Sobrien\setfont\sectt\ttbshape{12}{\magstep1}
161796263Sobrien\setfont\secttsl\ttslshape{10}{\magstep2}
161896263Sobrien\setfont\secsf\sfbshape{12}{\magstep1}
161996263Sobrien\let\secbf\secrm
162096263Sobrien\setfont\secsc\scbshape{10}{\magstep2}
162196263Sobrien\font\seci=cmmi12 scaled \magstep1
162296263Sobrien\font\secsy=cmsy10 scaled \magstep2
162396263Sobrien
162496263Sobrien% Subsection fonts (13.15pt).
1625169689Skan\def\ssecnominalsize{13pt}
162696263Sobrien\setfont\ssecrm\rmbshape{12}{\magstephalf}
162796263Sobrien\setfont\ssecit\itbshape{10}{1315}
162896263Sobrien\setfont\ssecsl\slbshape{10}{1315}
162996263Sobrien\setfont\ssectt\ttbshape{12}{\magstephalf}
163096263Sobrien\setfont\ssecttsl\ttslshape{10}{1315}
163196263Sobrien\setfont\ssecsf\sfbshape{12}{\magstephalf}
163296263Sobrien\let\ssecbf\ssecrm
1633132718Skan\setfont\ssecsc\scbshape{10}{1315}
163496263Sobrien\font\sseci=cmmi12 scaled \magstephalf
163596263Sobrien\font\ssecsy=cmsy10 scaled 1315
163696263Sobrien
1637132718Skan% Reduced fonts for @acro in text (10pt).
1638169689Skan\def\reducednominalsize{10pt}
1639132718Skan\setfont\reducedrm\rmshape{10}{1000}
1640132718Skan\setfont\reducedtt\ttshape{10}{1000}
1641132718Skan\setfont\reducedbf\bfshape{10}{1000}
1642132718Skan\setfont\reducedit\itshape{10}{1000}
1643132718Skan\setfont\reducedsl\slshape{10}{1000}
1644132718Skan\setfont\reducedsf\sfshape{10}{1000}
1645132718Skan\setfont\reducedsc\scshape{10}{1000}
1646132718Skan\setfont\reducedttsl\ttslshape{10}{1000}
1647132718Skan\font\reducedi=cmmi10
1648132718Skan\font\reducedsy=cmsy10
1649132718Skan
165096263Sobrien% In order for the font changes to affect most math symbols and letters,
165196263Sobrien% we have to define the \textfont of the standard families.  Since
165296263Sobrien% texinfo doesn't allow for producing subscripts and superscripts except
165396263Sobrien% in the main text, we don't bother to reset \scriptfont and
165496263Sobrien% \scriptscriptfont (which would also require loading a lot more fonts).
165596263Sobrien%
165696263Sobrien\def\resetmathfonts{%
165796263Sobrien  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
165896263Sobrien  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
165996263Sobrien  \textfont\ttfam=\tentt \textfont\sffam=\tensf
166096263Sobrien}
166196263Sobrien
166296263Sobrien% The font-changing commands redefine the meanings of \tenSTYLE, instead
1663132718Skan% of just \STYLE.  We do this because \STYLE needs to also set the
1664132718Skan% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
1665132718Skan% \tenSTYLE to set the current font.
1666169689Skan%
1667132718Skan% Each font-changing command also sets the names \lsize (one size lower)
1668132718Skan% and \lllsize (three sizes lower).  These relative commands are used in
1669132718Skan% the LaTeX logo and acronyms.
1670169689Skan%
1671132718Skan% This all needs generalizing, badly.
1672169689Skan%
167396263Sobrien\def\textfonts{%
167496263Sobrien  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
167596263Sobrien  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
1676132718Skan  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
1677132718Skan  \let\tenttsl=\textttsl
1678169689Skan  \def\curfontsize{text}%
1679132718Skan  \def\lsize{reduced}\def\lllsize{smaller}%
168096263Sobrien  \resetmathfonts \setleading{\textleading}}
168196263Sobrien\def\titlefonts{%
168296263Sobrien  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
168396263Sobrien  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
168496263Sobrien  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
168596263Sobrien  \let\tenttsl=\titlettsl
1686169689Skan  \def\curfontsize{title}%
1687132718Skan  \def\lsize{chap}\def\lllsize{subsec}%
168896263Sobrien  \resetmathfonts \setleading{25pt}}
168996263Sobrien\def\titlefont#1{{\titlefonts\rm #1}}
169096263Sobrien\def\chapfonts{%
169196263Sobrien  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
169296263Sobrien  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
1693169689Skan  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
1694169689Skan  \let\tenttsl=\chapttsl
1695169689Skan  \def\curfontsize{chap}%
1696132718Skan  \def\lsize{sec}\def\lllsize{text}%
169796263Sobrien  \resetmathfonts \setleading{19pt}}
169896263Sobrien\def\secfonts{%
169996263Sobrien  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
170096263Sobrien  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
1701132718Skan  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
1702132718Skan  \let\tenttsl=\secttsl
1703169689Skan  \def\curfontsize{sec}%
1704132718Skan  \def\lsize{subsec}\def\lllsize{reduced}%
170596263Sobrien  \resetmathfonts \setleading{16pt}}
170696263Sobrien\def\subsecfonts{%
170796263Sobrien  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
170896263Sobrien  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
1709132718Skan  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
1710132718Skan  \let\tenttsl=\ssecttsl
1711169689Skan  \def\curfontsize{ssec}%
1712132718Skan  \def\lsize{text}\def\lllsize{small}%
171396263Sobrien  \resetmathfonts \setleading{15pt}}
1714132718Skan\let\subsubsecfonts = \subsecfonts
1715132718Skan\def\reducedfonts{%
1716132718Skan  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
1717132718Skan  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
1718132718Skan  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
1719132718Skan  \let\tenttsl=\reducedttsl
1720169689Skan  \def\curfontsize{reduced}%
1721132718Skan  \def\lsize{small}\def\lllsize{smaller}%
1722132718Skan  \resetmathfonts \setleading{10.5pt}}
172396263Sobrien\def\smallfonts{%
172496263Sobrien  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
172596263Sobrien  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
172696263Sobrien  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
172796263Sobrien  \let\tenttsl=\smallttsl
1728169689Skan  \def\curfontsize{small}%
1729132718Skan  \def\lsize{smaller}\def\lllsize{smaller}%
173096263Sobrien  \resetmathfonts \setleading{10.5pt}}
173196263Sobrien\def\smallerfonts{%
173296263Sobrien  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
173396263Sobrien  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
173496263Sobrien  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
173596263Sobrien  \let\tenttsl=\smallerttsl
1736169689Skan  \def\curfontsize{smaller}%
1737132718Skan  \def\lsize{smaller}\def\lllsize{smaller}%
173896263Sobrien  \resetmathfonts \setleading{9.5pt}}
173996263Sobrien
1740119256Skan% Set the fonts to use with the @small... environments.
1741119256Skan\let\smallexamplefonts = \smallfonts
1742119256Skan
1743119256Skan% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
1744119256Skan% can fit this many characters:
1745119256Skan%   8.5x11=86   smallbook=72  a4=90  a5=69
1746132718Skan% If we use \scriptfonts (8pt), then we can fit this many characters:
1747119256Skan%   8.5x11=90+  smallbook=80  a4=90+  a5=77
1748119256Skan% For me, subjectively, the few extra characters that fit aren't worth
1749119256Skan% the additional smallness of 8pt.  So I'm making the default 9pt.
1750119256Skan%
1751119256Skan% By the way, for comparison, here's what fits with @example (10pt):
1752119256Skan%   8.5x11=71  smallbook=60  a4=75  a5=58
1753119256Skan%
1754132718Skan% I wish the USA used A4 paper.
1755119256Skan% --karl, 24jan03.
1756119256Skan
1757119256Skan
175896263Sobrien% Set up the default fonts, so we can use them for creating boxes.
175996263Sobrien%
1760132718Skan\textfonts \rm
176196263Sobrien
176296263Sobrien% Define these so they can be easily changed for other fonts.
176396263Sobrien\def\angleleft{$\langle$}
176496263Sobrien\def\angleright{$\rangle$}
176596263Sobrien
176696263Sobrien% Count depth in font-changes, for error checks
176796263Sobrien\newcount\fontdepth \fontdepth=0
176896263Sobrien
176996263Sobrien% Fonts for short table of contents.
177096263Sobrien\setfont\shortcontrm\rmshape{12}{1000}
1771132718Skan\setfont\shortcontbf\bfshape{10}{\magstep1}  % no cmb12
177296263Sobrien\setfont\shortcontsl\slshape{12}{1000}
1773117395Skan\setfont\shortconttt\ttshape{12}{1000}
177496263Sobrien
177596263Sobrien%% Add scribe-like font environments, plus @l for inline lisp (usually sans
177696263Sobrien%% serif) and @ii for TeX italic
177796263Sobrien
177896263Sobrien% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
177996263Sobrien% unless the following character is such as not to need one.
1780119256Skan\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
1781119256Skan                    \ptexslash\fi\fi\fi}
1782117395Skan\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
1783117395Skan\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
178496263Sobrien
1785132718Skan% like \smartslanted except unconditionally uses \ttsl.
1786132718Skan% @var is set to this for defun arguments.
1787132718Skan\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
1788132718Skan
1789132718Skan% like \smartslanted except unconditionally use \sl.  We never want
1790132718Skan% ttsl for book titles, do we?
1791132718Skan\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
1792132718Skan
179396263Sobrien\let\i=\smartitalic
1794169689Skan\let\slanted=\smartslanted
179596263Sobrien\let\var=\smartslanted
179696263Sobrien\let\dfn=\smartslanted
179796263Sobrien\let\emph=\smartitalic
179896263Sobrien
1799169689Skan% @b, explicit bold.
180096263Sobrien\def\b#1{{\bf #1}}
180196263Sobrien\let\strong=\b
180296263Sobrien
1803169689Skan% @sansserif, explicit sans.
1804169689Skan\def\sansserif#1{{\sf #1}}
1805169689Skan
180696263Sobrien% We can't just use \exhyphenpenalty, because that only has effect at
180796263Sobrien% the end of a paragraph.  Restore normal hyphenation at the end of the
180896263Sobrien% group within which \nohyphenation is presumably called.
180996263Sobrien%
181096263Sobrien\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
181196263Sobrien\def\restorehyphenation{\hyphenchar\font = `- }
181296263Sobrien
1813119256Skan% Set sfcode to normal for the chars that usually have another value.
1814119256Skan% Can't use plain's \frenchspacing because it uses the `\x notation, and
1815119256Skan% sometimes \x has an active definition that messes things up.
1816119256Skan%
1817119256Skan\catcode`@=11
1818169689Skan  \def\plainfrenchspacing{%
1819119256Skan    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
1820119256Skan    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
1821169689Skan    \def\endofsentencespacefactor{1000}% for @. and friends
1822119256Skan  }
1823169689Skan  \def\plainnonfrenchspacing{%
1824169689Skan    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
1825169689Skan    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
1826169689Skan    \def\endofsentencespacefactor{3000}% for @. and friends
1827169689Skan  }
1828119256Skan\catcode`@=\other
1829169689Skan\def\endofsentencespacefactor{3000}% default
1830119256Skan
183196263Sobrien\def\t#1{%
1832169689Skan  {\tt \rawbackslash \plainfrenchspacing #1}%
183396263Sobrien  \null
183496263Sobrien}
183596263Sobrien\def\samp#1{`\tclose{#1}'\null}
183696263Sobrien\setfont\keyrm\rmshape{8}{1000}
183796263Sobrien\font\keysy=cmsy9
183896263Sobrien\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
183996263Sobrien  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
184096263Sobrien    \vbox{\hrule\kern-0.4pt
184196263Sobrien     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
184296263Sobrien    \kern-0.4pt\hrule}%
184396263Sobrien  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
184496263Sobrien% The old definition, with no lozenge:
184596263Sobrien%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
184696263Sobrien\def\ctrl #1{{\tt \rawbackslash \hat}#1}
184796263Sobrien
184896263Sobrien% @file, @option are the same as @samp.
184996263Sobrien\let\file=\samp
185096263Sobrien\let\option=\samp
185196263Sobrien
185296263Sobrien% @code is a modification of @t,
185396263Sobrien% which makes spaces the same size as normal in the surrounding text.
185496263Sobrien\def\tclose#1{%
185596263Sobrien  {%
185696263Sobrien    % Change normal interword space to be same as for the current font.
185796263Sobrien    \spaceskip = \fontdimen2\font
185896263Sobrien    %
185996263Sobrien    % Switch to typewriter.
186096263Sobrien    \tt
186196263Sobrien    %
186296263Sobrien    % But `\ ' produces the large typewriter interword space.
186396263Sobrien    \def\ {{\spaceskip = 0pt{} }}%
186496263Sobrien    %
186596263Sobrien    % Turn off hyphenation.
186696263Sobrien    \nohyphenation
186796263Sobrien    %
186896263Sobrien    \rawbackslash
1869169689Skan    \plainfrenchspacing
187096263Sobrien    #1%
187196263Sobrien  }%
187296263Sobrien  \null
187396263Sobrien}
187496263Sobrien
1875132718Skan% We *must* turn on hyphenation at `-' and `_' in @code.
187696263Sobrien% Otherwise, it is too hard to avoid overfull hboxes
187796263Sobrien% in the Emacs manual, the Library manual, etc.
187896263Sobrien
187996263Sobrien% Unfortunately, TeX uses one parameter (\hyphenchar) to control
188096263Sobrien% both hyphenation at - and hyphenation within words.
188196263Sobrien% We must therefore turn them both off (\tclose does that)
188296263Sobrien% and arrange explicitly to hyphenate at a dash.
188396263Sobrien%  -- rms.
188496263Sobrien{
188596263Sobrien  \catcode`\-=\active
188696263Sobrien  \catcode`\_=\active
188796263Sobrien  %
188896263Sobrien  \global\def\code{\begingroup
1889169689Skan    \catcode`\-=\active  \catcode`\_=\active
1890169689Skan    \ifallowcodebreaks
1891169689Skan     \let-\codedash
1892169689Skan     \let_\codeunder
1893169689Skan    \else
1894169689Skan     \let-\realdash
1895169689Skan     \let_\realunder
1896169689Skan    \fi
189796263Sobrien    \codex
189896263Sobrien  }
189996263Sobrien}
190096263Sobrien
190196263Sobrien\def\realdash{-}
190296263Sobrien\def\codedash{-\discretionary{}{}{}}
1903117395Skan\def\codeunder{%
1904117395Skan  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
1905117395Skan  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
1906117395Skan  % will therefore expand the active definition of _, which is us
1907117395Skan  % (inside @code that is), therefore an endless loop.
1908117395Skan  \ifusingtt{\ifmmode
1909117395Skan               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
1910117395Skan             \else\normalunderscore \fi
1911117395Skan             \discretionary{}{}{}}%
1912117395Skan            {\_}%
1913117395Skan}
191496263Sobrien\def\codex #1{\tclose{#1}\endgroup}
191596263Sobrien
1916169689Skan% An additional complication: the above will allow breaks after, e.g.,
1917169689Skan% each of the four underscores in __typeof__.  This is undesirable in
1918169689Skan% some manuals, especially if they don't have long identifiers in
1919169689Skan% general.  @allowcodebreaks provides a way to control this.
1920169689Skan% 
1921169689Skan\newif\ifallowcodebreaks  \allowcodebreakstrue
1922169689Skan
1923169689Skan\def\keywordtrue{true}
1924169689Skan\def\keywordfalse{false}
1925169689Skan
1926169689Skan\parseargdef\allowcodebreaks{%
1927169689Skan  \def\txiarg{#1}%
1928169689Skan  \ifx\txiarg\keywordtrue
1929169689Skan    \allowcodebreakstrue
1930169689Skan  \else\ifx\txiarg\keywordfalse
1931169689Skan    \allowcodebreaksfalse
1932169689Skan  \else
1933169689Skan    \errhelp = \EMsimple
1934169689Skan    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
1935169689Skan  \fi\fi
1936169689Skan}
1937169689Skan
193896263Sobrien% @kbd is like @code, except that if the argument is just one @key command,
193996263Sobrien% then @kbd has no effect.
194096263Sobrien
194196263Sobrien% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
194296263Sobrien%   `example' (@kbd uses ttsl only inside of @example and friends),
194396263Sobrien%   or `code' (@kbd uses normal tty font always).
1944132718Skan\parseargdef\kbdinputstyle{%
1945169689Skan  \def\txiarg{#1}%
1946169689Skan  \ifx\txiarg\worddistinct
194796263Sobrien    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
1948169689Skan  \else\ifx\txiarg\wordexample
194996263Sobrien    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
1950169689Skan  \else\ifx\txiarg\wordcode
195196263Sobrien    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
1952119256Skan  \else
1953119256Skan    \errhelp = \EMsimple
1954169689Skan    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
195596263Sobrien  \fi\fi\fi
195696263Sobrien}
195796263Sobrien\def\worddistinct{distinct}
195896263Sobrien\def\wordexample{example}
195996263Sobrien\def\wordcode{code}
196096263Sobrien
1961119256Skan% Default is `distinct.'
1962119256Skan\kbdinputstyle distinct
196396263Sobrien
196496263Sobrien\def\xkey{\key}
196596263Sobrien\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
196696263Sobrien\ifx\one\xkey\ifx\threex\three \key{#2}%
196796263Sobrien\else{\tclose{\kbdfont\look}}\fi
196896263Sobrien\else{\tclose{\kbdfont\look}}\fi}
196996263Sobrien
1970169689Skan% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
1971169689Skan\let\indicateurl=\code
197296263Sobrien\let\env=\code
197396263Sobrien\let\command=\code
197496263Sobrien
197596263Sobrien% @uref (abbreviation for `urlref') takes an optional (comma-separated)
197696263Sobrien% second argument specifying the text to display and an optional third
197796263Sobrien% arg as text to display instead of (rather than in addition to) the url
197896263Sobrien% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
197996263Sobrien% a hypertex \special here.
198096263Sobrien%
198196263Sobrien\def\uref#1{\douref #1,,,\finish}
198296263Sobrien\def\douref#1,#2,#3,#4\finish{\begingroup
198396263Sobrien  \unsepspaces
198496263Sobrien  \pdfurl{#1}%
198596263Sobrien  \setbox0 = \hbox{\ignorespaces #3}%
198696263Sobrien  \ifdim\wd0 > 0pt
198796263Sobrien    \unhbox0 % third arg given, show only that
198896263Sobrien  \else
198996263Sobrien    \setbox0 = \hbox{\ignorespaces #2}%
199096263Sobrien    \ifdim\wd0 > 0pt
199196263Sobrien      \ifpdf
199296263Sobrien        \unhbox0             % PDF: 2nd arg given, show only it
199396263Sobrien      \else
199496263Sobrien        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
199596263Sobrien      \fi
199696263Sobrien    \else
199796263Sobrien      \code{#1}% only url given, so show it
199896263Sobrien    \fi
199996263Sobrien  \fi
200096263Sobrien  \endlink
200196263Sobrien\endgroup}
200296263Sobrien
2003169689Skan% @url synonym for @uref, since that's how everyone uses it.
2004169689Skan%
2005169689Skan\let\url=\uref
2006169689Skan
200796263Sobrien% rms does not like angle brackets --karl, 17may97.
200896263Sobrien% So now @email is just like @uref, unless we are pdf.
2009119256Skan%
201096263Sobrien%\def\email#1{\angleleft{\tt #1}\angleright}
201196263Sobrien\ifpdf
201296263Sobrien  \def\email#1{\doemail#1,,\finish}
201396263Sobrien  \def\doemail#1,#2,#3\finish{\begingroup
201496263Sobrien    \unsepspaces
201596263Sobrien    \pdfurl{mailto:#1}%
201696263Sobrien    \setbox0 = \hbox{\ignorespaces #2}%
201796263Sobrien    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
201896263Sobrien    \endlink
201996263Sobrien  \endgroup}
202096263Sobrien\else
202196263Sobrien  \let\email=\uref
202296263Sobrien\fi
202396263Sobrien
202496263Sobrien% Check if we are currently using a typewriter font.  Since all the
202596263Sobrien% Computer Modern typewriter fonts have zero interword stretch (and
202696263Sobrien% shrink), and it is reasonable to expect all typewriter fonts to have
202796263Sobrien% this property, we can check that font parameter.
202896263Sobrien%
202996263Sobrien\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
203096263Sobrien
203196263Sobrien% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
203296263Sobrien% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
203396263Sobrien%
203496263Sobrien\def\dmn#1{\thinspace #1}
203596263Sobrien
203696263Sobrien\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
203796263Sobrien
203896263Sobrien% @l was never documented to mean ``switch to the Lisp font'',
203996263Sobrien% and it is not used as such in any manual I can find.  We need it for
204096263Sobrien% Polish suppressed-l.  --karl, 22sep96.
204196263Sobrien%\def\l#1{{\li #1}\null}
204296263Sobrien
204396263Sobrien% Explicit font changes: @r, @sc, undocumented @ii.
204496263Sobrien\def\r#1{{\rm #1}}              % roman font
204596263Sobrien\def\sc#1{{\smallcaps#1}}       % smallcaps font
204696263Sobrien\def\ii#1{{\it #1}}             % italic font
204796263Sobrien
2048169689Skan% @acronym for "FBI", "NATO", and the like.
2049169689Skan% We print this one point size smaller, since it's intended for
2050169689Skan% all-uppercase.
2051169689Skan% 
2052132718Skan\def\acronym#1{\doacronym #1,,\finish}
2053132718Skan\def\doacronym#1,#2,#3\finish{%
2054132718Skan  {\selectfonts\lsize #1}%
2055132718Skan  \def\temp{#2}%
2056132718Skan  \ifx\temp\empty \else
2057132718Skan    \space ({\unsepspaces \ignorespaces \temp \unskip})%
2058132718Skan  \fi
2059132718Skan}
206096263Sobrien
2061169689Skan% @abbr for "Comput. J." and the like.
2062169689Skan% No font change, but don't do end-of-sentence spacing.
2063132718Skan% 
2064169689Skan\def\abbr#1{\doabbr #1,,\finish}
2065169689Skan\def\doabbr#1,#2,#3\finish{%
2066169689Skan  {\plainfrenchspacing #1}%
2067169689Skan  \def\temp{#2}%
2068169689Skan  \ifx\temp\empty \else
2069169689Skan    \space ({\unsepspaces \ignorespaces \temp \unskip})%
2070169689Skan  \fi
2071169689Skan}
2072169689Skan
2073169689Skan% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
2074169689Skan%
207596263Sobrien\def\pounds{{\it\$}}
207696263Sobrien
2077169689Skan% @euro{} comes from a separate font, depending on the current style.
2078169689Skan% We use the free feym* fonts from the eurosym package by Henrik
2079169689Skan% Theiling, which support regular, slanted, bold and bold slanted (and
2080169689Skan% "outlined" (blackboard board, sort of) versions, which we don't need).
2081169689Skan% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
2082169689Skan% 
2083169689Skan% Although only regular is the truly official Euro symbol, we ignore
2084169689Skan% that.  The Euro is designed to be slightly taller than the regular
2085169689Skan% font height.
2086169689Skan% 
2087169689Skan% feymr - regular
2088169689Skan% feymo - slanted
2089169689Skan% feybr - bold
2090169689Skan% feybo - bold slanted
2091169689Skan% 
2092169689Skan% There is no good (free) typewriter version, to my knowledge.
2093169689Skan% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
2094169689Skan% Hmm.
2095169689Skan% 
2096169689Skan% Also doesn't work in math.  Do we need to do math with euro symbols?
2097169689Skan% Hope not.
2098169689Skan% 
2099169689Skan% 
2100169689Skan\def\euro{{\eurofont e}}
2101169689Skan\def\eurofont{%
2102169689Skan  % We set the font at each command, rather than predefining it in
2103169689Skan  % \textfonts and the other font-switching commands, so that
2104169689Skan  % installations which never need the symbol don't have to have the
2105169689Skan  % font installed.
2106169689Skan  % 
2107169689Skan  % There is only one designed size (nominal 10pt), so we always scale
2108169689Skan  % that to the current nominal size.
2109169689Skan  % 
2110169689Skan  % By the way, simply using "at 1em" works for cmr10 and the like, but
2111169689Skan  % does not work for cmbx10 and other extended/shrunken fonts.
2112169689Skan  % 
2113169689Skan  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
2114169689Skan  %
2115169689Skan  \ifx\curfontstyle\bfstylename 
2116169689Skan    % bold:
2117169689Skan    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
2118169689Skan  \else 
2119169689Skan    % regular:
2120169689Skan    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
2121169689Skan  \fi
2122169689Skan  \thiseurofont
2123169689Skan}
2124169689Skan
2125132718Skan% @registeredsymbol - R in a circle.  The font for the R should really
2126132718Skan% be smaller yet, but lllsize is the best we can do for now.
2127119256Skan% Adapted from the plain.tex definition of \copyright.
2128119256Skan%
2129119256Skan\def\registeredsymbol{%
2130132718Skan  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
2131132718Skan               \hfil\crcr\Orb}}%
2132119256Skan    }$%
2133119256Skan}
213496263Sobrien
2135169689Skan% Laurent Siebenmann reports \Orb undefined with:
2136169689Skan%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
2137169689Skan% so we'll define it if necessary.
2138169689Skan% 
2139169689Skan\ifx\Orb\undefined
2140169689Skan\def\Orb{\mathhexbox20D}
2141169689Skan\fi
2142119256Skan
2143169689Skan
214496263Sobrien\message{page headings,}
214596263Sobrien
214696263Sobrien\newskip\titlepagetopglue \titlepagetopglue = 1.5in
214796263Sobrien\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
214896263Sobrien
214996263Sobrien% First the title page.  Must do @settitle before @titlepage.
215096263Sobrien\newif\ifseenauthor
215196263Sobrien\newif\iffinishedtitlepage
215296263Sobrien
215396263Sobrien% Do an implicit @contents or @shortcontents after @end titlepage if the
215496263Sobrien% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
215596263Sobrien%
215696263Sobrien\newif\ifsetcontentsaftertitlepage
215796263Sobrien \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
215896263Sobrien\newif\ifsetshortcontentsaftertitlepage
215996263Sobrien \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
216096263Sobrien
2161132718Skan\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
216296263Sobrien        \endgroup\page\hbox{}\page}
216396263Sobrien
2164132718Skan\envdef\titlepage{%
2165132718Skan  % Open one extra group, as we want to close it in the middle of \Etitlepage.
2166132718Skan  \begingroup
2167132718Skan    \parindent=0pt \textfonts
2168132718Skan    % Leave some space at the very top of the page.
2169132718Skan    \vglue\titlepagetopglue
2170132718Skan    % No rule at page bottom unless we print one at the top with @title.
2171132718Skan    \finishedtitlepagetrue
2172132718Skan    %
2173132718Skan    % Most title ``pages'' are actually two pages long, with space
2174132718Skan    % at the top of the second.  We don't want the ragged left on the second.
2175132718Skan    \let\oldpage = \page
2176132718Skan    \def\page{%
217796263Sobrien      \iffinishedtitlepage\else
2178132718Skan	 \finishtitlepage
217996263Sobrien      \fi
218096263Sobrien      \let\page = \oldpage
2181132718Skan      \page
2182132718Skan      \null
2183132718Skan    }%
218496263Sobrien}
218596263Sobrien
218696263Sobrien\def\Etitlepage{%
2187132718Skan    \iffinishedtitlepage\else
2188132718Skan	\finishtitlepage
2189132718Skan    \fi
2190132718Skan    % It is important to do the page break before ending the group,
2191132718Skan    % because the headline and footline are only empty inside the group.
2192132718Skan    % If we use the new definition of \page, we always get a blank page
2193132718Skan    % after the title page, which we certainly don't want.
2194132718Skan    \oldpage
2195132718Skan  \endgroup
2196132718Skan  %
2197132718Skan  % Need this before the \...aftertitlepage checks so that if they are
2198132718Skan  % in effect the toc pages will come out with page numbers.
2199132718Skan  \HEADINGSon
2200132718Skan  %
2201132718Skan  % If they want short, they certainly want long too.
2202132718Skan  \ifsetshortcontentsaftertitlepage
2203132718Skan    \shortcontents
2204132718Skan    \contents
2205132718Skan    \global\let\shortcontents = \relax
2206132718Skan    \global\let\contents = \relax
2207132718Skan  \fi
2208132718Skan  %
2209132718Skan  \ifsetcontentsaftertitlepage
2210132718Skan    \contents
2211132718Skan    \global\let\contents = \relax
2212132718Skan    \global\let\shortcontents = \relax
2213132718Skan  \fi
221496263Sobrien}
221596263Sobrien
221696263Sobrien\def\finishtitlepage{%
2217132718Skan  \vskip4pt \hrule height 2pt width \hsize
2218132718Skan  \vskip\titlepagebottomglue
2219132718Skan  \finishedtitlepagetrue
222096263Sobrien}
222196263Sobrien
2222132718Skan%%% Macros to be used within @titlepage:
2223132718Skan
2224132718Skan\let\subtitlerm=\tenrm
2225132718Skan\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
2226132718Skan
2227132718Skan\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
2228132718Skan		\let\tt=\authortt}
2229132718Skan
2230132718Skan\parseargdef\title{%
2231132718Skan  \checkenv\titlepage
2232132718Skan  \leftline{\titlefonts\rm #1}
2233132718Skan  % print a rule at the page bottom also.
2234132718Skan  \finishedtitlepagefalse
2235132718Skan  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
2236132718Skan}
2237132718Skan
2238132718Skan\parseargdef\subtitle{%
2239132718Skan  \checkenv\titlepage
2240132718Skan  {\subtitlefont \rightline{#1}}%
2241132718Skan}
2242132718Skan
2243132718Skan% @author should come last, but may come many times.
2244169689Skan% It can also be used inside @quotation.
2245169689Skan%
2246132718Skan\parseargdef\author{%
2247132718Skan  \def\temp{\quotation}%
2248132718Skan  \ifx\thisenv\temp
2249169689Skan    \def\quotationauthor{#1}% printed in \Equotation.
2250132718Skan  \else
2251132718Skan    \checkenv\titlepage
2252132718Skan    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
2253132718Skan    {\authorfont \leftline{#1}}%
2254132718Skan  \fi
2255132718Skan}
2256132718Skan
2257132718Skan
225896263Sobrien%%% Set up page headings and footings.
225996263Sobrien
226096263Sobrien\let\thispage=\folio
226196263Sobrien
226296263Sobrien\newtoks\evenheadline    % headline on even pages
226396263Sobrien\newtoks\oddheadline     % headline on odd pages
226496263Sobrien\newtoks\evenfootline    % footline on even pages
226596263Sobrien\newtoks\oddfootline     % footline on odd pages
226696263Sobrien
2267132718Skan% Now make TeX use those variables
226896263Sobrien\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
226996263Sobrien                            \else \the\evenheadline \fi}}
227096263Sobrien\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
227196263Sobrien                            \else \the\evenfootline \fi}\HEADINGShook}
227296263Sobrien\let\HEADINGShook=\relax
227396263Sobrien
227496263Sobrien% Commands to set those variables.
227596263Sobrien% For example, this is what  @headings on  does
227696263Sobrien% @evenheading @thistitle|@thispage|@thischapter
227796263Sobrien% @oddheading @thischapter|@thispage|@thistitle
227896263Sobrien% @evenfooting @thisfile||
227996263Sobrien% @oddfooting ||@thisfile
228096263Sobrien
2281132718Skan
228296263Sobrien\def\evenheading{\parsearg\evenheadingxxx}
2283132718Skan\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
2284132718Skan\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
228596263Sobrien\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
228696263Sobrien
2287132718Skan\def\oddheading{\parsearg\oddheadingxxx}
2288132718Skan\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
2289132718Skan\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
229096263Sobrien\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
229196263Sobrien
2292132718Skan\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
229396263Sobrien
2294132718Skan\def\evenfooting{\parsearg\evenfootingxxx}
2295132718Skan\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
2296132718Skan\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
229796263Sobrien\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
229896263Sobrien
2299132718Skan\def\oddfooting{\parsearg\oddfootingxxx}
2300132718Skan\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
2301132718Skan\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
230296263Sobrien  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
230396263Sobrien  %
230496263Sobrien  % Leave some space for the footline.  Hopefully ok to assume
230596263Sobrien  % @evenfooting will not be used by itself.
230696263Sobrien  \global\advance\pageheight by -\baselineskip
230796263Sobrien  \global\advance\vsize by -\baselineskip
230896263Sobrien}
230996263Sobrien
2310132718Skan\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
231196263Sobrien
2312132718Skan
231396263Sobrien% @headings double      turns headings on for double-sided printing.
231496263Sobrien% @headings single      turns headings on for single-sided printing.
231596263Sobrien% @headings off         turns them off.
231696263Sobrien% @headings on          same as @headings double, retained for compatibility.
231796263Sobrien% @headings after       turns on double-sided headings after this page.
231896263Sobrien% @headings doubleafter turns on double-sided headings after this page.
231996263Sobrien% @headings singleafter turns on single-sided headings after this page.
232096263Sobrien% By default, they are off at the start of a document,
232196263Sobrien% and turned `on' after @end titlepage.
232296263Sobrien
232396263Sobrien\def\headings #1 {\csname HEADINGS#1\endcsname}
232496263Sobrien
2325132718Skan\def\HEADINGSoff{%
232696263Sobrien\global\evenheadline={\hfil} \global\evenfootline={\hfil}
232796263Sobrien\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
232896263Sobrien\HEADINGSoff
232996263Sobrien% When we turn headings on, set the page number to 1.
233096263Sobrien% For double-sided printing, put current file name in lower left corner,
233196263Sobrien% chapter name on inside top of right hand pages, document
233296263Sobrien% title on inside top of left hand pages, and page numbers on outside top
233396263Sobrien% edge of all pages.
2334132718Skan\def\HEADINGSdouble{%
233596263Sobrien\global\pageno=1
233696263Sobrien\global\evenfootline={\hfil}
233796263Sobrien\global\oddfootline={\hfil}
233896263Sobrien\global\evenheadline={\line{\folio\hfil\thistitle}}
233996263Sobrien\global\oddheadline={\line{\thischapter\hfil\folio}}
234096263Sobrien\global\let\contentsalignmacro = \chapoddpage
234196263Sobrien}
234296263Sobrien\let\contentsalignmacro = \chappager
234396263Sobrien
234496263Sobrien% For single-sided printing, chapter title goes across top left of page,
234596263Sobrien% page number on top right.
2346132718Skan\def\HEADINGSsingle{%
234796263Sobrien\global\pageno=1
234896263Sobrien\global\evenfootline={\hfil}
234996263Sobrien\global\oddfootline={\hfil}
235096263Sobrien\global\evenheadline={\line{\thischapter\hfil\folio}}
235196263Sobrien\global\oddheadline={\line{\thischapter\hfil\folio}}
235296263Sobrien\global\let\contentsalignmacro = \chappager
235396263Sobrien}
235496263Sobrien\def\HEADINGSon{\HEADINGSdouble}
235596263Sobrien
235696263Sobrien\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
235796263Sobrien\let\HEADINGSdoubleafter=\HEADINGSafter
235896263Sobrien\def\HEADINGSdoublex{%
235996263Sobrien\global\evenfootline={\hfil}
236096263Sobrien\global\oddfootline={\hfil}
236196263Sobrien\global\evenheadline={\line{\folio\hfil\thistitle}}
236296263Sobrien\global\oddheadline={\line{\thischapter\hfil\folio}}
236396263Sobrien\global\let\contentsalignmacro = \chapoddpage
236496263Sobrien}
236596263Sobrien
236696263Sobrien\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
236796263Sobrien\def\HEADINGSsinglex{%
236896263Sobrien\global\evenfootline={\hfil}
236996263Sobrien\global\oddfootline={\hfil}
237096263Sobrien\global\evenheadline={\line{\thischapter\hfil\folio}}
237196263Sobrien\global\oddheadline={\line{\thischapter\hfil\folio}}
237296263Sobrien\global\let\contentsalignmacro = \chappager
237396263Sobrien}
237496263Sobrien
237596263Sobrien% Subroutines used in generating headings
237696263Sobrien% This produces Day Month Year style of output.
237796263Sobrien% Only define if not already defined, in case a txi-??.tex file has set
237896263Sobrien% up a different format (e.g., txi-cs.tex does this).
237996263Sobrien\ifx\today\undefined
238096263Sobrien\def\today{%
238196263Sobrien  \number\day\space
238296263Sobrien  \ifcase\month
238396263Sobrien  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
238496263Sobrien  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
238596263Sobrien  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
238696263Sobrien  \fi
238796263Sobrien  \space\number\year}
238896263Sobrien\fi
238996263Sobrien
239096263Sobrien% @settitle line...  specifies the title of the document, for headings.
239196263Sobrien% It generates no output of its own.
239296263Sobrien\def\thistitle{\putwordNoTitle}
2393132718Skan\def\settitle{\parsearg{\gdef\thistitle}}
239496263Sobrien
239596263Sobrien
239696263Sobrien\message{tables,}
2397132718Skan% Tables -- @table, @ftable, @vtable, @item(x).
239896263Sobrien
239996263Sobrien% default indentation of table text
240096263Sobrien\newdimen\tableindent \tableindent=.8in
240196263Sobrien% default indentation of @itemize and @enumerate text
240296263Sobrien\newdimen\itemindent  \itemindent=.3in
240396263Sobrien% margin between end of table item and start of table text.
240496263Sobrien\newdimen\itemmargin  \itemmargin=.1in
240596263Sobrien
240696263Sobrien% used internally for \itemindent minus \itemmargin
240796263Sobrien\newdimen\itemmax
240896263Sobrien
2409132718Skan% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
241096263Sobrien% these defs.
241196263Sobrien% They also define \itemindex
241296263Sobrien% to index the item name in whatever manner is desired (perhaps none).
241396263Sobrien
241496263Sobrien\newif\ifitemxneedsnegativevskip
241596263Sobrien
241696263Sobrien\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
241796263Sobrien
241896263Sobrien\def\internalBitem{\smallbreak \parsearg\itemzzz}
241996263Sobrien\def\internalBitemx{\itemxpar \parsearg\itemzzz}
242096263Sobrien
242196263Sobrien\def\itemzzz #1{\begingroup %
242296263Sobrien  \advance\hsize by -\rightskip
242396263Sobrien  \advance\hsize by -\tableindent
2424132718Skan  \setbox0=\hbox{\itemindicate{#1}}%
242596263Sobrien  \itemindex{#1}%
242696263Sobrien  \nobreak % This prevents a break before @itemx.
242796263Sobrien  %
242896263Sobrien  % If the item text does not fit in the space we have, put it on a line
242996263Sobrien  % by itself, and do not allow a page break either before or after that
243096263Sobrien  % line.  We do not start a paragraph here because then if the next
243196263Sobrien  % command is, e.g., @kindex, the whatsit would get put into the
243296263Sobrien  % horizontal list on a line by itself, resulting in extra blank space.
243396263Sobrien  \ifdim \wd0>\itemmax
243496263Sobrien    %
243596263Sobrien    % Make this a paragraph so we get the \parskip glue and wrapping,
243696263Sobrien    % but leave it ragged-right.
243796263Sobrien    \begingroup
243896263Sobrien      \advance\leftskip by-\tableindent
243996263Sobrien      \advance\hsize by\tableindent
244096263Sobrien      \advance\rightskip by0pt plus1fil
244196263Sobrien      \leavevmode\unhbox0\par
244296263Sobrien    \endgroup
244396263Sobrien    %
244496263Sobrien    % We're going to be starting a paragraph, but we don't want the
244596263Sobrien    % \parskip glue -- logically it's part of the @item we just started.
244696263Sobrien    \nobreak \vskip-\parskip
244796263Sobrien    %
2448169689Skan    % Stop a page break at the \parskip glue coming up.  However, if
2449169689Skan    % what follows is an environment such as @example, there will be no
2450169689Skan    % \parskip glue; then the negative vskip we just inserted would
2451169689Skan    % cause the example and the item to crash together.  So we use this
2452169689Skan    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
2453169689Skan    % \parskip glue after all.  Section titles are handled this way also.
2454169689Skan    % 
2455117395Skan    \penalty 10001
245696263Sobrien    \endgroup
245796263Sobrien    \itemxneedsnegativevskipfalse
245896263Sobrien  \else
245996263Sobrien    % The item text fits into the space.  Start a paragraph, so that the
246096263Sobrien    % following text (if any) will end up on the same line.
246196263Sobrien    \noindent
246296263Sobrien    % Do this with kerns and \unhbox so that if there is a footnote in
246396263Sobrien    % the item text, it can migrate to the main vertical list and
246496263Sobrien    % eventually be printed.
246596263Sobrien    \nobreak\kern-\tableindent
246696263Sobrien    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
246796263Sobrien    \unhbox0
246896263Sobrien    \nobreak\kern\dimen0
246996263Sobrien    \endgroup
247096263Sobrien    \itemxneedsnegativevskiptrue
247196263Sobrien  \fi
247296263Sobrien}
247396263Sobrien
2474132718Skan\def\item{\errmessage{@item while not in a list environment}}
2475132718Skan\def\itemx{\errmessage{@itemx while not in a list environment}}
247696263Sobrien
247796263Sobrien% @table, @ftable, @vtable.
2478132718Skan\envdef\table{%
2479132718Skan  \let\itemindex\gobble
2480169689Skan  \tablecheck{table}%
248196263Sobrien}
2482132718Skan\envdef\ftable{%
2483132718Skan  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
2484169689Skan  \tablecheck{ftable}%
2485132718Skan}
2486132718Skan\envdef\vtable{%
2487132718Skan  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
2488169689Skan  \tablecheck{vtable}%
2489132718Skan}
2490169689Skan\def\tablecheck#1{%
2491169689Skan  \ifnum \the\catcode`\^^M=\active
2492169689Skan    \endgroup
2493169689Skan    \errmessage{This command won't work in this context; perhaps the problem is
2494169689Skan      that we are \inenvironment\thisenv}%
2495169689Skan    \def\next{\doignore{#1}}%
2496169689Skan  \else
2497169689Skan    \let\next\tablex
2498169689Skan  \fi
2499169689Skan  \next
2500169689Skan}
2501132718Skan\def\tablex#1{%
2502132718Skan  \def\itemindicate{#1}%
2503132718Skan  \parsearg\tabley
2504132718Skan}
2505132718Skan\def\tabley#1{%
2506132718Skan  {%
2507132718Skan    \makevalueexpandable
2508132718Skan    \edef\temp{\noexpand\tablez #1\space\space\space}%
2509132718Skan    \expandafter
2510132718Skan  }\temp \endtablez
2511132718Skan}
2512132718Skan\def\tablez #1 #2 #3 #4\endtablez{%
2513132718Skan  \aboveenvbreak
2514132718Skan  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
2515132718Skan  \ifnum 0#2>0 \tableindent=#2\mil \fi
2516132718Skan  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
2517132718Skan  \itemmax=\tableindent
2518132718Skan  \advance \itemmax by -\itemmargin
2519132718Skan  \advance \leftskip by \tableindent
2520132718Skan  \exdentamount=\tableindent
2521132718Skan  \parindent = 0pt
2522132718Skan  \parskip = \smallskipamount
2523132718Skan  \ifdim \parskip=0pt \parskip=2pt \fi
2524132718Skan  \let\item = \internalBitem
2525132718Skan  \let\itemx = \internalBitemx
2526132718Skan}
2527132718Skan\def\Etable{\endgraf\afterenvbreak}
2528132718Skan\let\Eftable\Etable
2529132718Skan\let\Evtable\Etable
2530132718Skan\let\Eitemize\Etable
2531132718Skan\let\Eenumerate\Etable
253296263Sobrien
253396263Sobrien% This is the counter used by @enumerate, which is really @itemize
253496263Sobrien
253596263Sobrien\newcount \itemno
253696263Sobrien
2537169689Skan\envdef\itemize{\parsearg\doitemize}
253896263Sobrien
2539169689Skan\def\doitemize#1{%
2540119256Skan  \aboveenvbreak
2541119256Skan  \itemmax=\itemindent
2542119256Skan  \advance\itemmax by -\itemmargin
2543119256Skan  \advance\leftskip by \itemindent
2544119256Skan  \exdentamount=\itemindent
2545119256Skan  \parindent=0pt
2546119256Skan  \parskip=\smallskipamount
2547119256Skan  \ifdim\parskip=0pt \parskip=2pt \fi
2548119256Skan  \def\itemcontents{#1}%
2549119256Skan  % @itemize with no arg is equivalent to @itemize @bullet.
2550119256Skan  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
2551119256Skan  \let\item=\itemizeitem
2552119256Skan}
255396263Sobrien
2554169689Skan% Definition of @item while inside @itemize and @enumerate.
2555169689Skan%
2556169689Skan\def\itemizeitem{%
2557169689Skan  \advance\itemno by 1  % for enumerations
2558169689Skan  {\let\par=\endgraf \smallbreak}% reasonable place to break
2559169689Skan  {%
2560169689Skan   % If the document has an @itemize directly after a section title, a
2561169689Skan   % \nobreak will be last on the list, and \sectionheading will have
2562169689Skan   % done a \vskip-\parskip.  In that case, we don't want to zero
2563169689Skan   % parskip, or the item text will crash with the heading.  On the
2564169689Skan   % other hand, when there is normal text preceding the item (as there
2565169689Skan   % usually is), we do want to zero parskip, or there would be too much
2566169689Skan   % space.  In that case, we won't have a \nobreak before.  At least
2567169689Skan   % that's the theory.
2568169689Skan   \ifnum\lastpenalty<10000 \parskip=0in \fi
2569169689Skan   \noindent
2570169689Skan   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
2571169689Skan   \vadjust{\penalty 1200}}% not good to break after first line of item.
2572169689Skan  \flushcr
2573169689Skan}
2574169689Skan
257596263Sobrien% \splitoff TOKENS\endmark defines \first to be the first token in
257696263Sobrien% TOKENS, and \rest to be the remainder.
257796263Sobrien%
257896263Sobrien\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
257996263Sobrien
258096263Sobrien% Allow an optional argument of an uppercase letter, lowercase letter,
258196263Sobrien% or number, to specify the first label in the enumerated list.  No
258296263Sobrien% argument is the same as `1'.
258396263Sobrien%
2584132718Skan\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
258596263Sobrien\def\enumeratey #1 #2\endenumeratey{%
258696263Sobrien  % If we were given no argument, pretend we were given `1'.
258796263Sobrien  \def\thearg{#1}%
258896263Sobrien  \ifx\thearg\empty \def\thearg{1}\fi
258996263Sobrien  %
259096263Sobrien  % Detect if the argument is a single token.  If so, it might be a
259196263Sobrien  % letter.  Otherwise, the only valid thing it can be is a number.
259296263Sobrien  % (We will always have one token, because of the test we just made.
259396263Sobrien  % This is a good thing, since \splitoff doesn't work given nothing at
259496263Sobrien  % all -- the first parameter is undelimited.)
259596263Sobrien  \expandafter\splitoff\thearg\endmark
259696263Sobrien  \ifx\rest\empty
259796263Sobrien    % Only one token in the argument.  It could still be anything.
259896263Sobrien    % A ``lowercase letter'' is one whose \lccode is nonzero.
259996263Sobrien    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
260096263Sobrien    %   not equal to itself.
260196263Sobrien    % Otherwise, we assume it's a number.
260296263Sobrien    %
260396263Sobrien    % We need the \relax at the end of the \ifnum lines to stop TeX from
260496263Sobrien    % continuing to look for a <number>.
260596263Sobrien    %
260696263Sobrien    \ifnum\lccode\expandafter`\thearg=0\relax
260796263Sobrien      \numericenumerate % a number (we hope)
260896263Sobrien    \else
260996263Sobrien      % It's a letter.
261096263Sobrien      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
261196263Sobrien        \lowercaseenumerate % lowercase letter
261296263Sobrien      \else
261396263Sobrien        \uppercaseenumerate % uppercase letter
261496263Sobrien      \fi
261596263Sobrien    \fi
261696263Sobrien  \else
261796263Sobrien    % Multiple tokens in the argument.  We hope it's a number.
261896263Sobrien    \numericenumerate
261996263Sobrien  \fi
262096263Sobrien}
262196263Sobrien
262296263Sobrien% An @enumerate whose labels are integers.  The starting integer is
262396263Sobrien% given in \thearg.
262496263Sobrien%
262596263Sobrien\def\numericenumerate{%
262696263Sobrien  \itemno = \thearg
262796263Sobrien  \startenumeration{\the\itemno}%
262896263Sobrien}
262996263Sobrien
263096263Sobrien% The starting (lowercase) letter is in \thearg.
263196263Sobrien\def\lowercaseenumerate{%
263296263Sobrien  \itemno = \expandafter`\thearg
263396263Sobrien  \startenumeration{%
263496263Sobrien    % Be sure we're not beyond the end of the alphabet.
263596263Sobrien    \ifnum\itemno=0
263696263Sobrien      \errmessage{No more lowercase letters in @enumerate; get a bigger
263796263Sobrien                  alphabet}%
263896263Sobrien    \fi
263996263Sobrien    \char\lccode\itemno
264096263Sobrien  }%
264196263Sobrien}
264296263Sobrien
264396263Sobrien% The starting (uppercase) letter is in \thearg.
264496263Sobrien\def\uppercaseenumerate{%
264596263Sobrien  \itemno = \expandafter`\thearg
264696263Sobrien  \startenumeration{%
264796263Sobrien    % Be sure we're not beyond the end of the alphabet.
264896263Sobrien    \ifnum\itemno=0
264996263Sobrien      \errmessage{No more uppercase letters in @enumerate; get a bigger
265096263Sobrien                  alphabet}
265196263Sobrien    \fi
265296263Sobrien    \char\uccode\itemno
265396263Sobrien  }%
265496263Sobrien}
265596263Sobrien
2656169689Skan% Call \doitemize, adding a period to the first argument and supplying the
265796263Sobrien% common last two arguments.  Also subtract one from the initial value in
265896263Sobrien% \itemno, since @item increments \itemno.
265996263Sobrien%
266096263Sobrien\def\startenumeration#1{%
266196263Sobrien  \advance\itemno by -1
2662169689Skan  \doitemize{#1.}\flushcr
266396263Sobrien}
266496263Sobrien
266596263Sobrien% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
266696263Sobrien% to @enumerate.
266796263Sobrien%
266896263Sobrien\def\alphaenumerate{\enumerate{a}}
266996263Sobrien\def\capsenumerate{\enumerate{A}}
267096263Sobrien\def\Ealphaenumerate{\Eenumerate}
267196263Sobrien\def\Ecapsenumerate{\Eenumerate}
267296263Sobrien
267396263Sobrien
267496263Sobrien% @multitable macros
267596263Sobrien% Amy Hendrickson, 8/18/94, 3/6/96
267696263Sobrien%
267796263Sobrien% @multitable ... @end multitable will make as many columns as desired.
267896263Sobrien% Contents of each column will wrap at width given in preamble.  Width
267996263Sobrien% can be specified either with sample text given in a template line,
268096263Sobrien% or in percent of \hsize, the current width of text on page.
268196263Sobrien
268296263Sobrien% Table can continue over pages but will only break between lines.
268396263Sobrien
268496263Sobrien% To make preamble:
268596263Sobrien%
268696263Sobrien% Either define widths of columns in terms of percent of \hsize:
268796263Sobrien%   @multitable @columnfractions .25 .3 .45
268896263Sobrien%   @item ...
268996263Sobrien%
269096263Sobrien%   Numbers following @columnfractions are the percent of the total
269196263Sobrien%   current hsize to be used for each column. You may use as many
269296263Sobrien%   columns as desired.
269396263Sobrien
269496263Sobrien
269596263Sobrien% Or use a template:
269696263Sobrien%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
269796263Sobrien%   @item ...
269896263Sobrien%   using the widest term desired in each column.
269996263Sobrien
270096263Sobrien% Each new table line starts with @item, each subsequent new column
270196263Sobrien% starts with @tab. Empty columns may be produced by supplying @tab's
270296263Sobrien% with nothing between them for as many times as empty columns are needed,
270396263Sobrien% ie, @tab@tab@tab will produce two empty columns.
270496263Sobrien
2705132718Skan% @item, @tab do not need to be on their own lines, but it will not hurt
2706132718Skan% if they are.
270796263Sobrien
270896263Sobrien% Sample multitable:
270996263Sobrien
271096263Sobrien%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
271196263Sobrien%   @item first col stuff @tab second col stuff @tab third col
271296263Sobrien%   @item
271396263Sobrien%   first col stuff
271496263Sobrien%   @tab
271596263Sobrien%   second col stuff
271696263Sobrien%   @tab
271796263Sobrien%   third col
271896263Sobrien%   @item first col stuff @tab second col stuff
271996263Sobrien%   @tab Many paragraphs of text may be used in any column.
272096263Sobrien%
272196263Sobrien%         They will wrap at the width determined by the template.
272296263Sobrien%   @item@tab@tab This will be in third column.
272396263Sobrien%   @end multitable
272496263Sobrien
272596263Sobrien% Default dimensions may be reset by user.
272696263Sobrien% @multitableparskip is vertical space between paragraphs in table.
272796263Sobrien% @multitableparindent is paragraph indent in table.
272896263Sobrien% @multitablecolmargin is horizontal space to be left between columns.
272996263Sobrien% @multitablelinespace is space to leave between table items, baseline
273096263Sobrien%                                                            to baseline.
273196263Sobrien%   0pt means it depends on current normal line spacing.
273296263Sobrien%
273396263Sobrien\newskip\multitableparskip
273496263Sobrien\newskip\multitableparindent
273596263Sobrien\newdimen\multitablecolspace
273696263Sobrien\newskip\multitablelinespace
273796263Sobrien\multitableparskip=0pt
273896263Sobrien\multitableparindent=6pt
273996263Sobrien\multitablecolspace=12pt
274096263Sobrien\multitablelinespace=0pt
274196263Sobrien
274296263Sobrien% Macros used to set up halign preamble:
274396263Sobrien%
274496263Sobrien\let\endsetuptable\relax
274596263Sobrien\def\xendsetuptable{\endsetuptable}
274696263Sobrien\let\columnfractions\relax
274796263Sobrien\def\xcolumnfractions{\columnfractions}
274896263Sobrien\newif\ifsetpercent
274996263Sobrien
2750169689Skan% #1 is the @columnfraction, usually a decimal number like .5, but might
2751169689Skan% be just 1.  We just use it, whatever it is.
2752169689Skan%
2753169689Skan\def\pickupwholefraction#1 {%
275496263Sobrien  \global\advance\colcount by 1
2755169689Skan  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
275696263Sobrien  \setuptable
275796263Sobrien}
275896263Sobrien
275996263Sobrien\newcount\colcount
276096263Sobrien\def\setuptable#1{%
276196263Sobrien  \def\firstarg{#1}%
276296263Sobrien  \ifx\firstarg\xendsetuptable
276396263Sobrien    \let\go = \relax
276496263Sobrien  \else
276596263Sobrien    \ifx\firstarg\xcolumnfractions
276696263Sobrien      \global\setpercenttrue
276796263Sobrien    \else
276896263Sobrien      \ifsetpercent
276996263Sobrien         \let\go\pickupwholefraction
277096263Sobrien      \else
277196263Sobrien         \global\advance\colcount by 1
2772119256Skan         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
2773119256Skan                   % separator; typically that is always in the input, anyway.
277496263Sobrien         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
277596263Sobrien      \fi
277696263Sobrien    \fi
277796263Sobrien    \ifx\go\pickupwholefraction
277896263Sobrien      % Put the argument back for the \pickupwholefraction call, so
277996263Sobrien      % we'll always have a period there to be parsed.
278096263Sobrien      \def\go{\pickupwholefraction#1}%
278196263Sobrien    \else
278296263Sobrien      \let\go = \setuptable
278396263Sobrien    \fi%
278496263Sobrien  \fi
278596263Sobrien  \go
278696263Sobrien}
278796263Sobrien
2788132718Skan% multitable-only commands.
2789132718Skan%
2790132718Skan% @headitem starts a heading row, which we typeset in bold.
2791132718Skan% Assignments have to be global since we are inside the implicit group
2792132718Skan% of an alignment entry.  Note that \everycr resets \everytab.
2793132718Skan\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
2794132718Skan%
2795132718Skan% A \tab used to include \hskip1sp.  But then the space in a template
2796132718Skan% line is not enough.  That is bad.  So let's go back to just `&' until
2797132718Skan% we encounter the problem it was intended to solve again.
2798132718Skan%					--karl, nathan@acm.org, 20apr99.
2799132718Skan\def\tab{\checkenv\multitable &\the\everytab}%
2800132718Skan
280196263Sobrien% @multitable ... @end multitable definitions:
280296263Sobrien%
2803132718Skan\newtoks\everytab  % insert after every tab.
2804132718Skan%
2805132718Skan\envdef\multitable{%
280696263Sobrien  \vskip\parskip
2807132718Skan  \startsavinginserts
2808132718Skan  %
2809132718Skan  % @item within a multitable starts a normal row.
2810169689Skan  % We use \def instead of \let so that if one of the multitable entries
2811169689Skan  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
2812169689Skan  % \endtemplate) expanding \doitemize.
2813169689Skan  \def\item{\crcr}%
2814132718Skan  %
281596263Sobrien  \tolerance=9500
281696263Sobrien  \hbadness=9500
281796263Sobrien  \setmultitablespacing
281896263Sobrien  \parskip=\multitableparskip
281996263Sobrien  \parindent=\multitableparindent
282096263Sobrien  \overfullrule=0pt
282196263Sobrien  \global\colcount=0
2822132718Skan  %
2823132718Skan  \everycr = {%
2824132718Skan    \noalign{%
2825132718Skan      \global\everytab={}%
2826132718Skan      \global\colcount=0 % Reset the column counter.
2827132718Skan      % Check for saved footnotes, etc.
2828132718Skan      \checkinserts
2829132718Skan      % Keeps underfull box messages off when table breaks over pages.
2830132718Skan      %\filbreak
2831132718Skan	% Maybe so, but it also creates really weird page breaks when the
2832132718Skan	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
2833132718Skan	% problem manifests itself, so it can be fixed for real --karl.
2834132718Skan    }%
2835119256Skan  }%
283696263Sobrien  %
2837132718Skan  \parsearg\domultitable
2838132718Skan}
2839132718Skan\def\domultitable#1{%
284096263Sobrien  % To parse everything between @multitable and @item:
284196263Sobrien  \setuptable#1 \endsetuptable
284296263Sobrien  %
284396263Sobrien  % This preamble sets up a generic column definition, which will
284496263Sobrien  % be used as many times as user calls for columns.
284596263Sobrien  % \vtop will set a single line and will also let text wrap and
284696263Sobrien  % continue for many paragraphs if desired.
2847132718Skan  \halign\bgroup &%
2848132718Skan    \global\advance\colcount by 1
2849132718Skan    \multistrut
2850132718Skan    \vtop{%
2851132718Skan      % Use the current \colcount to find the correct column width:
2852132718Skan      \hsize=\expandafter\csname col\the\colcount\endcsname
2853132718Skan      %
2854132718Skan      % In order to keep entries from bumping into each other
2855132718Skan      % we will add a \leftskip of \multitablecolspace to all columns after
2856132718Skan      % the first one.
2857132718Skan      %
2858132718Skan      % If a template has been used, we will add \multitablecolspace
2859132718Skan      % to the width of each template entry.
2860132718Skan      %
2861132718Skan      % If the user has set preamble in terms of percent of \hsize we will
2862132718Skan      % use that dimension as the width of the column, and the \leftskip
2863132718Skan      % will keep entries from bumping into each other.  Table will start at
2864132718Skan      % left margin and final column will justify at right margin.
2865132718Skan      %
2866132718Skan      % Make sure we don't inherit \rightskip from the outer environment.
2867132718Skan      \rightskip=0pt
2868132718Skan      \ifnum\colcount=1
2869132718Skan	% The first column will be indented with the surrounding text.
2870132718Skan	\advance\hsize by\leftskip
2871132718Skan      \else
2872132718Skan	\ifsetpercent \else
2873132718Skan	  % If user has not set preamble in terms of percent of \hsize
2874132718Skan	  % we will advance \hsize by \multitablecolspace.
2875132718Skan	  \advance\hsize by \multitablecolspace
2876132718Skan	\fi
2877132718Skan       % In either case we will make \leftskip=\multitablecolspace:
2878132718Skan      \leftskip=\multitablecolspace
2879132718Skan      \fi
2880132718Skan      % Ignoring space at the beginning and end avoids an occasional spurious
2881132718Skan      % blank line, when TeX decides to break the line at the space before the
2882132718Skan      % box from the multistrut, so the strut ends up on a line by itself.
2883132718Skan      % For example:
2884132718Skan      % @multitable @columnfractions .11 .89
2885132718Skan      % @item @code{#}
2886132718Skan      % @tab Legal holiday which is valid in major parts of the whole country.
2887132718Skan      % Is automatically provided with highlighting sequences respectively
2888132718Skan      % marking characters.
2889132718Skan      \noindent\ignorespaces##\unskip\multistrut
2890132718Skan    }\cr
289196263Sobrien}
2892132718Skan\def\Emultitable{%
2893132718Skan  \crcr
2894132718Skan  \egroup % end the \halign
2895132718Skan  \global\setpercentfalse
2896132718Skan}
289796263Sobrien
2898169689Skan\def\setmultitablespacing{%
2899169689Skan  \def\multistrut{\strut}% just use the standard line spacing
2900169689Skan  %
2901169689Skan  % Compute \multitablelinespace (if not defined by user) for use in
2902169689Skan  % \multitableparskip calculation.  We used define \multistrut based on
2903169689Skan  % this, but (ironically) that caused the spacing to be off.
2904169689Skan  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
290596263Sobrien\ifdim\multitablelinespace=0pt
290696263Sobrien\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
290796263Sobrien\global\advance\multitablelinespace by-\ht0
2908169689Skan\fi
290996263Sobrien%% Test to see if parskip is larger than space between lines of
291096263Sobrien%% table. If not, do nothing.
291196263Sobrien%%        If so, set to same dimension as multitablelinespace.
291296263Sobrien\ifdim\multitableparskip>\multitablelinespace
291396263Sobrien\global\multitableparskip=\multitablelinespace
291496263Sobrien\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
291596263Sobrien                                      %% than skip between lines in the table.
291696263Sobrien\fi%
291796263Sobrien\ifdim\multitableparskip=0pt
291896263Sobrien\global\multitableparskip=\multitablelinespace
291996263Sobrien\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
292096263Sobrien                                      %% than skip between lines in the table.
292196263Sobrien\fi}
292296263Sobrien
292396263Sobrien
292496263Sobrien\message{conditionals,}
292596263Sobrien
2926132718Skan% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
2927132718Skan% @ifnotxml always succeed.  They currently do nothing; we don't
2928132718Skan% attempt to check whether the conditionals are properly nested.  But we
2929132718Skan% have to remember that they are conditionals, so that @end doesn't
2930132718Skan% attempt to close an environment group.
293196263Sobrien%
2932132718Skan\def\makecond#1{%
2933132718Skan  \expandafter\let\csname #1\endcsname = \relax
2934132718Skan  \expandafter\let\csname iscond.#1\endcsname = 1
293596263Sobrien}
2936132718Skan\makecond{iftex}
2937132718Skan\makecond{ifnotdocbook}
2938132718Skan\makecond{ifnothtml}
2939132718Skan\makecond{ifnotinfo}
2940132718Skan\makecond{ifnotplaintext}
2941132718Skan\makecond{ifnotxml}
294296263Sobrien
2943117395Skan% Ignore @ignore, @ifhtml, @ifinfo, and the like.
294496263Sobrien%
2945117395Skan\def\direntry{\doignore{direntry}}
2946117395Skan\def\documentdescription{\doignore{documentdescription}}
2947132718Skan\def\docbook{\doignore{docbook}}
2948117395Skan\def\html{\doignore{html}}
2949132718Skan\def\ifdocbook{\doignore{ifdocbook}}
2950117395Skan\def\ifhtml{\doignore{ifhtml}}
295196263Sobrien\def\ifinfo{\doignore{ifinfo}}
295296263Sobrien\def\ifnottex{\doignore{ifnottex}}
2953117395Skan\def\ifplaintext{\doignore{ifplaintext}}
2954117395Skan\def\ifxml{\doignore{ifxml}}
2955117395Skan\def\ignore{\doignore{ignore}}
295696263Sobrien\def\menu{\doignore{menu}}
2957117395Skan\def\xml{\doignore{xml}}
295896263Sobrien
2959132718Skan% Ignore text until a line `@end #1', keeping track of nested conditionals.
2960132718Skan%
2961132718Skan% A count to remember the depth of nesting.
2962132718Skan\newcount\doignorecount
296396263Sobrien
296496263Sobrien\def\doignore#1{\begingroup
2965132718Skan  % Scan in ``verbatim'' mode:
2966132718Skan  \catcode`\@ = \other
2967132718Skan  \catcode`\{ = \other
2968132718Skan  \catcode`\} = \other
296996263Sobrien  %
297096263Sobrien  % Make sure that spaces turn into tokens that match what \doignoretext wants.
2971132718Skan  \spaceisspace
297296263Sobrien  %
2973132718Skan  % Count number of #1's that we've seen.
2974132718Skan  \doignorecount = 0
297596263Sobrien  %
2976132718Skan  % Swallow text until we reach the matching `@end #1'.
2977169689Skan  \dodoignore{#1}%
2978132718Skan}
2979132718Skan
2980132718Skan{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
2981132718Skan  \obeylines %
298296263Sobrien  %
2983132718Skan  \gdef\dodoignore#1{%
2984169689Skan    % #1 contains the command name as a string, e.g., `ifinfo'.
2985132718Skan    %
2986132718Skan    % Define a command to find the next `@end #1', which must be on a line
2987132718Skan    % by itself.
2988132718Skan    \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
2989132718Skan    % And this command to find another #1 command, at the beginning of a
2990132718Skan    % line.  (Otherwise, we would consider a line `@c @ifset', for
2991132718Skan    % example, to count as an @ifset for nesting.)
2992132718Skan    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
2993132718Skan    %
2994132718Skan    % And now expand that command.
2995132718Skan    \obeylines %
2996132718Skan    \doignoretext ^^M%
2997132718Skan  }%
2998132718Skan}
2999132718Skan
3000132718Skan\def\doignoreyyy#1{%
3001132718Skan  \def\temp{#1}%
3002132718Skan  \ifx\temp\empty			% Nothing found.
3003132718Skan    \let\next\doignoretextzzz
3004132718Skan  \else					% Found a nested condition, ...
3005132718Skan    \advance\doignorecount by 1
3006132718Skan    \let\next\doignoretextyyy		% ..., look for another.
3007132718Skan    % If we're here, #1 ends with ^^M\ifinfo (for example).
3008117395Skan  \fi
3009132718Skan  \next #1% the token \_STOP_ is present just after this macro.
301096263Sobrien}
301196263Sobrien
3012132718Skan% We have to swallow the remaining "\_STOP_".
3013169689Skan%
3014132718Skan\def\doignoretextzzz#1{%
3015132718Skan  \ifnum\doignorecount = 0	% We have just found the outermost @end.
3016132718Skan    \let\next\enddoignore
3017132718Skan  \else				% Still inside a nested condition.
3018132718Skan    \advance\doignorecount by -1
3019132718Skan    \let\next\doignoretext      % Look for the next @end.
3020132718Skan  \fi
3021132718Skan  \next
302296263Sobrien}
302396263Sobrien
3024132718Skan% Finish off ignored text.
3025132718Skan\def\enddoignore{\endgroup\ignorespaces}
302696263Sobrien
302796263Sobrien
302896263Sobrien% @set VAR sets the variable VAR to an empty value.
302996263Sobrien% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
303096263Sobrien%
303196263Sobrien% Since we want to separate VAR from REST-OF-LINE (which might be
303296263Sobrien% empty), we can't just use \parsearg; we have to insert a space of our
303396263Sobrien% own to delimit the rest of the line, and then take it out again if we
3034132718Skan% didn't need it.
3035132718Skan% We rely on the fact that \parsearg sets \catcode`\ =10.
303696263Sobrien%
3037132718Skan\parseargdef\set{\setyyy#1 \endsetyyy}
303896263Sobrien\def\setyyy#1 #2\endsetyyy{%
3039132718Skan  {%
3040132718Skan    \makevalueexpandable
3041132718Skan    \def\temp{#2}%
3042132718Skan    \edef\next{\gdef\makecsname{SET#1}}%
3043132718Skan    \ifx\temp\empty
3044132718Skan      \next{}%
3045132718Skan    \else
3046132718Skan      \setzzz#2\endsetzzz
3047132718Skan    \fi
3048132718Skan  }%
304996263Sobrien}
3050132718Skan% Remove the trailing space \setxxx inserted.
3051132718Skan\def\setzzz#1 \endsetzzz{\next{#1}}
305296263Sobrien
305396263Sobrien% @clear VAR clears (i.e., unsets) the variable VAR.
305496263Sobrien%
3055132718Skan\parseargdef\clear{%
3056132718Skan  {%
3057132718Skan    \makevalueexpandable
3058132718Skan    \global\expandafter\let\csname SET#1\endcsname=\relax
3059132718Skan  }%
3060132718Skan}
306196263Sobrien
306296263Sobrien% @value{foo} gets the text saved in variable foo.
3063132718Skan\def\value{\begingroup\makevalueexpandable\valuexxx}
3064132718Skan\def\valuexxx#1{\expandablevalue{#1}\endgroup}
306596263Sobrien{
3066132718Skan  \catcode`\- = \active \catcode`\_ = \active
306796263Sobrien  %
3068132718Skan  \gdef\makevalueexpandable{%
3069132718Skan    \let\value = \expandablevalue
3070132718Skan    % We don't want these characters active, ...
3071119256Skan    \catcode`\-=\other \catcode`\_=\other
3072132718Skan    % ..., but we might end up with active ones in the argument if
3073132718Skan    % we're called from @code, as @code{@value{foo-bar_}}, though.
3074132718Skan    % So \let them to their normal equivalents.
3075132718Skan    \let-\realdash \let_\normalunderscore
3076132718Skan  }
307796263Sobrien}
307896263Sobrien
307996263Sobrien% We have this subroutine so that we can handle at least some @value's
3080132718Skan% properly in indexes (we call \makevalueexpandable in \indexdummies).
3081132718Skan% The command has to be fully expandable (if the variable is set), since
3082132718Skan% the result winds up in the index file.  This means that if the
3083132718Skan% variable's value contains other Texinfo commands, it's almost certain
3084132718Skan% it will fail (although perhaps we could fix that with sufficient work
3085132718Skan% to do a one-level expansion on the result, instead of complete).
308696263Sobrien%
308796263Sobrien\def\expandablevalue#1{%
308896263Sobrien  \expandafter\ifx\csname SET#1\endcsname\relax
308996263Sobrien    {[No value for ``#1'']}%
3090119256Skan    \message{Variable `#1', used in @value, is not set.}%
309196263Sobrien  \else
309296263Sobrien    \csname SET#1\endcsname
309396263Sobrien  \fi
309496263Sobrien}
309596263Sobrien
309696263Sobrien% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
309796263Sobrien% with @set.
309896263Sobrien%
3099132718Skan% To get special treatment of `@end ifset,' call \makeond and the redefine.
3100132718Skan%
3101132718Skan\makecond{ifset}
3102132718Skan\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
3103132718Skan\def\doifset#1#2{%
3104132718Skan  {%
3105132718Skan    \makevalueexpandable
3106132718Skan    \let\next=\empty
3107132718Skan    \expandafter\ifx\csname SET#2\endcsname\relax
3108132718Skan      #1% If not set, redefine \next.
3109132718Skan    \fi
3110132718Skan    \expandafter
3111132718Skan  }\next
311296263Sobrien}
3113132718Skan\def\ifsetfail{\doignore{ifset}}
311496263Sobrien
311596263Sobrien% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
311696263Sobrien% defined with @set, or has been undefined with @clear.
311796263Sobrien%
3118132718Skan% The `\else' inside the `\doifset' parameter is a trick to reuse the
3119132718Skan% above code: if the variable is not set, do nothing, if it is set,
3120132718Skan% then redefine \next to \ifclearfail.
312196263Sobrien%
3122132718Skan\makecond{ifclear}
3123132718Skan\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
3124132718Skan\def\ifclearfail{\doignore{ifclear}}
312596263Sobrien
3126132718Skan% @dircategory CATEGORY  -- specify a category of the dir file
3127132718Skan% which this file should belong to.  Ignore this in TeX.
3128132718Skan\let\dircategory=\comment
312996263Sobrien
313096263Sobrien% @defininfoenclose.
313196263Sobrien\let\definfoenclose=\comment
313296263Sobrien
313396263Sobrien
313496263Sobrien\message{indexing,}
313596263Sobrien% Index generation facilities
313696263Sobrien
313796263Sobrien% Define \newwrite to be identical to plain tex's \newwrite
3138169689Skan% except not \outer, so it can be used within macros and \if's.
3139169689Skan\edef\newwrite{\makecsname{ptexnewwrite}}
314096263Sobrien
314196263Sobrien% \newindex {foo} defines an index named foo.
314296263Sobrien% It automatically defines \fooindex such that
314396263Sobrien% \fooindex ...rest of line... puts an entry in the index foo.
314496263Sobrien% It also defines \fooindfile to be the number of the output channel for
314596263Sobrien% the file that accumulates this index.  The file's extension is foo.
314696263Sobrien% The name of an index should be no more than 2 characters long
314796263Sobrien% for the sake of vms.
314896263Sobrien%
314996263Sobrien\def\newindex#1{%
315096263Sobrien  \iflinks
315196263Sobrien    \expandafter\newwrite \csname#1indfile\endcsname
315296263Sobrien    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
315396263Sobrien  \fi
315496263Sobrien  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
315596263Sobrien    \noexpand\doindex{#1}}
315696263Sobrien}
315796263Sobrien
315896263Sobrien% @defindex foo  ==  \newindex{foo}
315996263Sobrien%
316096263Sobrien\def\defindex{\parsearg\newindex}
316196263Sobrien
316296263Sobrien% Define @defcodeindex, like @defindex except put all entries in @code.
316396263Sobrien%
316496263Sobrien\def\defcodeindex{\parsearg\newcodeindex}
316596263Sobrien%
316696263Sobrien\def\newcodeindex#1{%
316796263Sobrien  \iflinks
316896263Sobrien    \expandafter\newwrite \csname#1indfile\endcsname
316996263Sobrien    \openout \csname#1indfile\endcsname \jobname.#1
317096263Sobrien  \fi
317196263Sobrien  \expandafter\xdef\csname#1index\endcsname{%
317296263Sobrien    \noexpand\docodeindex{#1}}%
317396263Sobrien}
317496263Sobrien
317596263Sobrien
317696263Sobrien% @synindex foo bar    makes index foo feed into index bar.
317796263Sobrien% Do this instead of @defindex foo if you don't want it as a separate index.
3178119256Skan%
317996263Sobrien% @syncodeindex foo bar   similar, but put all entries made for index foo
318096263Sobrien% inside @code.
3181119256Skan%
318296263Sobrien\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
318396263Sobrien\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
318496263Sobrien
318596263Sobrien% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
318696263Sobrien% #3 the target index (bar).
318796263Sobrien\def\dosynindex#1#2#3{%
318896263Sobrien  % Only do \closeout if we haven't already done it, else we'll end up
318996263Sobrien  % closing the target index.
319096263Sobrien  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
319196263Sobrien    % The \closeout helps reduce unnecessary open files; the limit on the
319296263Sobrien    % Acorn RISC OS is a mere 16 files.
319396263Sobrien    \expandafter\closeout\csname#2indfile\endcsname
319496263Sobrien    \expandafter\let\csname\donesynindex#2\endcsname = 1
319596263Sobrien  \fi
319696263Sobrien  % redefine \fooindfile:
319796263Sobrien  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
319896263Sobrien  \expandafter\let\csname#2indfile\endcsname=\temp
319996263Sobrien  % redefine \fooindex:
320096263Sobrien  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
320196263Sobrien}
320296263Sobrien
320396263Sobrien% Define \doindex, the driver for all \fooindex macros.
320496263Sobrien% Argument #1 is generated by the calling \fooindex macro,
320596263Sobrien%  and it is "foo", the name of the index.
320696263Sobrien
320796263Sobrien% \doindex just uses \parsearg; it calls \doind for the actual work.
320896263Sobrien% This is because \doind is more useful to call from other macros.
320996263Sobrien
321096263Sobrien% There is also \dosubind {index}{topic}{subtopic}
321196263Sobrien% which makes an entry in a two-level index such as the operation index.
321296263Sobrien
321396263Sobrien\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
321496263Sobrien\def\singleindexer #1{\doind{\indexname}{#1}}
321596263Sobrien
321696263Sobrien% like the previous two, but they put @code around the argument.
321796263Sobrien\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
321896263Sobrien\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
321996263Sobrien
3220119256Skan% Take care of Texinfo commands that can appear in an index entry.
3221119256Skan% Since there are some commands we want to expand, and others we don't,
3222119256Skan% we have to laboriously prevent expansion for those that we don't.
3223119256Skan%
322496263Sobrien\def\indexdummies{%
3225119256Skan  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
3226119256Skan  \def\ {\realbackslash\space }%
3227119256Skan  % Need these in case \tex is in effect and \{ is a \delimiter again.
3228119256Skan  % But can't use \lbracecmd and \rbracecmd because texindex assumes
3229119256Skan  % braces and backslashes are used only as delimiters.
3230119256Skan  \let\{ = \mylbrace
3231119256Skan  \let\} = \myrbrace
3232119256Skan  %
3233119256Skan  % \definedummyword defines \#1 as \realbackslash #1\space, thus
3234119256Skan  % effectively preventing its expansion.  This is used only for control
3235119256Skan  % words, not control letters, because the \space would be incorrect
3236119256Skan  % for control characters, but is needed to separate the control word
3237119256Skan  % from whatever follows.
3238119256Skan  %
3239119256Skan  % For control letters, we have \definedummyletter, which omits the
3240119256Skan  % space.
3241119256Skan  %
3242119256Skan  % These can be used both for control words that take an argument and
3243119256Skan  % those that do not.  If it is followed by {arg} in the input, then
3244119256Skan  % that will dutifully get written to the index (or wherever).
3245119256Skan  %
3246119256Skan  \def\definedummyword##1{%
3247119256Skan    \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
3248119256Skan  }%
3249119256Skan  \def\definedummyletter##1{%
3250119256Skan    \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
3251119256Skan  }%
3252169689Skan  \let\definedummyaccent\definedummyletter
3253119256Skan  %
3254119256Skan  % Do the redefinitions.
3255119256Skan  \commondummies
3256119256Skan}
3257119256Skan
3258169689Skan% For the aux and toc files, @ is the escape character.  So we want to
3259169689Skan% redefine everything using @ as the escape character (instead of
3260169689Skan% \realbackslash, still used for index files).  When everything uses @,
3261169689Skan% this will be simpler.
326296263Sobrien%
3263119256Skan\def\atdummies{%
3264119256Skan  \def\@{@@}%
3265119256Skan  \def\ {@ }%
3266119256Skan  \let\{ = \lbraceatcmd
3267119256Skan  \let\} = \rbraceatcmd
3268119256Skan  %
3269119256Skan  % (See comments in \indexdummies.)
3270119256Skan  \def\definedummyword##1{%
3271119256Skan    \expandafter\def\csname ##1\endcsname{@##1\space}%
3272119256Skan  }%
3273119256Skan  \def\definedummyletter##1{%
3274119256Skan    \expandafter\def\csname ##1\endcsname{@##1}%
3275119256Skan  }%
3276169689Skan  \let\definedummyaccent\definedummyletter
3277119256Skan  %
3278119256Skan  % Do the redefinitions.
3279119256Skan  \commondummies
3280119256Skan}
3281119256Skan
3282119256Skan% Called from \indexdummies and \atdummies.  \definedummyword and
3283119256Skan% \definedummyletter must be defined first.
328496263Sobrien%
3285119256Skan\def\commondummies{%
3286119256Skan  %
3287119256Skan  \normalturnoffactive
3288119256Skan  %
3289169689Skan  \commondummiesnofonts
3290169689Skan  %
3291119256Skan  \definedummyletter{_}%
3292119256Skan  %
3293169689Skan  % Non-English letters.
3294119256Skan  \definedummyword{AA}%
3295119256Skan  \definedummyword{AE}%
3296119256Skan  \definedummyword{L}%
3297119256Skan  \definedummyword{OE}%
3298119256Skan  \definedummyword{O}%
3299119256Skan  \definedummyword{aa}%
3300119256Skan  \definedummyword{ae}%
3301119256Skan  \definedummyword{l}%
3302119256Skan  \definedummyword{oe}%
3303119256Skan  \definedummyword{o}%
3304119256Skan  \definedummyword{ss}%
3305132718Skan  \definedummyword{exclamdown}%
3306132718Skan  \definedummyword{questiondown}%
3307169689Skan  \definedummyword{ordf}%
3308132718Skan  \definedummyword{ordm}%
3309119256Skan  %
3310119256Skan  % Although these internal commands shouldn't show up, sometimes they do.
3311119256Skan  \definedummyword{bf}%
3312119256Skan  \definedummyword{gtr}%
3313119256Skan  \definedummyword{hat}%
3314119256Skan  \definedummyword{less}%
3315119256Skan  \definedummyword{sf}%
3316119256Skan  \definedummyword{sl}%
3317119256Skan  \definedummyword{tclose}%
3318119256Skan  \definedummyword{tt}%
3319119256Skan  %
3320132718Skan  \definedummyword{LaTeX}%
3321119256Skan  \definedummyword{TeX}%
3322119256Skan  %
3323119256Skan  % Assorted special characters.
3324119256Skan  \definedummyword{bullet}%
3325169689Skan  \definedummyword{comma}%
3326119256Skan  \definedummyword{copyright}%
3327132718Skan  \definedummyword{registeredsymbol}%
3328119256Skan  \definedummyword{dots}%
3329119256Skan  \definedummyword{enddots}%
3330119256Skan  \definedummyword{equiv}%
3331119256Skan  \definedummyword{error}%
3332169689Skan  \definedummyword{euro}%
3333119256Skan  \definedummyword{expansion}%
3334119256Skan  \definedummyword{minus}%
3335119256Skan  \definedummyword{pounds}%
3336119256Skan  \definedummyword{point}%
3337119256Skan  \definedummyword{print}%
3338119256Skan  \definedummyword{result}%
3339119256Skan  %
3340132718Skan  % Handle some cases of @value -- where it does not contain any
3341119256Skan  % (non-fully-expandable) commands.
3342132718Skan  \makevalueexpandable
3343119256Skan  %
3344119256Skan  % Normal spaces, not active ones.
3345119256Skan  \unsepspaces
3346119256Skan  %
3347119256Skan  % No macro expansion.
3348119256Skan  \turnoffmacros
334996263Sobrien}
335096263Sobrien
3351169689Skan% \commondummiesnofonts: common to \commondummies and \indexnofonts.
3352169689Skan%
3353169689Skan% Better have this without active chars.
3354169689Skan{
3355169689Skan  \catcode`\~=\other
3356169689Skan  \gdef\commondummiesnofonts{%
3357169689Skan    % Control letters and accents.
3358169689Skan    \definedummyletter{!}%
3359169689Skan    \definedummyaccent{"}%
3360169689Skan    \definedummyaccent{'}%
3361169689Skan    \definedummyletter{*}%
3362169689Skan    \definedummyaccent{,}%
3363169689Skan    \definedummyletter{.}%
3364169689Skan    \definedummyletter{/}%
3365169689Skan    \definedummyletter{:}%
3366169689Skan    \definedummyaccent{=}%
3367169689Skan    \definedummyletter{?}%
3368169689Skan    \definedummyaccent{^}%
3369169689Skan    \definedummyaccent{`}%
3370169689Skan    \definedummyaccent{~}%
3371169689Skan    \definedummyword{u}%
3372169689Skan    \definedummyword{v}%
3373169689Skan    \definedummyword{H}%
3374169689Skan    \definedummyword{dotaccent}%
3375169689Skan    \definedummyword{ringaccent}%
3376169689Skan    \definedummyword{tieaccent}%
3377169689Skan    \definedummyword{ubaraccent}%
3378169689Skan    \definedummyword{udotaccent}%
3379169689Skan    \definedummyword{dotless}%
3380169689Skan    %
3381169689Skan    % Texinfo font commands.
3382169689Skan    \definedummyword{b}%
3383169689Skan    \definedummyword{i}%
3384169689Skan    \definedummyword{r}%
3385169689Skan    \definedummyword{sc}%
3386169689Skan    \definedummyword{t}%
3387169689Skan    %
3388169689Skan    % Commands that take arguments.
3389169689Skan    \definedummyword{acronym}%
3390169689Skan    \definedummyword{cite}%
3391169689Skan    \definedummyword{code}%
3392169689Skan    \definedummyword{command}%
3393169689Skan    \definedummyword{dfn}%
3394169689Skan    \definedummyword{emph}%
3395169689Skan    \definedummyword{env}%
3396169689Skan    \definedummyword{file}%
3397169689Skan    \definedummyword{kbd}%
3398169689Skan    \definedummyword{key}%
3399169689Skan    \definedummyword{math}%
3400169689Skan    \definedummyword{option}%
3401169689Skan    \definedummyword{samp}%
3402169689Skan    \definedummyword{strong}%
3403169689Skan    \definedummyword{tie}%
3404169689Skan    \definedummyword{uref}%
3405169689Skan    \definedummyword{url}%
3406169689Skan    \definedummyword{var}%
3407169689Skan    \definedummyword{verb}%
3408169689Skan    \definedummyword{w}%
3409169689Skan  }
3410169689Skan}
341196263Sobrien
3412119256Skan% \indexnofonts is used when outputting the strings to sort the index
3413119256Skan% by, and when constructing control sequence names.  It eliminates all
3414119256Skan% control sequences and just writes whatever the best ASCII sort string
3415119256Skan% would be for a given command (usually its argument).
3416119256Skan%
341796263Sobrien\def\indexnofonts{%
3418169689Skan  % Accent commands should become @asis.
3419169689Skan  \def\definedummyaccent##1{%
3420169689Skan    \expandafter\let\csname ##1\endcsname\asis
3421169689Skan  }%
3422169689Skan  % We can just ignore other control letters.
3423169689Skan  \def\definedummyletter##1{%
3424169689Skan    \expandafter\def\csname ##1\endcsname{}%
3425169689Skan  }%
3426169689Skan  % Hopefully, all control words can become @asis.
3427169689Skan  \let\definedummyword\definedummyaccent
3428169689Skan  %
3429169689Skan  \commondummiesnofonts
3430169689Skan  %
3431169689Skan  % Don't no-op \tt, since it isn't a user-level command
3432169689Skan  % and is used in the definitions of the active chars like <, >, |, etc.
3433169689Skan  % Likewise with the other plain tex font commands.
3434169689Skan  %\let\tt=\asis
3435169689Skan  %
3436119256Skan  \def\ { }%
3437119256Skan  \def\@{@}%
3438119256Skan  % how to handle braces?
3439119256Skan  \def\_{\normalunderscore}%
3440119256Skan  %
3441169689Skan  % Non-English letters.
3442119256Skan  \def\AA{AA}%
3443119256Skan  \def\AE{AE}%
3444119256Skan  \def\L{L}%
3445119256Skan  \def\OE{OE}%
3446119256Skan  \def\O{O}%
3447119256Skan  \def\aa{aa}%
3448119256Skan  \def\ae{ae}%
3449119256Skan  \def\l{l}%
3450119256Skan  \def\oe{oe}%
3451119256Skan  \def\o{o}%
3452119256Skan  \def\ss{ss}%
3453119256Skan  \def\exclamdown{!}%
3454119256Skan  \def\questiondown{?}%
3455132718Skan  \def\ordf{a}%
3456132718Skan  \def\ordm{o}%
3457119256Skan  %
3458169689Skan  \def\LaTeX{LaTeX}%
3459169689Skan  \def\TeX{TeX}%
3460119256Skan  %
3461169689Skan  % Assorted special characters.
3462169689Skan  % (The following {} will end up in the sort string, but that's ok.)
3463169689Skan  \def\bullet{bullet}%
3464169689Skan  \def\comma{,}%
3465169689Skan  \def\copyright{copyright}%
3466169689Skan  \def\registeredsymbol{R}%
3467169689Skan  \def\dots{...}%
3468169689Skan  \def\enddots{...}%
3469169689Skan  \def\equiv{==}%
3470169689Skan  \def\error{error}%
3471169689Skan  \def\euro{euro}%
3472169689Skan  \def\expansion{==>}%
3473169689Skan  \def\minus{-}%
3474169689Skan  \def\pounds{pounds}%
3475169689Skan  \def\point{.}%
3476169689Skan  \def\print{-|}%
3477169689Skan  \def\result{=>}%
3478119256Skan  %
3479169689Skan  % Don't write macro names.
3480169689Skan  \emptyusermacros
348196263Sobrien}
348296263Sobrien
348396263Sobrien\let\indexbackslash=0  %overridden during \printindex.
348496263Sobrien\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
348596263Sobrien
348696263Sobrien% Most index entries go through here, but \dosubind is the general case.
3487132718Skan% #1 is the index name, #2 is the entry text.
3488132718Skan\def\doind#1#2{\dosubind{#1}{#2}{}}
348996263Sobrien
349096263Sobrien% Workhorse for all \fooindexes.
349196263Sobrien% #1 is name of index, #2 is stuff to put there, #3 is subentry --
3492132718Skan% empty if called from \doind, as we usually are (the main exception
3493132718Skan% is with most defuns, which call us directly).
349496263Sobrien%
349596263Sobrien\def\dosubind#1#2#3{%
3496132718Skan  \iflinks
3497132718Skan  {%
3498132718Skan    % Store the main index entry text (including the third arg).
3499132718Skan    \toks0 = {#2}%
3500132718Skan    % If third arg is present, precede it with a space.
3501132718Skan    \def\thirdarg{#3}%
3502132718Skan    \ifx\thirdarg\empty \else
3503132718Skan      \toks0 = \expandafter{\the\toks0 \space #3}%
3504132718Skan    \fi
3505132718Skan    %
3506132718Skan    \edef\writeto{\csname#1indfile\endcsname}%
3507132718Skan    %
3508132718Skan    \ifvmode
3509132718Skan      \dosubindsanitize
3510132718Skan    \else
3511132718Skan      \dosubindwrite
3512132718Skan    \fi
3513132718Skan  }%
3514132718Skan  \fi
3515132718Skan}
3516132718Skan
3517132718Skan% Write the entry in \toks0 to the index file:
3518132718Skan%
3519132718Skan\def\dosubindwrite{%
352096263Sobrien  % Put the index entry in the margin if desired.
352196263Sobrien  \ifx\SETmarginindex\relax\else
3522132718Skan    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
352396263Sobrien  \fi
3524132718Skan  %
3525132718Skan  % Remember, we are within a group.
3526132718Skan  \indexdummies % Must do this here, since \bf, etc expand at this stage
3527132718Skan  \escapechar=`\\
3528169689Skan  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
3529132718Skan      % so it will be output as is; and it will print as backslash.
3530132718Skan  %
3531132718Skan  % Process the index entry with all font commands turned off, to
3532132718Skan  % get the string to sort by.
3533132718Skan  {\indexnofonts
3534132718Skan   \edef\temp{\the\toks0}% need full expansion
3535132718Skan   \xdef\indexsorttmp{\temp}%
353696263Sobrien  }%
3537132718Skan  %
3538132718Skan  % Set up the complete index entry, with both the sort key and
3539132718Skan  % the original text, including any font commands.  We write
3540132718Skan  % three arguments to \entry to the .?? file (four in the
3541132718Skan  % subentry case), texindex reduces to two when writing the .??s
3542132718Skan  % sorted result.
3543132718Skan  \edef\temp{%
3544132718Skan    \write\writeto{%
3545132718Skan      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
3546132718Skan  }%
3547132718Skan  \temp
354896263Sobrien}
354996263Sobrien
3550132718Skan% Take care of unwanted page breaks:
3551132718Skan%
3552132718Skan% If a skip is the last thing on the list now, preserve it
3553132718Skan% by backing up by \lastskip, doing the \write, then inserting
3554132718Skan% the skip again.  Otherwise, the whatsit generated by the
3555132718Skan% \write will make \lastskip zero.  The result is that sequences
3556132718Skan% like this:
3557132718Skan% @end defun
3558132718Skan% @tindex whatever
3559132718Skan% @defun ...
3560132718Skan% will have extra space inserted, because the \medbreak in the
3561132718Skan% start of the @defun won't see the skip inserted by the @end of
3562132718Skan% the previous defun.
3563132718Skan%
3564132718Skan% But don't do any of this if we're not in vertical mode.  We
3565132718Skan% don't want to do a \vskip and prematurely end a paragraph.
3566132718Skan%
3567132718Skan% Avoid page breaks due to these extra skips, too.
3568132718Skan%
3569132718Skan% But wait, there is a catch there:
3570132718Skan% We'll have to check whether \lastskip is zero skip.  \ifdim is not
3571132718Skan% sufficient for this purpose, as it ignores stretch and shrink parts
3572132718Skan% of the skip.  The only way seems to be to check the textual
3573132718Skan% representation of the skip.
3574132718Skan%
3575132718Skan% The following is almost like \def\zeroskipmacro{0.0pt} except that
3576132718Skan% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
3577132718Skan%
3578132718Skan\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
3579132718Skan%
3580132718Skan% ..., ready, GO:
3581132718Skan%
3582132718Skan\def\dosubindsanitize{%
3583132718Skan  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
3584132718Skan  \skip0 = \lastskip
3585132718Skan  \edef\lastskipmacro{\the\lastskip}%
3586132718Skan  \count255 = \lastpenalty
3587132718Skan  %
3588132718Skan  % If \lastskip is nonzero, that means the last item was a
3589132718Skan  % skip.  And since a skip is discardable, that means this
3590132718Skan  % -\skip0 glue we're inserting is preceded by a
3591132718Skan  % non-discardable item, therefore it is not a potential
3592132718Skan  % breakpoint, therefore no \nobreak needed.
3593132718Skan  \ifx\lastskipmacro\zeroskipmacro
3594132718Skan  \else
3595132718Skan    \vskip-\skip0
3596132718Skan  \fi
3597132718Skan  %
3598132718Skan  \dosubindwrite
3599132718Skan  %
3600132718Skan  \ifx\lastskipmacro\zeroskipmacro
3601169689Skan    % If \lastskip was zero, perhaps the last item was a penalty, and
3602169689Skan    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
3603169689Skan    % to re-insert the same penalty (values >10000 are used for various
3604169689Skan    % signals); since we just inserted a non-discardable item, any
3605169689Skan    % following glue (such as a \parskip) would be a breakpoint.  For example:
3606169689Skan    % 
3607132718Skan    %   @deffn deffn-whatever
3608132718Skan    %   @vindex index-whatever
3609132718Skan    %   Description.
3610132718Skan    % would allow a break between the index-whatever whatsit
3611132718Skan    % and the "Description." paragraph.
3612169689Skan    \ifnum\count255>9999 \penalty\count255 \fi
3613132718Skan  \else
3614132718Skan    % On the other hand, if we had a nonzero \lastskip,
3615132718Skan    % this make-up glue would be preceded by a non-discardable item
3616132718Skan    % (the whatsit from the \write), so we must insert a \nobreak.
3617132718Skan    \nobreak\vskip\skip0
3618132718Skan  \fi
3619132718Skan}
3620132718Skan
362196263Sobrien% The index entry written in the file actually looks like
362296263Sobrien%  \entry {sortstring}{page}{topic}
362396263Sobrien% or
362496263Sobrien%  \entry {sortstring}{page}{topic}{subtopic}
362596263Sobrien% The texindex program reads in these files and writes files
362696263Sobrien% containing these kinds of lines:
362796263Sobrien%  \initial {c}
362896263Sobrien%     before the first topic whose initial is c
362996263Sobrien%  \entry {topic}{pagelist}
363096263Sobrien%     for a topic that is used without subtopics
363196263Sobrien%  \primary {topic}
363296263Sobrien%     for the beginning of a topic that is used with subtopics
363396263Sobrien%  \secondary {subtopic}{pagelist}
363496263Sobrien%     for each subtopic.
363596263Sobrien
363696263Sobrien% Define the user-accessible indexing commands
363796263Sobrien% @findex, @vindex, @kindex, @cindex.
363896263Sobrien
363996263Sobrien\def\findex {\fnindex}
364096263Sobrien\def\kindex {\kyindex}
364196263Sobrien\def\cindex {\cpindex}
364296263Sobrien\def\vindex {\vrindex}
364396263Sobrien\def\tindex {\tpindex}
364496263Sobrien\def\pindex {\pgindex}
364596263Sobrien
364696263Sobrien\def\cindexsub {\begingroup\obeylines\cindexsub}
364796263Sobrien{\obeylines %
364896263Sobrien\gdef\cindexsub "#1" #2^^M{\endgroup %
364996263Sobrien\dosubind{cp}{#2}{#1}}}
365096263Sobrien
365196263Sobrien% Define the macros used in formatting output of the sorted index material.
365296263Sobrien
365396263Sobrien% @printindex causes a particular index (the ??s file) to get printed.
365496263Sobrien% It does not print any chapter heading (usually an @unnumbered).
365596263Sobrien%
3656132718Skan\parseargdef\printindex{\begingroup
365796263Sobrien  \dobreak \chapheadingskip{10000}%
365896263Sobrien  %
365996263Sobrien  \smallfonts \rm
366096263Sobrien  \tolerance = 9500
3661119256Skan  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
366296263Sobrien  %
366396263Sobrien  % See if the index file exists and is nonempty.
366496263Sobrien  % Change catcode of @ here so that if the index file contains
366596263Sobrien  % \initial {@}
366696263Sobrien  % as its first line, TeX doesn't complain about mismatched braces
366796263Sobrien  % (because it thinks @} is a control sequence).
366896263Sobrien  \catcode`\@ = 11
366996263Sobrien  \openin 1 \jobname.#1s
367096263Sobrien  \ifeof 1
367196263Sobrien    % \enddoublecolumns gets confused if there is no text in the index,
367296263Sobrien    % and it loses the chapter title and the aux file entries for the
367396263Sobrien    % index.  The easiest way to prevent this problem is to make sure
367496263Sobrien    % there is some text.
367596263Sobrien    \putwordIndexNonexistent
367696263Sobrien  \else
367796263Sobrien    %
367896263Sobrien    % If the index file exists but is empty, then \openin leaves \ifeof
367996263Sobrien    % false.  We have to make TeX try to read something from the file, so
368096263Sobrien    % it can discover if there is anything in it.
368196263Sobrien    \read 1 to \temp
368296263Sobrien    \ifeof 1
368396263Sobrien      \putwordIndexIsEmpty
368496263Sobrien    \else
368596263Sobrien      % Index files are almost Texinfo source, but we use \ as the escape
368696263Sobrien      % character.  It would be better to use @, but that's too big a change
368796263Sobrien      % to make right now.
3688169689Skan      \def\indexbackslash{\backslashcurfont}%
368996263Sobrien      \catcode`\\ = 0
369096263Sobrien      \escapechar = `\\
369196263Sobrien      \begindoublecolumns
369296263Sobrien      \input \jobname.#1s
369396263Sobrien      \enddoublecolumns
369496263Sobrien    \fi
369596263Sobrien  \fi
369696263Sobrien  \closein 1
369796263Sobrien\endgroup}
369896263Sobrien
369996263Sobrien% These macros are used by the sorted index file itself.
370096263Sobrien% Change them to control the appearance of the index.
370196263Sobrien
370296263Sobrien\def\initial#1{{%
370396263Sobrien  % Some minor font changes for the special characters.
370496263Sobrien  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
370596263Sobrien  %
370696263Sobrien  % Remove any glue we may have, we'll be inserting our own.
370796263Sobrien  \removelastskip
370896263Sobrien  %
370996263Sobrien  % We like breaks before the index initials, so insert a bonus.
3710169689Skan  \nobreak
3711169689Skan  \vskip 0pt plus 3\baselineskip
3712169689Skan  \penalty 0
3713169689Skan  \vskip 0pt plus -3\baselineskip
371496263Sobrien  %
371596263Sobrien  % Typeset the initial.  Making this add up to a whole number of
371696263Sobrien  % baselineskips increases the chance of the dots lining up from column
371796263Sobrien  % to column.  It still won't often be perfect, because of the stretch
371896263Sobrien  % we need before each entry, but it's better.
371996263Sobrien  %
372096263Sobrien  % No shrink because it confuses \balancecolumns.
372196263Sobrien  \vskip 1.67\baselineskip plus .5\baselineskip
372296263Sobrien  \leftline{\secbf #1}%
372396263Sobrien  % Do our best not to break after the initial.
372496263Sobrien  \nobreak
3725169689Skan  \vskip .33\baselineskip plus .1\baselineskip
372696263Sobrien}}
372796263Sobrien
3728132718Skan% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
3729132718Skan% then page number (#2) flushed to the right margin.  It is used for index
3730132718Skan% and table of contents entries.  The paragraph is indented by \leftskip.
373196263Sobrien%
3732169689Skan% A straightforward implementation would start like this:
3733132718Skan%	\def\entry#1#2{...
3734132718Skan% But this frozes the catcodes in the argument, and can cause problems to
3735169689Skan% @code, which sets - active.  This problem was fixed by a kludge---
3736169689Skan% ``-'' was active throughout whole index, but this isn't really right.
3737169689Skan%
3738132718Skan% The right solution is to prevent \entry from swallowing the whole text.
3739132718Skan%                                 --kasal, 21nov03
3740132718Skan\def\entry{%
3741132718Skan  \begingroup
374296263Sobrien    %
3743132718Skan    % Start a new paragraph if necessary, so our assignments below can't
3744132718Skan    % affect previous text.
3745132718Skan    \par
374696263Sobrien    %
3747132718Skan    % Do not fill out the last line with white space.
3748132718Skan    \parfillskip = 0in
3749132718Skan    %
3750132718Skan    % No extra space above this paragraph.
3751132718Skan    \parskip = 0in
3752132718Skan    %
3753132718Skan    % Do not prefer a separate line ending with a hyphen to fewer lines.
3754132718Skan    \finalhyphendemerits = 0
3755132718Skan    %
3756132718Skan    % \hangindent is only relevant when the entry text and page number
3757132718Skan    % don't both fit on one line.  In that case, bob suggests starting the
3758132718Skan    % dots pretty far over on the line.  Unfortunately, a large
3759132718Skan    % indentation looks wrong when the entry text itself is broken across
3760132718Skan    % lines.  So we use a small indentation and put up with long leaders.
3761132718Skan    %
3762132718Skan    % \hangafter is reset to 1 (which is the value we want) at the start
3763132718Skan    % of each paragraph, so we need not do anything with that.
3764132718Skan    \hangindent = 2em
3765132718Skan    %
3766132718Skan    % When the entry text needs to be broken, just fill out the first line
3767132718Skan    % with blank space.
3768132718Skan    \rightskip = 0pt plus1fil
3769132718Skan    %
3770132718Skan    % A bit of stretch before each entry for the benefit of balancing
3771132718Skan    % columns.
3772132718Skan    \vskip 0pt plus1pt
3773132718Skan    %
3774132718Skan    % Swallow the left brace of the text (first parameter):
3775132718Skan    \afterassignment\doentry
3776132718Skan    \let\temp =
3777132718Skan}
3778132718Skan\def\doentry{%
3779132718Skan    \bgroup % Instead of the swallowed brace.
3780132718Skan      \noindent
3781132718Skan      \aftergroup\finishentry
3782132718Skan      % And now comes the text of the entry.
3783132718Skan}
3784132718Skan\def\finishentry#1{%
3785132718Skan    % #1 is the page number.
3786132718Skan    %
3787132718Skan    % The following is kludged to not output a line of dots in the index if
3788132718Skan    % there are no page numbers.  The next person who breaks this will be
3789132718Skan    % cursed by a Unix daemon.
3790132718Skan    \def\tempa{{\rm }}%
3791132718Skan    \def\tempb{#1}%
3792132718Skan    \edef\tempc{\tempa}%
3793132718Skan    \edef\tempd{\tempb}%
3794132718Skan    \ifx\tempc\tempd
3795132718Skan      \ %
379696263Sobrien    \else
3797132718Skan      %
3798132718Skan      % If we must, put the page number on a line of its own, and fill out
3799132718Skan      % this line with blank space.  (The \hfil is overwhelmed with the
3800132718Skan      % fill leaders glue in \indexdotfill if the page number does fit.)
3801132718Skan      \hfil\penalty50
3802132718Skan      \null\nobreak\indexdotfill % Have leaders before the page number.
3803132718Skan      %
3804132718Skan      % The `\ ' here is removed by the implicit \unskip that TeX does as
3805132718Skan      % part of (the primitive) \par.  Without it, a spurious underfull
3806132718Skan      % \hbox ensues.
3807132718Skan      \ifpdf
3808169689Skan	\pdfgettoks#1.%
3809169689Skan	\ \the\toksA
3810132718Skan      \else
3811132718Skan	\ #1%
3812132718Skan      \fi
381396263Sobrien    \fi
3814132718Skan    \par
3815132718Skan  \endgroup
3816132718Skan}
381796263Sobrien
381896263Sobrien% Like \dotfill except takes at least 1 em.
381996263Sobrien\def\indexdotfill{\cleaders
382096263Sobrien  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
382196263Sobrien
382296263Sobrien\def\primary #1{\line{#1\hfil}}
382396263Sobrien
382496263Sobrien\newskip\secondaryindent \secondaryindent=0.5cm
382596263Sobrien\def\secondary#1#2{{%
382696263Sobrien  \parfillskip=0in
382796263Sobrien  \parskip=0in
382896263Sobrien  \hangindent=1in
382996263Sobrien  \hangafter=1
383096263Sobrien  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
383196263Sobrien  \ifpdf
383296263Sobrien    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
383396263Sobrien  \else
383496263Sobrien    #2
383596263Sobrien  \fi
383696263Sobrien  \par
383796263Sobrien}}
383896263Sobrien
383996263Sobrien% Define two-column mode, which we use to typeset indexes.
384096263Sobrien% Adapted from the TeXbook, page 416, which is to say,
384196263Sobrien% the manmac.tex format used to print the TeXbook itself.
384296263Sobrien\catcode`\@=11
384396263Sobrien
384496263Sobrien\newbox\partialpage
384596263Sobrien\newdimen\doublecolumnhsize
384696263Sobrien
384796263Sobrien\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
384896263Sobrien  % Grab any single-column material above us.
384996263Sobrien  \output = {%
385096263Sobrien    %
385196263Sobrien    % Here is a possibility not foreseen in manmac: if we accumulate a
385296263Sobrien    % whole lot of material, we might end up calling this \output
385396263Sobrien    % routine twice in a row (see the doublecol-lose test, which is
385496263Sobrien    % essentially a couple of indexes with @setchapternewpage off).  In
385596263Sobrien    % that case we just ship out what is in \partialpage with the normal
385696263Sobrien    % output routine.  Generally, \partialpage will be empty when this
385796263Sobrien    % runs and this will be a no-op.  See the indexspread.tex test case.
385896263Sobrien    \ifvoid\partialpage \else
385996263Sobrien      \onepageout{\pagecontents\partialpage}%
386096263Sobrien    \fi
386196263Sobrien    %
386296263Sobrien    \global\setbox\partialpage = \vbox{%
386396263Sobrien      % Unvbox the main output page.
386496263Sobrien      \unvbox\PAGE
386596263Sobrien      \kern-\topskip \kern\baselineskip
386696263Sobrien    }%
386796263Sobrien  }%
386896263Sobrien  \eject % run that output routine to set \partialpage
386996263Sobrien  %
387096263Sobrien  % Use the double-column output routine for subsequent pages.
387196263Sobrien  \output = {\doublecolumnout}%
387296263Sobrien  %
387396263Sobrien  % Change the page size parameters.  We could do this once outside this
387496263Sobrien  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
387596263Sobrien  % format, but then we repeat the same computation.  Repeating a couple
387696263Sobrien  % of assignments once per index is clearly meaningless for the
387796263Sobrien  % execution time, so we may as well do it in one place.
387896263Sobrien  %
387996263Sobrien  % First we halve the line length, less a little for the gutter between
388096263Sobrien  % the columns.  We compute the gutter based on the line length, so it
388196263Sobrien  % changes automatically with the paper format.  The magic constant
388296263Sobrien  % below is chosen so that the gutter has the same value (well, +-<1pt)
388396263Sobrien  % as it did when we hard-coded it.
388496263Sobrien  %
388596263Sobrien  % We put the result in a separate register, \doublecolumhsize, so we
388696263Sobrien  % can restore it in \pagesofar, after \hsize itself has (potentially)
388796263Sobrien  % been clobbered.
388896263Sobrien  %
388996263Sobrien  \doublecolumnhsize = \hsize
389096263Sobrien    \advance\doublecolumnhsize by -.04154\hsize
389196263Sobrien    \divide\doublecolumnhsize by 2
389296263Sobrien  \hsize = \doublecolumnhsize
389396263Sobrien  %
389496263Sobrien  % Double the \vsize as well.  (We don't need a separate register here,
389596263Sobrien  % since nobody clobbers \vsize.)
389696263Sobrien  \vsize = 2\vsize
389796263Sobrien}
389896263Sobrien
389996263Sobrien% The double-column output routine for all double-column pages except
390096263Sobrien% the last.
390196263Sobrien%
390296263Sobrien\def\doublecolumnout{%
390396263Sobrien  \splittopskip=\topskip \splitmaxdepth=\maxdepth
390496263Sobrien  % Get the available space for the double columns -- the normal
390596263Sobrien  % (undoubled) page height minus any material left over from the
390696263Sobrien  % previous page.
390796263Sobrien  \dimen@ = \vsize
390896263Sobrien  \divide\dimen@ by 2
390996263Sobrien  \advance\dimen@ by -\ht\partialpage
391096263Sobrien  %
391196263Sobrien  % box0 will be the left-hand column, box2 the right.
391296263Sobrien  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
391396263Sobrien  \onepageout\pagesofar
391496263Sobrien  \unvbox255
391596263Sobrien  \penalty\outputpenalty
391696263Sobrien}
391796263Sobrien%
391896263Sobrien% Re-output the contents of the output page -- any previous material,
391996263Sobrien% followed by the two boxes we just split, in box0 and box2.
392096263Sobrien\def\pagesofar{%
392196263Sobrien  \unvbox\partialpage
392296263Sobrien  %
392396263Sobrien  \hsize = \doublecolumnhsize
392496263Sobrien  \wd0=\hsize \wd2=\hsize
392596263Sobrien  \hbox to\pagewidth{\box0\hfil\box2}%
392696263Sobrien}
3927119256Skan%
392896263Sobrien% All done with double columns.
392996263Sobrien\def\enddoublecolumns{%
393096263Sobrien  \output = {%
393196263Sobrien    % Split the last of the double-column material.  Leave it on the
393296263Sobrien    % current page, no automatic page break.
393396263Sobrien    \balancecolumns
393496263Sobrien    %
393596263Sobrien    % If we end up splitting too much material for the current page,
393696263Sobrien    % though, there will be another page break right after this \output
393796263Sobrien    % invocation ends.  Having called \balancecolumns once, we do not
393896263Sobrien    % want to call it again.  Therefore, reset \output to its normal
393996263Sobrien    % definition right away.  (We hope \balancecolumns will never be
394096263Sobrien    % called on to balance too much material, but if it is, this makes
394196263Sobrien    % the output somewhat more palatable.)
394296263Sobrien    \global\output = {\onepageout{\pagecontents\PAGE}}%
394396263Sobrien  }%
394496263Sobrien  \eject
394596263Sobrien  \endgroup % started in \begindoublecolumns
394696263Sobrien  %
394796263Sobrien  % \pagegoal was set to the doubled \vsize above, since we restarted
394896263Sobrien  % the current page.  We're now back to normal single-column
394996263Sobrien  % typesetting, so reset \pagegoal to the normal \vsize (after the
395096263Sobrien  % \endgroup where \vsize got restored).
395196263Sobrien  \pagegoal = \vsize
395296263Sobrien}
395396263Sobrien%
395496263Sobrien% Called at the end of the double column material.
395596263Sobrien\def\balancecolumns{%
395696263Sobrien  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
395796263Sobrien  \dimen@ = \ht0
395896263Sobrien  \advance\dimen@ by \topskip
395996263Sobrien  \advance\dimen@ by-\baselineskip
396096263Sobrien  \divide\dimen@ by 2 % target to split to
396196263Sobrien  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
396296263Sobrien  \splittopskip = \topskip
396396263Sobrien  % Loop until we get a decent breakpoint.
396496263Sobrien  {%
396596263Sobrien    \vbadness = 10000
396696263Sobrien    \loop
396796263Sobrien      \global\setbox3 = \copy0
396896263Sobrien      \global\setbox1 = \vsplit3 to \dimen@
396996263Sobrien    \ifdim\ht3>\dimen@
397096263Sobrien      \global\advance\dimen@ by 1pt
397196263Sobrien    \repeat
397296263Sobrien  }%
397396263Sobrien  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
397496263Sobrien  \setbox0=\vbox to\dimen@{\unvbox1}%
397596263Sobrien  \setbox2=\vbox to\dimen@{\unvbox3}%
397696263Sobrien  %
397796263Sobrien  \pagesofar
397896263Sobrien}
397996263Sobrien\catcode`\@ = \other
398096263Sobrien
398196263Sobrien
398296263Sobrien\message{sectioning,}
398396263Sobrien% Chapters, sections, etc.
398496263Sobrien
3985132718Skan% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
3986132718Skan% sections so that we can refer to them unambiguously in the pdf
3987132718Skan% outlines by their "section number".  We avoid collisions with chapter
3988132718Skan% numbers by starting them at 10000.  (If a document ever has 10000
3989132718Skan% chapters, we're in trouble anyway, I'm sure.)
3990132718Skan\newcount\unnumberedno \unnumberedno = 10000
399196263Sobrien\newcount\chapno
399296263Sobrien\newcount\secno        \secno=0
399396263Sobrien\newcount\subsecno     \subsecno=0
399496263Sobrien\newcount\subsubsecno  \subsubsecno=0
399596263Sobrien
399696263Sobrien% This counter is funny since it counts through charcodes of letters A, B, ...
399796263Sobrien\newcount\appendixno  \appendixno = `\@
3998132718Skan%
399996263Sobrien% \def\appendixletter{\char\the\appendixno}
4000132718Skan% We do the following ugly conditional instead of the above simple
4001132718Skan% construct for the sake of pdftex, which needs the actual
400296263Sobrien% letter in the expansion, not just typeset.
4003169689Skan%
400496263Sobrien\def\appendixletter{%
400596263Sobrien  \ifnum\appendixno=`A A%
400696263Sobrien  \else\ifnum\appendixno=`B B%
400796263Sobrien  \else\ifnum\appendixno=`C C%
400896263Sobrien  \else\ifnum\appendixno=`D D%
400996263Sobrien  \else\ifnum\appendixno=`E E%
401096263Sobrien  \else\ifnum\appendixno=`F F%
401196263Sobrien  \else\ifnum\appendixno=`G G%
401296263Sobrien  \else\ifnum\appendixno=`H H%
401396263Sobrien  \else\ifnum\appendixno=`I I%
401496263Sobrien  \else\ifnum\appendixno=`J J%
401596263Sobrien  \else\ifnum\appendixno=`K K%
401696263Sobrien  \else\ifnum\appendixno=`L L%
401796263Sobrien  \else\ifnum\appendixno=`M M%
401896263Sobrien  \else\ifnum\appendixno=`N N%
401996263Sobrien  \else\ifnum\appendixno=`O O%
402096263Sobrien  \else\ifnum\appendixno=`P P%
402196263Sobrien  \else\ifnum\appendixno=`Q Q%
402296263Sobrien  \else\ifnum\appendixno=`R R%
402396263Sobrien  \else\ifnum\appendixno=`S S%
402496263Sobrien  \else\ifnum\appendixno=`T T%
402596263Sobrien  \else\ifnum\appendixno=`U U%
402696263Sobrien  \else\ifnum\appendixno=`V V%
402796263Sobrien  \else\ifnum\appendixno=`W W%
402896263Sobrien  \else\ifnum\appendixno=`X X%
402996263Sobrien  \else\ifnum\appendixno=`Y Y%
403096263Sobrien  \else\ifnum\appendixno=`Z Z%
403196263Sobrien  % The \the is necessary, despite appearances, because \appendixletter is
403296263Sobrien  % expanded while writing the .toc file.  \char\appendixno is not
403396263Sobrien  % expandable, thus it is written literally, thus all appendixes come out
403496263Sobrien  % with the same letter (or @) in the toc without it.
403596263Sobrien  \else\char\the\appendixno
403696263Sobrien  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
403796263Sobrien  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
403896263Sobrien
403996263Sobrien% Each @chapter defines this as the name of the chapter.
404096263Sobrien% page headings and footings can use it.  @section does likewise.
4041132718Skan% However, they are not reliable, because we don't use marks.
404296263Sobrien\def\thischapter{}
404396263Sobrien\def\thissection{}
404496263Sobrien
404596263Sobrien\newcount\absseclevel % used to calculate proper heading level
4046132718Skan\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
404796263Sobrien
404896263Sobrien% @raisesections: treat @section as chapter, @subsection as section, etc.
404996263Sobrien\def\raisesections{\global\advance\secbase by -1}
405096263Sobrien\let\up=\raisesections % original BFox name
405196263Sobrien
405296263Sobrien% @lowersections: treat @chapter as section, @section as subsection, etc.
405396263Sobrien\def\lowersections{\global\advance\secbase by 1}
405496263Sobrien\let\down=\lowersections % original BFox name
405596263Sobrien
4056169689Skan% we only have subsub.
4057169689Skan\chardef\maxseclevel = 3
4058169689Skan%
4059169689Skan% A numbered section within an unnumbered changes to unnumbered too.
4060169689Skan% To achive this, remember the "biggest" unnum. sec. we are currently in:
4061169689Skan\chardef\unmlevel = \maxseclevel
4062169689Skan%
4063169689Skan% Trace whether the current chapter is an appendix or not:
4064169689Skan% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
4065169689Skan\def\chapheadtype{N}
4066169689Skan
4067169689Skan% Choose a heading macro
4068169689Skan% #1 is heading type
4069169689Skan% #2 is heading level
4070169689Skan% #3 is text for heading
4071169689Skan\def\genhead#1#2#3{%
4072169689Skan  % Compute the abs. sec. level:
4073169689Skan  \absseclevel=#2
4074169689Skan  \advance\absseclevel by \secbase
4075169689Skan  % Make sure \absseclevel doesn't fall outside the range:
4076169689Skan  \ifnum \absseclevel < 0
4077169689Skan    \absseclevel = 0
407896263Sobrien  \else
4079169689Skan    \ifnum \absseclevel > 3
4080169689Skan      \absseclevel = 3
4081132718Skan    \fi
408296263Sobrien  \fi
4083169689Skan  % The heading type:
4084169689Skan  \def\headtype{#1}%
4085169689Skan  \if \headtype U%
4086169689Skan    \ifnum \absseclevel < \unmlevel
4087169689Skan      \chardef\unmlevel = \absseclevel
4088169689Skan    \fi
408996263Sobrien  \else
4090169689Skan    % Check for appendix sections:
4091169689Skan    \ifnum \absseclevel = 0
4092169689Skan      \edef\chapheadtype{\headtype}%
4093169689Skan    \else
4094169689Skan      \if \headtype A\if \chapheadtype N%
4095169689Skan	\errmessage{@appendix... within a non-appendix chapter}%
4096169689Skan      \fi\fi
4097132718Skan    \fi
4098169689Skan    % Check for numbered within unnumbered:
4099169689Skan    \ifnum \absseclevel > \unmlevel
4100169689Skan      \def\headtype{U}%
4101169689Skan    \else
4102169689Skan      \chardef\unmlevel = 3
4103169689Skan    \fi
410496263Sobrien  \fi
4105169689Skan  % Now print the heading:
4106169689Skan  \if \headtype U%
4107169689Skan    \ifcase\absseclevel
4108169689Skan	\unnumberedzzz{#3}%
4109169689Skan    \or \unnumberedseczzz{#3}%
4110169689Skan    \or \unnumberedsubseczzz{#3}%
4111169689Skan    \or \unnumberedsubsubseczzz{#3}%
4112169689Skan    \fi
411396263Sobrien  \else
4114169689Skan    \if \headtype A%
4115169689Skan      \ifcase\absseclevel
4116169689Skan	  \appendixzzz{#3}%
4117169689Skan      \or \appendixsectionzzz{#3}%
4118169689Skan      \or \appendixsubseczzz{#3}%
4119169689Skan      \or \appendixsubsubseczzz{#3}%
4120169689Skan      \fi
4121169689Skan    \else
4122169689Skan      \ifcase\absseclevel
4123169689Skan	  \chapterzzz{#3}%
4124169689Skan      \or \seczzz{#3}%
4125169689Skan      \or \numberedsubseczzz{#3}%
4126169689Skan      \or \numberedsubsubseczzz{#3}%
4127169689Skan      \fi
4128132718Skan    \fi
412996263Sobrien  \fi
4130132718Skan  \suppressfirstparagraphindent
413196263Sobrien}
413296263Sobrien
4133169689Skan% an interface:
4134169689Skan\def\numhead{\genhead N}
4135169689Skan\def\apphead{\genhead A}
4136169689Skan\def\unnmhead{\genhead U}
4137169689Skan
4138132718Skan% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
4139132718Skan% all lower-level sectioning counters to zero.
4140169689Skan%
4141132718Skan% Also set \chaplevelprefix, which we prepend to @float sequence numbers
4142132718Skan% (e.g., figures), q.v.  By default (before any chapter), that is empty.
4143132718Skan\let\chaplevelprefix = \empty
4144169689Skan%
4145132718Skan\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
4146132718Skan\def\chapterzzz#1{%
4147132718Skan  % section resetting is \global in case the chapter is in a group, such
4148132718Skan  % as an @include file.
4149132718Skan  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
4150132718Skan    \global\advance\chapno by 1
4151132718Skan  %
4152132718Skan  % Used for \float.
4153132718Skan  \gdef\chaplevelprefix{\the\chapno.}%
4154132718Skan  \resetallfloatnos
4155132718Skan  %
4156132718Skan  \message{\putwordChapter\space \the\chapno}%
4157132718Skan  %
4158132718Skan  % Write the actual heading.
4159132718Skan  \chapmacro{#1}{Ynumbered}{\the\chapno}%
4160132718Skan  %
4161132718Skan  % So @section and the like are numbered underneath this chapter.
4162119256Skan  \global\let\section = \numberedsec
4163119256Skan  \global\let\subsection = \numberedsubsec
4164119256Skan  \global\let\subsubsection = \numberedsubsubsec
416596263Sobrien}
416696263Sobrien
4167132718Skan\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
4168132718Skan\def\appendixzzz#1{%
4169132718Skan  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
4170132718Skan    \global\advance\appendixno by 1
4171132718Skan  \gdef\chaplevelprefix{\appendixletter.}%
4172132718Skan  \resetallfloatnos
4173132718Skan  %
4174132718Skan  \def\appendixnum{\putwordAppendix\space \appendixletter}%
4175132718Skan  \message{\appendixnum}%
4176132718Skan  %
4177132718Skan  \chapmacro{#1}{Yappendix}{\appendixletter}%
4178132718Skan  %
4179119256Skan  \global\let\section = \appendixsec
4180119256Skan  \global\let\subsection = \appendixsubsec
4181119256Skan  \global\let\subsubsection = \appendixsubsubsec
418296263Sobrien}
418396263Sobrien
4184132718Skan\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
4185132718Skan\def\unnumberedzzz#1{%
4186132718Skan  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
4187132718Skan    \global\advance\unnumberedno by 1
4188119256Skan  %
4189132718Skan  % Since an unnumbered has no number, no prefix for figures.
4190132718Skan  \global\let\chaplevelprefix = \empty
4191132718Skan  \resetallfloatnos
4192132718Skan  %
4193119256Skan  % This used to be simply \message{#1}, but TeX fully expands the
4194119256Skan  % argument to \message.  Therefore, if #1 contained @-commands, TeX
4195119256Skan  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
4196119256Skan  % expanded @cite (which turns out to cause errors because \cite is meant
4197119256Skan  % to be executed, not expanded).
4198119256Skan  %
4199119256Skan  % Anyway, we don't want the fully-expanded definition of @cite to appear
4200119256Skan  % as a result of the \message, we just want `@cite' itself.  We use
4201119256Skan  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
4202119256Skan  % simply yielding the contents of <toks register>.  (We also do this for
4203119256Skan  % the toc entries.)
4204132718Skan  \toks0 = {#1}%
4205132718Skan  \message{(\the\toks0)}%
4206119256Skan  %
4207132718Skan  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
4208132718Skan  %
4209119256Skan  \global\let\section = \unnumberedsec
4210119256Skan  \global\let\subsection = \unnumberedsubsec
4211119256Skan  \global\let\subsubsection = \unnumberedsubsubsec
421296263Sobrien}
421396263Sobrien
4214169689Skan% @centerchap is like @unnumbered, but the heading is centered.
4215169689Skan\outer\parseargdef\centerchap{%
4216169689Skan  % Well, we could do the following in a group, but that would break
4217169689Skan  % an assumption that \chapmacro is called at the outermost level.
4218169689Skan  % Thus we are safer this way:		--kasal, 24feb04
4219169689Skan  \let\centerparametersmaybe = \centerparameters
4220169689Skan  \unnmhead0{#1}%
4221169689Skan  \let\centerparametersmaybe = \relax
4222169689Skan}
4223169689Skan
4224132718Skan% @top is like @unnumbered.
4225132718Skan\let\top\unnumbered
4226132718Skan
422796263Sobrien% Sections.
4228132718Skan\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
4229132718Skan\def\seczzz#1{%
4230132718Skan  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
4231132718Skan  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
423296263Sobrien}
423396263Sobrien
4234132718Skan\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
4235132718Skan\def\appendixsectionzzz#1{%
4236132718Skan  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
4237132718Skan  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
423896263Sobrien}
4239132718Skan\let\appendixsec\appendixsection
424096263Sobrien
4241132718Skan\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
4242132718Skan\def\unnumberedseczzz#1{%
4243132718Skan  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
4244132718Skan  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
424596263Sobrien}
424696263Sobrien
424796263Sobrien% Subsections.
4248132718Skan\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
4249132718Skan\def\numberedsubseczzz#1{%
4250132718Skan  \global\subsubsecno=0  \global\advance\subsecno by 1
4251132718Skan  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
425296263Sobrien}
425396263Sobrien
4254132718Skan\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
4255132718Skan\def\appendixsubseczzz#1{%
4256132718Skan  \global\subsubsecno=0  \global\advance\subsecno by 1
4257132718Skan  \sectionheading{#1}{subsec}{Yappendix}%
4258132718Skan                 {\appendixletter.\the\secno.\the\subsecno}%
425996263Sobrien}
426096263Sobrien
4261132718Skan\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
4262132718Skan\def\unnumberedsubseczzz#1{%
4263132718Skan  \global\subsubsecno=0  \global\advance\subsecno by 1
4264132718Skan  \sectionheading{#1}{subsec}{Ynothing}%
4265132718Skan                 {\the\unnumberedno.\the\secno.\the\subsecno}%
426696263Sobrien}
426796263Sobrien
426896263Sobrien% Subsubsections.
4269132718Skan\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
4270132718Skan\def\numberedsubsubseczzz#1{%
4271132718Skan  \global\advance\subsubsecno by 1
4272132718Skan  \sectionheading{#1}{subsubsec}{Ynumbered}%
4273132718Skan                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
427496263Sobrien}
427596263Sobrien
4276132718Skan\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
4277132718Skan\def\appendixsubsubseczzz#1{%
4278132718Skan  \global\advance\subsubsecno by 1
4279132718Skan  \sectionheading{#1}{subsubsec}{Yappendix}%
4280132718Skan                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
428196263Sobrien}
428296263Sobrien
4283132718Skan\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
4284132718Skan\def\unnumberedsubsubseczzz#1{%
4285132718Skan  \global\advance\subsubsecno by 1
4286132718Skan  \sectionheading{#1}{subsubsec}{Ynothing}%
4287132718Skan                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
428896263Sobrien}
428996263Sobrien
429096263Sobrien% These macros control what the section commands do, according
429196263Sobrien% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
429296263Sobrien% Define them by default for a numbered chapter.
4293132718Skan\let\section = \numberedsec
4294132718Skan\let\subsection = \numberedsubsec
4295132718Skan\let\subsubsection = \numberedsubsubsec
429696263Sobrien
429796263Sobrien% Define @majorheading, @heading and @subheading
429896263Sobrien
429996263Sobrien% NOTE on use of \vbox for chapter headings, section headings, and such:
430096263Sobrien%       1) We use \vbox rather than the earlier \line to permit
430196263Sobrien%          overlong headings to fold.
430296263Sobrien%       2) \hyphenpenalty is set to 10000 because hyphenation in a
430396263Sobrien%          heading is obnoxious; this forbids it.
430496263Sobrien%       3) Likewise, headings look best if no \parindent is used, and
430596263Sobrien%          if justification is not attempted.  Hence \raggedright.
430696263Sobrien
430796263Sobrien
4308132718Skan\def\majorheading{%
4309119256Skan  {\advance\chapheadingskip by 10pt \chapbreak }%
4310132718Skan  \parsearg\chapheadingzzz
4311132718Skan}
431296263Sobrien
4313132718Skan\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
4314132718Skan\def\chapheadingzzz#1{%
4315119256Skan  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
4316119256Skan                    \parindent=0pt\raggedright
4317132718Skan                    \rm #1\hfill}}%
4318132718Skan  \bigskip \par\penalty 200\relax
4319132718Skan  \suppressfirstparagraphindent
4320132718Skan}
432196263Sobrien
432296263Sobrien% @heading, @subheading, @subsubheading.
4323132718Skan\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
4324132718Skan  \suppressfirstparagraphindent}
4325132718Skan\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
4326132718Skan  \suppressfirstparagraphindent}
4327132718Skan\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
4328132718Skan  \suppressfirstparagraphindent}
432996263Sobrien
433096263Sobrien% These macros generate a chapter, section, etc. heading only
433196263Sobrien% (including whitespace, linebreaking, etc. around it),
433296263Sobrien% given all the information in convenient, parsed form.
433396263Sobrien
433496263Sobrien%%% Args are the skip and penalty (usually negative)
433596263Sobrien\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
433696263Sobrien
433796263Sobrien%%% Define plain chapter starts, and page on/off switching for it
433896263Sobrien% Parameter controlling skip before chapter headings (if needed)
433996263Sobrien
434096263Sobrien\newskip\chapheadingskip
434196263Sobrien
434296263Sobrien\def\chapbreak{\dobreak \chapheadingskip {-4000}}
434396263Sobrien\def\chappager{\par\vfill\supereject}
434496263Sobrien\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
434596263Sobrien
434696263Sobrien\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
434796263Sobrien
434896263Sobrien\def\CHAPPAGoff{%
434996263Sobrien\global\let\contentsalignmacro = \chappager
435096263Sobrien\global\let\pchapsepmacro=\chapbreak
435196263Sobrien\global\let\pagealignmacro=\chappager}
435296263Sobrien
435396263Sobrien\def\CHAPPAGon{%
435496263Sobrien\global\let\contentsalignmacro = \chappager
435596263Sobrien\global\let\pchapsepmacro=\chappager
435696263Sobrien\global\let\pagealignmacro=\chappager
435796263Sobrien\global\def\HEADINGSon{\HEADINGSsingle}}
435896263Sobrien
4359132718Skan\def\CHAPPAGodd{%
436096263Sobrien\global\let\contentsalignmacro = \chapoddpage
436196263Sobrien\global\let\pchapsepmacro=\chapoddpage
436296263Sobrien\global\let\pagealignmacro=\chapoddpage
436396263Sobrien\global\def\HEADINGSon{\HEADINGSdouble}}
436496263Sobrien
436596263Sobrien\CHAPPAGon
436696263Sobrien
4367169689Skan% Chapter opening.
4368169689Skan%
4369132718Skan% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
4370132718Skan% Yappendix, Yomitfromtoc), #3 the chapter number.
4371169689Skan%
4372132718Skan% To test against our argument.
4373132718Skan\def\Ynothingkeyword{Ynothing}
4374132718Skan\def\Yomitfromtockeyword{Yomitfromtoc}
4375132718Skan\def\Yappendixkeyword{Yappendix}
4376132718Skan%
4377169689Skan\def\chapmacro#1#2#3{%
437896263Sobrien  \pchapsepmacro
437996263Sobrien  {%
438096263Sobrien    \chapfonts \rm
4381132718Skan    %
4382132718Skan    % Have to define \thissection before calling \donoderef, because the
4383132718Skan    % xref code eventually uses it.  On the other hand, it has to be called
4384132718Skan    % after \pchapsepmacro, or the headline will change too soon.
4385132718Skan    \gdef\thissection{#1}%
4386132718Skan    \gdef\thischaptername{#1}%
4387132718Skan    %
4388132718Skan    % Only insert the separating space if we have a chapter/appendix
4389132718Skan    % number, and don't print the unnumbered ``number''.
4390132718Skan    \def\temptype{#2}%
4391132718Skan    \ifx\temptype\Ynothingkeyword
4392132718Skan      \setbox0 = \hbox{}%
4393132718Skan      \def\toctype{unnchap}%
4394169689Skan      \gdef\thischapter{#1}%
4395132718Skan    \else\ifx\temptype\Yomitfromtockeyword
4396132718Skan      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
4397132718Skan      \def\toctype{omit}%
4398169689Skan      \gdef\thischapter{}%
4399132718Skan    \else\ifx\temptype\Yappendixkeyword
4400132718Skan      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
4401132718Skan      \def\toctype{app}%
4402132718Skan      % We don't substitute the actual chapter name into \thischapter
4403132718Skan      % because we don't want its macros evaluated now.  And we don't
4404132718Skan      % use \thissection because that changes with each section.
4405132718Skan      %
4406132718Skan      \xdef\thischapter{\putwordAppendix{} \appendixletter:
4407132718Skan                        \noexpand\thischaptername}%
4408132718Skan    \else
4409132718Skan      \setbox0 = \hbox{#3\enspace}%
4410132718Skan      \def\toctype{numchap}%
4411132718Skan      \xdef\thischapter{\putwordChapter{} \the\chapno:
4412132718Skan                        \noexpand\thischaptername}%
4413132718Skan    \fi\fi\fi
4414132718Skan    %
4415132718Skan    % Write the toc entry for this chapter.  Must come before the
4416132718Skan    % \donoderef, because we include the current node name in the toc
4417132718Skan    % entry, and \donoderef resets it to empty.
4418132718Skan    \writetocentry{\toctype}{#1}{#3}%
4419132718Skan    %
4420132718Skan    % For pdftex, we have to write out the node definition (aka, make
4421132718Skan    % the pdfdest) after any page break, but before the actual text has
4422132718Skan    % been typeset.  If the destination for the pdf outline is after the
4423132718Skan    % text, then jumping from the outline may wind up with the text not
4424132718Skan    % being visible, for instance under high magnification.
4425132718Skan    \donoderef{#2}%
4426132718Skan    %
4427132718Skan    % Typeset the actual heading.
442896263Sobrien    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
4429132718Skan          \hangindent=\wd0 \centerparametersmaybe
443096263Sobrien          \unhbox0 #1\par}%
443196263Sobrien  }%
443296263Sobrien  \nobreak\bigskip % no page break after a chapter title
443396263Sobrien  \nobreak
443496263Sobrien}
443596263Sobrien
443696263Sobrien% @centerchap -- centered and unnumbered.
443796263Sobrien\let\centerparametersmaybe = \relax
4438169689Skan\def\centerparameters{%
4439169689Skan  \advance\rightskip by 3\rightskip
4440169689Skan  \leftskip = \rightskip
4441169689Skan  \parfillskip = 0pt
4442169689Skan}
444396263Sobrien
444496263Sobrien
4445132718Skan% I don't think this chapter style is supported any more, so I'm not
4446132718Skan% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
4447169689Skan%
4448169689Skan\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
4449169689Skan%
445096263Sobrien\def\unnchfopen #1{%
445196263Sobrien\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
445296263Sobrien                       \parindent=0pt\raggedright
445396263Sobrien                       \rm #1\hfill}}\bigskip \par\nobreak
445496263Sobrien}
445596263Sobrien\def\chfopen #1#2{\chapoddpage {\chapfonts
445696263Sobrien\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
445796263Sobrien\par\penalty 5000 %
445896263Sobrien}
445996263Sobrien\def\centerchfopen #1{%
446096263Sobrien\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
446196263Sobrien                       \parindent=0pt
446296263Sobrien                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
446396263Sobrien}
4464132718Skan\def\CHAPFopen{%
4465169689Skan  \global\let\chapmacro=\chfopen
4466169689Skan  \global\let\centerchapmacro=\centerchfopen}
446796263Sobrien
446896263Sobrien
4469132718Skan% Section titles.  These macros combine the section number parts and
4470132718Skan% call the generic \sectionheading to do the printing.
4471169689Skan%
447296263Sobrien\newskip\secheadingskip
4473132718Skan\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
447496263Sobrien
447596263Sobrien% Subsection titles.
4476132718Skan\newskip\subsecheadingskip
4477132718Skan\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
447896263Sobrien
447996263Sobrien% Subsubsection titles.
4480132718Skan\def\subsubsecheadingskip{\subsecheadingskip}
4481132718Skan\def\subsubsecheadingbreak{\subsecheadingbreak}
448296263Sobrien
448396263Sobrien
4484132718Skan% Print any size, any type, section title.
4485169689Skan%
4486132718Skan% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
4487132718Skan% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
4488132718Skan% section number.
4489169689Skan%
4490132718Skan\def\sectionheading#1#2#3#4{%
449196263Sobrien  {%
449296263Sobrien    % Switch to the right set of fonts.
4493132718Skan    \csname #2fonts\endcsname \rm
449496263Sobrien    %
4495132718Skan    % Insert space above the heading.
4496132718Skan    \csname #2headingbreak\endcsname
449796263Sobrien    %
4498132718Skan    % Only insert the space after the number if we have a section number.
4499132718Skan    \def\sectionlevel{#2}%
4500132718Skan    \def\temptype{#3}%
4501132718Skan    %
4502132718Skan    \ifx\temptype\Ynothingkeyword
4503132718Skan      \setbox0 = \hbox{}%
4504132718Skan      \def\toctype{unn}%
4505132718Skan      \gdef\thissection{#1}%
4506132718Skan    \else\ifx\temptype\Yomitfromtockeyword
4507132718Skan      % for @headings -- no section number, don't include in toc,
4508132718Skan      % and don't redefine \thissection.
4509132718Skan      \setbox0 = \hbox{}%
4510132718Skan      \def\toctype{omit}%
4511132718Skan      \let\sectionlevel=\empty
4512132718Skan    \else\ifx\temptype\Yappendixkeyword
4513132718Skan      \setbox0 = \hbox{#4\enspace}%
4514132718Skan      \def\toctype{app}%
4515132718Skan      \gdef\thissection{#1}%
4516132718Skan    \else
4517132718Skan      \setbox0 = \hbox{#4\enspace}%
4518132718Skan      \def\toctype{num}%
4519132718Skan      \gdef\thissection{#1}%
4520132718Skan    \fi\fi\fi
4521132718Skan    %
4522132718Skan    % Write the toc entry (before \donoderef).  See comments in \chfplain.
4523132718Skan    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
4524132718Skan    %
4525132718Skan    % Write the node reference (= pdf destination for pdftex).
4526132718Skan    % Again, see comments in \chfplain.
4527132718Skan    \donoderef{#3}%
4528132718Skan    %
4529132718Skan    % Output the actual section heading.
453096263Sobrien    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
4531132718Skan          \hangindent=\wd0  % zero if no section number
4532132718Skan          \unhbox0 #1}%
453396263Sobrien  }%
4534132718Skan  % Add extra space after the heading -- half of whatever came above it.
4535132718Skan  % Don't allow stretch, though.
4536132718Skan  \kern .5 \csname #2headingskip\endcsname
4537132718Skan  %
4538132718Skan  % Do not let the kern be a potential breakpoint, as it would be if it
4539132718Skan  % was followed by glue.
4540117395Skan  \nobreak
4541132718Skan  %
4542132718Skan  % We'll almost certainly start a paragraph next, so don't let that
4543132718Skan  % glue accumulate.  (Not a breakpoint because it's preceded by a
4544132718Skan  % discardable item.)
4545132718Skan  \vskip-\parskip
4546169689Skan  % 
4547169689Skan  % This is purely so the last item on the list is a known \penalty >
4548169689Skan  % 10000.  This is so \startdefun can avoid allowing breakpoints after
4549169689Skan  % section headings.  Otherwise, it would insert a valid breakpoint between:
4550169689Skan  % 
4551132718Skan  %   @section sec-whatever
4552132718Skan  %   @deffn def-whatever
4553169689Skan  \penalty 10001
455496263Sobrien}
455596263Sobrien
455696263Sobrien
455796263Sobrien\message{toc,}
455896263Sobrien% Table of contents.
455996263Sobrien\newwrite\tocfile
456096263Sobrien
456196263Sobrien% Write an entry to the toc file, opening it if necessary.
4562169689Skan% Called from @chapter, etc.
4563169689Skan%
4564132718Skan% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
4565132718Skan% We append the current node name (if any) and page number as additional
4566132718Skan% arguments for the \{chap,sec,...}entry macros which will eventually
4567132718Skan% read this.  The node name is used in the pdf outlines as the
4568132718Skan% destination to jump to.
4569169689Skan%
4570119256Skan% We open the .toc file for writing here instead of at @setfilename (or
4571119256Skan% any other fixed time) so that @contents can be anywhere in the document.
4572132718Skan% But if #1 is `omit', then we don't do anything.  This is used for the
4573132718Skan% table of contents chapter openings themselves.
457496263Sobrien%
457596263Sobrien\newif\iftocfileopened
4576132718Skan\def\omitkeyword{omit}%
4577132718Skan%
4578119256Skan\def\writetocentry#1#2#3{%
4579132718Skan  \edef\writetoctype{#1}%
4580132718Skan  \ifx\writetoctype\omitkeyword \else
4581132718Skan    \iftocfileopened\else
4582132718Skan      \immediate\openout\tocfile = \jobname.toc
4583132718Skan      \global\tocfileopenedtrue
4584132718Skan    \fi
4585132718Skan    %
4586132718Skan    \iflinks
4587169689Skan      {\atdummies \turnoffactive
4588169689Skan       \edef\temp{%
4589169689Skan         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
4590169689Skan       \temp
4591169689Skan      }
4592132718Skan    \fi
459396263Sobrien  \fi
4594117395Skan  %
4595132718Skan  % Tell \shipout to create a pdf destination on each page, if we're
4596132718Skan  % writing pdf.  These are used in the table of contents.  We can't
4597132718Skan  % just write one on every page because the title pages are numbered
4598132718Skan  % 1 and 2 (the page numbers aren't printed), and so are the first
4599132718Skan  % two pages of the document.  Thus, we'd have two destinations named
4600132718Skan  % `1', and two named `2'.
4601132718Skan  \ifpdf \global\pdfmakepagedesttrue \fi
460296263Sobrien}
460396263Sobrien
4604169689Skan
4605169689Skan% These characters do not print properly in the Computer Modern roman
4606169689Skan% fonts, so we must take special care.  This is more or less redundant
4607169689Skan% with the Texinfo input format setup at the end of this file.
4608169689Skan% 
4609169689Skan\def\activecatcodes{%
4610169689Skan  \catcode`\"=\active
4611169689Skan  \catcode`\$=\active
4612169689Skan  \catcode`\<=\active
4613169689Skan  \catcode`\>=\active
4614169689Skan  \catcode`\\=\active
4615169689Skan  \catcode`\^=\active
4616169689Skan  \catcode`\_=\active
4617169689Skan  \catcode`\|=\active
4618169689Skan  \catcode`\~=\active
4619169689Skan}
4620169689Skan
4621169689Skan
4622169689Skan% Read the toc file, which is essentially Texinfo input.
4623169689Skan\def\readtocfile{%
4624169689Skan  \setupdatafile
4625169689Skan  \activecatcodes
4626169689Skan  \input \jobname.toc
4627169689Skan}
4628169689Skan
462996263Sobrien\newskip\contentsrightmargin \contentsrightmargin=1in
463096263Sobrien\newcount\savepageno
463196263Sobrien\newcount\lastnegativepageno \lastnegativepageno = -1
463296263Sobrien
4633132718Skan% Prepare to read what we've written to \tocfile.
463496263Sobrien%
463596263Sobrien\def\startcontents#1{%
4636132718Skan  % If @setchapternewpage on, and @headings double, the contents should
4637132718Skan  % start on an odd page, unlike chapters.  Thus, we maintain
4638132718Skan  % \contentsalignmacro in parallel with \pagealignmacro.
4639132718Skan  % From: Torbjorn Granlund <tege@matematik.su.se>
4640132718Skan  \contentsalignmacro
4641132718Skan  \immediate\closeout\tocfile
4642132718Skan  %
4643132718Skan  % Don't need to put `Contents' or `Short Contents' in the headline.
4644132718Skan  % It is abundantly clear what they are.
4645132718Skan  \def\thischapter{}%
4646132718Skan  \chapmacro{#1}{Yomitfromtoc}{}%
4647132718Skan  %
4648132718Skan  \savepageno = \pageno
4649132718Skan  \begingroup                  % Set up to handle contents files properly.
4650169689Skan    \raggedbottom              % Worry more about breakpoints than the bottom.
4651132718Skan    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
4652132718Skan    %
4653132718Skan    % Roman numerals for page numbers.
4654132718Skan    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
465596263Sobrien}
465696263Sobrien
465796263Sobrien
465896263Sobrien% Normal (long) toc.
465996263Sobrien\def\contents{%
4660132718Skan  \startcontents{\putwordTOC}%
4661132718Skan    \openin 1 \jobname.toc
4662132718Skan    \ifeof 1 \else
4663169689Skan      \readtocfile
4664132718Skan    \fi
4665132718Skan    \vfill \eject
4666132718Skan    \contentsalignmacro % in case @setchapternewpage odd is in effect
4667132718Skan    \ifeof 1 \else
4668132718Skan      \pdfmakeoutlines
4669132718Skan    \fi
4670132718Skan    \closein 1
4671132718Skan  \endgroup
4672132718Skan  \lastnegativepageno = \pageno
4673132718Skan  \global\pageno = \savepageno
467496263Sobrien}
467596263Sobrien
467696263Sobrien% And just the chapters.
467796263Sobrien\def\summarycontents{%
4678132718Skan  \startcontents{\putwordShortTOC}%
4679132718Skan    %
4680132718Skan    \let\numchapentry = \shortchapentry
4681132718Skan    \let\appentry = \shortchapentry
4682132718Skan    \let\unnchapentry = \shortunnchapentry
4683132718Skan    % We want a true roman here for the page numbers.
4684132718Skan    \secfonts
4685132718Skan    \let\rm=\shortcontrm \let\bf=\shortcontbf
4686132718Skan    \let\sl=\shortcontsl \let\tt=\shortconttt
4687132718Skan    \rm
4688132718Skan    \hyphenpenalty = 10000
4689132718Skan    \advance\baselineskip by 1pt % Open it up a little.
4690132718Skan    \def\numsecentry##1##2##3##4{}
4691132718Skan    \let\appsecentry = \numsecentry
4692132718Skan    \let\unnsecentry = \numsecentry
4693132718Skan    \let\numsubsecentry = \numsecentry
4694132718Skan    \let\appsubsecentry = \numsecentry
4695132718Skan    \let\unnsubsecentry = \numsecentry
4696132718Skan    \let\numsubsubsecentry = \numsecentry
4697132718Skan    \let\appsubsubsecentry = \numsecentry
4698132718Skan    \let\unnsubsubsecentry = \numsecentry
4699132718Skan    \openin 1 \jobname.toc
4700132718Skan    \ifeof 1 \else
4701169689Skan      \readtocfile
4702132718Skan    \fi
4703132718Skan    \closein 1
4704132718Skan    \vfill \eject
4705132718Skan    \contentsalignmacro % in case @setchapternewpage odd is in effect
4706132718Skan  \endgroup
4707132718Skan  \lastnegativepageno = \pageno
4708132718Skan  \global\pageno = \savepageno
470996263Sobrien}
471096263Sobrien\let\shortcontents = \summarycontents
471196263Sobrien
4712132718Skan% Typeset the label for a chapter or appendix for the short contents.
4713132718Skan% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
4714132718Skan%
4715132718Skan\def\shortchaplabel#1{%
4716132718Skan  % This space should be enough, since a single number is .5em, and the
4717132718Skan  % widest letter (M) is 1em, at least in the Computer Modern fonts.
4718132718Skan  % But use \hss just in case.
4719132718Skan  % (This space doesn't include the extra space that gets added after
4720132718Skan  % the label; that gets put in by \shortchapentry above.)
4721169689Skan  %
4722132718Skan  % We'd like to right-justify chapter numbers, but that looks strange
4723132718Skan  % with appendix letters.  And right-justifying numbers and
4724132718Skan  % left-justifying letters looks strange when there is less than 10
4725132718Skan  % chapters.  Have to read the whole toc once to know how many chapters
4726132718Skan  % there are before deciding ...
4727132718Skan  \hbox to 1em{#1\hss}%
4728132718Skan}
472996263Sobrien
473096263Sobrien% These macros generate individual entries in the table of contents.
473196263Sobrien% The first argument is the chapter or section name.
473296263Sobrien% The last argument is the page number.
473396263Sobrien% The arguments in between are the chapter number, section number, ...
473496263Sobrien
473596263Sobrien% Chapters, in the main contents.
4736132718Skan\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
473796263Sobrien%
473896263Sobrien% Chapters, in the short toc.
473996263Sobrien% See comments in \dochapentry re vbox and related settings.
4740132718Skan\def\shortchapentry#1#2#3#4{%
4741132718Skan  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
474296263Sobrien}
474396263Sobrien
474496263Sobrien% Appendices, in the main contents.
4745132718Skan% Need the word Appendix, and a fixed-size box.
4746169689Skan%
4747132718Skan\def\appendixbox#1{%
4748132718Skan  % We use M since it's probably the widest letter.
4749132718Skan  \setbox0 = \hbox{\putwordAppendix{} M}%
4750132718Skan  \hbox to \wd0{\putwordAppendix{} #1\hss}}
475196263Sobrien%
4752132718Skan\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
475396263Sobrien
475496263Sobrien% Unnumbered chapters.
4755132718Skan\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
4756132718Skan\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
475796263Sobrien
475896263Sobrien% Sections.
4759132718Skan\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
4760132718Skan\let\appsecentry=\numsecentry
4761132718Skan\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
476296263Sobrien
476396263Sobrien% Subsections.
4764132718Skan\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
4765132718Skan\let\appsubsecentry=\numsubsecentry
4766132718Skan\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
476796263Sobrien
476896263Sobrien% And subsubsections.
4769132718Skan\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
4770132718Skan\let\appsubsubsecentry=\numsubsubsecentry
4771132718Skan\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
477296263Sobrien
477396263Sobrien% This parameter controls the indentation of the various levels.
4774169689Skan% Same as \defaultparindent.
4775169689Skan\newdimen\tocindent \tocindent = 15pt
477696263Sobrien
477796263Sobrien% Now for the actual typesetting. In all these, #1 is the text and #2 is the
477896263Sobrien% page number.
477996263Sobrien%
478096263Sobrien% If the toc has to be broken over pages, we want it to be at chapters
478196263Sobrien% if at all possible; hence the \penalty.
478296263Sobrien\def\dochapentry#1#2{%
478396263Sobrien   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
478496263Sobrien   \begingroup
478596263Sobrien     \chapentryfonts
478696263Sobrien     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
478796263Sobrien   \endgroup
478896263Sobrien   \nobreak\vskip .25\baselineskip plus.1\baselineskip
478996263Sobrien}
479096263Sobrien
479196263Sobrien\def\dosecentry#1#2{\begingroup
479296263Sobrien  \secentryfonts \leftskip=\tocindent
479396263Sobrien  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
479496263Sobrien\endgroup}
479596263Sobrien
479696263Sobrien\def\dosubsecentry#1#2{\begingroup
479796263Sobrien  \subsecentryfonts \leftskip=2\tocindent
479896263Sobrien  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
479996263Sobrien\endgroup}
480096263Sobrien
480196263Sobrien\def\dosubsubsecentry#1#2{\begingroup
480296263Sobrien  \subsubsecentryfonts \leftskip=3\tocindent
480396263Sobrien  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
480496263Sobrien\endgroup}
480596263Sobrien
4806132718Skan% We use the same \entry macro as for the index entries.
4807132718Skan\let\tocentry = \entry
480896263Sobrien
480996263Sobrien% Space between chapter (or whatever) number and the title.
481096263Sobrien\def\labelspace{\hskip1em \relax}
481196263Sobrien
481296263Sobrien\def\dopageno#1{{\rm #1}}
481396263Sobrien\def\doshortpageno#1{{\rm #1}}
481496263Sobrien
481596263Sobrien\def\chapentryfonts{\secfonts \rm}
481696263Sobrien\def\secentryfonts{\textfonts}
4817132718Skan\def\subsecentryfonts{\textfonts}
4818132718Skan\def\subsubsecentryfonts{\textfonts}
481996263Sobrien
482096263Sobrien
482196263Sobrien\message{environments,}
482296263Sobrien% @foo ... @end foo.
482396263Sobrien
4824117395Skan% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
4825119256Skan%
482696263Sobrien% Since these characters are used in examples, it should be an even number of
482796263Sobrien% \tt widths. Each \tt character is 1en, so two makes it 1em.
4828117395Skan%
482996263Sobrien\def\point{$\star$}
483096263Sobrien\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
483196263Sobrien\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
483296263Sobrien\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
483396263Sobrien\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
483496263Sobrien
4835117395Skan% The @error{} command.
483696263Sobrien% Adapted from the TeXbook's \boxit.
4837119256Skan%
4838117395Skan\newbox\errorbox
4839117395Skan%
484096263Sobrien{\tentt \global\dimen0 = 3em}% Width of the box.
484196263Sobrien\dimen2 = .55pt % Thickness of rules
484296263Sobrien% The text. (`r' is open on the right, `e' somewhat less so on the left.)
484396263Sobrien\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
4844117395Skan%
4845132718Skan\setbox\errorbox=\hbox to \dimen0{\hfil
484696263Sobrien   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
484796263Sobrien   \advance\hsize by -2\dimen2 % Rules.
4848132718Skan   \vbox{%
484996263Sobrien      \hrule height\dimen2
485096263Sobrien      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
485196263Sobrien         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
485296263Sobrien         \kern3pt\vrule width\dimen2}% Space to right.
485396263Sobrien      \hrule height\dimen2}
485496263Sobrien    \hfil}
4855117395Skan%
485696263Sobrien\def\error{\leavevmode\lower.7ex\copy\errorbox}
485796263Sobrien
485896263Sobrien% @tex ... @end tex    escapes into raw Tex temporarily.
485996263Sobrien% One exception: @ is still an escape character, so that @end tex works.
486096263Sobrien% But \@ or @@ will get a plain tex @ character.
486196263Sobrien
4862132718Skan\envdef\tex{%
486396263Sobrien  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
486496263Sobrien  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
4865119256Skan  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
486696263Sobrien  \catcode `\%=14
4867119256Skan  \catcode `\+=\other
4868119256Skan  \catcode `\"=\other
4869119256Skan  \catcode `\|=\other
4870119256Skan  \catcode `\<=\other
4871119256Skan  \catcode `\>=\other
487296263Sobrien  \escapechar=`\\
487396263Sobrien  %
487496263Sobrien  \let\b=\ptexb
487596263Sobrien  \let\bullet=\ptexbullet
487696263Sobrien  \let\c=\ptexc
487796263Sobrien  \let\,=\ptexcomma
487896263Sobrien  \let\.=\ptexdot
487996263Sobrien  \let\dots=\ptexdots
488096263Sobrien  \let\equiv=\ptexequiv
488196263Sobrien  \let\!=\ptexexclam
488296263Sobrien  \let\i=\ptexi
4883119256Skan  \let\indent=\ptexindent
4884132718Skan  \let\noindent=\ptexnoindent
488596263Sobrien  \let\{=\ptexlbrace
488696263Sobrien  \let\+=\tabalign
488796263Sobrien  \let\}=\ptexrbrace
4888119256Skan  \let\/=\ptexslash
488996263Sobrien  \let\*=\ptexstar
489096263Sobrien  \let\t=\ptext
4891169689Skan  \let\frenchspacing=\plainfrenchspacing
489296263Sobrien  %
489396263Sobrien  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
489496263Sobrien  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
489596263Sobrien  \def\@{@}%
4896132718Skan}
4897132718Skan% There is no need to define \Etex.
489896263Sobrien
4899117395Skan% Define @lisp ... @end lisp.
4900132718Skan% @lisp environment forms a group so it can rebind things,
4901117395Skan% including the definition of @end lisp (which normally is erroneous).
490296263Sobrien
490396263Sobrien% Amount to narrow the margins by for @lisp.
490496263Sobrien\newskip\lispnarrowing \lispnarrowing=0.4in
490596263Sobrien
490696263Sobrien% This is the definition that ^^M gets inside @lisp, @example, and other
490796263Sobrien% such environments.  \null is better than a space, since it doesn't
490896263Sobrien% have any width.
490996263Sobrien\def\lisppar{\null\endgraf}
491096263Sobrien
491196263Sobrien% This space is always present above and below environments.
491296263Sobrien\newskip\envskipamount \envskipamount = 0pt
491396263Sobrien
491496263Sobrien% Make spacing and below environment symmetrical.  We use \parskip here
491596263Sobrien% to help in doing that, since in @example-like environments \parskip
491696263Sobrien% is reset to zero; thus the \afterenvbreak inserts no space -- but the
4917117395Skan% start of the next paragraph will insert \parskip.
491896263Sobrien%
491996263Sobrien\def\aboveenvbreak{{%
4920169689Skan  % =10000 instead of <10000 because of a special case in \itemzzz and
4921169689Skan  % \sectionheading, q.v.
4922117395Skan  \ifnum \lastpenalty=10000 \else
492396263Sobrien    \advance\envskipamount by \parskip
492496263Sobrien    \endgraf
492596263Sobrien    \ifdim\lastskip<\envskipamount
492696263Sobrien      \removelastskip
4927117395Skan      % it's not a good place to break if the last penalty was \nobreak
4928117395Skan      % or better ...
4929169689Skan      \ifnum\lastpenalty<10000 \penalty-50 \fi
493096263Sobrien      \vskip\envskipamount
493196263Sobrien    \fi
493296263Sobrien  \fi
493396263Sobrien}}
493496263Sobrien
493596263Sobrien\let\afterenvbreak = \aboveenvbreak
493696263Sobrien
493796263Sobrien% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
493896263Sobrien\let\nonarrowing=\relax
493996263Sobrien
494096263Sobrien% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
494196263Sobrien% environment contents.
494296263Sobrien\font\circle=lcircle10
494396263Sobrien\newdimen\circthick
494496263Sobrien\newdimen\cartouter\newdimen\cartinner
494596263Sobrien\newskip\normbskip\newskip\normpskip\newskip\normlskip
494696263Sobrien\circthick=\fontdimen8\circle
494796263Sobrien%
494896263Sobrien\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
494996263Sobrien\def\ctr{{\hskip 6pt\circle\char'010}}
495096263Sobrien\def\cbl{{\circle\char'012\hskip -6pt}}
495196263Sobrien\def\cbr{{\hskip 6pt\circle\char'011}}
495296263Sobrien\def\carttop{\hbox to \cartouter{\hskip\lskip
495396263Sobrien        \ctl\leaders\hrule height\circthick\hfil\ctr
495496263Sobrien        \hskip\rskip}}
495596263Sobrien\def\cartbot{\hbox to \cartouter{\hskip\lskip
495696263Sobrien        \cbl\leaders\hrule height\circthick\hfil\cbr
495796263Sobrien        \hskip\rskip}}
495896263Sobrien%
495996263Sobrien\newskip\lskip\newskip\rskip
496096263Sobrien
4961132718Skan\envdef\cartouche{%
4962132718Skan  \ifhmode\par\fi  % can't be in the midst of a paragraph.
4963132718Skan  \startsavinginserts
4964132718Skan  \lskip=\leftskip \rskip=\rightskip
4965132718Skan  \leftskip=0pt\rightskip=0pt % we want these *outside*.
4966132718Skan  \cartinner=\hsize \advance\cartinner by-\lskip
4967132718Skan  \advance\cartinner by-\rskip
4968132718Skan  \cartouter=\hsize
4969132718Skan  \advance\cartouter by 18.4pt	% allow for 3pt kerns on either
4970132718Skan				% side, and for 6pt waste from
4971132718Skan				% each corner char, and rule thickness
4972132718Skan  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
4973132718Skan  % Flag to tell @lisp, etc., not to narrow margin.
4974132718Skan  \let\nonarrowing=\comment
4975132718Skan  \vbox\bgroup
4976132718Skan      \baselineskip=0pt\parskip=0pt\lineskip=0pt
4977132718Skan      \carttop
4978132718Skan      \hbox\bgroup
4979132718Skan	  \hskip\lskip
4980132718Skan	  \vrule\kern3pt
4981132718Skan	  \vbox\bgroup
4982132718Skan	      \kern3pt
4983132718Skan	      \hsize=\cartinner
4984132718Skan	      \baselineskip=\normbskip
4985132718Skan	      \lineskip=\normlskip
4986132718Skan	      \parskip=\normpskip
4987132718Skan	      \vskip -\parskip
4988132718Skan	      \comment % For explanation, see the end of \def\group.
4989132718Skan}
499096263Sobrien\def\Ecartouche{%
4991132718Skan              \ifhmode\par\fi
4992132718Skan	      \kern3pt
4993132718Skan	  \egroup
4994132718Skan	  \kern3pt\vrule
4995132718Skan	  \hskip\rskip
4996132718Skan      \egroup
4997132718Skan      \cartbot
4998132718Skan  \egroup
4999132718Skan  \checkinserts
5000132718Skan}
500196263Sobrien
500296263Sobrien
500396263Sobrien% This macro is called at the beginning of all the @example variants,
500496263Sobrien% inside a group.
500596263Sobrien\def\nonfillstart{%
500696263Sobrien  \aboveenvbreak
500796263Sobrien  \hfuzz = 12pt % Don't be fussy
500896263Sobrien  \sepspaces % Make spaces be word-separators rather than space tokens.
500996263Sobrien  \let\par = \lisppar % don't ignore blank lines
501096263Sobrien  \obeylines % each line of input is a line of output
501196263Sobrien  \parskip = 0pt
501296263Sobrien  \parindent = 0pt
501396263Sobrien  \emergencystretch = 0pt % don't try to avoid overfull boxes
501496263Sobrien  % @cartouche defines \nonarrowing to inhibit narrowing
501596263Sobrien  % at next level down.
501696263Sobrien  \ifx\nonarrowing\relax
501796263Sobrien    \advance \leftskip by \lispnarrowing
501896263Sobrien    \exdentamount=\lispnarrowing
501996263Sobrien  \fi
5020132718Skan  \let\exdent=\nofillexdent
502196263Sobrien}
502296263Sobrien
5023169689Skan% If you want all examples etc. small: @set dispenvsize small.
5024169689Skan% If you want even small examples the full size: @set dispenvsize nosmall.
5025169689Skan% This affects the following displayed environments:
5026169689Skan%    @example, @display, @format, @lisp
5027169689Skan%
5028169689Skan\def\smallword{small}
5029169689Skan\def\nosmallword{nosmall}
5030169689Skan\let\SETdispenvsize\relax
5031169689Skan\def\setnormaldispenv{%
5032169689Skan  \ifx\SETdispenvsize\smallword
5033169689Skan    \smallexamplefonts \rm
5034169689Skan  \fi
5035169689Skan}
5036169689Skan\def\setsmalldispenv{%
5037169689Skan  \ifx\SETdispenvsize\nosmallword
5038169689Skan  \else
5039169689Skan    \smallexamplefonts \rm
5040169689Skan  \fi
5041169689Skan}
5042169689Skan
5043132718Skan% We often define two environments, @foo and @smallfoo.
5044132718Skan% Let's do it by one command:
5045132718Skan\def\makedispenv #1#2{
5046169689Skan  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
5047169689Skan  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
5048132718Skan  \expandafter\let\csname E#1\endcsname \afterenvbreak
5049132718Skan  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
5050132718Skan}
5051132718Skan
5052169689Skan% Define two synonyms:
5053132718Skan\def\maketwodispenvs #1#2#3{
5054132718Skan  \makedispenv{#1}{#3}
5055132718Skan  \makedispenv{#2}{#3}
5056132718Skan}
5057132718Skan
5058132718Skan% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
505996263Sobrien%
5060132718Skan% @smallexample and @smalllisp: use smaller fonts.
5061132718Skan% Originally contributed by Pavel@xerox.
506296263Sobrien%
5063132718Skan\maketwodispenvs {lisp}{example}{%
506496263Sobrien  \nonfillstart
506596263Sobrien  \tt
506696263Sobrien  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
506796263Sobrien  \gobble       % eat return
506896263Sobrien}
506996263Sobrien
5070132718Skan% @display/@smalldisplay: same as @lisp except keep current font.
507196263Sobrien%
5072132718Skan\makedispenv {display}{%
507396263Sobrien  \nonfillstart
507496263Sobrien  \gobble
507596263Sobrien}
507696263Sobrien
5077132718Skan% @format/@smallformat: same as @display except don't narrow margins.
507896263Sobrien%
5079169689Skan\makedispenv{format}{%
5080132718Skan  \let\nonarrowing = t%
508196263Sobrien  \nonfillstart
508296263Sobrien  \gobble
508396263Sobrien}
508496263Sobrien
5085169689Skan% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
5086169689Skan\envdef\flushleft{%
5087169689Skan  \let\nonarrowing = t%
5088169689Skan  \nonfillstart
5089169689Skan  \gobble
5090169689Skan}
5091169689Skan\let\Eflushleft = \afterenvbreak
5092169689Skan
509396263Sobrien% @flushright.
509496263Sobrien%
5095132718Skan\envdef\flushright{%
5096132718Skan  \let\nonarrowing = t%
509796263Sobrien  \nonfillstart
509896263Sobrien  \advance\leftskip by 0pt plus 1fill
509996263Sobrien  \gobble
510096263Sobrien}
5101132718Skan\let\Eflushright = \afterenvbreak
510296263Sobrien
510396263Sobrien
510496263Sobrien% @quotation does normal linebreaking (hence we can't use \nonfillstart)
5105169689Skan% and narrows the margins.  We keep \parskip nonzero in general, since
5106169689Skan% we're doing normal filling.  So, when using \aboveenvbreak and
5107169689Skan% \afterenvbreak, temporarily make \parskip 0.
510896263Sobrien%
5109132718Skan\envdef\quotation{%
511096263Sobrien  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
511196263Sobrien  \parindent=0pt
511296263Sobrien  %
511396263Sobrien  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
511496263Sobrien  \ifx\nonarrowing\relax
511596263Sobrien    \advance\leftskip by \lispnarrowing
511696263Sobrien    \advance\rightskip by \lispnarrowing
511796263Sobrien    \exdentamount = \lispnarrowing
511896263Sobrien    \let\nonarrowing = \relax
511996263Sobrien  \fi
5120132718Skan  \parsearg\quotationlabel
512196263Sobrien}
512296263Sobrien
5123132718Skan% We have retained a nonzero parskip for the environment, since we're
5124169689Skan% doing normal filling.
5125169689Skan%
5126169689Skan\def\Equotation{%
5127169689Skan  \par
5128169689Skan  \ifx\quotationauthor\undefined\else
5129169689Skan    % indent a bit.
5130169689Skan    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
5131169689Skan  \fi
5132169689Skan  {\parskip=0pt \afterenvbreak}%
5133169689Skan}
513496263Sobrien
5135132718Skan% If we're given an argument, typeset it in bold with a colon after.
5136132718Skan\def\quotationlabel#1{%
5137132718Skan  \def\temp{#1}%
5138132718Skan  \ifx\temp\empty \else
5139132718Skan    {\bf #1: }%
5140132718Skan  \fi
5141132718Skan}
5142132718Skan
5143132718Skan
514496263Sobrien% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
5145119256Skan% If we want to allow any <char> as delimiter,
514696263Sobrien% we need the curly braces so that makeinfo sees the @verb command, eg:
514796263Sobrien% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
514896263Sobrien%
514996263Sobrien% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
515096263Sobrien%
5151117395Skan% [Knuth] p.344; only we need to do the other characters Texinfo sets
5152117395Skan% active too.  Otherwise, they get lost as the first character on a
5153117395Skan% verbatim line.
515496263Sobrien\def\dospecials{%
5155117395Skan  \do\ \do\\\do\{\do\}\do\$\do\&%
5156117395Skan  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
5157117395Skan  \do\<\do\>\do\|\do\@\do+\do\"%
5158117395Skan}
515996263Sobrien%
516096263Sobrien% [Knuth] p. 380
516196263Sobrien\def\uncatcodespecials{%
5162132718Skan  \def\do##1{\catcode`##1=\other}\dospecials}
516396263Sobrien%
516496263Sobrien% [Knuth] pp. 380,381,391
516596263Sobrien% Disable Spanish ligatures ?` and !` of \tt font
516696263Sobrien\begingroup
516796263Sobrien  \catcode`\`=\active\gdef`{\relax\lq}
516896263Sobrien\endgroup
516996263Sobrien%
517096263Sobrien% Setup for the @verb command.
517196263Sobrien%
517296263Sobrien% Eight spaces for a tab
517396263Sobrien\begingroup
517496263Sobrien  \catcode`\^^I=\active
517596263Sobrien  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
517696263Sobrien\endgroup
517796263Sobrien%
517896263Sobrien\def\setupverb{%
517996263Sobrien  \tt  % easiest (and conventionally used) font for verbatim
518096263Sobrien  \def\par{\leavevmode\endgraf}%
518196263Sobrien  \catcode`\`=\active
518296263Sobrien  \tabeightspaces
518396263Sobrien  % Respect line breaks,
518496263Sobrien  % print special symbols as themselves, and
518596263Sobrien  % make each space count
518696263Sobrien  % must do in this order:
518796263Sobrien  \obeylines \uncatcodespecials \sepspaces
518896263Sobrien}
518996263Sobrien
519096263Sobrien% Setup for the @verbatim environment
519196263Sobrien%
519296263Sobrien% Real tab expansion
519396263Sobrien\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
519496263Sobrien%
519596263Sobrien\def\starttabbox{\setbox0=\hbox\bgroup}
519696263Sobrien\begingroup
519796263Sobrien  \catcode`\^^I=\active
519896263Sobrien  \gdef\tabexpand{%
519996263Sobrien    \catcode`\^^I=\active
520096263Sobrien    \def^^I{\leavevmode\egroup
520196263Sobrien      \dimen0=\wd0 % the width so far, or since the previous tab
520296263Sobrien      \divide\dimen0 by\tabw
520396263Sobrien      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
520496263Sobrien      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
520596263Sobrien      \wd0=\dimen0 \box0 \starttabbox
520696263Sobrien    }%
520796263Sobrien  }
520896263Sobrien\endgroup
520996263Sobrien\def\setupverbatim{%
5210132718Skan  \nonfillstart
5211132718Skan  \advance\leftskip by -\defbodyindent
521296263Sobrien  % Easiest (and conventionally used) font for verbatim
521396263Sobrien  \tt
521496263Sobrien  \def\par{\leavevmode\egroup\box0\endgraf}%
521596263Sobrien  \catcode`\`=\active
521696263Sobrien  \tabexpand
521796263Sobrien  % Respect line breaks,
521896263Sobrien  % print special symbols as themselves, and
521996263Sobrien  % make each space count
522096263Sobrien  % must do in this order:
522196263Sobrien  \obeylines \uncatcodespecials \sepspaces
522296263Sobrien  \everypar{\starttabbox}%
522396263Sobrien}
522496263Sobrien
5225119256Skan% Do the @verb magic: verbatim text is quoted by unique
5226119256Skan% delimiter characters.  Before first delimiter expect a
522796263Sobrien% right brace, after last delimiter expect closing brace:
522896263Sobrien%
522996263Sobrien%    \def\doverb'{'<char>#1<char>'}'{#1}
523096263Sobrien%
523196263Sobrien% [Knuth] p. 382; only eat outer {}
523296263Sobrien\begingroup
5233132718Skan  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
523496263Sobrien  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
523596263Sobrien\endgroup
523696263Sobrien%
523796263Sobrien\def\verb{\begingroup\setupverb\doverb}
523896263Sobrien%
523996263Sobrien%
524096263Sobrien% Do the @verbatim magic: define the macro \doverbatim so that
524196263Sobrien% the (first) argument ends when '@end verbatim' is reached, ie:
524296263Sobrien%
524396263Sobrien%     \def\doverbatim#1@end verbatim{#1}
524496263Sobrien%
5245119256Skan% For Texinfo it's a lot easier than for LaTeX,
524696263Sobrien% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
5247117395Skan% we need not redefine '\', '{' and '}'.
524896263Sobrien%
524996263Sobrien% Inspired by LaTeX's verbatim command set [latex.ltx]
5250117395Skan%
525196263Sobrien\begingroup
525296263Sobrien  \catcode`\ =\active
5253117395Skan  \obeylines %
5254117395Skan  % ignore everything up to the first ^^M, that's the newline at the end
5255117395Skan  % of the @verbatim input line itself.  Otherwise we get an extra blank
5256117395Skan  % line in the output.
5257132718Skan  \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
5258132718Skan  % We really want {...\end verbatim} in the body of the macro, but
5259132718Skan  % without the active space; thus we have to use \xdef and \gobble.
526096263Sobrien\endgroup
526196263Sobrien%
5262132718Skan\envdef\verbatim{%
5263132718Skan    \setupverbatim\doverbatim
526496263Sobrien}
5265132718Skan\let\Everbatim = \afterenvbreak
526696263Sobrien
5267132718Skan
526896263Sobrien% @verbatiminclude FILE - insert text of file in verbatim environment.
526996263Sobrien%
5270132718Skan\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
527196263Sobrien%
527296263Sobrien\def\doverbatiminclude#1{%
5273132718Skan  {%
5274132718Skan    \makevalueexpandable
5275132718Skan    \setupverbatim
5276132718Skan    \input #1
5277132718Skan    \afterenvbreak
5278132718Skan  }%
527996263Sobrien}
528096263Sobrien
5281117395Skan% @copying ... @end copying.
5282169689Skan% Save the text away for @insertcopying later.
5283119256Skan%
5284117395Skan% We save the uninterpreted tokens, rather than creating a box.
5285117395Skan% Saving the text in a box would be much easier, but then all the
5286117395Skan% typesetting commands (@smallbook, font changes, etc.) have to be done
5287117395Skan% beforehand -- and a) we want @copying to be done first in the source
5288117395Skan% file; b) letting users define the frontmatter in as flexible order as
5289117395Skan% possible is very desirable.
5290119256Skan%
5291169689Skan\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
5292169689Skan\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
5293117395Skan%
5294169689Skan\def\insertcopying{%
5295169689Skan  \begingroup
5296169689Skan    \parindent = 0pt  % paragraph indentation looks wrong on title page
5297169689Skan    \scanexp\copyingtext
5298169689Skan  \endgroup
5299117395Skan}
5300117395Skan
530196263Sobrien\message{defuns,}
530296263Sobrien% @defun etc.
530396263Sobrien
530496263Sobrien\newskip\defbodyindent \defbodyindent=.4in
530596263Sobrien\newskip\defargsindent \defargsindent=50pt
530696263Sobrien\newskip\deflastargmargin \deflastargmargin=18pt
530796263Sobrien
5308132718Skan% Start the processing of @deffn:
5309132718Skan\def\startdefun{%
5310132718Skan  \ifnum\lastpenalty<10000
5311132718Skan    \medbreak
5312117395Skan  \else
5313132718Skan    % If there are two @def commands in a row, we'll have a \nobreak,
5314132718Skan    % which is there to keep the function description together with its
5315132718Skan    % header.  But if there's nothing but headers, we need to allow a
5316169689Skan    % break somewhere.  Check specifically for penalty 10002, inserted
5317169689Skan    % by \defargscommonending, instead of 10000, since the sectioning
5318169689Skan    % commands also insert a nobreak penalty, and we don't want to allow
5319169689Skan    % a break between a section heading and a defun.
5320169689Skan    % 
5321132718Skan    \ifnum\lastpenalty=10002 \penalty2000 \fi
5322132718Skan    %
5323132718Skan    % Similarly, after a section heading, do not allow a break.
5324132718Skan    % But do insert the glue.
5325132718Skan    \medskip  % preceded by discardable penalty, so not a breakpoint
5326117395Skan  \fi
5327117395Skan  %
5328117395Skan  \parindent=0in
5329117395Skan  \advance\leftskip by \defbodyindent
5330117395Skan  \exdentamount=\defbodyindent
533196263Sobrien}
533296263Sobrien
5333132718Skan\def\dodefunx#1{%
5334132718Skan  % First, check whether we are in the right environment:
5335132718Skan  \checkenv#1%
5336117395Skan  %
5337132718Skan  % As above, allow line break if we have multiple x headers in a row.
5338132718Skan  % It's not a great place, though.
5339132718Skan  \ifnum\lastpenalty=10002 \penalty3000 \fi
5340132718Skan  %
5341132718Skan  % And now, it's time to reuse the body of the original defun:
5342132718Skan  \expandafter\gobbledefun#1%
5343117395Skan}
5344132718Skan\def\gobbledefun#1\startdefun{}
534596263Sobrien
5346132718Skan% \printdefunline \deffnheader{text}
5347117395Skan%
5348132718Skan\def\printdefunline#1#2{%
5349132718Skan  \begingroup
5350132718Skan    % call \deffnheader:
5351132718Skan    #1#2 \endheader
5352132718Skan    % common ending:
5353132718Skan    \interlinepenalty = 10000
5354132718Skan    \advance\rightskip by 0pt plus 1fil
5355132718Skan    \endgraf
5356132718Skan    \nobreak\vskip -\parskip
5357132718Skan    \penalty 10002  % signal to \startdefun and \dodefunx
5358132718Skan    % Some of the @defun-type tags do not enable magic parentheses,
5359132718Skan    % rendering the following check redundant.  But we don't optimize.
5360132718Skan    \checkparencounts
5361132718Skan  \endgroup
5362117395Skan}
536396263Sobrien
5364132718Skan\def\Edefun{\endgraf\medbreak}
536596263Sobrien
5366132718Skan% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
5367132718Skan% the only thing remainnig is to define \deffnheader.
536896263Sobrien%
5369132718Skan\def\makedefun#1{%
5370132718Skan  \expandafter\let\csname E#1\endcsname = \Edefun
5371132718Skan  \edef\temp{\noexpand\domakedefun
5372132718Skan    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
5373132718Skan  \temp
5374117395Skan}
537596263Sobrien
5376132718Skan% \domakedefun \deffn \deffnx \deffnheader
5377119256Skan%
5378132718Skan% Define \deffn and \deffnx, without parameters.
5379132718Skan% \deffnheader has to be defined explicitly.
5380132718Skan%
5381132718Skan\def\domakedefun#1#2#3{%
5382132718Skan  \envdef#1{%
5383132718Skan    \startdefun
5384132718Skan    \parseargusing\activeparens{\printdefunline#3}%
5385132718Skan  }%
5386132718Skan  \def#2{\dodefunx#1}%
5387132718Skan  \def#3%
5388117395Skan}
538996263Sobrien
5390132718Skan%%% Untyped functions:
539196263Sobrien
5392132718Skan% @deffn category name args
5393132718Skan\makedefun{deffn}{\deffngeneral{}}
539496263Sobrien
5395132718Skan% @deffn category class name args
5396132718Skan\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
5397117395Skan
5398132718Skan% \defopon {category on}class name args
5399132718Skan\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
540096263Sobrien
5401132718Skan% \deffngeneral {subind}category name args
540296263Sobrien%
5403132718Skan\def\deffngeneral#1#2 #3 #4\endheader{%
5404169689Skan  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
5405132718Skan  \dosubind{fn}{\code{#3}}{#1}%
5406132718Skan  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
540796263Sobrien}
540896263Sobrien
5409132718Skan%%% Typed functions:
541096263Sobrien
5411132718Skan% @deftypefn category type name args
5412132718Skan\makedefun{deftypefn}{\deftypefngeneral{}}
541396263Sobrien
5414132718Skan% @deftypeop category class type name args
5415132718Skan\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
541696263Sobrien
5417132718Skan% \deftypeopon {category on}class type name args
5418132718Skan\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
541996263Sobrien
5420132718Skan% \deftypefngeneral {subind}category type name args
5421119256Skan%
5422132718Skan\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
5423132718Skan  \dosubind{fn}{\code{#4}}{#1}%
5424132718Skan  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
5425119256Skan}
542696263Sobrien
5427132718Skan%%% Typed variables:
542896263Sobrien
5429132718Skan% @deftypevr category type var args
5430132718Skan\makedefun{deftypevr}{\deftypecvgeneral{}}
543196263Sobrien
5432132718Skan% @deftypecv category class type var args
5433132718Skan\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
543496263Sobrien
5435132718Skan% \deftypecvof {category of}class type var args
5436132718Skan\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
543796263Sobrien
5438132718Skan% \deftypecvgeneral {subind}category type var args
5439132718Skan%
5440132718Skan\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
5441132718Skan  \dosubind{vr}{\code{#4}}{#1}%
5442132718Skan  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
544396263Sobrien}
544496263Sobrien
5445132718Skan%%% Untyped variables:
544696263Sobrien
5447132718Skan% @defvr category var args
5448132718Skan\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
544996263Sobrien
5450132718Skan% @defcv category class var args
5451132718Skan\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
545296263Sobrien
5453132718Skan% \defcvof {category of}class var args
5454132718Skan\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
545596263Sobrien
5456132718Skan%%% Type:
5457132718Skan% @deftp category name args
5458132718Skan\makedefun{deftp}#1 #2 #3\endheader{%
5459132718Skan  \doind{tp}{\code{#2}}%
5460132718Skan  \defname{#1}{}{#2}\defunargs{#3\unskip}%
546196263Sobrien}
546296263Sobrien
5463132718Skan% Remaining @defun-like shortcuts:
5464132718Skan\makedefun{defun}{\deffnheader{\putwordDeffunc} }
5465132718Skan\makedefun{defmac}{\deffnheader{\putwordDefmac} }
5466132718Skan\makedefun{defspec}{\deffnheader{\putwordDefspec} }
5467132718Skan\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
5468132718Skan\makedefun{defvar}{\defvrheader{\putwordDefvar} }
5469132718Skan\makedefun{defopt}{\defvrheader{\putwordDefopt} }
5470132718Skan\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
5471132718Skan\makedefun{defmethod}{\defopon\putwordMethodon}
5472132718Skan\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
5473132718Skan\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
5474132718Skan\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
547596263Sobrien
5476132718Skan% \defname, which formats the name of the @def (not the args).
5477132718Skan% #1 is the category, such as "Function".
5478132718Skan% #2 is the return type, if any.
5479132718Skan% #3 is the function name.
5480169689Skan%
5481132718Skan% We are followed by (but not passed) the arguments, if any.
5482132718Skan%
5483132718Skan\def\defname#1#2#3{%
5484132718Skan  % Get the values of \leftskip and \rightskip as they were outside the @def...
5485132718Skan  \advance\leftskip by -\defbodyindent
5486132718Skan  %
5487132718Skan  % How we'll format the type name.  Putting it in brackets helps
5488132718Skan  % distinguish it from the body text that may end up on the next line
5489132718Skan  % just below it.
5490132718Skan  \def\temp{#1}%
5491132718Skan  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
5492132718Skan  %
5493132718Skan  % Figure out line sizes for the paragraph shape.
5494132718Skan  % The first line needs space for \box0; but if \rightskip is nonzero,
5495132718Skan  % we need only space for the part of \box0 which exceeds it:
5496132718Skan  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
5497132718Skan  % The continuations:
5498132718Skan  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
5499132718Skan  % (plain.tex says that \dimen1 should be used only as global.)
5500132718Skan  \parshape 2 0in \dimen0 \defargsindent \dimen2
5501132718Skan  %
5502132718Skan  % Put the type name to the right margin.
5503132718Skan  \noindent
5504132718Skan  \hbox to 0pt{%
5505132718Skan    \hfil\box0 \kern-\hsize
5506132718Skan    % \hsize has to be shortened this way:
5507132718Skan    \kern\leftskip
5508132718Skan    % Intentionally do not respect \rightskip, since we need the space.
5509132718Skan  }%
5510132718Skan  %
5511132718Skan  % Allow all lines to be underfull without complaint:
5512132718Skan  \tolerance=10000 \hbadness=10000
5513132718Skan  \exdentamount=\defbodyindent
5514132718Skan  {%
5515132718Skan    % defun fonts. We use typewriter by default (used to be bold) because:
5516132718Skan    % . we're printing identifiers, they should be in tt in principle.
5517132718Skan    % . in languages with many accents, such as Czech or French, it's
5518132718Skan    %   common to leave accents off identifiers.  The result looks ok in
5519132718Skan    %   tt, but exceedingly strange in rm.
5520132718Skan    % . we don't want -- and --- to be treated as ligatures.
5521132718Skan    % . this still does not fix the ?` and !` ligatures, but so far no
5522132718Skan    %   one has made identifiers using them :).
5523132718Skan    \df \tt
5524132718Skan    \def\temp{#2}% return value type
5525132718Skan    \ifx\temp\empty\else \tclose{\temp} \fi
5526132718Skan    #3% output function name
5527132718Skan  }%
5528132718Skan  {\rm\enskip}% hskip 0.5 em of \tenrm
5529132718Skan  %
5530132718Skan  \boldbrax
5531132718Skan  % arguments will be output next, if any.
5532132718Skan}
553396263Sobrien
5534169689Skan% Print arguments in slanted roman (not ttsl), inconsistently with using
5535169689Skan% tt for the name.  This is because literal text is sometimes needed in
5536169689Skan% the argument list (groff manual), and ttsl and tt are not very
5537169689Skan% distinguishable.  Prevent hyphenation at `-' chars.
5538169689Skan%
5539132718Skan\def\defunargs#1{%
5540169689Skan  % use sl by default (not ttsl),
5541132718Skan  % tt for the names.
5542132718Skan  \df \sl \hyphenchar\font=0
5543169689Skan  %
5544132718Skan  % On the other hand, if an argument has two dashes (for instance), we
5545132718Skan  % want a way to get ttsl.  Let's try @var for that.
5546132718Skan  \let\var=\ttslanted
5547132718Skan  #1%
5548132718Skan  \sl\hyphenchar\font=45
5549132718Skan}
555096263Sobrien
5551132718Skan% We want ()&[] to print specially on the defun line.
5552132718Skan%
5553132718Skan\def\activeparens{%
5554132718Skan  \catcode`\(=\active \catcode`\)=\active
5555132718Skan  \catcode`\[=\active \catcode`\]=\active
5556132718Skan  \catcode`\&=\active
555796263Sobrien}
555896263Sobrien
5559132718Skan% Make control sequences which act like normal parenthesis chars.
5560132718Skan\let\lparen = ( \let\rparen = )
556196263Sobrien
5562132718Skan% Be sure that we always have a definition for `(', etc.  For example,
5563132718Skan% if the fn name has parens in it, \boldbrax will not be in effect yet,
5564132718Skan% so TeX would otherwise complain about undefined control sequence.
5565132718Skan{
5566132718Skan  \activeparens
5567132718Skan  \global\let(=\lparen \global\let)=\rparen
5568132718Skan  \global\let[=\lbrack \global\let]=\rbrack
5569132718Skan  \global\let& = \&
557096263Sobrien
5571132718Skan  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
5572132718Skan  \gdef\magicamp{\let&=\amprm}
557396263Sobrien}
557496263Sobrien
5575132718Skan\newcount\parencount
557696263Sobrien
5577132718Skan% If we encounter &foo, then turn on ()-hacking afterwards
5578132718Skan\newif\ifampseen
5579132718Skan\def\amprm#1 {\ampseentrue{\bf\&#1 }}
558096263Sobrien
5581132718Skan\def\parenfont{%
5582132718Skan  \ifampseen
5583132718Skan    % At the first level, print parens in roman,
5584132718Skan    % otherwise use the default font.
5585132718Skan    \ifnum \parencount=1 \rm \fi
5586132718Skan  \else
5587132718Skan    % The \sf parens (in \boldbrax) actually are a little bolder than
5588132718Skan    % the contained text.  This is especially needed for [ and ] .
5589132718Skan    \sf
5590132718Skan  \fi
559196263Sobrien}
5592132718Skan\def\infirstlevel#1{%
5593132718Skan  \ifampseen
5594132718Skan    \ifnum\parencount=1
5595132718Skan      #1%
5596132718Skan    \fi
5597132718Skan  \fi
559896263Sobrien}
5599132718Skan\def\bfafterword#1 {#1 \bf}
560096263Sobrien
5601132718Skan\def\opnr{%
5602132718Skan  \global\advance\parencount by 1
5603132718Skan  {\parenfont(}%
5604132718Skan  \infirstlevel \bfafterword
560596263Sobrien}
5606132718Skan\def\clnr{%
5607132718Skan  {\parenfont)}%
5608132718Skan  \infirstlevel \sl
5609132718Skan  \global\advance\parencount by -1
561096263Sobrien}
561196263Sobrien
5612132718Skan\newcount\brackcount
5613132718Skan\def\lbrb{%
5614132718Skan  \global\advance\brackcount by 1
5615132718Skan  {\bf[}%
561696263Sobrien}
5617132718Skan\def\rbrb{%
5618132718Skan  {\bf]}%
5619132718Skan  \global\advance\brackcount by -1
562096263Sobrien}
562196263Sobrien
5622132718Skan\def\checkparencounts{%
5623132718Skan  \ifnum\parencount=0 \else \badparencount \fi
5624132718Skan  \ifnum\brackcount=0 \else \badbrackcount \fi
562596263Sobrien}
5626132718Skan\def\badparencount{%
5627132718Skan  \errmessage{Unbalanced parentheses in @def}%
5628132718Skan  \global\parencount=0
562996263Sobrien}
5630132718Skan\def\badbrackcount{%
5631132718Skan  \errmessage{Unbalanced square braces in @def}%
5632132718Skan  \global\brackcount=0
5633119256Skan}
563496263Sobrien
563596263Sobrien
563696263Sobrien\message{macros,}
563796263Sobrien% @macro.
563896263Sobrien
563996263Sobrien% To do this right we need a feature of e-TeX, \scantokens,
564096263Sobrien% which we arrange to emulate with a temporary file in ordinary TeX.
564196263Sobrien\ifx\eTeXversion\undefined
5642132718Skan  \newwrite\macscribble
5643132718Skan  \def\scantokens#1{%
5644169689Skan    \toks0={#1}%
5645132718Skan    \immediate\openout\macscribble=\jobname.tmp
5646132718Skan    \immediate\write\macscribble{\the\toks0}%
5647132718Skan    \immediate\closeout\macscribble
5648132718Skan    \input \jobname.tmp
5649132718Skan  }
565096263Sobrien\fi
565196263Sobrien
5652132718Skan\def\scanmacro#1{%
5653132718Skan  \begingroup
5654132718Skan    \newlinechar`\^^M
5655132718Skan    \let\xeatspaces\eatspaces
5656132718Skan    % Undo catcode changes of \startcontents and \doprintindex
5657169689Skan    % When called from @insertcopying or (short)caption, we need active
5658169689Skan    % backslash to get it printed correctly.  Previously, we had
5659169689Skan    % \catcode`\\=\other instead.  We'll see whether a problem appears
5660169689Skan    % with macro expansion.				--kasal, 19aug04
5661169689Skan    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
5662132718Skan    % ... and \example
5663132718Skan    \spaceisspace
5664132718Skan    %
5665132718Skan    % Append \endinput to make sure that TeX does not see the ending newline.
5666132718Skan    %
5667132718Skan    % I've verified that it is necessary both for e-TeX and for ordinary TeX
5668132718Skan    %							--kasal, 29nov03
5669132718Skan    \scantokens{#1\endinput}%
5670132718Skan  \endgroup
5671132718Skan}
5672132718Skan
5673169689Skan\def\scanexp#1{%
5674169689Skan  \edef\temp{\noexpand\scanmacro{#1}}%
5675169689Skan  \temp
5676169689Skan}
5677169689Skan
567896263Sobrien\newcount\paramno   % Count of parameters
567996263Sobrien\newtoks\macname    % Macro name
568096263Sobrien\newif\ifrecursive  % Is it recursive?
568196263Sobrien\def\macrolist{}    % List of all defined macros in the form
568296263Sobrien                    % \do\macro1\do\macro2...
568396263Sobrien
568496263Sobrien% Utility routines.
5685169689Skan% This does \let #1 = #2, with \csnames; that is,
5686169689Skan%   \let \csname#1\endcsname = \csname#2\endcsname
5687169689Skan% (except of course we have to play expansion games).
5688169689Skan% 
568996263Sobrien\def\cslet#1#2{%
5690169689Skan  \expandafter\let
5691169689Skan  \csname#1\expandafter\endcsname
5692169689Skan  \csname#2\endcsname
5693169689Skan}
569496263Sobrien
569596263Sobrien% Trim leading and trailing spaces off a string.
569696263Sobrien% Concepts from aro-bend problem 15 (see CTAN).
569796263Sobrien{\catcode`\@=11
569896263Sobrien\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
569996263Sobrien\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
570096263Sobrien\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
570196263Sobrien\def\unbrace#1{#1}
570296263Sobrien\unbrace{\gdef\trim@@@ #1 } #2@{#1}
570396263Sobrien}
570496263Sobrien
570596263Sobrien% Trim a single trailing ^^M off a string.
5706119256Skan{\catcode`\^^M=\other \catcode`\Q=3%
570796263Sobrien\gdef\eatcr #1{\eatcra #1Q^^MQ}%
570896263Sobrien\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
570996263Sobrien\gdef\eatcrb#1Q#2Q{#1}%
571096263Sobrien}
571196263Sobrien
571296263Sobrien% Macro bodies are absorbed as an argument in a context where
571396263Sobrien% all characters are catcode 10, 11 or 12, except \ which is active
571496263Sobrien% (as in normal texinfo). It is necessary to change the definition of \.
571596263Sobrien
571696263Sobrien% It's necessary to have hard CRs when the macro is executed. This is
571796263Sobrien% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
571896263Sobrien% body, and then making it the \newlinechar in \scanmacro.
571996263Sobrien
5720169689Skan\def\scanctxt{%
5721169689Skan  \catcode`\"=\other
5722169689Skan  \catcode`\+=\other
5723169689Skan  \catcode`\<=\other
5724169689Skan  \catcode`\>=\other
5725169689Skan  \catcode`\@=\other
5726119256Skan  \catcode`\^=\other
5727119256Skan  \catcode`\_=\other
5728119256Skan  \catcode`\|=\other
5729169689Skan  \catcode`\~=\other
5730169689Skan}
5731169689Skan
5732169689Skan\def\scanargctxt{%
5733169689Skan  \scanctxt
5734169689Skan  \catcode`\\=\other
5735169689Skan  \catcode`\^^M=\other
5736169689Skan}
5737169689Skan
5738169689Skan\def\macrobodyctxt{%
5739169689Skan  \scanctxt
5740119256Skan  \catcode`\{=\other
5741119256Skan  \catcode`\}=\other
5742119256Skan  \catcode`\^^M=\other
5743169689Skan  \usembodybackslash
5744169689Skan}
574596263Sobrien
574696263Sobrien\def\macroargctxt{%
5747169689Skan  \scanctxt
5748169689Skan  \catcode`\\=\other
5749169689Skan}
575096263Sobrien
575196263Sobrien% \mbodybackslash is the definition of \ in @macro bodies.
575296263Sobrien% It maps \foo\ => \csname macarg.foo\endcsname => #N
575396263Sobrien% where N is the macro parameter number.
575496263Sobrien% We define \csname macarg.\endcsname to be \realbackslash, so
575596263Sobrien% \\ in macro replacement text gets you a backslash.
575696263Sobrien
575796263Sobrien{\catcode`@=0 @catcode`@\=@active
575896263Sobrien @gdef@usembodybackslash{@let\=@mbodybackslash}
575996263Sobrien @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
576096263Sobrien}
576196263Sobrien\expandafter\def\csname macarg.\endcsname{\realbackslash}
576296263Sobrien
576396263Sobrien\def\macro{\recursivefalse\parsearg\macroxxx}
576496263Sobrien\def\rmacro{\recursivetrue\parsearg\macroxxx}
576596263Sobrien
576696263Sobrien\def\macroxxx#1{%
576796263Sobrien  \getargs{#1}%           now \macname is the macname and \argl the arglist
576896263Sobrien  \ifx\argl\empty       % no arguments
576996263Sobrien     \paramno=0%
577096263Sobrien  \else
577196263Sobrien     \expandafter\parsemargdef \argl;%
577296263Sobrien  \fi
577396263Sobrien  \if1\csname ismacro.\the\macname\endcsname
577496263Sobrien     \message{Warning: redefining \the\macname}%
577596263Sobrien  \else
577696263Sobrien     \expandafter\ifx\csname \the\macname\endcsname \relax
5777117395Skan     \else \errmessage{Macro name \the\macname\space already defined}\fi
577896263Sobrien     \global\cslet{macsave.\the\macname}{\the\macname}%
577996263Sobrien     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
578096263Sobrien     % Add the macroname to \macrolist
578196263Sobrien     \toks0 = \expandafter{\macrolist\do}%
578296263Sobrien     \xdef\macrolist{\the\toks0
578396263Sobrien       \expandafter\noexpand\csname\the\macname\endcsname}%
578496263Sobrien  \fi
578596263Sobrien  \begingroup \macrobodyctxt
578696263Sobrien  \ifrecursive \expandafter\parsermacbody
578796263Sobrien  \else \expandafter\parsemacbody
578896263Sobrien  \fi}
578996263Sobrien
5790132718Skan\parseargdef\unmacro{%
579196263Sobrien  \if1\csname ismacro.#1\endcsname
579296263Sobrien    \global\cslet{#1}{macsave.#1}%
579396263Sobrien    \global\expandafter\let \csname ismacro.#1\endcsname=0%
5794119256Skan    % Remove the macro name from \macrolist:
579596263Sobrien    \begingroup
5796119256Skan      \expandafter\let\csname#1\endcsname \relax
5797119256Skan      \let\do\unmacrodo
5798119256Skan      \xdef\macrolist{\macrolist}%
579996263Sobrien    \endgroup
580096263Sobrien  \else
580196263Sobrien    \errmessage{Macro #1 not defined}%
580296263Sobrien  \fi
580396263Sobrien}
580496263Sobrien
5805119256Skan% Called by \do from \dounmacro on each macro.  The idea is to omit any
5806119256Skan% macro definitions that have been changed to \relax.
5807119256Skan%
5808119256Skan\def\unmacrodo#1{%
5809119256Skan  \ifx#1\relax
5810119256Skan    % remove this
5811119256Skan  \else
5812119256Skan    \noexpand\do \noexpand #1%
5813119256Skan  \fi
5814119256Skan}
5815119256Skan
581696263Sobrien% This makes use of the obscure feature that if the last token of a
581796263Sobrien% <parameter list> is #, then the preceding argument is delimited by
581896263Sobrien% an opening brace, and that opening brace is not consumed.
581996263Sobrien\def\getargs#1{\getargsxxx#1{}}
582096263Sobrien\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
582196263Sobrien\def\getmacname #1 #2\relax{\macname={#1}}
582296263Sobrien\def\getmacargs#1{\def\argl{#1}}
582396263Sobrien
582496263Sobrien% Parse the optional {params} list.  Set up \paramno and \paramlist
582596263Sobrien% so \defmacro knows what to do.  Define \macarg.blah for each blah
582696263Sobrien% in the params list, to be ##N where N is the position in that list.
582796263Sobrien% That gets used by \mbodybackslash (above).
582896263Sobrien
582996263Sobrien% We need to get `macro parameter char #' into several definitions.
583096263Sobrien% The technique used is stolen from LaTeX:  let \hash be something
583196263Sobrien% unexpandable, insert that wherever you need a #, and then redefine
583296263Sobrien% it to # just before using the token list produced.
583396263Sobrien%
583496263Sobrien% The same technique is used to protect \eatspaces till just before
583596263Sobrien% the macro is used.
583696263Sobrien
583796263Sobrien\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
583896263Sobrien        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
583996263Sobrien\def\parsemargdefxxx#1,{%
584096263Sobrien  \if#1;\let\next=\relax
584196263Sobrien  \else \let\next=\parsemargdefxxx
584296263Sobrien    \advance\paramno by 1%
584396263Sobrien    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
584496263Sobrien        {\xeatspaces{\hash\the\paramno}}%
584596263Sobrien    \edef\paramlist{\paramlist\hash\the\paramno,}%
584696263Sobrien  \fi\next}
584796263Sobrien
584896263Sobrien% These two commands read recursive and nonrecursive macro bodies.
584996263Sobrien% (They're different since rec and nonrec macros end differently.)
585096263Sobrien
585196263Sobrien\long\def\parsemacbody#1@end macro%
585296263Sobrien{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
585396263Sobrien\long\def\parsermacbody#1@end rmacro%
585496263Sobrien{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
585596263Sobrien
585696263Sobrien% This defines the macro itself. There are six cases: recursive and
585796263Sobrien% nonrecursive macros of zero, one, and many arguments.
585896263Sobrien% Much magic with \expandafter here.
585996263Sobrien% \xdef is used so that macro definitions will survive the file
586096263Sobrien% they're defined in; @include reads the file inside a group.
586196263Sobrien\def\defmacro{%
586296263Sobrien  \let\hash=##% convert placeholders to macro parameter chars
586396263Sobrien  \ifrecursive
586496263Sobrien    \ifcase\paramno
586596263Sobrien    % 0
586696263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
586796263Sobrien        \noexpand\scanmacro{\temp}}%
586896263Sobrien    \or % 1
586996263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
587096263Sobrien         \bgroup\noexpand\macroargctxt
587196263Sobrien         \noexpand\braceorline
587296263Sobrien         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
587396263Sobrien      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
587496263Sobrien         \egroup\noexpand\scanmacro{\temp}}%
587596263Sobrien    \else % many
587696263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
587796263Sobrien         \bgroup\noexpand\macroargctxt
587896263Sobrien         \noexpand\csname\the\macname xx\endcsname}%
587996263Sobrien      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
588096263Sobrien          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
588196263Sobrien      \expandafter\expandafter
588296263Sobrien      \expandafter\xdef
588396263Sobrien      \expandafter\expandafter
588496263Sobrien        \csname\the\macname xxx\endcsname
588596263Sobrien          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
588696263Sobrien    \fi
588796263Sobrien  \else
588896263Sobrien    \ifcase\paramno
588996263Sobrien    % 0
589096263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
589196263Sobrien        \noexpand\norecurse{\the\macname}%
589296263Sobrien        \noexpand\scanmacro{\temp}\egroup}%
589396263Sobrien    \or % 1
589496263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
589596263Sobrien         \bgroup\noexpand\macroargctxt
589696263Sobrien         \noexpand\braceorline
589796263Sobrien         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
589896263Sobrien      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
589996263Sobrien        \egroup
590096263Sobrien        \noexpand\norecurse{\the\macname}%
590196263Sobrien        \noexpand\scanmacro{\temp}\egroup}%
590296263Sobrien    \else % many
590396263Sobrien      \expandafter\xdef\csname\the\macname\endcsname{%
590496263Sobrien         \bgroup\noexpand\macroargctxt
590596263Sobrien         \expandafter\noexpand\csname\the\macname xx\endcsname}%
590696263Sobrien      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
590796263Sobrien          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
590896263Sobrien      \expandafter\expandafter
590996263Sobrien      \expandafter\xdef
591096263Sobrien      \expandafter\expandafter
591196263Sobrien      \csname\the\macname xxx\endcsname
591296263Sobrien      \paramlist{%
591396263Sobrien          \egroup
591496263Sobrien          \noexpand\norecurse{\the\macname}%
591596263Sobrien          \noexpand\scanmacro{\temp}\egroup}%
591696263Sobrien    \fi
591796263Sobrien  \fi}
591896263Sobrien
591996263Sobrien\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
592096263Sobrien
592196263Sobrien% \braceorline decides whether the next nonwhitespace character is a
592296263Sobrien% {.  If so it reads up to the closing }, if not, it reads the whole
592396263Sobrien% line.  Whatever was read is then fed to the next control sequence
592496263Sobrien% as an argument (by \parsebrace or \parsearg)
592596263Sobrien\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
592696263Sobrien\def\braceorlinexxx{%
592796263Sobrien  \ifx\nchar\bgroup\else
592896263Sobrien    \expandafter\parsearg
592996263Sobrien  \fi \next}
593096263Sobrien
5931169689Skan% We want to disable all macros during \shipout so that they are not
593296263Sobrien% expanded by \write.
593396263Sobrien\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
593496263Sobrien  \edef\next{\macrolist}\expandafter\endgroup\next}
593596263Sobrien
5936169689Skan% For \indexnofonts, we need to get rid of all macros, leaving only the
5937169689Skan% arguments (if present).  Of course this is not nearly correct, but it
5938169689Skan% is the best we can do for now.  makeinfo does not expand macros in the
5939169689Skan% argument to @deffn, which ends up writing an index entry, and texindex
5940169689Skan% isn't prepared for an index sort entry that starts with \.
5941169689Skan% 
5942169689Skan% Since macro invocations are followed by braces, we can just redefine them
5943169689Skan% to take a single TeX argument.  The case of a macro invocation that
5944169689Skan% goes to end-of-line is not handled.
5945169689Skan% 
5946169689Skan\def\emptyusermacros{\begingroup
5947169689Skan  \def\do##1{\let\noexpand##1=\noexpand\asis}%
5948169689Skan  \edef\next{\macrolist}\expandafter\endgroup\next}
594996263Sobrien
5950169689Skan
595196263Sobrien% @alias.
595296263Sobrien% We need some trickery to remove the optional spaces around the equal
595396263Sobrien% sign.  Just make them active and then expand them all to nothing.
5954132718Skan\def\alias{\parseargusing\obeyspaces\aliasxxx}
595596263Sobrien\def\aliasxxx #1{\aliasyyy#1\relax}
5956132718Skan\def\aliasyyy #1=#2\relax{%
5957132718Skan  {%
5958132718Skan    \expandafter\let\obeyedspace=\empty
5959132718Skan    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
5960132718Skan  }%
5961132718Skan  \next
5962132718Skan}
596396263Sobrien
596496263Sobrien
596596263Sobrien\message{cross references,}
596696263Sobrien
596796263Sobrien\newwrite\auxfile
596896263Sobrien
596996263Sobrien\newif\ifhavexrefs    % True if xref values are known.
597096263Sobrien\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
597196263Sobrien
597296263Sobrien% @inforef is relatively simple.
597396263Sobrien\def\inforef #1{\inforefzzz #1,,,,**}
597496263Sobrien\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
597596263Sobrien  node \samp{\ignorespaces#1{}}}
597696263Sobrien
5977132718Skan% @node's only job in TeX is to define \lastnode, which is used in
5978169689Skan% cross-references.  The @node line might or might not have commas, and
5979169689Skan% might or might not have spaces before the first comma, like:
5980169689Skan% @node foo , bar , ...
5981169689Skan% We don't want such trailing spaces in the node name.
5982169689Skan%
5983169689Skan\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
5984169689Skan%
5985169689Skan% also remove a trailing comma, in case of something like this:
5986169689Skan% @node Help-Cross,  ,  , Cross-refs
5987169689Skan\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
5988169689Skan\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
5989169689Skan
599096263Sobrien\let\nwnode=\node
5991132718Skan\let\lastnode=\empty
599296263Sobrien
5993132718Skan% Write a cross-reference definition for the current node.  #1 is the
5994132718Skan% type (Ynumbered, Yappendix, Ynothing).
5995169689Skan%
5996132718Skan\def\donoderef#1{%
5997132718Skan  \ifx\lastnode\empty\else
5998132718Skan    \setref{\lastnode}{#1}%
5999132718Skan    \global\let\lastnode=\empty
600096263Sobrien  \fi
600196263Sobrien}
600296263Sobrien
600396263Sobrien% @anchor{NAME} -- define xref target at arbitrary point.
600496263Sobrien%
600596263Sobrien\newcount\savesfregister
6006132718Skan%
6007132718Skan\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
6008132718Skan\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
6009132718Skan\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
601096263Sobrien
6011119256Skan% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
6012132718Skan% anchor), which consists of three parts:
6013169689Skan% 1) NAME-title - the current sectioning name taken from \thissection,
6014169689Skan%                 or the anchor name.
6015169689Skan% 2) NAME-snt   - section number and type, passed as the SNT arg, or
6016169689Skan%                 empty for anchors.
6017132718Skan% 3) NAME-pg    - the page number.
601896263Sobrien%
6019169689Skan% This is called from \donoderef, \anchor, and \dofloat.  In the case of
6020169689Skan% floats, there is an additional part, which is not written here:
6021169689Skan% 4) NAME-lof   - the text as it should appear in a @listoffloats.
6022119256Skan%
6023132718Skan\def\setref#1#2{%
602496263Sobrien  \pdfmkdest{#1}%
6025132718Skan  \iflinks
6026132718Skan    {%
6027169689Skan      \atdummies  % preserve commands, but don't expand them
6028132718Skan      \turnoffactive
6029132718Skan      \edef\writexrdef##1##2{%
6030132718Skan	\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
6031132718Skan	  ##1}{##2}}% these are parameters of \writexrdef
6032132718Skan      }%
6033132718Skan      \toks0 = \expandafter{\thissection}%
6034132718Skan      \immediate \writexrdef{title}{\the\toks0 }%
6035132718Skan      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
6036132718Skan      \writexrdef{pg}{\folio}% will be written later, during \shipout
6037132718Skan    }%
6038132718Skan  \fi
6039132718Skan}
604096263Sobrien
604196263Sobrien% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
604296263Sobrien% the node name, #2 the name of the Info cross-reference, #3 the printed
604396263Sobrien% node name, #4 the name of the Info file, #5 the name of the printed
604496263Sobrien% manual.  All but the node name can be omitted.
604596263Sobrien%
604696263Sobrien\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
604796263Sobrien\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
604896263Sobrien\def\ref#1{\xrefX[#1,,,,,,,]}
604996263Sobrien\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
605096263Sobrien  \unsepspaces
605196263Sobrien  \def\printedmanual{\ignorespaces #5}%
6052132718Skan  \def\printedrefname{\ignorespaces #3}%
6053132718Skan  \setbox1=\hbox{\printedmanual\unskip}%
6054132718Skan  \setbox0=\hbox{\printedrefname\unskip}%
605596263Sobrien  \ifdim \wd0 = 0pt
605696263Sobrien    % No printed node name was explicitly given.
605796263Sobrien    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
605896263Sobrien      % Use the node name inside the square brackets.
6059132718Skan      \def\printedrefname{\ignorespaces #1}%
606096263Sobrien    \else
606196263Sobrien      % Use the actual chapter/section title appear inside
606296263Sobrien      % the square brackets.  Use the real section title if we have it.
606396263Sobrien      \ifdim \wd1 > 0pt
606496263Sobrien        % It is in another manual, so we don't have it.
6065132718Skan        \def\printedrefname{\ignorespaces #1}%
606696263Sobrien      \else
606796263Sobrien        \ifhavexrefs
606896263Sobrien          % We know the real title if we have the xref values.
6069132718Skan          \def\printedrefname{\refx{#1-title}{}}%
607096263Sobrien        \else
607196263Sobrien          % Otherwise just copy the Info node name.
6072132718Skan          \def\printedrefname{\ignorespaces #1}%
607396263Sobrien        \fi%
607496263Sobrien      \fi
607596263Sobrien    \fi
607696263Sobrien  \fi
607796263Sobrien  %
6078132718Skan  % Make link in pdf output.
607996263Sobrien  \ifpdf
608096263Sobrien    \leavevmode
608196263Sobrien    \getfilename{#4}%
6082169689Skan    {\turnoffactive
6083169689Skan     % See comments at \activebackslashdouble.
6084169689Skan     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
6085169689Skan      \backslashparens\pdfxrefdest}%
6086169689Skan     %
608796263Sobrien     \ifnum\filenamelength>0
608896263Sobrien       \startlink attr{/Border [0 0 0]}%
6089169689Skan         goto file{\the\filename.pdf} name{\pdfxrefdest}%
609096263Sobrien     \else
609196263Sobrien       \startlink attr{/Border [0 0 0]}%
6092169689Skan         goto name{\pdfmkpgn{\pdfxrefdest}}%
609396263Sobrien     \fi
609496263Sobrien    }%
609596263Sobrien    \linkcolor
609696263Sobrien  \fi
609796263Sobrien  %
6098132718Skan  % Float references are printed completely differently: "Figure 1.2"
6099132718Skan  % instead of "[somenode], p.3".  We distinguish them by the
6100132718Skan  % LABEL-title being set to a magic string.
6101132718Skan  {%
6102132718Skan    % Have to otherify everything special to allow the \csname to
6103132718Skan    % include an _ in the xref name, etc.
6104132718Skan    \indexnofonts
6105132718Skan    \turnoffactive
6106132718Skan    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
6107169689Skan      \csname XR#1-title\endcsname
6108132718Skan  }%
6109169689Skan  \iffloat\Xthisreftitle
6110132718Skan    % If the user specified the print name (third arg) to the ref,
6111132718Skan    % print it instead of our usual "Figure 1.2".
6112132718Skan    \ifdim\wd0 = 0pt
6113132718Skan      \refx{#1-snt}%
6114132718Skan    \else
6115132718Skan      \printedrefname
6116132718Skan    \fi
6117132718Skan    %
6118132718Skan    % if the user also gave the printed manual name (fifth arg), append
6119169689Skan    % "in MANUALNAME".
6120132718Skan    \ifdim \wd1 > 0pt
6121132718Skan      \space \putwordin{} \cite{\printedmanual}%
6122132718Skan    \fi
612396263Sobrien  \else
6124132718Skan    % node/anchor (non-float) references.
6125169689Skan    %
6126132718Skan    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
6127132718Skan    % insert empty discretionaries after hyphens, which means that it will
6128132718Skan    % not find a line break at a hyphen in a node names.  Since some manuals
6129132718Skan    % are best written with fairly long node names, containing hyphens, this
6130132718Skan    % is a loss.  Therefore, we give the text of the node name again, so it
6131132718Skan    % is as if TeX is seeing it for the first time.
6132132718Skan    \ifdim \wd1 > 0pt
6133132718Skan      \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
6134132718Skan    \else
6135132718Skan      % _ (for example) has to be the character _ for the purposes of the
6136132718Skan      % control sequence corresponding to the node, but it has to expand
6137132718Skan      % into the usual \leavevmode...\vrule stuff for purposes of
6138132718Skan      % printing. So we \turnoffactive for the \refx-snt, back on for the
6139132718Skan      % printing, back off for the \refx-pg.
6140169689Skan      {\turnoffactive
6141132718Skan       % Only output a following space if the -snt ref is nonempty; for
6142132718Skan       % @unnumbered and @anchor, it won't be.
6143132718Skan       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
6144132718Skan       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
6145132718Skan      }%
6146132718Skan      % output the `[mynode]' via a macro so it can be overridden.
6147132718Skan      \xrefprintnodename\printedrefname
6148132718Skan      %
6149132718Skan      % But we always want a comma and a space:
6150132718Skan      ,\space
6151132718Skan      %
6152132718Skan      % output the `page 3'.
6153169689Skan      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
6154132718Skan    \fi
615596263Sobrien  \fi
615696263Sobrien  \endlink
615796263Sobrien\endgroup}
615896263Sobrien
6159119256Skan% This macro is called from \xrefX for the `[nodename]' part of xref
6160119256Skan% output.  It's a separate macro only so it can be changed more easily,
6161132718Skan% since square brackets don't work well in some documents.  Particularly
6162119256Skan% one that Bob is working on :).
6163119256Skan%
6164119256Skan\def\xrefprintnodename#1{[#1]}
616596263Sobrien
6166132718Skan% Things referred to by \setref.
6167119256Skan%
616896263Sobrien\def\Ynothing{}
6169132718Skan\def\Yomitfromtoc{}
6170132718Skan\def\Ynumbered{%
6171119256Skan  \ifnum\secno=0
6172119256Skan    \putwordChapter@tie \the\chapno
6173119256Skan  \else \ifnum\subsecno=0
6174119256Skan    \putwordSection@tie \the\chapno.\the\secno
6175119256Skan  \else \ifnum\subsubsecno=0
6176119256Skan    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
6177119256Skan  \else
6178119256Skan    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
6179119256Skan  \fi\fi\fi
6180119256Skan}
6181132718Skan\def\Yappendix{%
6182119256Skan  \ifnum\secno=0
6183119256Skan     \putwordAppendix@tie @char\the\appendixno{}%
6184119256Skan  \else \ifnum\subsecno=0
6185119256Skan     \putwordSection@tie @char\the\appendixno.\the\secno
6186119256Skan  \else \ifnum\subsubsecno=0
6187119256Skan    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
6188119256Skan  \else
6189119256Skan    \putwordSection@tie
6190119256Skan      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
6191119256Skan  \fi\fi\fi
6192119256Skan}
619396263Sobrien
619496263Sobrien% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
619596263Sobrien% If its value is nonempty, SUFFIX is output afterward.
6196119256Skan%
619796263Sobrien\def\refx#1#2{%
6198119256Skan  {%
6199119256Skan    \indexnofonts
6200119256Skan    \otherbackslash
6201119256Skan    \expandafter\global\expandafter\let\expandafter\thisrefX
6202169689Skan      \csname XR#1\endcsname
6203119256Skan  }%
6204119256Skan  \ifx\thisrefX\relax
620596263Sobrien    % If not defined, say something at least.
620696263Sobrien    \angleleft un\-de\-fined\angleright
620796263Sobrien    \iflinks
620896263Sobrien      \ifhavexrefs
620996263Sobrien        \message{\linenumber Undefined cross reference `#1'.}%
621096263Sobrien      \else
621196263Sobrien        \ifwarnedxrefs\else
621296263Sobrien          \global\warnedxrefstrue
621396263Sobrien          \message{Cross reference values unknown; you must run TeX again.}%
621496263Sobrien        \fi
621596263Sobrien      \fi
621696263Sobrien    \fi
621796263Sobrien  \else
621896263Sobrien    % It's defined, so just use it.
6219119256Skan    \thisrefX
622096263Sobrien  \fi
622196263Sobrien  #2% Output the suffix in any case.
622296263Sobrien}
622396263Sobrien
6224169689Skan% This is the macro invoked by entries in the aux file.  Usually it's
6225169689Skan% just a \def (we prepend XR to the control sequence name to avoid
6226169689Skan% collisions).  But if this is a float type, we have more work to do.
622796263Sobrien%
6228169689Skan\def\xrdef#1#2{%
6229169689Skan  \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
6230169689Skan  %
6231169689Skan  % Was that xref control sequence that we just defined for a float?
6232169689Skan  \expandafter\iffloat\csname XR#1\endcsname
6233169689Skan    % it was a float, and we have the (safe) float type in \iffloattype.
6234169689Skan    \expandafter\let\expandafter\floatlist
6235169689Skan      \csname floatlist\iffloattype\endcsname
6236169689Skan    %
6237169689Skan    % Is this the first time we've seen this float type?
6238169689Skan    \expandafter\ifx\floatlist\relax
6239169689Skan      \toks0 = {\do}% yes, so just \do
6240169689Skan    \else
6241169689Skan      % had it before, so preserve previous elements in list.
6242169689Skan      \toks0 = \expandafter{\floatlist\do}%
6243169689Skan    \fi
6244169689Skan    %
6245169689Skan    % Remember this xref in the control sequence \floatlistFLOATTYPE,
6246169689Skan    % for later use in \listoffloats.
6247169689Skan    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
6248169689Skan  \fi
6249169689Skan}
625096263Sobrien
625196263Sobrien% Read the last existing aux file, if any.  No error if none exists.
6252169689Skan%
6253132718Skan\def\tryauxfile{%
6254132718Skan  \openin 1 \jobname.aux
6255132718Skan  \ifeof 1 \else
6256169689Skan    \readdatafile{aux}%
6257132718Skan    \global\havexrefstrue
6258132718Skan  \fi
6259132718Skan  \closein 1
6260132718Skan}
6261132718Skan
6262169689Skan\def\setupdatafile{%
626396263Sobrien  \catcode`\^^@=\other
626496263Sobrien  \catcode`\^^A=\other
626596263Sobrien  \catcode`\^^B=\other
626696263Sobrien  \catcode`\^^C=\other
626796263Sobrien  \catcode`\^^D=\other
626896263Sobrien  \catcode`\^^E=\other
626996263Sobrien  \catcode`\^^F=\other
627096263Sobrien  \catcode`\^^G=\other
627196263Sobrien  \catcode`\^^H=\other
627296263Sobrien  \catcode`\^^K=\other
627396263Sobrien  \catcode`\^^L=\other
627496263Sobrien  \catcode`\^^N=\other
627596263Sobrien  \catcode`\^^P=\other
627696263Sobrien  \catcode`\^^Q=\other
627796263Sobrien  \catcode`\^^R=\other
627896263Sobrien  \catcode`\^^S=\other
627996263Sobrien  \catcode`\^^T=\other
628096263Sobrien  \catcode`\^^U=\other
628196263Sobrien  \catcode`\^^V=\other
628296263Sobrien  \catcode`\^^W=\other
628396263Sobrien  \catcode`\^^X=\other
628496263Sobrien  \catcode`\^^Z=\other
628596263Sobrien  \catcode`\^^[=\other
628696263Sobrien  \catcode`\^^\=\other
628796263Sobrien  \catcode`\^^]=\other
628896263Sobrien  \catcode`\^^^=\other
628996263Sobrien  \catcode`\^^_=\other
6290119256Skan  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
629196263Sobrien  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
629296263Sobrien  % supported in the main text, it doesn't seem desirable.  Furthermore,
629396263Sobrien  % that is not enough: for node names that actually contain a ^
629496263Sobrien  % character, we would end up writing a line like this: 'xrdef {'hat
629596263Sobrien  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
629696263Sobrien  % argument, and \hat is not an expandable control sequence.  It could
629796263Sobrien  % all be worked out, but why?  Either we support ^^ or we don't.
629896263Sobrien  %
629996263Sobrien  % The other change necessary for this was to define \auxhat:
630096263Sobrien  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
630196263Sobrien  % and then to call \auxhat in \setq.
630296263Sobrien  %
6303119256Skan  \catcode`\^=\other
6304119256Skan  %
6305119256Skan  % Special characters.  Should be turned off anyway, but...
630696263Sobrien  \catcode`\~=\other
630796263Sobrien  \catcode`\[=\other
630896263Sobrien  \catcode`\]=\other
630996263Sobrien  \catcode`\"=\other
631096263Sobrien  \catcode`\_=\other
631196263Sobrien  \catcode`\|=\other
631296263Sobrien  \catcode`\<=\other
631396263Sobrien  \catcode`\>=\other
631496263Sobrien  \catcode`\$=\other
631596263Sobrien  \catcode`\#=\other
631696263Sobrien  \catcode`\&=\other
6317119256Skan  \catcode`\%=\other
631896263Sobrien  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
6319119256Skan  %
6320169689Skan  % This is to support \ in node names and titles, since the \
6321169689Skan  % characters end up in a \csname.  It's easier than
6322169689Skan  % leaving it active and making its active definition an actual \
6323169689Skan  % character.  What I don't understand is why it works in the *value*
6324169689Skan  % of the xrdef.  Seems like it should be a catcode12 \, and that
6325169689Skan  % should not typeset properly.  But it works, so I'm moving on for
6326169689Skan  % now.  --karl, 15jan04.
6327169689Skan  \catcode`\\=\other
6328169689Skan  %
6329169689Skan  % Make the characters 128-255 be printing characters.
633096263Sobrien  {%
6331169689Skan    \count1=128
633296263Sobrien    \def\loop{%
6333169689Skan      \catcode\count1=\other
6334169689Skan      \advance\count1 by 1
6335169689Skan      \ifnum \count1<256 \loop \fi
633696263Sobrien    }%
633796263Sobrien  }%
6338119256Skan  %
6339169689Skan  % @ is our escape character in .aux files, and we need braces.
634096263Sobrien  \catcode`\{=1
634196263Sobrien  \catcode`\}=2
6342119256Skan  \catcode`\@=0
6343169689Skan}
6344169689Skan
6345169689Skan\def\readdatafile#1{%
6346169689Skan\begingroup
6347169689Skan  \setupdatafile
6348169689Skan  \input\jobname.#1
634996263Sobrien\endgroup}
635096263Sobrien
6351132718Skan\message{insertions,}
6352132718Skan% including footnotes.
635396263Sobrien
635496263Sobrien\newcount \footnoteno
635596263Sobrien
635696263Sobrien% The trailing space in the following definition for supereject is
635796263Sobrien% vital for proper filling; pages come out unaligned when you do a
635896263Sobrien% pagealignmacro call if that space before the closing brace is
635996263Sobrien% removed. (Generally, numeric constants should always be followed by a
636096263Sobrien% space to prevent strange expansion errors.)
636196263Sobrien\def\supereject{\par\penalty -20000\footnoteno =0 }
636296263Sobrien
636396263Sobrien% @footnotestyle is meaningful for info output only.
636496263Sobrien\let\footnotestyle=\comment
636596263Sobrien
636696263Sobrien{\catcode `\@=11
636796263Sobrien%
636896263Sobrien% Auto-number footnotes.  Otherwise like plain.
636996263Sobrien\gdef\footnote{%
6370119256Skan  \let\indent=\ptexindent
6371132718Skan  \let\noindent=\ptexnoindent
637296263Sobrien  \global\advance\footnoteno by \@ne
637396263Sobrien  \edef\thisfootno{$^{\the\footnoteno}$}%
637496263Sobrien  %
637596263Sobrien  % In case the footnote comes at the end of a sentence, preserve the
637696263Sobrien  % extra spacing after we do the footnote number.
637796263Sobrien  \let\@sf\empty
6378119256Skan  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
637996263Sobrien  %
638096263Sobrien  % Remove inadvertent blank space before typesetting the footnote number.
638196263Sobrien  \unskip
638296263Sobrien  \thisfootno\@sf
6383119256Skan  \dofootnote
638496263Sobrien}%
638596263Sobrien
638696263Sobrien% Don't bother with the trickery in plain.tex to not require the
638796263Sobrien% footnote text as a parameter.  Our footnotes don't need to be so general.
638896263Sobrien%
6389132718Skan% Oh yes, they do; otherwise, @ifset (and anything else that uses
6390132718Skan% \parseargline) fails inside footnotes because the tokens are fixed when
639196263Sobrien% the footnote is read.  --karl, 16nov96.
639296263Sobrien%
6393119256Skan\gdef\dofootnote{%
6394132718Skan  \insert\footins\bgroup
639596263Sobrien  % We want to typeset this text as a normal paragraph, even if the
639696263Sobrien  % footnote reference occurs in (for example) a display environment.
639796263Sobrien  % So reset some parameters.
6398119256Skan  \hsize=\pagewidth
639996263Sobrien  \interlinepenalty\interfootnotelinepenalty
640096263Sobrien  \splittopskip\ht\strutbox % top baseline for broken footnotes
640196263Sobrien  \splitmaxdepth\dp\strutbox
640296263Sobrien  \floatingpenalty\@MM
640396263Sobrien  \leftskip\z@skip
640496263Sobrien  \rightskip\z@skip
640596263Sobrien  \spaceskip\z@skip
640696263Sobrien  \xspaceskip\z@skip
640796263Sobrien  \parindent\defaultparindent
640896263Sobrien  %
640996263Sobrien  \smallfonts \rm
641096263Sobrien  %
641196263Sobrien  % Because we use hanging indentation in footnotes, a @noindent appears
641296263Sobrien  % to exdent this text, so make it be a no-op.  makeinfo does not use
641396263Sobrien  % hanging indentation so @noindent can still be needed within footnote
641496263Sobrien  % text after an @example or the like (not that this is good style).
641596263Sobrien  \let\noindent = \relax
641696263Sobrien  %
641796263Sobrien  % Hang the footnote text off the number.  Use \everypar in case the
641896263Sobrien  % footnote extends for more than one paragraph.
641996263Sobrien  \everypar = {\hang}%
642096263Sobrien  \textindent{\thisfootno}%
642196263Sobrien  %
642296263Sobrien  % Don't crash into the line above the footnote text.  Since this
642396263Sobrien  % expands into a box, it must come within the paragraph, lest it
642496263Sobrien  % provide a place where TeX can split the footnote.
642596263Sobrien  \footstrut
642696263Sobrien  \futurelet\next\fo@t
642796263Sobrien}
642896263Sobrien}%end \catcode `\@=11
642996263Sobrien
6430132718Skan% In case a @footnote appears in a vbox, save the footnote text and create
6431132718Skan% the real \insert just after the vbox finished.  Otherwise, the insertion
6432132718Skan% would be lost.
6433132718Skan% Similarily, if a @footnote appears inside an alignment, save the footnote
6434132718Skan% text to a box and make the \insert when a row of the table is finished.
6435132718Skan% And the same can be done for other insert classes.  --kasal, 16nov03.
6436132718Skan
6437132718Skan% Replace the \insert primitive by a cheating macro.
6438132718Skan% Deeper inside, just make sure that the saved insertions are not spilled
6439132718Skan% out prematurely.
644096263Sobrien%
6441132718Skan\def\startsavinginserts{%
6442132718Skan  \ifx \insert\ptexinsert
6443132718Skan    \let\insert\saveinsert
6444132718Skan  \else
6445132718Skan    \let\checkinserts\relax
6446132718Skan  \fi
644796263Sobrien}
644896263Sobrien
6449169689Skan% This \insert replacement works for both \insert\footins{foo} and
6450169689Skan% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
645196263Sobrien%
6452132718Skan\def\saveinsert#1{%
6453132718Skan  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
6454132718Skan  \afterassignment\next
6455132718Skan  % swallow the left brace
6456132718Skan  \let\temp =
6457132718Skan}
6458132718Skan\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
6459132718Skan\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
646096263Sobrien
6461132718Skan\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
6462132718Skan
6463132718Skan\def\placesaveins#1{%
6464132718Skan  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
6465132718Skan    {\box#1}%
6466132718Skan}
6467132718Skan
6468132718Skan% eat @SAVE -- beware, all of them have catcode \other:
6469132718Skan{
6470132718Skan  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
6471132718Skan  \gdef\gobblesave @SAVE{}
6472132718Skan}
6473132718Skan
6474132718Skan% initialization:
6475132718Skan\def\newsaveins #1{%
6476132718Skan  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
6477132718Skan  \next
6478132718Skan}
6479132718Skan\def\newsaveinsX #1{%
6480132718Skan  \csname newbox\endcsname #1%
6481132718Skan  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
6482132718Skan    \checksaveins #1}%
6483132718Skan}
6484132718Skan
6485132718Skan% initialize:
6486132718Skan\let\checkinserts\empty
6487132718Skan\newsaveins\footins
6488132718Skan\newsaveins\margin
6489132718Skan
6490132718Skan
649196263Sobrien% @image.  We use the macros from epsf.tex to support this.
649296263Sobrien% If epsf.tex is not installed and @image is used, we complain.
649396263Sobrien%
649496263Sobrien% Check for and read epsf.tex up front.  If we read it only at @image
649596263Sobrien% time, we might be inside a group, and then its definitions would get
649696263Sobrien% undone and the next image would fail.
649796263Sobrien\openin 1 = epsf.tex
649896263Sobrien\ifeof 1 \else
6499119256Skan  % Do not bother showing banner with epsf.tex v2.7k (available in
6500119256Skan  % doc/epsf.tex and on ctan).
650196263Sobrien  \def\epsfannounce{\toks0 = }%
650296263Sobrien  \input epsf.tex
650396263Sobrien\fi
6504132718Skan\closein 1
650596263Sobrien%
650696263Sobrien% We will only complain once about lack of epsf.tex.
650796263Sobrien\newif\ifwarnednoepsf
650896263Sobrien\newhelp\noepsfhelp{epsf.tex must be installed for images to
650996263Sobrien  work.  It is also included in the Texinfo distribution, or you can get
651096263Sobrien  it from ftp://tug.org/tex/epsf.tex.}
651196263Sobrien%
651296263Sobrien\def\image#1{%
651396263Sobrien  \ifx\epsfbox\undefined
651496263Sobrien    \ifwarnednoepsf \else
651596263Sobrien      \errhelp = \noepsfhelp
651696263Sobrien      \errmessage{epsf.tex not found, images will be ignored}%
651796263Sobrien      \global\warnednoepsftrue
651896263Sobrien    \fi
651996263Sobrien  \else
652096263Sobrien    \imagexxx #1,,,,,\finish
652196263Sobrien  \fi
652296263Sobrien}
652396263Sobrien%
652496263Sobrien% Arguments to @image:
652596263Sobrien% #1 is (mandatory) image filename; we tack on .eps extension.
652696263Sobrien% #2 is (optional) width, #3 is (optional) height.
652796263Sobrien% #4 is (ignored optional) html alt text.
652896263Sobrien% #5 is (ignored optional) extension.
652996263Sobrien% #6 is just the usual extra ignored arg for parsing this stuff.
653096263Sobrien\newif\ifimagevmode
653196263Sobrien\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
653296263Sobrien  \catcode`\^^M = 5     % in case we're inside an example
653396263Sobrien  \normalturnoffactive  % allow _ et al. in names
653496263Sobrien  % If the image is by itself, center it.
653596263Sobrien  \ifvmode
653696263Sobrien    \imagevmodetrue
653796263Sobrien    \nobreak\bigskip
653896263Sobrien    % Usually we'll have text after the image which will insert
653996263Sobrien    % \parskip glue, so insert it here too to equalize the space
6540119256Skan    % above and below.
654196263Sobrien    \nobreak\vskip\parskip
654296263Sobrien    \nobreak
654396263Sobrien    \line\bgroup\hss
654496263Sobrien  \fi
654596263Sobrien  %
654696263Sobrien  % Output the image.
654796263Sobrien  \ifpdf
654896263Sobrien    \dopdfimage{#1}{#2}{#3}%
654996263Sobrien  \else
655096263Sobrien    % \epsfbox itself resets \epsf?size at each figure.
655196263Sobrien    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
655296263Sobrien    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
655396263Sobrien    \epsfbox{#1.eps}%
655496263Sobrien  \fi
655596263Sobrien  %
655696263Sobrien  \ifimagevmode \hss \egroup \bigbreak \fi  % space after the image
655796263Sobrien\endgroup}
655896263Sobrien
655996263Sobrien
6560169689Skan% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
6561169689Skan% etc.  We don't actually implement floating yet, we always include the
6562169689Skan% float "here".  But it seemed the best name for the future.
6563169689Skan%
6564169689Skan\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
6565132718Skan
6566169689Skan% There may be a space before second and/or third parameter; delete it.
6567169689Skan\def\eatcommaspace#1, {#1,}
6568169689Skan
6569132718Skan% #1 is the optional FLOATTYPE, the text label for this float, typically
6570132718Skan% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
6571132718Skan% this float will not be numbered and cannot be referred to.
6572169689Skan%
6573132718Skan% #2 is the optional xref label.  Also must be present for the float to
6574132718Skan% be referable.
6575169689Skan%
6576132718Skan% #3 is the optional positioning argument; for now, it is ignored.  It
6577132718Skan% will somehow specify the positions allowed to float to (here, top, bottom).
6578169689Skan%
6579132718Skan% We keep a separate counter for each FLOATTYPE, which we reset at each
6580132718Skan% chapter-level command.
6581132718Skan\let\resetallfloatnos=\empty
6582132718Skan%
6583132718Skan\def\dofloat#1,#2,#3,#4\finish{%
6584169689Skan  \let\thiscaption=\empty
6585169689Skan  \let\thisshortcaption=\empty
6586169689Skan  %
6587132718Skan  % don't lose footnotes inside @float.
6588169689Skan  %
6589169689Skan  % BEWARE: when the floats start float, we have to issue warning whenever an
6590169689Skan  % insert appears inside a float which could possibly float. --kasal, 26may04
6591169689Skan  %
6592132718Skan  \startsavinginserts
6593132718Skan  %
6594169689Skan  % We can't be used inside a paragraph.
6595169689Skan  \par
6596169689Skan  %
6597132718Skan  \vtop\bgroup
6598132718Skan    \def\floattype{#1}%
6599132718Skan    \def\floatlabel{#2}%
6600132718Skan    \def\floatloc{#3}% we do nothing with this yet.
6601132718Skan    %
6602169689Skan    \ifx\floattype\empty
6603169689Skan      \let\safefloattype=\empty
6604169689Skan    \else
6605169689Skan      {%
6606169689Skan        % the floattype might have accents or other special characters,
6607169689Skan        % but we need to use it in a control sequence name.
6608169689Skan        \indexnofonts
6609169689Skan        \turnoffactive
6610169689Skan        \xdef\safefloattype{\floattype}%
6611169689Skan      }%
6612169689Skan    \fi
6613169689Skan    %
6614169689Skan    % If label is given but no type, we handle that as the empty type.
6615169689Skan    \ifx\floatlabel\empty \else
6616169689Skan      % We want each FLOATTYPE to be numbered separately (Figure 1,
6617169689Skan      % Table 1, Figure 2, ...).  (And if no label, no number.)
6618169689Skan      %
6619169689Skan      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
6620132718Skan      \global\advance\floatno by 1
6621132718Skan      %
6622169689Skan      {%
6623169689Skan        % This magic value for \thissection is output by \setref as the
6624169689Skan        % XREFLABEL-title value.  \xrefX uses it to distinguish float
6625169689Skan        % labels (which have a completely different output format) from
6626169689Skan        % node and anchor labels.  And \xrdef uses it to construct the
6627169689Skan        % lists of floats.
6628169689Skan        %
6629169689Skan        \edef\thissection{\floatmagic=\safefloattype}%
6630169689Skan        \setref{\floatlabel}{Yfloat}%
6631169689Skan      }%
6632132718Skan    \fi
6633169689Skan    %
6634169689Skan    % start with \parskip glue, I guess.
6635169689Skan    \vskip\parskip
6636169689Skan    %
6637169689Skan    % Don't suppress indentation if a float happens to start a section.
6638169689Skan    \restorefirstparagraphindent
6639132718Skan}
6640132718Skan
6641169689Skan% we have these possibilities:
6642169689Skan% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
6643169689Skan% @float Foo,lbl & no caption:    Foo 1.1
6644169689Skan% @float Foo & @caption{Cap}:     Foo: Cap
6645169689Skan% @float Foo & no caption:        Foo
6646169689Skan% @float ,lbl & Caption{Cap}:     1.1: Cap
6647169689Skan% @float ,lbl & no caption:       1.1
6648169689Skan% @float & @caption{Cap}:         Cap
6649132718Skan% @float & no caption:
6650132718Skan%
6651132718Skan\def\Efloat{%
6652169689Skan    \let\floatident = \empty
6653132718Skan    %
6654169689Skan    % In all cases, if we have a float type, it comes first.
6655169689Skan    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
6656169689Skan    %
6657169689Skan    % If we have an xref label, the number comes next.
6658169689Skan    \ifx\floatlabel\empty \else
6659169689Skan      \ifx\floattype\empty \else % if also had float type, need tie first.
6660169689Skan        \appendtomacro\floatident{\tie}%
6661169689Skan      \fi
6662169689Skan      % the number.
6663169689Skan      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
6664132718Skan    \fi
6665132718Skan    %
6666169689Skan    % Start the printed caption with what we've constructed in
6667169689Skan    % \floatident, but keep it separate; we need \floatident again.
6668169689Skan    \let\captionline = \floatident
6669169689Skan    %
6670132718Skan    \ifx\thiscaption\empty \else
6671169689Skan      \ifx\floatident\empty \else
6672169689Skan	\appendtomacro\captionline{: }% had ident, so need a colon between
6673132718Skan      \fi
6674132718Skan      %
6675169689Skan      % caption text.
6676169689Skan      \appendtomacro\captionline{\scanexp\thiscaption}%
6677132718Skan    \fi
6678132718Skan    %
6679169689Skan    % If we have anything to print, print it, with space before.
6680169689Skan    % Eventually this needs to become an \insert.
6681169689Skan    \ifx\captionline\empty \else
6682169689Skan      \vskip.5\parskip
6683169689Skan      \captionline
6684169689Skan      %
6685169689Skan      % Space below caption.
6686169689Skan      \vskip\parskip
6687169689Skan    \fi
6688132718Skan    %
6689169689Skan    % If have an xref label, write the list of floats info.  Do this
6690169689Skan    % after the caption, to avoid chance of it being a breakpoint.
6691169689Skan    \ifx\floatlabel\empty \else
6692169689Skan      % Write the text that goes in the lof to the aux file as
6693169689Skan      % \floatlabel-lof.  Besides \floatident, we include the short
6694169689Skan      % caption if specified, else the full caption if specified, else nothing.
6695169689Skan      {%
6696169689Skan        \atdummies \turnoffactive
6697169689Skan        % since we read the caption text in the macro world, where ^^M
6698169689Skan        % is turned into a normal character, we have to scan it back, so
6699169689Skan        % we don't write the literal three characters "^^M" into the aux file.
6700169689Skan	\scanexp{%
6701169689Skan	  \xdef\noexpand\gtemp{%
6702169689Skan	    \ifx\thisshortcaption\empty
6703169689Skan	      \thiscaption
6704169689Skan	    \else
6705169689Skan	      \thisshortcaption
6706169689Skan	    \fi
6707169689Skan	  }%
6708169689Skan	}%
6709169689Skan        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
6710169689Skan	  \ifx\gtemp\empty \else : \gtemp \fi}}%
6711169689Skan      }%
6712169689Skan    \fi
6713132718Skan  \egroup  % end of \vtop
6714169689Skan  %
6715169689Skan  % place the captured inserts
6716169689Skan  %
6717169689Skan  % BEWARE: when the floats start float, we have to issue warning whenever an
6718169689Skan  % insert appears inside a float which could possibly float. --kasal, 26may04
6719169689Skan  %
6720132718Skan  \checkinserts
6721132718Skan}
6722132718Skan
6723169689Skan% Append the tokens #2 to the definition of macro #1, not expanding either.
6724169689Skan%
6725169689Skan\def\appendtomacro#1#2{%
6726169689Skan  \expandafter\def\expandafter#1\expandafter{#1#2}%
6727169689Skan}
6728132718Skan
6729169689Skan% @caption, @shortcaption
6730169689Skan%
6731169689Skan\def\caption{\docaption\thiscaption}
6732169689Skan\def\shortcaption{\docaption\thisshortcaption}
6733169689Skan\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
6734169689Skan\def\defcaption#1#2{\egroup \def#1{#2}}
6735169689Skan
6736132718Skan% The parameter is the control sequence identifying the counter we are
6737132718Skan% going to use.  Create it if it doesn't exist and assign it to \floatno.
6738132718Skan\def\getfloatno#1{%
6739132718Skan  \ifx#1\relax
6740132718Skan      % Haven't seen this figure type before.
6741132718Skan      \csname newcount\endcsname #1%
6742132718Skan      %
6743132718Skan      % Remember to reset this floatno at the next chap.
6744132718Skan      \expandafter\gdef\expandafter\resetallfloatnos
6745132718Skan        \expandafter{\resetallfloatnos #1=0 }%
6746132718Skan  \fi
6747132718Skan  \let\floatno#1%
6748132718Skan}
6749132718Skan
6750132718Skan% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
6751132718Skan% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
6752132718Skan% first read the @float command.
6753169689Skan%
6754169689Skan\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
6755132718Skan
6756132718Skan% Magic string used for the XREFLABEL-title value, so \xrefX can
6757132718Skan% distinguish floats from other xref types.
6758132718Skan\def\floatmagic{!!float!!}
6759132718Skan
6760169689Skan% #1 is the control sequence we are passed; we expand into a conditional
6761169689Skan% which is true if #1 represents a float ref.  That is, the magic
6762169689Skan% \thissection value which we \setref above.
6763169689Skan%
6764169689Skan\def\iffloat#1{\expandafter\doiffloat#1==\finish}
6765169689Skan%
6766169689Skan% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
6767169689Skan% (safe) float type for this float.  We set \iffloattype to #2.
6768169689Skan%
6769169689Skan\def\doiffloat#1=#2=#3\finish{%
6770169689Skan  \def\temp{#1}%
6771169689Skan  \def\iffloattype{#2}%
6772169689Skan  \ifx\temp\floatmagic
6773169689Skan}
6774169689Skan
6775132718Skan% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
6776169689Skan%
6777169689Skan\parseargdef\listoffloats{%
6778169689Skan  \def\floattype{#1}% floattype
6779169689Skan  {%
6780169689Skan    % the floattype might have accents or other special characters,
6781169689Skan    % but we need to use it in a control sequence name.
6782169689Skan    \indexnofonts
6783169689Skan    \turnoffactive
6784169689Skan    \xdef\safefloattype{\floattype}%
6785169689Skan  }%
6786169689Skan  %
6787169689Skan  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
6788169689Skan  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
6789169689Skan    \ifhavexrefs
6790169689Skan      % if the user said @listoffloats foo but never @float foo.
6791169689Skan      \message{\linenumber No `\safefloattype' floats to list.}%
6792169689Skan    \fi
6793169689Skan  \else
6794169689Skan    \begingroup
6795169689Skan      \leftskip=\tocindent  % indent these entries like a toc
6796169689Skan      \let\do=\listoffloatsdo
6797169689Skan      \csname floatlist\safefloattype\endcsname
6798169689Skan    \endgroup
6799169689Skan  \fi
6800132718Skan}
6801132718Skan
6802169689Skan% This is called on each entry in a list of floats.  We're passed the
6803169689Skan% xref label, in the form LABEL-title, which is how we save it in the
6804169689Skan% aux file.  We strip off the -title and look up \XRLABEL-lof, which
6805169689Skan% has the text we're supposed to typeset here.
6806169689Skan%
6807169689Skan% Figures without xref labels will not be included in the list (since
6808169689Skan% they won't appear in the aux file).
6809169689Skan%
6810169689Skan\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
6811169689Skan\def\listoffloatsdoentry#1-title\finish{{%
6812169689Skan  % Can't fully expand XR#1-lof because it can contain anything.  Just
6813169689Skan  % pass the control sequence.  On the other hand, XR#1-pg is just the
6814169689Skan  % page number, and we want to fully expand that so we can get a link
6815169689Skan  % in pdf output.
6816169689Skan  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
6817169689Skan  %
6818169689Skan  % use the same \entry macro we use to generate the TOC and index.
6819169689Skan  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
6820169689Skan  \writeentry
6821169689Skan}}
6822132718Skan
682396263Sobrien\message{localization,}
682496263Sobrien% and i18n.
682596263Sobrien
682696263Sobrien% @documentlanguage is usually given very early, just after
682796263Sobrien% @setfilename.  If done too late, it may not override everything
682896263Sobrien% properly.  Single argument is the language abbreviation.
682996263Sobrien% It would be nice if we could set up a hyphenation file here.
683096263Sobrien%
6831132718Skan\parseargdef\documentlanguage{%
683296263Sobrien  \tex % read txi-??.tex file in plain TeX.
6833132718Skan    % Read the file if it exists.
6834132718Skan    \openin 1 txi-#1.tex
6835132718Skan    \ifeof 1
6836132718Skan      \errhelp = \nolanghelp
6837132718Skan      \errmessage{Cannot read language file txi-#1.tex}%
6838132718Skan    \else
6839132718Skan      \input txi-#1.tex
6840132718Skan    \fi
6841132718Skan    \closein 1
684296263Sobrien  \endgroup
684396263Sobrien}
684496263Sobrien\newhelp\nolanghelp{The given language definition file cannot be found or
684596263Sobrienis empty.  Maybe you need to install it?  In the current directory
684696263Sobrienshould work if nowhere else does.}
684796263Sobrien
684896263Sobrien
684996263Sobrien% @documentencoding should change something in TeX eventually, most
685096263Sobrien% likely, but for now just recognize it.
685196263Sobrien\let\documentencoding = \comment
685296263Sobrien
685396263Sobrien
685496263Sobrien% Page size parameters.
685596263Sobrien%
685696263Sobrien\newdimen\defaultparindent \defaultparindent = 15pt
685796263Sobrien
685896263Sobrien\chapheadingskip = 15pt plus 4pt minus 2pt
685996263Sobrien\secheadingskip = 12pt plus 3pt minus 2pt
686096263Sobrien\subsecheadingskip = 9pt plus 2pt minus 2pt
686196263Sobrien
686296263Sobrien% Prevent underfull vbox error messages.
686396263Sobrien\vbadness = 10000
686496263Sobrien
686596263Sobrien% Don't be so finicky about underfull hboxes, either.
686696263Sobrien\hbadness = 2000
686796263Sobrien
686896263Sobrien% Following George Bush, just get rid of widows and orphans.
686996263Sobrien\widowpenalty=10000
687096263Sobrien\clubpenalty=10000
687196263Sobrien
687296263Sobrien% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
687396263Sobrien% using an old version of TeX, don't do anything.  We want the amount of
687496263Sobrien% stretch added to depend on the line length, hence the dependence on
687596263Sobrien% \hsize.  We call this whenever the paper size is set.
687696263Sobrien%
687796263Sobrien\def\setemergencystretch{%
687896263Sobrien  \ifx\emergencystretch\thisisundefined
687996263Sobrien    % Allow us to assign to \emergencystretch anyway.
688096263Sobrien    \def\emergencystretch{\dimen0}%
688196263Sobrien  \else
688296263Sobrien    \emergencystretch = .15\hsize
688396263Sobrien  \fi
688496263Sobrien}
688596263Sobrien
6886169689Skan% Parameters in order: 1) textheight; 2) textwidth;
6887169689Skan% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
6888169689Skan% 7) physical page height; 8) physical page width.
6889119256Skan%
6890117395Skan% We also call \setleading{\textleading}, so the caller should define
6891117395Skan% \textleading.  The caller should also set \parskip.
689296263Sobrien%
6893117395Skan\def\internalpagesizes#1#2#3#4#5#6#7#8{%
689496263Sobrien  \voffset = #3\relax
689596263Sobrien  \topskip = #6\relax
689696263Sobrien  \splittopskip = \topskip
689796263Sobrien  %
689896263Sobrien  \vsize = #1\relax
689996263Sobrien  \advance\vsize by \topskip
690096263Sobrien  \outervsize = \vsize
690196263Sobrien  \advance\outervsize by 2\topandbottommargin
690296263Sobrien  \pageheight = \vsize
690396263Sobrien  %
690496263Sobrien  \hsize = #2\relax
690596263Sobrien  \outerhsize = \hsize
690696263Sobrien  \advance\outerhsize by 0.5in
690796263Sobrien  \pagewidth = \hsize
690896263Sobrien  %
690996263Sobrien  \normaloffset = #4\relax
691096263Sobrien  \bindingoffset = #5\relax
691196263Sobrien  %
6912117395Skan  \ifpdf
6913117395Skan    \pdfpageheight #7\relax
6914117395Skan    \pdfpagewidth #8\relax
6915117395Skan  \fi
6916117395Skan  %
691796263Sobrien  \setleading{\textleading}
691896263Sobrien  %
691996263Sobrien  \parindent = \defaultparindent
692096263Sobrien  \setemergencystretch
692196263Sobrien}
692296263Sobrien
692396263Sobrien% @letterpaper (the default).
692496263Sobrien\def\letterpaper{{\globaldefs = 1
692596263Sobrien  \parskip = 3pt plus 2pt minus 1pt
692696263Sobrien  \textleading = 13.2pt
692796263Sobrien  %
692896263Sobrien  % If page is nothing but text, make it come out even.
6929117395Skan  \internalpagesizes{46\baselineskip}{6in}%
6930117395Skan                    {\voffset}{.25in}%
6931117395Skan                    {\bindingoffset}{36pt}%
6932117395Skan                    {11in}{8.5in}%
693396263Sobrien}}
693496263Sobrien
6935169689Skan% Use @smallbook to reset parameters for 7x9.25 trim size.
693696263Sobrien\def\smallbook{{\globaldefs = 1
693796263Sobrien  \parskip = 2pt plus 1pt
693896263Sobrien  \textleading = 12pt
693996263Sobrien  %
6940117395Skan  \internalpagesizes{7.5in}{5in}%
6941117395Skan                    {\voffset}{.25in}%
6942117395Skan                    {\bindingoffset}{16pt}%
6943117395Skan                    {9.25in}{7in}%
694496263Sobrien  %
694596263Sobrien  \lispnarrowing = 0.3in
694696263Sobrien  \tolerance = 700
694796263Sobrien  \hfuzz = 1pt
694896263Sobrien  \contentsrightmargin = 0pt
694996263Sobrien  \defbodyindent = .5cm
695096263Sobrien}}
695196263Sobrien
6952169689Skan% Use @smallerbook to reset parameters for 6x9 trim size.
6953169689Skan% (Just testing, parameters still in flux.)
6954169689Skan\def\smallerbook{{\globaldefs = 1
6955169689Skan  \parskip = 1.5pt plus 1pt
6956169689Skan  \textleading = 12pt
6957169689Skan  %
6958169689Skan  \internalpagesizes{7.4in}{4.8in}%
6959169689Skan                    {-.2in}{-.4in}%
6960169689Skan                    {0pt}{14pt}%
6961169689Skan                    {9in}{6in}%
6962169689Skan  %
6963169689Skan  \lispnarrowing = 0.25in
6964169689Skan  \tolerance = 700
6965169689Skan  \hfuzz = 1pt
6966169689Skan  \contentsrightmargin = 0pt
6967169689Skan  \defbodyindent = .4cm
6968169689Skan}}
6969169689Skan
697096263Sobrien% Use @afourpaper to print on European A4 paper.
697196263Sobrien\def\afourpaper{{\globaldefs = 1
697296263Sobrien  \parskip = 3pt plus 2pt minus 1pt
6973117395Skan  \textleading = 13.2pt
697496263Sobrien  %
6975119256Skan  % Double-side printing via postscript on Laserjet 4050
6976117395Skan  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
6977117395Skan  % To change the settings for a different printer or situation, adjust
6978117395Skan  % \normaloffset until the front-side and back-side texts align.  Then
6979117395Skan  % do the same for \bindingoffset.  You can set these for testing in
6980117395Skan  % your texinfo source file like this:
6981117395Skan  % @tex
6982117395Skan  % \global\normaloffset = -6mm
6983117395Skan  % \global\bindingoffset = 10mm
6984117395Skan  % @end tex
6985117395Skan  \internalpagesizes{51\baselineskip}{160mm}
6986117395Skan                    {\voffset}{\hoffset}%
6987117395Skan                    {\bindingoffset}{44pt}%
6988117395Skan                    {297mm}{210mm}%
698996263Sobrien  %
699096263Sobrien  \tolerance = 700
699196263Sobrien  \hfuzz = 1pt
6992117395Skan  \contentsrightmargin = 0pt
6993117395Skan  \defbodyindent = 5mm
699496263Sobrien}}
699596263Sobrien
699696263Sobrien% Use @afivepaper to print on European A5 paper.
699796263Sobrien% From romildo@urano.iceb.ufop.br, 2 July 2000.
699896263Sobrien% He also recommends making @example and @lisp be small.
699996263Sobrien\def\afivepaper{{\globaldefs = 1
700096263Sobrien  \parskip = 2pt plus 1pt minus 0.1pt
700196263Sobrien  \textleading = 12.5pt
700296263Sobrien  %
7003117395Skan  \internalpagesizes{160mm}{120mm}%
7004117395Skan                    {\voffset}{\hoffset}%
7005117395Skan                    {\bindingoffset}{8pt}%
7006117395Skan                    {210mm}{148mm}%
700796263Sobrien  %
700896263Sobrien  \lispnarrowing = 0.2in
700996263Sobrien  \tolerance = 800
701096263Sobrien  \hfuzz = 1.2pt
7011117395Skan  \contentsrightmargin = 0pt
701296263Sobrien  \defbodyindent = 2mm
701396263Sobrien  \tableindent = 12mm
701496263Sobrien}}
701596263Sobrien
7016119256Skan% A specific text layout, 24x15cm overall, intended for A4 paper.
701796263Sobrien\def\afourlatex{{\globaldefs = 1
701896263Sobrien  \afourpaper
7019117395Skan  \internalpagesizes{237mm}{150mm}%
7020117395Skan                    {\voffset}{4.6mm}%
7021117395Skan                    {\bindingoffset}{7mm}%
7022117395Skan                    {297mm}{210mm}%
702396263Sobrien  %
7024117395Skan  % Must explicitly reset to 0 because we call \afourpaper.
702596263Sobrien  \globaldefs = 0
702696263Sobrien}}
702796263Sobrien
7028117395Skan% Use @afourwide to print on A4 paper in landscape format.
7029117395Skan\def\afourwide{{\globaldefs = 1
703096263Sobrien  \afourpaper
7031117395Skan  \internalpagesizes{241mm}{165mm}%
7032117395Skan                    {\voffset}{-2.95mm}%
7033117395Skan                    {\bindingoffset}{7mm}%
7034117395Skan                    {297mm}{210mm}%
7035117395Skan  \globaldefs = 0
7036117395Skan}}
703796263Sobrien
703896263Sobrien% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
703996263Sobrien% Perhaps we should allow setting the margins, \topskip, \parskip,
704096263Sobrien% and/or leading, also. Or perhaps we should compute them somehow.
704196263Sobrien%
7042132718Skan\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
704396263Sobrien\def\pagesizesyyy#1,#2,#3\finish{{%
704496263Sobrien  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
704596263Sobrien  \globaldefs = 1
704696263Sobrien  %
704796263Sobrien  \parskip = 3pt plus 2pt minus 1pt
704896263Sobrien  \setleading{\textleading}%
704996263Sobrien  %
7050117395Skan  \dimen0 = #1
7051117395Skan  \advance\dimen0 by \voffset
7052117395Skan  %
7053117395Skan  \dimen2 = \hsize
7054117395Skan  \advance\dimen2 by \normaloffset
7055117395Skan  %
7056117395Skan  \internalpagesizes{#1}{\hsize}%
7057117395Skan                    {\voffset}{\normaloffset}%
7058117395Skan                    {\bindingoffset}{44pt}%
7059117395Skan                    {\dimen0}{\dimen2}%
706096263Sobrien}}
706196263Sobrien
706296263Sobrien% Set default to letter.
706396263Sobrien%
706496263Sobrien\letterpaper
706596263Sobrien
706696263Sobrien
706796263Sobrien\message{and turning on texinfo input format.}
706896263Sobrien
706996263Sobrien% Define macros to output various characters with catcode for normal text.
707096263Sobrien\catcode`\"=\other
707196263Sobrien\catcode`\~=\other
707296263Sobrien\catcode`\^=\other
707396263Sobrien\catcode`\_=\other
707496263Sobrien\catcode`\|=\other
707596263Sobrien\catcode`\<=\other
707696263Sobrien\catcode`\>=\other
707796263Sobrien\catcode`\+=\other
707896263Sobrien\catcode`\$=\other
707996263Sobrien\def\normaldoublequote{"}
708096263Sobrien\def\normaltilde{~}
708196263Sobrien\def\normalcaret{^}
708296263Sobrien\def\normalunderscore{_}
708396263Sobrien\def\normalverticalbar{|}
708496263Sobrien\def\normalless{<}
708596263Sobrien\def\normalgreater{>}
708696263Sobrien\def\normalplus{+}
708796263Sobrien\def\normaldollar{$}%$ font-lock fix
708896263Sobrien
7089132718Skan% This macro is used to make a character print one way in \tt
7090132718Skan% (where it can probably be output as-is), and another way in other fonts,
709196263Sobrien% where something hairier probably needs to be done.
709296263Sobrien%
709396263Sobrien% #1 is what to print if we are indeed using \tt; #2 is what to print
709496263Sobrien% otherwise.  Since all the Computer Modern typewriter fonts have zero
709596263Sobrien% interword stretch (and shrink), and it is reasonable to expect all
709696263Sobrien% typewriter fonts to have this, we can check that font parameter.
709796263Sobrien%
709896263Sobrien\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
709996263Sobrien
710096263Sobrien% Same as above, but check for italic font.  Actually this also catches
710196263Sobrien% non-italic slanted fonts since it is impossible to distinguish them from
710296263Sobrien% italic fonts.  But since this is only used by $ and it uses \sl anyway
710396263Sobrien% this is not a problem.
710496263Sobrien\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
710596263Sobrien
710696263Sobrien% Turn off all special characters except @
710796263Sobrien% (and those which the user can use as if they were ordinary).
710896263Sobrien% Most of these we simply print from the \tt font, but for some, we can
710996263Sobrien% use math or other variants that look better in normal text.
711096263Sobrien
711196263Sobrien\catcode`\"=\active
711296263Sobrien\def\activedoublequote{{\tt\char34}}
711396263Sobrien\let"=\activedoublequote
711496263Sobrien\catcode`\~=\active
711596263Sobrien\def~{{\tt\char126}}
711696263Sobrien\chardef\hat=`\^
711796263Sobrien\catcode`\^=\active
711896263Sobrien\def^{{\tt \hat}}
711996263Sobrien
712096263Sobrien\catcode`\_=\active
712196263Sobrien\def_{\ifusingtt\normalunderscore\_}
7122169689Skan\let\realunder=_
712396263Sobrien% Subroutine for the previous macro.
7124119256Skan\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
712596263Sobrien
712696263Sobrien\catcode`\|=\active
712796263Sobrien\def|{{\tt\char124}}
712896263Sobrien\chardef \less=`\<
712996263Sobrien\catcode`\<=\active
713096263Sobrien\def<{{\tt \less}}
713196263Sobrien\chardef \gtr=`\>
713296263Sobrien\catcode`\>=\active
713396263Sobrien\def>{{\tt \gtr}}
713496263Sobrien\catcode`\+=\active
713596263Sobrien\def+{{\tt \char 43}}
713696263Sobrien\catcode`\$=\active
713796263Sobrien\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
713896263Sobrien
713996263Sobrien% If a .fmt file is being used, characters that might appear in a file
714096263Sobrien% name cannot be active until we have parsed the command line.
714196263Sobrien% So turn them off again, and have \everyjob (or @setfilename) turn them on.
714296263Sobrien% \otherifyactive is called near the end of this file.
714396263Sobrien\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
714496263Sobrien
714596263Sobrien\catcode`\@=0
714696263Sobrien
7147169689Skan% \backslashcurfont outputs one backslash character in current font,
7148119256Skan% as in \char`\\.
7149169689Skan\global\chardef\backslashcurfont=`\\
7150169689Skan\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
715196263Sobrien
7152169689Skan% \rawbackslash defines an active \ to do \backslashcurfont.
7153119256Skan% \otherbackslash defines an active \ to be a literal `\' character with
7154119256Skan% catcode other.
715596263Sobrien{\catcode`\\=\active
7156169689Skan @gdef@rawbackslash{@let\=@backslashcurfont}
7157119256Skan @gdef@otherbackslash{@let\=@realbackslash}
7158119256Skan}
715996263Sobrien
7160169689Skan% \realbackslash is an actual character `\' with catcode other, and
7161169689Skan% \doublebackslash is two of them (for the pdf outlines).
7162169689Skan{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
7163119256Skan
716496263Sobrien% \normalbackslash outputs one backslash in fixed width font.
7165169689Skan\def\normalbackslash{{\tt\backslashcurfont}}
716696263Sobrien
716796263Sobrien\catcode`\\=\active
716896263Sobrien
716996263Sobrien% Used sometimes to turn off (effectively) the active characters
717096263Sobrien% even after parsing them.
7171119256Skan@def@turnoffactive{%
7172119256Skan  @let"=@normaldoublequote
7173119256Skan  @let\=@realbackslash
7174119256Skan  @let~=@normaltilde
7175119256Skan  @let^=@normalcaret
7176119256Skan  @let_=@normalunderscore
7177119256Skan  @let|=@normalverticalbar
7178119256Skan  @let<=@normalless
7179119256Skan  @let>=@normalgreater
7180119256Skan  @let+=@normalplus
7181119256Skan  @let$=@normaldollar %$ font-lock fix
7182132718Skan  @unsepspaces
7183119256Skan}
718496263Sobrien
7185119256Skan% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
7186119256Skan% the literal character `\'.  (Thus, \ is not expandable when this is in
7187119256Skan% effect.)
7188119256Skan%
7189117395Skan@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
719096263Sobrien
719196263Sobrien% Make _ and + \other characters, temporarily.
719296263Sobrien% This is canceled by @fixbackslash.
719396263Sobrien@otherifyactive
719496263Sobrien
719596263Sobrien% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
719696263Sobrien% That is what \eatinput is for; after that, the `\' should revert to printing
719796263Sobrien% a backslash.
719896263Sobrien%
719996263Sobrien@gdef@eatinput input texinfo{@fixbackslash}
720096263Sobrien@global@let\ = @eatinput
720196263Sobrien
720296263Sobrien% On the other hand, perhaps the file did not have a `\input texinfo'. Then
720396263Sobrien% the first `\{ in the file would cause an error. This macro tries to fix
720496263Sobrien% that, assuming it is called before the first `\' could plausibly occur.
7205169689Skan% Also turn back on active characters that might appear in the input
720696263Sobrien% file name, in case not using a pre-dumped format.
720796263Sobrien%
720896263Sobrien@gdef@fixbackslash{%
720996263Sobrien  @ifx\@eatinput @let\ = @normalbackslash @fi
721096263Sobrien  @catcode`+=@active
721196263Sobrien  @catcode`@_=@active
721296263Sobrien}
721396263Sobrien
721496263Sobrien% Say @foo, not \foo, in error messages.
721596263Sobrien@escapechar = `@@
721696263Sobrien
7217119256Skan% These look ok in all fonts, so just make them not special.
721896263Sobrien@catcode`@& = @other
721996263Sobrien@catcode`@# = @other
722096263Sobrien@catcode`@% = @other
722196263Sobrien
722296263Sobrien
722396263Sobrien@c Local variables:
722496263Sobrien@c eval: (add-hook 'write-file-hooks 'time-stamp)
722596263Sobrien@c page-delimiter: "^\\\\message"
722696263Sobrien@c time-stamp-start: "def\\\\texinfoversion{"
722796263Sobrien@c time-stamp-format: "%:y-%02m-%02d.%02H"
722896263Sobrien@c time-stamp-end: "}"
722996263Sobrien@c End:
7230132718Skan
7231132718Skan@c vim:sw=2:
7232132718Skan
7233132718Skan@ignore
7234132718Skan   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
7235132718Skan@end ignore
7236