src/work/alpar/attic/texi/texinfo.tex
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
alpar@464
     1
% texinfo.tex -- TeX macros to handle Texinfo files.
alpar@464
     2
%
alpar@464
     3
% Load plain if necessary, i.e., if running under initex.
alpar@464
     4
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
alpar@464
     5
%
alpar@464
     6
\def\texinfoversion{2003-07-28.08}
alpar@464
     7
%
alpar@464
     8
% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
alpar@464
     9
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
alpar@464
    10
%
alpar@464
    11
% This texinfo.tex file is free software; you can redistribute it and/or
alpar@464
    12
% modify it under the terms of the GNU General Public License as
alpar@464
    13
% published by the Free Software Foundation; either version 2, or (at
alpar@464
    14
% your option) any later version.
alpar@464
    15
%
alpar@464
    16
% This texinfo.tex file is distributed in the hope that it will be
alpar@464
    17
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
alpar@464
    18
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
alpar@464
    19
% General Public License for more details.
alpar@464
    20
%
alpar@464
    21
% You should have received a copy of the GNU General Public License
alpar@464
    22
% along with this texinfo.tex file; see the file COPYING.  If not, write
alpar@464
    23
% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
alpar@464
    24
% Boston, MA 02111-1307, USA.
alpar@464
    25
%
alpar@464
    26
% In other words, you are welcome to use, share and improve this program.
alpar@464
    27
% You are forbidden to forbid anyone else to use, share and improve
alpar@464
    28
% what you give them.   Help stamp out software-hoarding!
alpar@464
    29
%
alpar@464
    30
% Please try the latest version of texinfo.tex before submitting bug
alpar@464
    31
% reports; you can get the latest version from:
alpar@464
    32
%   ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex
alpar@464
    33
%     (and all GNU mirrors, see http://www.gnu.org/order/ftp.html)
alpar@464
    34
%   ftp://tug.org/tex/texinfo.tex
alpar@464
    35
%     (and all CTAN mirrors, see http://www.ctan.org),
alpar@464
    36
%   and /home/gd/gnu/doc/texinfo.tex on the GNU machines.
alpar@464
    37
%
alpar@464
    38
% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
alpar@464
    39
%
alpar@464
    40
% The texinfo.tex in any given Texinfo distribution could well be out
alpar@464
    41
% of date, so if that's what you're using, please check.
alpar@464
    42
%
alpar@464
    43
% Send bug reports to bug-texinfo@gnu.org.  Please include including a
alpar@464
    44
% complete document in each bug report with which we can reproduce the
alpar@464
    45
% problem.  Patches are, of course, greatly appreciated.
alpar@464
    46
%
alpar@464
    47
% To process a Texinfo manual with TeX, it's most reliable to use the
alpar@464
    48
% texi2dvi shell script that comes with the distribution.  For a simple
alpar@464
    49
% manual foo.texi, however, you can get away with this:
alpar@464
    50
%   tex foo.texi
alpar@464
    51
%   texindex foo.??
alpar@464
    52
%   tex foo.texi
alpar@464
    53
%   tex foo.texi
alpar@464
    54
%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
alpar@464
    55
% The extra TeX runs get the cross-reference information correct.
alpar@464
    56
% Sometimes one run after texindex suffices, and sometimes you need more
alpar@464
    57
% than two; texi2dvi does it as many times as necessary.
alpar@464
    58
%
alpar@464
    59
% It is possible to adapt texinfo.tex for other languages, to some
alpar@464
    60
% extent.  You can get the existing language-specific files from the
alpar@464
    61
% full Texinfo distribution.
alpar@464
    62
alpar@464
    63
\message{Loading texinfo [version \texinfoversion]:}
alpar@464
    64
alpar@464
    65
% If in a .fmt file, print the version number
alpar@464
    66
% and turn on active characters that we couldn't do earlier because
alpar@464
    67
% they might have appeared in the input file name.
alpar@464
    68
\everyjob{\message{[Texinfo version \texinfoversion]}%
alpar@464
    69
  \catcode`+=\active \catcode`\_=\active}
alpar@464
    70
alpar@464
    71
\message{Basics,}
alpar@464
    72
\chardef\other=12
alpar@464
    73
alpar@464
    74
% We never want plain's \outer definition of \+ in Texinfo.
alpar@464
    75
% For @tex, we can use \tabalign.
alpar@464
    76
\let\+ = \relax
alpar@464
    77
alpar@464
    78
% Save some plain tex macros whose names we will redefine.
alpar@464
    79
\let\ptexb=\b
alpar@464
    80
\let\ptexbullet=\bullet
alpar@464
    81
\let\ptexc=\c
alpar@464
    82
\let\ptexcomma=\,
alpar@464
    83
\let\ptexdot=\.
alpar@464
    84
\let\ptexdots=\dots
alpar@464
    85
\let\ptexend=\end
alpar@464
    86
\let\ptexequiv=\equiv
alpar@464
    87
\let\ptexexclam=\!
alpar@464
    88
\let\ptexgtr=>
alpar@464
    89
\let\ptexhat=^
alpar@464
    90
\let\ptexi=\i
alpar@464
    91
\let\ptexindent=\indent
alpar@464
    92
\let\ptexlbrace=\{
alpar@464
    93
\let\ptexless=<
alpar@464
    94
\let\ptexplus=+
alpar@464
    95
\let\ptexrbrace=\}
alpar@464
    96
\let\ptexslash=\/
alpar@464
    97
\let\ptexstar=\*
alpar@464
    98
\let\ptext=\t
alpar@464
    99
alpar@464
   100
% If this character appears in an error message or help string, it
alpar@464
   101
% starts a new line in the output.
alpar@464
   102
\newlinechar = `^^J
alpar@464
   103
alpar@464
   104
% Set up fixed words for English if not already set.
alpar@464
   105
\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
alpar@464
   106
\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
alpar@464
   107
\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
alpar@464
   108
\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
alpar@464
   109
\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
alpar@464
   110
\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
alpar@464
   111
\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
alpar@464
   112
\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
alpar@464
   113
\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
alpar@464
   114
\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
alpar@464
   115
\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
alpar@464
   116
\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
alpar@464
   117
\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
alpar@464
   118
\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
alpar@464
   119
\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
alpar@464
   120
\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
alpar@464
   121
\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
alpar@464
   122
\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
alpar@464
   123
\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
alpar@464
   124
%
alpar@464
   125
\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
alpar@464
   126
\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
alpar@464
   127
\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
alpar@464
   128
\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
alpar@464
   129
\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
alpar@464
   130
\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
alpar@464
   131
\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
alpar@464
   132
\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
alpar@464
   133
\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
alpar@464
   134
\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
alpar@464
   135
\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
alpar@464
   136
\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
alpar@464
   137
%
alpar@464
   138
\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
alpar@464
   139
\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
alpar@464
   140
\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
alpar@464
   141
\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
alpar@464
   142
\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi
alpar@464
   143
\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
alpar@464
   144
\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi
alpar@464
   145
alpar@464
   146
% In some macros, we cannot use the `\? notation---the left quote is
alpar@464
   147
% in some cases the escape char.
alpar@464
   148
\chardef\colonChar = `\:
alpar@464
   149
\chardef\commaChar = `\,
alpar@464
   150
\chardef\dotChar   = `\.
alpar@464
   151
\chardef\equalChar = `\=
alpar@464
   152
\chardef\exclamChar= `\!
alpar@464
   153
\chardef\questChar = `\?
alpar@464
   154
\chardef\semiChar  = `\;
alpar@464
   155
\chardef\spaceChar = `\ %
alpar@464
   156
\chardef\underChar = `\_
alpar@464
   157
alpar@464
   158
% Ignore a token.
alpar@464
   159
%
alpar@464
   160
\def\gobble#1{}
alpar@464
   161
alpar@464
   162
% True if #1 is the empty string, i.e., called like `\ifempty{}'.
alpar@464
   163
%
alpar@464
   164
\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}%
alpar@464
   165
\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}%
alpar@464
   166
alpar@464
   167
% Hyphenation fixes.
alpar@464
   168
\hyphenation{ap-pen-dix}
alpar@464
   169
\hyphenation{eshell}
alpar@464
   170
\hyphenation{mini-buf-fer mini-buf-fers}
alpar@464
   171
\hyphenation{time-stamp}
alpar@464
   172
\hyphenation{white-space}
alpar@464
   173
alpar@464
   174
% Margin to add to right of even pages, to left of odd pages.
alpar@464
   175
\newdimen\bindingoffset
alpar@464
   176
\newdimen\normaloffset
alpar@464
   177
\newdimen\pagewidth \newdimen\pageheight
alpar@464
   178
alpar@464
   179
% Sometimes it is convenient to have everything in the transcript file
alpar@464
   180
% and nothing on the terminal.  We don't just call \tracingall here,
alpar@464
   181
% since that produces some useless output on the terminal.  We also make
alpar@464
   182
% some effort to order the tracing commands to reduce output in the log
alpar@464
   183
% file; cf. trace.sty in LaTeX.
alpar@464
   184
%
alpar@464
   185
\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
alpar@464
   186
\def\loggingall{%
alpar@464
   187
  \tracingstats2
alpar@464
   188
  \tracingpages1
alpar@464
   189
  \tracinglostchars2  % 2 gives us more in etex
alpar@464
   190
  \tracingparagraphs1
alpar@464
   191
  \tracingoutput1
alpar@464
   192
  \tracingmacros2
alpar@464
   193
  \tracingrestores1
alpar@464
   194
  \showboxbreadth\maxdimen \showboxdepth\maxdimen
alpar@464
   195
  \ifx\eTeXversion\undefined\else % etex gives us more logging
alpar@464
   196
    \tracingscantokens1
alpar@464
   197
    \tracingifs1
alpar@464
   198
    \tracinggroups1
alpar@464
   199
    \tracingnesting2
alpar@464
   200
    \tracingassigns1
alpar@464
   201
  \fi
alpar@464
   202
  \tracingcommands3  % 3 gives us more in etex
alpar@464
   203
  \errorcontextlines\maxdimen
alpar@464
   204
}%
alpar@464
   205
alpar@464
   206
% add check for \lastpenalty to plain's definitions.  If the last thing
alpar@464
   207
% we did was a \nobreak, we don't want to insert more space.
alpar@464
   208
%
alpar@464
   209
\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
alpar@464
   210
  \removelastskip\penalty-50\smallskip\fi\fi}
alpar@464
   211
\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
alpar@464
   212
  \removelastskip\penalty-100\medskip\fi\fi}
alpar@464
   213
\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
alpar@464
   214
  \removelastskip\penalty-200\bigskip\fi\fi}
alpar@464
   215
alpar@464
   216
% For @cropmarks command.
alpar@464
   217
% Do @cropmarks to get crop marks.
alpar@464
   218
%
alpar@464
   219
\newif\ifcropmarks
alpar@464
   220
\let\cropmarks = \cropmarkstrue
alpar@464
   221
%
alpar@464
   222
% Dimensions to add cropmarks at corners.
alpar@464
   223
% Added by P. A. MacKay, 12 Nov. 1986
alpar@464
   224
%
alpar@464
   225
\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
alpar@464
   226
\newdimen\cornerlong  \cornerlong=1pc
alpar@464
   227
\newdimen\cornerthick \cornerthick=.3pt
alpar@464
   228
\newdimen\topandbottommargin \topandbottommargin=.75in
alpar@464
   229
alpar@464
   230
% Main output routine.
alpar@464
   231
\chardef\PAGE = 255
alpar@464
   232
\output = {\onepageout{\pagecontents\PAGE}}
alpar@464
   233
alpar@464
   234
\newbox\headlinebox
alpar@464
   235
\newbox\footlinebox
alpar@464
   236
alpar@464
   237
% \onepageout takes a vbox as an argument.  Note that \pagecontents
alpar@464
   238
% does insertions, but you have to call it yourself.
alpar@464
   239
\def\onepageout#1{%
alpar@464
   240
  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
alpar@464
   241
  %
alpar@464
   242
  \ifodd\pageno  \advance\hoffset by \bindingoffset
alpar@464
   243
  \else \advance\hoffset by -\bindingoffset\fi
alpar@464
   244
  %
alpar@464
   245
  % Do this outside of the \shipout so @code etc. will be expanded in
alpar@464
   246
  % the headline as they should be, not taken literally (outputting ''code).
alpar@464
   247
  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
alpar@464
   248
  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
alpar@464
   249
  %
alpar@464
   250
  {%
alpar@464
   251
    % Have to do this stuff outside the \shipout because we want it to
alpar@464
   252
    % take effect in \write's, yet the group defined by the \vbox ends
alpar@464
   253
    % before the \shipout runs.
alpar@464
   254
    %
alpar@464
   255
    \escapechar = `\\     % use backslash in output files.
alpar@464
   256
    \indexdummies         % don't expand commands in the output.
alpar@464
   257
    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
alpar@464
   258
                   % the page break happens to be in the middle of an example.
alpar@464
   259
    \shipout\vbox{%
alpar@464
   260
      % Do this early so pdf references go to the beginning of the page.
alpar@464
   261
      \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi
alpar@464
   262
      %
alpar@464
   263
      \ifcropmarks \vbox to \outervsize\bgroup
alpar@464
   264
        \hsize = \outerhsize
alpar@464
   265
        \vskip-\topandbottommargin
alpar@464
   266
        \vtop to0pt{%
alpar@464
   267
          \line{\ewtop\hfil\ewtop}%
alpar@464
   268
          \nointerlineskip
alpar@464
   269
          \line{%
alpar@464
   270
            \vbox{\moveleft\cornerthick\nstop}%
alpar@464
   271
            \hfill
alpar@464
   272
            \vbox{\moveright\cornerthick\nstop}%
alpar@464
   273
          }%
alpar@464
   274
          \vss}%
alpar@464
   275
        \vskip\topandbottommargin
alpar@464
   276
        \line\bgroup
alpar@464
   277
          \hfil % center the page within the outer (page) hsize.
alpar@464
   278
          \ifodd\pageno\hskip\bindingoffset\fi
alpar@464
   279
          \vbox\bgroup
alpar@464
   280
      \fi
alpar@464
   281
      %
alpar@464
   282
      \unvbox\headlinebox
alpar@464
   283
      \pagebody{#1}%
alpar@464
   284
      \ifdim\ht\footlinebox > 0pt
alpar@464
   285
        % Only leave this space if the footline is nonempty.
alpar@464
   286
        % (We lessened \vsize for it in \oddfootingxxx.)
alpar@464
   287
        % The \baselineskip=24pt in plain's \makefootline has no effect.
alpar@464
   288
        \vskip 2\baselineskip
alpar@464
   289
        \unvbox\footlinebox
alpar@464
   290
      \fi
alpar@464
   291
      %
alpar@464
   292
      \ifcropmarks
alpar@464
   293
          \egroup % end of \vbox\bgroup
alpar@464
   294
        \hfil\egroup % end of (centering) \line\bgroup
alpar@464
   295
        \vskip\topandbottommargin plus1fill minus1fill
alpar@464
   296
        \boxmaxdepth = \cornerthick
alpar@464
   297
        \vbox to0pt{\vss
alpar@464
   298
          \line{%
alpar@464
   299
            \vbox{\moveleft\cornerthick\nsbot}%
alpar@464
   300
            \hfill
alpar@464
   301
            \vbox{\moveright\cornerthick\nsbot}%
alpar@464
   302
          }%
alpar@464
   303
          \nointerlineskip
alpar@464
   304
          \line{\ewbot\hfil\ewbot}%
alpar@464
   305
        }%
alpar@464
   306
      \egroup % \vbox from first cropmarks clause
alpar@464
   307
      \fi
alpar@464
   308
    }% end of \shipout\vbox
alpar@464
   309
  }% end of group with \normalturnoffactive
alpar@464
   310
  \advancepageno
alpar@464
   311
  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
alpar@464
   312
}
alpar@464
   313
alpar@464
   314
\newinsert\margin \dimen\margin=\maxdimen
alpar@464
   315
alpar@464
   316
\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
alpar@464
   317
{\catcode`\@ =11
alpar@464
   318
\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
alpar@464
   319
% marginal hacks, juha@viisa.uucp (Juha Takala)
alpar@464
   320
\ifvoid\margin\else % marginal info is present
alpar@464
   321
  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
alpar@464
   322
\dimen@=\dp#1 \unvbox#1
alpar@464
   323
\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
alpar@464
   324
\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
alpar@464
   325
}
alpar@464
   326
alpar@464
   327
% Here are the rules for the cropmarks.  Note that they are
alpar@464
   328
% offset so that the space between them is truly \outerhsize or \outervsize
alpar@464
   329
% (P. A. MacKay, 12 November, 1986)
alpar@464
   330
%
alpar@464
   331
\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
alpar@464
   332
\def\nstop{\vbox
alpar@464
   333
  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
alpar@464
   334
\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
alpar@464
   335
\def\nsbot{\vbox
alpar@464
   336
  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
alpar@464
   337
alpar@464
   338
% Parse an argument, then pass it to #1.  The argument is the rest of
alpar@464
   339
% the input line (except we remove a trailing comment).  #1 should be a
alpar@464
   340
% macro which expects an ordinary undelimited TeX argument.
alpar@464
   341
%
alpar@464
   342
\def\parsearg#1{%
alpar@464
   343
  \let\next = #1%
alpar@464
   344
  \begingroup
alpar@464
   345
    \obeylines
alpar@464
   346
    \futurelet\temp\parseargx
alpar@464
   347
}
alpar@464
   348
alpar@464
   349
% If the next token is an obeyed space (from an @example environment or
alpar@464
   350
% the like), remove it and recurse.  Otherwise, we're done.
alpar@464
   351
\def\parseargx{%
alpar@464
   352
  % \obeyedspace is defined far below, after the definition of \sepspaces.
alpar@464
   353
  \ifx\obeyedspace\temp
alpar@464
   354
    \expandafter\parseargdiscardspace
alpar@464
   355
  \else
alpar@464
   356
    \expandafter\parseargline
alpar@464
   357
  \fi
alpar@464
   358
}
alpar@464
   359
alpar@464
   360
% Remove a single space (as the delimiter token to the macro call).
alpar@464
   361
{\obeyspaces %
alpar@464
   362
 \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
alpar@464
   363
alpar@464
   364
{\obeylines %
alpar@464
   365
  \gdef\parseargline#1^^M{%
alpar@464
   366
    \endgroup % End of the group started in \parsearg.
alpar@464
   367
    %
alpar@464
   368
    % First remove any @c comment, then any @comment.
alpar@464
   369
    % Result of each macro is put in \toks0.
alpar@464
   370
    \argremovec #1\c\relax %
alpar@464
   371
    \expandafter\argremovecomment \the\toks0 \comment\relax %
alpar@464
   372
    %
alpar@464
   373
    % Call the caller's macro, saved as \next in \parsearg.
alpar@464
   374
    \expandafter\next\expandafter{\the\toks0}%
alpar@464
   375
  }%
alpar@464
   376
}
alpar@464
   377
alpar@464
   378
% Since all \c{,omment} does is throw away the argument, we can let TeX
alpar@464
   379
% do that for us.  The \relax here is matched by the \relax in the call
alpar@464
   380
% in \parseargline; it could be more or less anything, its purpose is
alpar@464
   381
% just to delimit the argument to the \c.
alpar@464
   382
\def\argremovec#1\c#2\relax{\toks0 = {#1}}
alpar@464
   383
\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
alpar@464
   384
alpar@464
   385
% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
alpar@464
   386
%    @end itemize  @c foo
alpar@464
   387
% will have two active spaces as part of the argument with the
alpar@464
   388
% `itemize'.  Here we remove all active spaces from #1, and assign the
alpar@464
   389
% result to \toks0.
alpar@464
   390
%
alpar@464
   391
% This loses if there are any *other* active characters besides spaces
alpar@464
   392
% in the argument -- _ ^ +, for example -- since they get expanded.
alpar@464
   393
% Fortunately, Texinfo does not define any such commands.  (If it ever
alpar@464
   394
% does, the catcode of the characters in questionwill have to be changed
alpar@464
   395
% here.)  But this means we cannot call \removeactivespaces as part of
alpar@464
   396
% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
alpar@464
   397
% that \parsearg gets might well have any character at all in it.
alpar@464
   398
%
alpar@464
   399
\def\removeactivespaces#1{%
alpar@464
   400
  \begingroup
alpar@464
   401
    \ignoreactivespaces
alpar@464
   402
    \edef\temp{#1}%
alpar@464
   403
    \global\toks0 = \expandafter{\temp}%
alpar@464
   404
  \endgroup
alpar@464
   405
}
alpar@464
   406
alpar@464
   407
% Change the active space to expand to nothing.
alpar@464
   408
%
alpar@464
   409
\begingroup
alpar@464
   410
  \obeyspaces
alpar@464
   411
  \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
alpar@464
   412
\endgroup
alpar@464
   413
alpar@464
   414
alpar@464
   415
\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
alpar@464
   416
alpar@464
   417
%% These are used to keep @begin/@end levels from running away
alpar@464
   418
%% Call \inENV within environments (after a \begingroup)
alpar@464
   419
\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
alpar@464
   420
\def\ENVcheck{%
alpar@464
   421
\ifENV\errmessage{Still within an environment; press RETURN to continue}
alpar@464
   422
\endgroup\fi} % This is not perfect, but it should reduce lossage
alpar@464
   423
alpar@464
   424
% @begin foo  is the same as @foo, for now.
alpar@464
   425
\newhelp\EMsimple{Press RETURN to continue.}
alpar@464
   426
alpar@464
   427
\outer\def\begin{\parsearg\beginxxx}
alpar@464
   428
alpar@464
   429
\def\beginxxx #1{%
alpar@464
   430
\expandafter\ifx\csname #1\endcsname\relax
alpar@464
   431
{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
alpar@464
   432
\csname #1\endcsname\fi}
alpar@464
   433
alpar@464
   434
% @end foo executes the definition of \Efoo.
alpar@464
   435
%
alpar@464
   436
\def\end{\parsearg\endxxx}
alpar@464
   437
\def\endxxx #1{%
alpar@464
   438
  \removeactivespaces{#1}%
alpar@464
   439
  \edef\endthing{\the\toks0}%
alpar@464
   440
  %
alpar@464
   441
  \expandafter\ifx\csname E\endthing\endcsname\relax
alpar@464
   442
    \expandafter\ifx\csname \endthing\endcsname\relax
alpar@464
   443
      % There's no \foo, i.e., no ``environment'' foo.
alpar@464
   444
      \errhelp = \EMsimple
alpar@464
   445
      \errmessage{Undefined command `@end \endthing'}%
alpar@464
   446
    \else
alpar@464
   447
      \unmatchedenderror\endthing
alpar@464
   448
    \fi
alpar@464
   449
  \else
alpar@464
   450
    % Everything's ok; the right environment has been started.
alpar@464
   451
    \csname E\endthing\endcsname
alpar@464
   452
  \fi
alpar@464
   453
}
alpar@464
   454
alpar@464
   455
% There is an environment #1, but it hasn't been started.  Give an error.
alpar@464
   456
%
alpar@464
   457
\def\unmatchedenderror#1{%
alpar@464
   458
  \errhelp = \EMsimple
alpar@464
   459
  \errmessage{This `@end #1' doesn't have a matching `@#1'}%
alpar@464
   460
}
alpar@464
   461
alpar@464
   462
% Define the control sequence \E#1 to give an unmatched @end error.
alpar@464
   463
%
alpar@464
   464
\def\defineunmatchedend#1{%
alpar@464
   465
  \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
alpar@464
   466
}
alpar@464
   467
alpar@464
   468
alpar@464
   469
%% Simple single-character @ commands
alpar@464
   470
alpar@464
   471
% @@ prints an @
alpar@464
   472
% Kludge this until the fonts are right (grr).
alpar@464
   473
\def\@{{\tt\char64}}
alpar@464
   474
alpar@464
   475
% This is turned off because it was never documented
alpar@464
   476
% and you can use @w{...} around a quote to suppress ligatures.
alpar@464
   477
%% Define @` and @' to be the same as ` and '
alpar@464
   478
%% but suppressing ligatures.
alpar@464
   479
%\def\`{{`}}
alpar@464
   480
%\def\'{{'}}
alpar@464
   481
alpar@464
   482
% Used to generate quoted braces.
alpar@464
   483
\def\mylbrace {{\tt\char123}}
alpar@464
   484
\def\myrbrace {{\tt\char125}}
alpar@464
   485
\let\{=\mylbrace
alpar@464
   486
\let\}=\myrbrace
alpar@464
   487
\begingroup
alpar@464
   488
  % Definitions to produce \{ and \} commands for indices,
alpar@464
   489
  % and @{ and @} for the aux file.
alpar@464
   490
  \catcode`\{ = \other \catcode`\} = \other
alpar@464
   491
  \catcode`\[ = 1 \catcode`\] = 2
alpar@464
   492
  \catcode`\! = 0 \catcode`\\ = \other
alpar@464
   493
  !gdef!lbracecmd[\{]%
alpar@464
   494
  !gdef!rbracecmd[\}]%
alpar@464
   495
  !gdef!lbraceatcmd[@{]%
alpar@464
   496
  !gdef!rbraceatcmd[@}]%
alpar@464
   497
!endgroup
alpar@464
   498
alpar@464
   499
% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
alpar@464
   500
% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
alpar@464
   501
\let\, = \c
alpar@464
   502
\let\dotaccent = \.
alpar@464
   503
\def\ringaccent#1{{\accent23 #1}}
alpar@464
   504
\let\tieaccent = \t
alpar@464
   505
\let\ubaraccent = \b
alpar@464
   506
\let\udotaccent = \d
alpar@464
   507
alpar@464
   508
% Other special characters: @questiondown @exclamdown
alpar@464
   509
% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
alpar@464
   510
\def\questiondown{?`}
alpar@464
   511
\def\exclamdown{!`}
alpar@464
   512
alpar@464
   513
% Dotless i and dotless j, used for accents.
alpar@464
   514
\def\imacro{i}
alpar@464
   515
\def\jmacro{j}
alpar@464
   516
\def\dotless#1{%
alpar@464
   517
  \def\temp{#1}%
alpar@464
   518
  \ifx\temp\imacro \ptexi
alpar@464
   519
  \else\ifx\temp\jmacro \j
alpar@464
   520
  \else \errmessage{@dotless can be used only with i or j}%
alpar@464
   521
  \fi\fi
alpar@464
   522
}
alpar@464
   523
alpar@464
   524
% Be sure we're in horizontal mode when doing a tie, since we make space
alpar@464
   525
% equivalent to this in @example-like environments. Otherwise, a space
alpar@464
   526
% at the beginning of a line will start with \penalty -- and
alpar@464
   527
% since \penalty is valid in vertical mode, we'd end up putting the
alpar@464
   528
% penalty on the vertical list instead of in the new paragraph.
alpar@464
   529
{\catcode`@ = 11
alpar@464
   530
 % Avoid using \@M directly, because that causes trouble
alpar@464
   531
 % if the definition is written into an index file.
alpar@464
   532
 \global\let\tiepenalty = \@M
alpar@464
   533
 \gdef\tie{\leavevmode\penalty\tiepenalty\ }
alpar@464
   534
}
alpar@464
   535
alpar@464
   536
% @: forces normal size whitespace following.
alpar@464
   537
\def\:{\spacefactor=1000 }
alpar@464
   538
alpar@464
   539
% @* forces a line break.
alpar@464
   540
\def\*{\hfil\break\hbox{}\ignorespaces}
alpar@464
   541
alpar@464
   542
% @/ allows a line break.
alpar@464
   543
\let\/=\allowbreak
alpar@464
   544
alpar@464
   545
% @. is an end-of-sentence period.
alpar@464
   546
\def\.{.\spacefactor=3000 }
alpar@464
   547
alpar@464
   548
% @! is an end-of-sentence bang.
alpar@464
   549
\def\!{!\spacefactor=3000 }
alpar@464
   550
alpar@464
   551
% @? is an end-of-sentence query.
alpar@464
   552
\def\?{?\spacefactor=3000 }
alpar@464
   553
alpar@464
   554
% @w prevents a word break.  Without the \leavevmode, @w at the
alpar@464
   555
% beginning of a paragraph, when TeX is still in vertical mode, would
alpar@464
   556
% produce a whole line of output instead of starting the paragraph.
alpar@464
   557
\def\w#1{\leavevmode\hbox{#1}}
alpar@464
   558
alpar@464
   559
% @group ... @end group forces ... to be all on one page, by enclosing
alpar@464
   560
% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
alpar@464
   561
% to keep its height that of a normal line.  According to the rules for
alpar@464
   562
% \topskip (p.114 of the TeXbook), the glue inserted is
alpar@464
   563
% max (\topskip - \ht (first item), 0).  If that height is large,
alpar@464
   564
% therefore, no glue is inserted, and the space between the headline and
alpar@464
   565
% the text is small, which looks bad.
alpar@464
   566
%
alpar@464
   567
% Another complication is that the group might be very large.  This can
alpar@464
   568
% cause the glue on the previous page to be unduly stretched, because it
alpar@464
   569
% does not have much material.  In this case, it's better to add an
alpar@464
   570
% explicit \vfill so that the extra space is at the bottom.  The
alpar@464
   571
% threshold for doing this is if the group is more than \vfilllimit
alpar@464
   572
% percent of a page (\vfilllimit can be changed inside of @tex).
alpar@464
   573
%
alpar@464
   574
\newbox\groupbox
alpar@464
   575
\def\vfilllimit{0.7}
alpar@464
   576
%
alpar@464
   577
\def\group{\begingroup
alpar@464
   578
  \ifnum\catcode13=\active \else
alpar@464
   579
    \errhelp = \groupinvalidhelp
alpar@464
   580
    \errmessage{@group invalid in context where filling is enabled}%
alpar@464
   581
  \fi
alpar@464
   582
  %
alpar@464
   583
  % The \vtop we start below produces a box with normal height and large
alpar@464
   584
  % depth; thus, TeX puts \baselineskip glue before it, and (when the
alpar@464
   585
  % next line of text is done) \lineskip glue after it.  (See p.82 of
alpar@464
   586
  % the TeXbook.)  Thus, space below is not quite equal to space
alpar@464
   587
  % above.  But it's pretty close.
alpar@464
   588
  \def\Egroup{%
alpar@464
   589
    \egroup           % End the \vtop.
alpar@464
   590
    % \dimen0 is the vertical size of the group's box.
alpar@464
   591
    \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
alpar@464
   592
    % \dimen2 is how much space is left on the page (more or less).
alpar@464
   593
    \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
alpar@464
   594
    % if the group doesn't fit on the current page, and it's a big big
alpar@464
   595
    % group, force a page break.
alpar@464
   596
    \ifdim \dimen0 > \dimen2
alpar@464
   597
      \ifdim \pagetotal < \vfilllimit\pageheight
alpar@464
   598
        \page
alpar@464
   599
      \fi
alpar@464
   600
    \fi
alpar@464
   601
    \copy\groupbox
alpar@464
   602
    \endgroup         % End the \group.
alpar@464
   603
  }%
alpar@464
   604
  %
alpar@464
   605
  \setbox\groupbox = \vtop\bgroup
alpar@464
   606
    % We have to put a strut on the last line in case the @group is in
alpar@464
   607
    % the midst of an example, rather than completely enclosing it.
alpar@464
   608
    % Otherwise, the interline space between the last line of the group
alpar@464
   609
    % and the first line afterwards is too small.  But we can't put the
alpar@464
   610
    % strut in \Egroup, since there it would be on a line by itself.
alpar@464
   611
    % Hence this just inserts a strut at the beginning of each line.
alpar@464
   612
    \everypar = {\strut}%
alpar@464
   613
    %
alpar@464
   614
    % Since we have a strut on every line, we don't need any of TeX's
alpar@464
   615
    % normal interline spacing.
alpar@464
   616
    \offinterlineskip
alpar@464
   617
    %
alpar@464
   618
    % OK, but now we have to do something about blank
alpar@464
   619
    % lines in the input in @example-like environments, which normally
alpar@464
   620
    % just turn into \lisppar, which will insert no space now that we've
alpar@464
   621
    % turned off the interline space.  Simplest is to make them be an
alpar@464
   622
    % empty paragraph.
alpar@464
   623
    \ifx\par\lisppar
alpar@464
   624
      \edef\par{\leavevmode \par}%
alpar@464
   625
      %
alpar@464
   626
      % Reset ^^M's definition to new definition of \par.
alpar@464
   627
      \obeylines
alpar@464
   628
    \fi
alpar@464
   629
    %
alpar@464
   630
    % Do @comment since we are called inside an environment such as
alpar@464
   631
    % @example, where each end-of-line in the input causes an
alpar@464
   632
    % end-of-line in the output.  We don't want the end-of-line after
alpar@464
   633
    % the `@group' to put extra space in the output.  Since @group
alpar@464
   634
    % should appear on a line by itself (according to the Texinfo
alpar@464
   635
    % manual), we don't worry about eating any user text.
alpar@464
   636
    \comment
alpar@464
   637
}
alpar@464
   638
%
alpar@464
   639
% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
alpar@464
   640
% message, so this ends up printing `@group can only ...'.
alpar@464
   641
%
alpar@464
   642
\newhelp\groupinvalidhelp{%
alpar@464
   643
group can only be used in environments such as @example,^^J%
alpar@464
   644
where each line of input produces a line of output.}
alpar@464
   645
alpar@464
   646
% @need space-in-mils
alpar@464
   647
% forces a page break if there is not space-in-mils remaining.
alpar@464
   648
alpar@464
   649
\newdimen\mil  \mil=0.001in
alpar@464
   650
alpar@464
   651
\def\need{\parsearg\needx}
alpar@464
   652
alpar@464
   653
% Old definition--didn't work.
alpar@464
   654
%\def\needx #1{\par %
alpar@464
   655
%% This method tries to make TeX break the page naturally
alpar@464
   656
%% if the depth of the box does not fit.
alpar@464
   657
%{\baselineskip=0pt%
alpar@464
   658
%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
alpar@464
   659
%\prevdepth=-1000pt
alpar@464
   660
%}}
alpar@464
   661
alpar@464
   662
\def\needx#1{%
alpar@464
   663
  % Ensure vertical mode, so we don't make a big box in the middle of a
alpar@464
   664
  % paragraph.
alpar@464
   665
  \par
alpar@464
   666
  %
alpar@464
   667
  % If the @need value is less than one line space, it's useless.
alpar@464
   668
  \dimen0 = #1\mil
alpar@464
   669
  \dimen2 = \ht\strutbox
alpar@464
   670
  \advance\dimen2 by \dp\strutbox
alpar@464
   671
  \ifdim\dimen0 > \dimen2
alpar@464
   672
    %
alpar@464
   673
    % Do a \strut just to make the height of this box be normal, so the
alpar@464
   674
    % normal leading is inserted relative to the preceding line.
alpar@464
   675
    % And a page break here is fine.
alpar@464
   676
    \vtop to #1\mil{\strut\vfil}%
alpar@464
   677
    %
alpar@464
   678
    % TeX does not even consider page breaks if a penalty added to the
alpar@464
   679
    % main vertical list is 10000 or more.  But in order to see if the
alpar@464
   680
    % empty box we just added fits on the page, we must make it consider
alpar@464
   681
    % page breaks.  On the other hand, we don't want to actually break the
alpar@464
   682
    % page after the empty box.  So we use a penalty of 9999.
alpar@464
   683
    %
alpar@464
   684
    % There is an extremely small chance that TeX will actually break the
alpar@464
   685
    % page at this \penalty, if there are no other feasible breakpoints in
alpar@464
   686
    % sight.  (If the user is using lots of big @group commands, which
alpar@464
   687
    % almost-but-not-quite fill up a page, TeX will have a hard time doing
alpar@464
   688
    % good page breaking, for example.)  However, I could not construct an
alpar@464
   689
    % example where a page broke at this \penalty; if it happens in a real
alpar@464
   690
    % document, then we can reconsider our strategy.
alpar@464
   691
    \penalty9999
alpar@464
   692
    %
alpar@464
   693
    % Back up by the size of the box, whether we did a page break or not.
alpar@464
   694
    \kern -#1\mil
alpar@464
   695
    %
alpar@464
   696
    % Do not allow a page break right after this kern.
alpar@464
   697
    \nobreak
alpar@464
   698
  \fi
alpar@464
   699
}
alpar@464
   700
alpar@464
   701
% @br   forces paragraph break
alpar@464
   702
alpar@464
   703
\let\br = \par
alpar@464
   704
alpar@464
   705
% @dots{} output an ellipsis using the current font.
alpar@464
   706
% We do .5em per period so that it has the same spacing in a typewriter
alpar@464
   707
% font as three actual period characters.
alpar@464
   708
%
alpar@464
   709
\def\dots{%
alpar@464
   710
  \leavevmode
alpar@464
   711
  \hbox to 1.5em{%
alpar@464
   712
    \hskip 0pt plus 0.25fil minus 0.25fil
alpar@464
   713
    .\hss.\hss.%
alpar@464
   714
    \hskip 0pt plus 0.5fil minus 0.5fil
alpar@464
   715
  }%
alpar@464
   716
}
alpar@464
   717
alpar@464
   718
% @enddots{} is an end-of-sentence ellipsis.
alpar@464
   719
%
alpar@464
   720
\def\enddots{%
alpar@464
   721
  \leavevmode
alpar@464
   722
  \hbox to 2em{%
alpar@464
   723
    \hskip 0pt plus 0.25fil minus 0.25fil
alpar@464
   724
    .\hss.\hss.\hss.%
alpar@464
   725
    \hskip 0pt plus 0.5fil minus 0.5fil
alpar@464
   726
  }%
alpar@464
   727
  \spacefactor=3000
alpar@464
   728
}
alpar@464
   729
alpar@464
   730
% @page forces the start of a new page.
alpar@464
   731
%
alpar@464
   732
\def\page{\par\vfill\supereject}
alpar@464
   733
alpar@464
   734
% @exdent text....
alpar@464
   735
% outputs text on separate line in roman font, starting at standard page margin
alpar@464
   736
alpar@464
   737
% This records the amount of indent in the innermost environment.
alpar@464
   738
% That's how much \exdent should take out.
alpar@464
   739
\newskip\exdentamount
alpar@464
   740
alpar@464
   741
% This defn is used inside fill environments such as @defun.
alpar@464
   742
\def\exdent{\parsearg\exdentyyy}
alpar@464
   743
\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
alpar@464
   744
alpar@464
   745
% This defn is used inside nofill environments such as @example.
alpar@464
   746
\def\nofillexdent{\parsearg\nofillexdentyyy}
alpar@464
   747
\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
alpar@464
   748
\leftline{\hskip\leftskip{\rm#1}}}}
alpar@464
   749
alpar@464
   750
% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
alpar@464
   751
% paragraph.  For more general purposes, use the \margin insertion
alpar@464
   752
% class.  WHICH is `l' or `r'.
alpar@464
   753
%
alpar@464
   754
\newskip\inmarginspacing \inmarginspacing=1cm
alpar@464
   755
\def\strutdepth{\dp\strutbox}
alpar@464
   756
%
alpar@464
   757
\def\doinmargin#1#2{\strut\vadjust{%
alpar@464
   758
  \nobreak
alpar@464
   759
  \kern-\strutdepth
alpar@464
   760
  \vtop to \strutdepth{%
alpar@464
   761
    \baselineskip=\strutdepth
alpar@464
   762
    \vss
alpar@464
   763
    % if you have multiple lines of stuff to put here, you'll need to
alpar@464
   764
    % make the vbox yourself of the appropriate size.
alpar@464
   765
    \ifx#1l%
alpar@464
   766
      \llap{\ignorespaces #2\hskip\inmarginspacing}%
alpar@464
   767
    \else
alpar@464
   768
      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
alpar@464
   769
    \fi
alpar@464
   770
    \null
alpar@464
   771
  }%
alpar@464
   772
}}
alpar@464
   773
\def\inleftmargin{\doinmargin l}
alpar@464
   774
\def\inrightmargin{\doinmargin r}
alpar@464
   775
%
alpar@464
   776
% @inmargin{TEXT [, RIGHT-TEXT]}
alpar@464
   777
% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
alpar@464
   778
% else use TEXT for both).
alpar@464
   779
%
alpar@464
   780
\def\inmargin#1{\parseinmargin #1,,\finish}
alpar@464
   781
\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
alpar@464
   782
  \setbox0 = \hbox{\ignorespaces #2}%
alpar@464
   783
  \ifdim\wd0 > 0pt
alpar@464
   784
    \def\lefttext{#1}%  have both texts
alpar@464
   785
    \def\righttext{#2}%
alpar@464
   786
  \else
alpar@464
   787
    \def\lefttext{#1}%  have only one text
alpar@464
   788
    \def\righttext{#1}%
alpar@464
   789
  \fi
alpar@464
   790
  %
alpar@464
   791
  \ifodd\pageno
alpar@464
   792
    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
alpar@464
   793
  \else
alpar@464
   794
    \def\temp{\inleftmargin\lefttext}%
alpar@464
   795
  \fi
alpar@464
   796
  \temp
alpar@464
   797
}
alpar@464
   798
alpar@464
   799
% @include file    insert text of that file as input.
alpar@464
   800
% Allow normal characters that  we make active in the argument (a file name).
alpar@464
   801
\def\include{\begingroup
alpar@464
   802
  \catcode`\\=\other
alpar@464
   803
  \catcode`~=\other
alpar@464
   804
  \catcode`^=\other
alpar@464
   805
  \catcode`_=\other
alpar@464
   806
  \catcode`|=\other
alpar@464
   807
  \catcode`<=\other
alpar@464
   808
  \catcode`>=\other
alpar@464
   809
  \catcode`+=\other
alpar@464
   810
  \parsearg\includezzz}
alpar@464
   811
% Restore active chars for included file.
alpar@464
   812
\def\includezzz#1{\endgroup\begingroup
alpar@464
   813
  % Read the included file in a group so nested @include's work.
alpar@464
   814
  \def\thisfile{#1}%
alpar@464
   815
  \let\value=\expandablevalue
alpar@464
   816
  \input\thisfile
alpar@464
   817
\endgroup}
alpar@464
   818
alpar@464
   819
\def\thisfile{}
alpar@464
   820
alpar@464
   821
% @center line
alpar@464
   822
% outputs that line, centered.
alpar@464
   823
%
alpar@464
   824
\def\center{\parsearg\docenter}
alpar@464
   825
\def\docenter#1{{%
alpar@464
   826
  \ifhmode \hfil\break \fi
alpar@464
   827
  \advance\hsize by -\leftskip
alpar@464
   828
  \advance\hsize by -\rightskip
alpar@464
   829
  \line{\hfil \ignorespaces#1\unskip \hfil}%
alpar@464
   830
  \ifhmode \break \fi
alpar@464
   831
}}
alpar@464
   832
alpar@464
   833
% @sp n   outputs n lines of vertical space
alpar@464
   834
alpar@464
   835
\def\sp{\parsearg\spxxx}
alpar@464
   836
\def\spxxx #1{\vskip #1\baselineskip}
alpar@464
   837
alpar@464
   838
% @comment ...line which is ignored...
alpar@464
   839
% @c is the same as @comment
alpar@464
   840
% @ignore ... @end ignore  is another way to write a comment
alpar@464
   841
alpar@464
   842
\def\comment{\begingroup \catcode`\^^M=\other%
alpar@464
   843
\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
alpar@464
   844
\commentxxx}
alpar@464
   845
{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
alpar@464
   846
alpar@464
   847
\let\c=\comment
alpar@464
   848
alpar@464
   849
% @paragraphindent NCHARS
alpar@464
   850
% We'll use ems for NCHARS, close enough.
alpar@464
   851
% NCHARS can also be the word `asis' or `none'.
alpar@464
   852
% We cannot feasibly implement @paragraphindent asis, though.
alpar@464
   853
%
alpar@464
   854
\def\asisword{asis} % no translation, these are keywords
alpar@464
   855
\def\noneword{none}
alpar@464
   856
%
alpar@464
   857
\def\paragraphindent{\parsearg\doparagraphindent}
alpar@464
   858
\def\doparagraphindent#1{%
alpar@464
   859
  \def\temp{#1}%
alpar@464
   860
  \ifx\temp\asisword
alpar@464
   861
  \else
alpar@464
   862
    \ifx\temp\noneword
alpar@464
   863
      \defaultparindent = 0pt
alpar@464
   864
    \else
alpar@464
   865
      \defaultparindent = #1em
alpar@464
   866
    \fi
alpar@464
   867
  \fi
alpar@464
   868
  \parindent = \defaultparindent
alpar@464
   869
}
alpar@464
   870
alpar@464
   871
% @exampleindent NCHARS
alpar@464
   872
% We'll use ems for NCHARS like @paragraphindent.
alpar@464
   873
% It seems @exampleindent asis isn't necessary, but
alpar@464
   874
% I preserve it to make it similar to @paragraphindent.
alpar@464
   875
\def\exampleindent{\parsearg\doexampleindent}
alpar@464
   876
\def\doexampleindent#1{%
alpar@464
   877
  \def\temp{#1}%
alpar@464
   878
  \ifx\temp\asisword
alpar@464
   879
  \else
alpar@464
   880
    \ifx\temp\noneword
alpar@464
   881
      \lispnarrowing = 0pt
alpar@464
   882
    \else
alpar@464
   883
      \lispnarrowing = #1em
alpar@464
   884
    \fi
alpar@464
   885
  \fi
alpar@464
   886
}
alpar@464
   887
alpar@464
   888
% @firstparagraphindent WORD
alpar@464
   889
% If WORD is `none', then suppress indentation of the first paragraph
alpar@464
   890
% after a section heading.  If WORD is `insert', then do indent at such
alpar@464
   891
% paragraphs.
alpar@464
   892
%
alpar@464
   893
% The paragraph indentation is suppressed or not by calling
alpar@464
   894
% \suppressfirstparagraphindent, which the sectioning commands do.
alpar@464
   895
% We switch the definition of this back and forth according to WORD.
alpar@464
   896
% By default, we suppress indentation.
alpar@464
   897
%
alpar@464
   898
\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
alpar@464
   899
\newdimen\currentparindent
alpar@464
   900
%
alpar@464
   901
\def\insertword{insert}
alpar@464
   902
%
alpar@464
   903
\def\firstparagraphindent{\parsearg\dofirstparagraphindent}
alpar@464
   904
\def\dofirstparagraphindent#1{%
alpar@464
   905
  \def\temp{#1}%
alpar@464
   906
  \ifx\temp\noneword
alpar@464
   907
    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
alpar@464
   908
  \else\ifx\temp\insertword
alpar@464
   909
    \let\suppressfirstparagraphindent = \relax
alpar@464
   910
  \else
alpar@464
   911
    \errhelp = \EMsimple
alpar@464
   912
    \errmessage{Unknown @firstparagraphindent option `\temp'}%
alpar@464
   913
  \fi\fi
alpar@464
   914
}
alpar@464
   915
alpar@464
   916
% Here is how we actually suppress indentation.  Redefine \everypar to
alpar@464
   917
% \kern backwards by \parindent, and then reset itself to empty.
alpar@464
   918
%
alpar@464
   919
% We also make \indent itself not actually do anything until the next
alpar@464
   920
% paragraph.
alpar@464
   921
%
alpar@464
   922
\gdef\dosuppressfirstparagraphindent{%
alpar@464
   923
  \gdef\indent{%
alpar@464
   924
    \global\let\indent=\ptexindent
alpar@464
   925
    \global\everypar = {}%
alpar@464
   926
  }%
alpar@464
   927
  \global\everypar = {%
alpar@464
   928
    \kern-\parindent
alpar@464
   929
    \global\let\indent=\ptexindent
alpar@464
   930
    \global\everypar = {}%
alpar@464
   931
  }%
alpar@464
   932
}%
alpar@464
   933
alpar@464
   934
alpar@464
   935
% @asis just yields its argument.  Used with @table, for example.
alpar@464
   936
%
alpar@464
   937
\def\asis#1{#1}
alpar@464
   938
alpar@464
   939
% @math outputs its argument in math mode.
alpar@464
   940
% We don't use $'s directly in the definition of \math because we need
alpar@464
   941
% to set catcodes according to plain TeX first, to allow for subscripts,
alpar@464
   942
% superscripts, special math chars, etc.
alpar@464
   943
%
alpar@464
   944
\let\implicitmath = $%$ font-lock fix
alpar@464
   945
%
alpar@464
   946
% One complication: _ usually means subscripts, but it could also mean
alpar@464
   947
% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
alpar@464
   948
% _ within @math be active (mathcode "8000), and distinguish by seeing
alpar@464
   949
% if the current family is \slfam, which is what @var uses.
alpar@464
   950
%
alpar@464
   951
{\catcode\underChar = \active
alpar@464
   952
\gdef\mathunderscore{%
alpar@464
   953
  \catcode\underChar=\active
alpar@464
   954
  \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
alpar@464
   955
}}
alpar@464
   956
%
alpar@464
   957
% Another complication: we want \\ (and @\) to output a \ character.
alpar@464
   958
% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
alpar@464
   959
% this is not advertised and we don't care.  Texinfo does not
alpar@464
   960
% otherwise define @\.
alpar@464
   961
%
alpar@464
   962
% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
alpar@464
   963
\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
alpar@464
   964
%
alpar@464
   965
\def\math{%
alpar@464
   966
  \tex
alpar@464
   967
  \mathcode`\_="8000 \mathunderscore
alpar@464
   968
  \let\\ = \mathbackslash
alpar@464
   969
  \mathactive
alpar@464
   970
  \implicitmath\finishmath}
alpar@464
   971
\def\finishmath#1{#1\implicitmath\Etex}
alpar@464
   972
alpar@464
   973
% Some active characters (such as <) are spaced differently in math.
alpar@464
   974
% We have to reset their definitions in case the @math was an
alpar@464
   975
% argument to a command which set the catcodes (such as @item or @section).
alpar@464
   976
%
alpar@464
   977
{
alpar@464
   978
  \catcode`^ = \active
alpar@464
   979
  \catcode`< = \active
alpar@464
   980
  \catcode`> = \active
alpar@464
   981
  \catcode`+ = \active
alpar@464
   982
  \gdef\mathactive{%
alpar@464
   983
    \let^ = \ptexhat
alpar@464
   984
    \let< = \ptexless
alpar@464
   985
    \let> = \ptexgtr
alpar@464
   986
    \let+ = \ptexplus
alpar@464
   987
  }
alpar@464
   988
}
alpar@464
   989
alpar@464
   990
% @bullet and @minus need the same treatment as @math, just above.
alpar@464
   991
\def\bullet{\implicitmath\ptexbullet\implicitmath}
alpar@464
   992
\def\minus{\implicitmath-\implicitmath}
alpar@464
   993
alpar@464
   994
% @refill is a no-op.
alpar@464
   995
\let\refill=\relax
alpar@464
   996
alpar@464
   997
% If working on a large document in chapters, it is convenient to
alpar@464
   998
% be able to disable indexing, cross-referencing, and contents, for test runs.
alpar@464
   999
% This is done with @novalidate (before @setfilename).
alpar@464
  1000
%
alpar@464
  1001
\newif\iflinks \linkstrue % by default we want the aux files.
alpar@464
  1002
\let\novalidate = \linksfalse
alpar@464
  1003
alpar@464
  1004
% @setfilename is done at the beginning of every texinfo file.
alpar@464
  1005
% So open here the files we need to have open while reading the input.
alpar@464
  1006
% This makes it possible to make a .fmt file for texinfo.
alpar@464
  1007
\def\setfilename{%
alpar@464
  1008
   \iflinks
alpar@464
  1009
     \readauxfile
alpar@464
  1010
   \fi % \openindices needs to do some work in any case.
alpar@464
  1011
   \openindices
alpar@464
  1012
   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
alpar@464
  1013
   \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
alpar@464
  1014
   %
alpar@464
  1015
   % If texinfo.cnf is present on the system, read it.
alpar@464
  1016
   % Useful for site-wide @afourpaper, etc.
alpar@464
  1017
   % Just to be on the safe side, close the input stream before the \input.
alpar@464
  1018
   \openin 1 texinfo.cnf
alpar@464
  1019
   \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi
alpar@464
  1020
   \closein1
alpar@464
  1021
   \temp
alpar@464
  1022
   %
alpar@464
  1023
   \comment % Ignore the actual filename.
alpar@464
  1024
}
alpar@464
  1025
alpar@464
  1026
% Called from \setfilename.
alpar@464
  1027
%
alpar@464
  1028
\def\openindices{%
alpar@464
  1029
  \newindex{cp}%
alpar@464
  1030
  \newcodeindex{fn}%
alpar@464
  1031
  \newcodeindex{vr}%
alpar@464
  1032
  \newcodeindex{tp}%
alpar@464
  1033
  \newcodeindex{ky}%
alpar@464
  1034
  \newcodeindex{pg}%
alpar@464
  1035
}
alpar@464
  1036
alpar@464
  1037
% @bye.
alpar@464
  1038
\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
alpar@464
  1039
alpar@464
  1040
alpar@464
  1041
\message{pdf,}
alpar@464
  1042
% adobe `portable' document format
alpar@464
  1043
\newcount\tempnum
alpar@464
  1044
\newcount\lnkcount
alpar@464
  1045
\newtoks\filename
alpar@464
  1046
\newcount\filenamelength
alpar@464
  1047
\newcount\pgn
alpar@464
  1048
\newtoks\toksA
alpar@464
  1049
\newtoks\toksB
alpar@464
  1050
\newtoks\toksC
alpar@464
  1051
\newtoks\toksD
alpar@464
  1052
\newbox\boxA
alpar@464
  1053
\newcount\countA
alpar@464
  1054
\newif\ifpdf
alpar@464
  1055
\newif\ifpdfmakepagedest
alpar@464
  1056
alpar@464
  1057
\ifx\pdfoutput\undefined
alpar@464
  1058
  \pdffalse
alpar@464
  1059
  \let\pdfmkdest = \gobble
alpar@464
  1060
  \let\pdfurl = \gobble
alpar@464
  1061
  \let\endlink = \relax
alpar@464
  1062
  \let\linkcolor = \relax
alpar@464
  1063
  \let\pdfmakeoutlines = \relax
alpar@464
  1064
\else
alpar@464
  1065
  \pdftrue
alpar@464
  1066
  \pdfoutput = 1
alpar@464
  1067
  \input pdfcolor
alpar@464
  1068
  \def\dopdfimage#1#2#3{%
alpar@464
  1069
    \def\imagewidth{#2}%
alpar@464
  1070
    \def\imageheight{#3}%
alpar@464
  1071
    % without \immediate, pdftex seg faults when the same image is
alpar@464
  1072
    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
alpar@464
  1073
    \ifnum\pdftexversion < 14
alpar@464
  1074
      \immediate\pdfimage
alpar@464
  1075
    \else
alpar@464
  1076
      \immediate\pdfximage
alpar@464
  1077
    \fi
alpar@464
  1078
      \ifx\empty\imagewidth\else width \imagewidth \fi
alpar@464
  1079
      \ifx\empty\imageheight\else height \imageheight \fi
alpar@464
  1080
      \ifnum\pdftexversion<13
alpar@464
  1081
         #1.pdf%
alpar@464
  1082
       \else
alpar@464
  1083
         {#1.pdf}%
alpar@464
  1084
       \fi
alpar@464
  1085
    \ifnum\pdftexversion < 14 \else
alpar@464
  1086
      \pdfrefximage \pdflastximage
alpar@464
  1087
    \fi}
alpar@464
  1088
  \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}}
alpar@464
  1089
  \def\pdfmkpgn#1{#1}
alpar@464
  1090
  \let\linkcolor = \Blue  % was Cyan, but that seems light?
alpar@464
  1091
  \def\endlink{\Black\pdfendlink}
alpar@464
  1092
  % Adding outlines to PDF; macros for calculating structure of outlines
alpar@464
  1093
  % come from Petr Olsak
alpar@464
  1094
  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
alpar@464
  1095
    \else \csname#1\endcsname \fi}
alpar@464
  1096
  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
alpar@464
  1097
    \advance\tempnum by1
alpar@464
  1098
    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
alpar@464
  1099
  \def\pdfmakeoutlines{{%
alpar@464
  1100
    \openin 1 \jobname.toc
alpar@464
  1101
    \ifeof 1\else\begingroup
alpar@464
  1102
      \closein 1
alpar@464
  1103
      % Thanh's hack / proper braces in bookmarks
alpar@464
  1104
      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
alpar@464
  1105
      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
alpar@464
  1106
      %
alpar@464
  1107
      \def\chapentry ##1##2##3{}
alpar@464
  1108
      \def\secentry ##1##2##3##4{\advancenumber{chap##2}}
alpar@464
  1109
      \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}}
alpar@464
  1110
      \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}}
alpar@464
  1111
      \let\appendixentry = \chapentry
alpar@464
  1112
      \let\unnumbchapentry = \chapentry
alpar@464
  1113
      \let\unnumbsecentry = \secentry
alpar@464
  1114
      \let\unnumbsubsecentry = \subsecentry
alpar@464
  1115
      \let\unnumbsubsubsecentry = \subsubsecentry
alpar@464
  1116
      \input \jobname.toc
alpar@464
  1117
      \def\chapentry ##1##2##3{%
alpar@464
  1118
        \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}}
alpar@464
  1119
      \def\secentry ##1##2##3##4{%
alpar@464
  1120
        \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}}
alpar@464
  1121
      \def\subsecentry ##1##2##3##4##5{%
alpar@464
  1122
        \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}}
alpar@464
  1123
      \def\subsubsecentry ##1##2##3##4##5##6{%
alpar@464
  1124
        \pdfoutline goto name{\pdfmkpgn{##6}}{##1}}
alpar@464
  1125
      \let\appendixentry = \chapentry
alpar@464
  1126
      \let\unnumbchapentry = \chapentry
alpar@464
  1127
      \let\unnumbsecentry = \secentry
alpar@464
  1128
      \let\unnumbsubsecentry = \subsecentry
alpar@464
  1129
      \let\unnumbsubsubsecentry = \subsubsecentry
alpar@464
  1130
      %
alpar@464
  1131
      % Make special characters normal for writing to the pdf file.
alpar@464
  1132
      %
alpar@464
  1133
      \indexnofonts
alpar@464
  1134
      \let\tt=\relax
alpar@464
  1135
      \turnoffactive
alpar@464
  1136
      \input \jobname.toc
alpar@464
  1137
    \endgroup\fi
alpar@464
  1138
  }}
alpar@464
  1139
  \def\makelinks #1,{%
alpar@464
  1140
    \def\params{#1}\def\E{END}%
alpar@464
  1141
    \ifx\params\E
alpar@464
  1142
      \let\nextmakelinks=\relax
alpar@464
  1143
    \else
alpar@464
  1144
      \let\nextmakelinks=\makelinks
alpar@464
  1145
      \ifnum\lnkcount>0,\fi
alpar@464
  1146
      \picknum{#1}%
alpar@464
  1147
      \startlink attr{/Border [0 0 0]}
alpar@464
  1148
        goto name{\pdfmkpgn{\the\pgn}}%
alpar@464
  1149
      \linkcolor #1%
alpar@464
  1150
      \advance\lnkcount by 1%
alpar@464
  1151
      \endlink
alpar@464
  1152
    \fi
alpar@464
  1153
    \nextmakelinks
alpar@464
  1154
  }
alpar@464
  1155
  \def\picknum#1{\expandafter\pn#1}
alpar@464
  1156
  \def\pn#1{%
alpar@464
  1157
    \def\p{#1}%
alpar@464
  1158
    \ifx\p\lbrace
alpar@464
  1159
      \let\nextpn=\ppn
alpar@464
  1160
    \else
alpar@464
  1161
      \let\nextpn=\ppnn
alpar@464
  1162
      \def\first{#1}
alpar@464
  1163
    \fi
alpar@464
  1164
    \nextpn
alpar@464
  1165
  }
alpar@464
  1166
  \def\ppn#1{\pgn=#1\gobble}
alpar@464
  1167
  \def\ppnn{\pgn=\first}
alpar@464
  1168
  \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,}
alpar@464
  1169
  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
alpar@464
  1170
  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
alpar@464
  1171
    \ifx\PP\D\let\nextsp\relax
alpar@464
  1172
    \else\let\nextsp\skipspaces
alpar@464
  1173
      \ifx\p\space\else\addtokens{\filename}{\PP}%
alpar@464
  1174
        \advance\filenamelength by 1
alpar@464
  1175
      \fi
alpar@464
  1176
    \fi
alpar@464
  1177
    \nextsp}
alpar@464
  1178
  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
alpar@464
  1179
  \ifnum\pdftexversion < 14
alpar@464
  1180
    \let \startlink \pdfannotlink
alpar@464
  1181
  \else
alpar@464
  1182
    \let \startlink \pdfstartlink
alpar@464
  1183
  \fi
alpar@464
  1184
  \def\pdfurl#1{%
alpar@464
  1185
    \begingroup
alpar@464
  1186
      \normalturnoffactive\def\@{@}%
alpar@464
  1187
      \let\value=\expandablevalue
alpar@464
  1188
      \leavevmode\Red
alpar@464
  1189
      \startlink attr{/Border [0 0 0]}%
alpar@464
  1190
        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
alpar@464
  1191
        % #1
alpar@464
  1192
    \endgroup}
alpar@464
  1193
  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
alpar@464
  1194
  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
alpar@464
  1195
  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
alpar@464
  1196
  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
alpar@464
  1197
  \def\maketoks{%
alpar@464
  1198
    \expandafter\poptoks\the\toksA|ENDTOKS|
alpar@464
  1199
    \ifx\first0\adn0
alpar@464
  1200
    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
alpar@464
  1201
    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
alpar@464
  1202
    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
alpar@464
  1203
    \else
alpar@464
  1204
      \ifnum0=\countA\else\makelink\fi
alpar@464
  1205
      \ifx\first.\let\next=\done\else
alpar@464
  1206
        \let\next=\maketoks
alpar@464
  1207
        \addtokens{\toksB}{\the\toksD}
alpar@464
  1208
        \ifx\first,\addtokens{\toksB}{\space}\fi
alpar@464
  1209
      \fi
alpar@464
  1210
    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
alpar@464
  1211
    \next}
alpar@464
  1212
  \def\makelink{\addtokens{\toksB}%
alpar@464
  1213
    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
alpar@464
  1214
  \def\pdflink#1{%
alpar@464
  1215
    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
alpar@464
  1216
    \linkcolor #1\endlink}
alpar@464
  1217
  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
alpar@464
  1218
\fi % \ifx\pdfoutput
alpar@464
  1219
alpar@464
  1220
alpar@464
  1221
\message{fonts,}
alpar@464
  1222
% Font-change commands.
alpar@464
  1223
alpar@464
  1224
% Texinfo sort of supports the sans serif font style, which plain TeX does not.
alpar@464
  1225
% So we set up a \sf analogous to plain's \rm, etc.
alpar@464
  1226
\newfam\sffam
alpar@464
  1227
\def\sf{\fam=\sffam \tensf}
alpar@464
  1228
\let\li = \sf % Sometimes we call it \li, not \sf.
alpar@464
  1229
alpar@464
  1230
% We don't need math for this one.
alpar@464
  1231
\def\ttsl{\tenttsl}
alpar@464
  1232
alpar@464
  1233
% Default leading.
alpar@464
  1234
\newdimen\textleading  \textleading = 13.2pt
alpar@464
  1235
alpar@464
  1236
% Set the baselineskip to #1, and the lineskip and strut size
alpar@464
  1237
% correspondingly.  There is no deep meaning behind these magic numbers
alpar@464
  1238
% used as factors; they just match (closely enough) what Knuth defined.
alpar@464
  1239
%
alpar@464
  1240
\def\lineskipfactor{.08333}
alpar@464
  1241
\def\strutheightpercent{.70833}
alpar@464
  1242
\def\strutdepthpercent {.29167}
alpar@464
  1243
%
alpar@464
  1244
\def\setleading#1{%
alpar@464
  1245
  \normalbaselineskip = #1\relax
alpar@464
  1246
  \normallineskip = \lineskipfactor\normalbaselineskip
alpar@464
  1247
  \normalbaselines
alpar@464
  1248
  \setbox\strutbox =\hbox{%
alpar@464
  1249
    \vrule width0pt height\strutheightpercent\baselineskip
alpar@464
  1250
                    depth \strutdepthpercent \baselineskip
alpar@464
  1251
  }%
alpar@464
  1252
}
alpar@464
  1253
alpar@464
  1254
% Set the font macro #1 to the font named #2, adding on the
alpar@464
  1255
% specified font prefix (normally `cm').
alpar@464
  1256
% #3 is the font's design size, #4 is a scale factor
alpar@464
  1257
\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
alpar@464
  1258
alpar@464
  1259
% Use cm as the default font prefix.
alpar@464
  1260
% To specify the font prefix, you must define \fontprefix
alpar@464
  1261
% before you read in texinfo.tex.
alpar@464
  1262
\ifx\fontprefix\undefined
alpar@464
  1263
\def\fontprefix{cm}
alpar@464
  1264
\fi
alpar@464
  1265
% Support font families that don't use the same naming scheme as CM.
alpar@464
  1266
\def\rmshape{r}
alpar@464
  1267
\def\rmbshape{bx}               %where the normal face is bold
alpar@464
  1268
\def\bfshape{b}
alpar@464
  1269
\def\bxshape{bx}
alpar@464
  1270
\def\ttshape{tt}
alpar@464
  1271
\def\ttbshape{tt}
alpar@464
  1272
\def\ttslshape{sltt}
alpar@464
  1273
\def\itshape{ti}
alpar@464
  1274
\def\itbshape{bxti}
alpar@464
  1275
\def\slshape{sl}
alpar@464
  1276
\def\slbshape{bxsl}
alpar@464
  1277
\def\sfshape{ss}
alpar@464
  1278
\def\sfbshape{ss}
alpar@464
  1279
\def\scshape{csc}
alpar@464
  1280
\def\scbshape{csc}
alpar@464
  1281
alpar@464
  1282
\newcount\mainmagstep
alpar@464
  1283
\ifx\bigger\relax
alpar@464
  1284
  % not really supported.
alpar@464
  1285
  \mainmagstep=\magstep1
alpar@464
  1286
  \setfont\textrm\rmshape{12}{1000}
alpar@464
  1287
  \setfont\texttt\ttshape{12}{1000}
alpar@464
  1288
\else
alpar@464
  1289
  \mainmagstep=\magstephalf
alpar@464
  1290
  \setfont\textrm\rmshape{10}{\mainmagstep}
alpar@464
  1291
  \setfont\texttt\ttshape{10}{\mainmagstep}
alpar@464
  1292
\fi
alpar@464
  1293
% Instead of cmb10, you may want to use cmbx10.
alpar@464
  1294
% cmbx10 is a prettier font on its own, but cmb10
alpar@464
  1295
% looks better when embedded in a line with cmr10
alpar@464
  1296
% (in Bob's opinion).
alpar@464
  1297
\setfont\textbf\bfshape{10}{\mainmagstep}
alpar@464
  1298
\setfont\textit\itshape{10}{\mainmagstep}
alpar@464
  1299
\setfont\textsl\slshape{10}{\mainmagstep}
alpar@464
  1300
\setfont\textsf\sfshape{10}{\mainmagstep}
alpar@464
  1301
\setfont\textsc\scshape{10}{\mainmagstep}
alpar@464
  1302
\setfont\textttsl\ttslshape{10}{\mainmagstep}
alpar@464
  1303
\font\texti=cmmi10 scaled \mainmagstep
alpar@464
  1304
\font\textsy=cmsy10 scaled \mainmagstep
alpar@464
  1305
alpar@464
  1306
% A few fonts for @defun, etc.
alpar@464
  1307
\setfont\defbf\bxshape{10}{\magstep1} %was 1314
alpar@464
  1308
\setfont\deftt\ttshape{10}{\magstep1}
alpar@464
  1309
\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
alpar@464
  1310
alpar@464
  1311
% Fonts for indices, footnotes, small examples (9pt).
alpar@464
  1312
\setfont\smallrm\rmshape{9}{1000}
alpar@464
  1313
\setfont\smalltt\ttshape{9}{1000}
alpar@464
  1314
\setfont\smallbf\bfshape{10}{900}
alpar@464
  1315
\setfont\smallit\itshape{9}{1000}
alpar@464
  1316
\setfont\smallsl\slshape{9}{1000}
alpar@464
  1317
\setfont\smallsf\sfshape{9}{1000}
alpar@464
  1318
\setfont\smallsc\scshape{10}{900}
alpar@464
  1319
\setfont\smallttsl\ttslshape{10}{900}
alpar@464
  1320
\font\smalli=cmmi9
alpar@464
  1321
\font\smallsy=cmsy9
alpar@464
  1322
alpar@464
  1323
% Fonts for small examples (8pt).
alpar@464
  1324
\setfont\smallerrm\rmshape{8}{1000}
alpar@464
  1325
\setfont\smallertt\ttshape{8}{1000}
alpar@464
  1326
\setfont\smallerbf\bfshape{10}{800}
alpar@464
  1327
\setfont\smallerit\itshape{8}{1000}
alpar@464
  1328
\setfont\smallersl\slshape{8}{1000}
alpar@464
  1329
\setfont\smallersf\sfshape{8}{1000}
alpar@464
  1330
\setfont\smallersc\scshape{10}{800}
alpar@464
  1331
\setfont\smallerttsl\ttslshape{10}{800}
alpar@464
  1332
\font\smalleri=cmmi8
alpar@464
  1333
\font\smallersy=cmsy8
alpar@464
  1334
alpar@464
  1335
% Fonts for title page:
alpar@464
  1336
\setfont\titlerm\rmbshape{12}{\magstep3}
alpar@464
  1337
\setfont\titleit\itbshape{10}{\magstep4}
alpar@464
  1338
\setfont\titlesl\slbshape{10}{\magstep4}
alpar@464
  1339
\setfont\titlett\ttbshape{12}{\magstep3}
alpar@464
  1340
\setfont\titlettsl\ttslshape{10}{\magstep4}
alpar@464
  1341
\setfont\titlesf\sfbshape{17}{\magstep1}
alpar@464
  1342
\let\titlebf=\titlerm
alpar@464
  1343
\setfont\titlesc\scbshape{10}{\magstep4}
alpar@464
  1344
\font\titlei=cmmi12 scaled \magstep3
alpar@464
  1345
\font\titlesy=cmsy10 scaled \magstep4
alpar@464
  1346
\def\authorrm{\secrm}
alpar@464
  1347
\def\authortt{\sectt}
alpar@464
  1348
alpar@464
  1349
% Chapter (and unnumbered) fonts (17.28pt).
alpar@464
  1350
\setfont\chaprm\rmbshape{12}{\magstep2}
alpar@464
  1351
\setfont\chapit\itbshape{10}{\magstep3}
alpar@464
  1352
\setfont\chapsl\slbshape{10}{\magstep3}
alpar@464
  1353
\setfont\chaptt\ttbshape{12}{\magstep2}
alpar@464
  1354
\setfont\chapttsl\ttslshape{10}{\magstep3}
alpar@464
  1355
\setfont\chapsf\sfbshape{17}{1000}
alpar@464
  1356
\let\chapbf=\chaprm
alpar@464
  1357
\setfont\chapsc\scbshape{10}{\magstep3}
alpar@464
  1358
\font\chapi=cmmi12 scaled \magstep2
alpar@464
  1359
\font\chapsy=cmsy10 scaled \magstep3
alpar@464
  1360
alpar@464
  1361
% Section fonts (14.4pt).
alpar@464
  1362
\setfont\secrm\rmbshape{12}{\magstep1}
alpar@464
  1363
\setfont\secit\itbshape{10}{\magstep2}
alpar@464
  1364
\setfont\secsl\slbshape{10}{\magstep2}
alpar@464
  1365
\setfont\sectt\ttbshape{12}{\magstep1}
alpar@464
  1366
\setfont\secttsl\ttslshape{10}{\magstep2}
alpar@464
  1367
\setfont\secsf\sfbshape{12}{\magstep1}
alpar@464
  1368
\let\secbf\secrm
alpar@464
  1369
\setfont\secsc\scbshape{10}{\magstep2}
alpar@464
  1370
\font\seci=cmmi12 scaled \magstep1
alpar@464
  1371
\font\secsy=cmsy10 scaled \magstep2
alpar@464
  1372
alpar@464
  1373
% Subsection fonts (13.15pt).
alpar@464
  1374
\setfont\ssecrm\rmbshape{12}{\magstephalf}
alpar@464
  1375
\setfont\ssecit\itbshape{10}{1315}
alpar@464
  1376
\setfont\ssecsl\slbshape{10}{1315}
alpar@464
  1377
\setfont\ssectt\ttbshape{12}{\magstephalf}
alpar@464
  1378
\setfont\ssecttsl\ttslshape{10}{1315}
alpar@464
  1379
\setfont\ssecsf\sfbshape{12}{\magstephalf}
alpar@464
  1380
\let\ssecbf\ssecrm
alpar@464
  1381
\setfont\ssecsc\scbshape{10}{\magstep1}
alpar@464
  1382
\font\sseci=cmmi12 scaled \magstephalf
alpar@464
  1383
\font\ssecsy=cmsy10 scaled 1315
alpar@464
  1384
% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
alpar@464
  1385
% but that is not a standard magnification.
alpar@464
  1386
alpar@464
  1387
% In order for the font changes to affect most math symbols and letters,
alpar@464
  1388
% we have to define the \textfont of the standard families.  Since
alpar@464
  1389
% texinfo doesn't allow for producing subscripts and superscripts except
alpar@464
  1390
% in the main text, we don't bother to reset \scriptfont and
alpar@464
  1391
% \scriptscriptfont (which would also require loading a lot more fonts).
alpar@464
  1392
%
alpar@464
  1393
\def\resetmathfonts{%
alpar@464
  1394
  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
alpar@464
  1395
  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
alpar@464
  1396
  \textfont\ttfam=\tentt \textfont\sffam=\tensf
alpar@464
  1397
}
alpar@464
  1398
alpar@464
  1399
% The font-changing commands redefine the meanings of \tenSTYLE, instead
alpar@464
  1400
% of just \STYLE.  We do this so that font changes will continue to work
alpar@464
  1401
% in math mode, where it is the current \fam that is relevant in most
alpar@464
  1402
% cases, not the current font.  Plain TeX does \def\bf{\fam=\bffam
alpar@464
  1403
% \tenbf}, for example.  By redefining \tenbf, we obviate the need to
alpar@464
  1404
% redefine \bf itself.
alpar@464
  1405
\def\textfonts{%
alpar@464
  1406
  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
alpar@464
  1407
  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
alpar@464
  1408
  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
alpar@464
  1409
  \resetmathfonts \setleading{\textleading}}
alpar@464
  1410
\def\titlefonts{%
alpar@464
  1411
  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
alpar@464
  1412
  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
alpar@464
  1413
  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
alpar@464
  1414
  \let\tenttsl=\titlettsl
alpar@464
  1415
  \resetmathfonts \setleading{25pt}}
alpar@464
  1416
\def\titlefont#1{{\titlefonts\rm #1}}
alpar@464
  1417
\def\chapfonts{%
alpar@464
  1418
  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
alpar@464
  1419
  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
alpar@464
  1420
  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
alpar@464
  1421
  \resetmathfonts \setleading{19pt}}
alpar@464
  1422
\def\secfonts{%
alpar@464
  1423
  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
alpar@464
  1424
  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
alpar@464
  1425
  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
alpar@464
  1426
  \resetmathfonts \setleading{16pt}}
alpar@464
  1427
\def\subsecfonts{%
alpar@464
  1428
  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
alpar@464
  1429
  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
alpar@464
  1430
  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
alpar@464
  1431
  \resetmathfonts \setleading{15pt}}
alpar@464
  1432
\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
alpar@464
  1433
\def\smallfonts{%
alpar@464
  1434
  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
alpar@464
  1435
  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
alpar@464
  1436
  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
alpar@464
  1437
  \let\tenttsl=\smallttsl
alpar@464
  1438
  \resetmathfonts \setleading{10.5pt}}
alpar@464
  1439
\def\smallerfonts{%
alpar@464
  1440
  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
alpar@464
  1441
  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
alpar@464
  1442
  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
alpar@464
  1443
  \let\tenttsl=\smallerttsl
alpar@464
  1444
  \resetmathfonts \setleading{9.5pt}}
alpar@464
  1445
alpar@464
  1446
% Set the fonts to use with the @small... environments.
alpar@464
  1447
\let\smallexamplefonts = \smallfonts
alpar@464
  1448
alpar@464
  1449
% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
alpar@464
  1450
% can fit this many characters:
alpar@464
  1451
%   8.5x11=86   smallbook=72  a4=90  a5=69
alpar@464
  1452
% If we use \smallerfonts (8pt), then we can fit this many characters:
alpar@464
  1453
%   8.5x11=90+  smallbook=80  a4=90+  a5=77
alpar@464
  1454
% For me, subjectively, the few extra characters that fit aren't worth
alpar@464
  1455
% the additional smallness of 8pt.  So I'm making the default 9pt.
alpar@464
  1456
%
alpar@464
  1457
% By the way, for comparison, here's what fits with @example (10pt):
alpar@464
  1458
%   8.5x11=71  smallbook=60  a4=75  a5=58
alpar@464
  1459
%
alpar@464
  1460
% I wish we used A4 paper on this side of the Atlantic.
alpar@464
  1461
%
alpar@464
  1462
% --karl, 24jan03.
alpar@464
  1463
alpar@464
  1464
alpar@464
  1465
% Set up the default fonts, so we can use them for creating boxes.
alpar@464
  1466
%
alpar@464
  1467
\textfonts
alpar@464
  1468
alpar@464
  1469
% Define these so they can be easily changed for other fonts.
alpar@464
  1470
\def\angleleft{$\langle$}
alpar@464
  1471
\def\angleright{$\rangle$}
alpar@464
  1472
alpar@464
  1473
% Count depth in font-changes, for error checks
alpar@464
  1474
\newcount\fontdepth \fontdepth=0
alpar@464
  1475
alpar@464
  1476
% Fonts for short table of contents.
alpar@464
  1477
\setfont\shortcontrm\rmshape{12}{1000}
alpar@464
  1478
\setfont\shortcontbf\bxshape{12}{1000}
alpar@464
  1479
\setfont\shortcontsl\slshape{12}{1000}
alpar@464
  1480
\setfont\shortconttt\ttshape{12}{1000}
alpar@464
  1481
alpar@464
  1482
%% Add scribe-like font environments, plus @l for inline lisp (usually sans
alpar@464
  1483
%% serif) and @ii for TeX italic
alpar@464
  1484
alpar@464
  1485
% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
alpar@464
  1486
% unless the following character is such as not to need one.
alpar@464
  1487
\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
alpar@464
  1488
                    \ptexslash\fi\fi\fi}
alpar@464
  1489
\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
alpar@464
  1490
\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
alpar@464
  1491
alpar@464
  1492
\let\i=\smartitalic
alpar@464
  1493
\let\var=\smartslanted
alpar@464
  1494
\let\dfn=\smartslanted
alpar@464
  1495
\let\emph=\smartitalic
alpar@464
  1496
\let\cite=\smartslanted
alpar@464
  1497
alpar@464
  1498
\def\b#1{{\bf #1}}
alpar@464
  1499
\let\strong=\b
alpar@464
  1500
alpar@464
  1501
% We can't just use \exhyphenpenalty, because that only has effect at
alpar@464
  1502
% the end of a paragraph.  Restore normal hyphenation at the end of the
alpar@464
  1503
% group within which \nohyphenation is presumably called.
alpar@464
  1504
%
alpar@464
  1505
\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
alpar@464
  1506
\def\restorehyphenation{\hyphenchar\font = `- }
alpar@464
  1507
alpar@464
  1508
% Set sfcode to normal for the chars that usually have another value.
alpar@464
  1509
% Can't use plain's \frenchspacing because it uses the `\x notation, and
alpar@464
  1510
% sometimes \x has an active definition that messes things up.
alpar@464
  1511
%
alpar@464
  1512
\catcode`@=11
alpar@464
  1513
  \def\frenchspacing{%
alpar@464
  1514
    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
alpar@464
  1515
    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
alpar@464
  1516
  }
alpar@464
  1517
\catcode`@=\other
alpar@464
  1518
alpar@464
  1519
\def\t#1{%
alpar@464
  1520
  {\tt \rawbackslash \frenchspacing #1}%
alpar@464
  1521
  \null
alpar@464
  1522
}
alpar@464
  1523
\let\ttfont=\t
alpar@464
  1524
\def\samp#1{`\tclose{#1}'\null}
alpar@464
  1525
\setfont\keyrm\rmshape{8}{1000}
alpar@464
  1526
\font\keysy=cmsy9
alpar@464
  1527
\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
alpar@464
  1528
  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
alpar@464
  1529
    \vbox{\hrule\kern-0.4pt
alpar@464
  1530
     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
alpar@464
  1531
    \kern-0.4pt\hrule}%
alpar@464
  1532
  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
alpar@464
  1533
% The old definition, with no lozenge:
alpar@464
  1534
%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
alpar@464
  1535
\def\ctrl #1{{\tt \rawbackslash \hat}#1}
alpar@464
  1536
alpar@464
  1537
% @file, @option are the same as @samp.
alpar@464
  1538
\let\file=\samp
alpar@464
  1539
\let\option=\samp
alpar@464
  1540
alpar@464
  1541
% @code is a modification of @t,
alpar@464
  1542
% which makes spaces the same size as normal in the surrounding text.
alpar@464
  1543
\def\tclose#1{%
alpar@464
  1544
  {%
alpar@464
  1545
    % Change normal interword space to be same as for the current font.
alpar@464
  1546
    \spaceskip = \fontdimen2\font
alpar@464
  1547
    %
alpar@464
  1548
    % Switch to typewriter.
alpar@464
  1549
    \tt
alpar@464
  1550
    %
alpar@464
  1551
    % But `\ ' produces the large typewriter interword space.
alpar@464
  1552
    \def\ {{\spaceskip = 0pt{} }}%
alpar@464
  1553
    %
alpar@464
  1554
    % Turn off hyphenation.
alpar@464
  1555
    \nohyphenation
alpar@464
  1556
    %
alpar@464
  1557
    \rawbackslash
alpar@464
  1558
    \frenchspacing
alpar@464
  1559
    #1%
alpar@464
  1560
  }%
alpar@464
  1561
  \null
alpar@464
  1562
}
alpar@464
  1563
alpar@464
  1564
% We *must* turn on hyphenation at `-' and `_' in \code.
alpar@464
  1565
% Otherwise, it is too hard to avoid overfull hboxes
alpar@464
  1566
% in the Emacs manual, the Library manual, etc.
alpar@464
  1567
alpar@464
  1568
% Unfortunately, TeX uses one parameter (\hyphenchar) to control
alpar@464
  1569
% both hyphenation at - and hyphenation within words.
alpar@464
  1570
% We must therefore turn them both off (\tclose does that)
alpar@464
  1571
% and arrange explicitly to hyphenate at a dash.
alpar@464
  1572
%  -- rms.
alpar@464
  1573
{
alpar@464
  1574
  \catcode`\-=\active
alpar@464
  1575
  \catcode`\_=\active
alpar@464
  1576
  %
alpar@464
  1577
  \global\def\code{\begingroup
alpar@464
  1578
    \catcode`\-=\active \let-\codedash
alpar@464
  1579
    \catcode`\_=\active \let_\codeunder
alpar@464
  1580
    \codex
alpar@464
  1581
  }
alpar@464
  1582
  %
alpar@464
  1583
  % If we end up with any active - characters when handling the index,
alpar@464
  1584
  % just treat them as a normal -.
alpar@464
  1585
  \global\def\indexbreaks{\catcode`\-=\active \let-\realdash}
alpar@464
  1586
}
alpar@464
  1587
alpar@464
  1588
\def\realdash{-}
alpar@464
  1589
\def\codedash{-\discretionary{}{}{}}
alpar@464
  1590
\def\codeunder{%
alpar@464
  1591
  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
alpar@464
  1592
  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
alpar@464
  1593
  % will therefore expand the active definition of _, which is us
alpar@464
  1594
  % (inside @code that is), therefore an endless loop.
alpar@464
  1595
  \ifusingtt{\ifmmode
alpar@464
  1596
               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
alpar@464
  1597
             \else\normalunderscore \fi
alpar@464
  1598
             \discretionary{}{}{}}%
alpar@464
  1599
            {\_}%
alpar@464
  1600
}
alpar@464
  1601
\def\codex #1{\tclose{#1}\endgroup}
alpar@464
  1602
alpar@464
  1603
% @kbd is like @code, except that if the argument is just one @key command,
alpar@464
  1604
% then @kbd has no effect.
alpar@464
  1605
alpar@464
  1606
% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
alpar@464
  1607
%   `example' (@kbd uses ttsl only inside of @example and friends),
alpar@464
  1608
%   or `code' (@kbd uses normal tty font always).
alpar@464
  1609
\def\kbdinputstyle{\parsearg\kbdinputstylexxx}
alpar@464
  1610
\def\kbdinputstylexxx#1{%
alpar@464
  1611
  \def\arg{#1}%
alpar@464
  1612
  \ifx\arg\worddistinct
alpar@464
  1613
    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
alpar@464
  1614
  \else\ifx\arg\wordexample
alpar@464
  1615
    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
alpar@464
  1616
  \else\ifx\arg\wordcode
alpar@464
  1617
    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
alpar@464
  1618
  \else
alpar@464
  1619
    \errhelp = \EMsimple
alpar@464
  1620
    \errmessage{Unknown @kbdinputstyle option `\arg'}%
alpar@464
  1621
  \fi\fi\fi
alpar@464
  1622
}
alpar@464
  1623
\def\worddistinct{distinct}
alpar@464
  1624
\def\wordexample{example}
alpar@464
  1625
\def\wordcode{code}
alpar@464
  1626
alpar@464
  1627
% Default is `distinct.'
alpar@464
  1628
\kbdinputstyle distinct
alpar@464
  1629
alpar@464
  1630
\def\xkey{\key}
alpar@464
  1631
\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
alpar@464
  1632
\ifx\one\xkey\ifx\threex\three \key{#2}%
alpar@464
  1633
\else{\tclose{\kbdfont\look}}\fi
alpar@464
  1634
\else{\tclose{\kbdfont\look}}\fi}
alpar@464
  1635
alpar@464
  1636
% For @url, @env, @command quotes seem unnecessary, so use \code.
alpar@464
  1637
\let\url=\code
alpar@464
  1638
\let\env=\code
alpar@464
  1639
\let\command=\code
alpar@464
  1640
alpar@464
  1641
% @uref (abbreviation for `urlref') takes an optional (comma-separated)
alpar@464
  1642
% second argument specifying the text to display and an optional third
alpar@464
  1643
% arg as text to display instead of (rather than in addition to) the url
alpar@464
  1644
% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
alpar@464
  1645
% a hypertex \special here.
alpar@464
  1646
%
alpar@464
  1647
\def\uref#1{\douref #1,,,\finish}
alpar@464
  1648
\def\douref#1,#2,#3,#4\finish{\begingroup
alpar@464
  1649
  \unsepspaces
alpar@464
  1650
  \pdfurl{#1}%
alpar@464
  1651
  \setbox0 = \hbox{\ignorespaces #3}%
alpar@464
  1652
  \ifdim\wd0 > 0pt
alpar@464
  1653
    \unhbox0 % third arg given, show only that
alpar@464
  1654
  \else
alpar@464
  1655
    \setbox0 = \hbox{\ignorespaces #2}%
alpar@464
  1656
    \ifdim\wd0 > 0pt
alpar@464
  1657
      \ifpdf
alpar@464
  1658
        \unhbox0             % PDF: 2nd arg given, show only it
alpar@464
  1659
      \else
alpar@464
  1660
        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
alpar@464
  1661
      \fi
alpar@464
  1662
    \else
alpar@464
  1663
      \code{#1}% only url given, so show it
alpar@464
  1664
    \fi
alpar@464
  1665
  \fi
alpar@464
  1666
  \endlink
alpar@464
  1667
\endgroup}
alpar@464
  1668
alpar@464
  1669
% rms does not like angle brackets --karl, 17may97.
alpar@464
  1670
% So now @email is just like @uref, unless we are pdf.
alpar@464
  1671
%
alpar@464
  1672
%\def\email#1{\angleleft{\tt #1}\angleright}
alpar@464
  1673
\ifpdf
alpar@464
  1674
  \def\email#1{\doemail#1,,\finish}
alpar@464
  1675
  \def\doemail#1,#2,#3\finish{\begingroup
alpar@464
  1676
    \unsepspaces
alpar@464
  1677
    \pdfurl{mailto:#1}%
alpar@464
  1678
    \setbox0 = \hbox{\ignorespaces #2}%
alpar@464
  1679
    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
alpar@464
  1680
    \endlink
alpar@464
  1681
  \endgroup}
alpar@464
  1682
\else
alpar@464
  1683
  \let\email=\uref
alpar@464
  1684
\fi
alpar@464
  1685
alpar@464
  1686
% Check if we are currently using a typewriter font.  Since all the
alpar@464
  1687
% Computer Modern typewriter fonts have zero interword stretch (and
alpar@464
  1688
% shrink), and it is reasonable to expect all typewriter fonts to have
alpar@464
  1689
% this property, we can check that font parameter.
alpar@464
  1690
%
alpar@464
  1691
\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
alpar@464
  1692
alpar@464
  1693
% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
alpar@464
  1694
% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
alpar@464
  1695
%
alpar@464
  1696
\def\dmn#1{\thinspace #1}
alpar@464
  1697
alpar@464
  1698
\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
alpar@464
  1699
alpar@464
  1700
% @l was never documented to mean ``switch to the Lisp font'',
alpar@464
  1701
% and it is not used as such in any manual I can find.  We need it for
alpar@464
  1702
% Polish suppressed-l.  --karl, 22sep96.
alpar@464
  1703
%\def\l#1{{\li #1}\null}
alpar@464
  1704
alpar@464
  1705
% Explicit font changes: @r, @sc, undocumented @ii.
alpar@464
  1706
\def\r#1{{\rm #1}}              % roman font
alpar@464
  1707
\def\sc#1{{\smallcaps#1}}       % smallcaps font
alpar@464
  1708
\def\ii#1{{\it #1}}             % italic font
alpar@464
  1709
alpar@464
  1710
% @acronym downcases the argument and prints in smallcaps.
alpar@464
  1711
\def\acronym#1{{\smallcaps \lowercase{#1}}}
alpar@464
  1712
alpar@464
  1713
% @pounds{} is a sterling sign.
alpar@464
  1714
\def\pounds{{\it\$}}
alpar@464
  1715
alpar@464
  1716
% @registeredsymbol - R in a circle.  For now, only works in text size;
alpar@464
  1717
% we'd have to redo the font mechanism to change the \scriptstyle and
alpar@464
  1718
% \scriptscriptstyle font sizes to make it look right in headings.
alpar@464
  1719
% Adapted from the plain.tex definition of \copyright.
alpar@464
  1720
%
alpar@464
  1721
\def\registeredsymbol{%
alpar@464
  1722
  $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}%
alpar@464
  1723
    }$%
alpar@464
  1724
}
alpar@464
  1725
alpar@464
  1726
alpar@464
  1727
\message{page headings,}
alpar@464
  1728
alpar@464
  1729
\newskip\titlepagetopglue \titlepagetopglue = 1.5in
alpar@464
  1730
\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
alpar@464
  1731
alpar@464
  1732
% First the title page.  Must do @settitle before @titlepage.
alpar@464
  1733
\newif\ifseenauthor
alpar@464
  1734
\newif\iffinishedtitlepage
alpar@464
  1735
alpar@464
  1736
% Do an implicit @contents or @shortcontents after @end titlepage if the
alpar@464
  1737
% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
alpar@464
  1738
%
alpar@464
  1739
\newif\ifsetcontentsaftertitlepage
alpar@464
  1740
 \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
alpar@464
  1741
\newif\ifsetshortcontentsaftertitlepage
alpar@464
  1742
 \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
alpar@464
  1743
alpar@464
  1744
\def\shorttitlepage{\parsearg\shorttitlepagezzz}
alpar@464
  1745
\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
alpar@464
  1746
        \endgroup\page\hbox{}\page}
alpar@464
  1747
alpar@464
  1748
\def\titlepage{\begingroup \parindent=0pt \textfonts
alpar@464
  1749
   \let\subtitlerm=\tenrm
alpar@464
  1750
   \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
alpar@464
  1751
   %
alpar@464
  1752
   \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
alpar@464
  1753
                   \let\tt=\authortt}%
alpar@464
  1754
   %
alpar@464
  1755
   % Leave some space at the very top of the page.
alpar@464
  1756
   \vglue\titlepagetopglue
alpar@464
  1757
   %
alpar@464
  1758
   % Now you can print the title using @title.
alpar@464
  1759
   \def\title{\parsearg\titlezzz}%
alpar@464
  1760
   \def\titlezzz##1{\leftline{\titlefonts\rm ##1}
alpar@464
  1761
                    % print a rule at the page bottom also.
alpar@464
  1762
                    \finishedtitlepagefalse
alpar@464
  1763
                    \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
alpar@464
  1764
   % No rule at page bottom unless we print one at the top with @title.
alpar@464
  1765
   \finishedtitlepagetrue
alpar@464
  1766
   %
alpar@464
  1767
   % Now you can put text using @subtitle.
alpar@464
  1768
   \def\subtitle{\parsearg\subtitlezzz}%
alpar@464
  1769
   \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
alpar@464
  1770
   %
alpar@464
  1771
   % @author should come last, but may come many times.
alpar@464
  1772
   \def\author{\parsearg\authorzzz}%
alpar@464
  1773
   \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
alpar@464
  1774
      {\authorfont \leftline{##1}}}%
alpar@464
  1775
   %
alpar@464
  1776
   % Most title ``pages'' are actually two pages long, with space
alpar@464
  1777
   % at the top of the second.  We don't want the ragged left on the second.
alpar@464
  1778
   \let\oldpage = \page
alpar@464
  1779
   \def\page{%
alpar@464
  1780
      \iffinishedtitlepage\else
alpar@464
  1781
         \finishtitlepage
alpar@464
  1782
      \fi
alpar@464
  1783
      \oldpage
alpar@464
  1784
      \let\page = \oldpage
alpar@464
  1785
      \hbox{}}%
alpar@464
  1786
%   \def\page{\oldpage \hbox{}}
alpar@464
  1787
}
alpar@464
  1788
alpar@464
  1789
\def\Etitlepage{%
alpar@464
  1790
   \iffinishedtitlepage\else
alpar@464
  1791
      \finishtitlepage
alpar@464
  1792
   \fi
alpar@464
  1793
   % It is important to do the page break before ending the group,
alpar@464
  1794
   % because the headline and footline are only empty inside the group.
alpar@464
  1795
   % If we use the new definition of \page, we always get a blank page
alpar@464
  1796
   % after the title page, which we certainly don't want.
alpar@464
  1797
   \oldpage
alpar@464
  1798
   \endgroup
alpar@464
  1799
   %
alpar@464
  1800
   % Need this before the \...aftertitlepage checks so that if they are
alpar@464
  1801
   % in effect the toc pages will come out with page numbers.
alpar@464
  1802
   \HEADINGSon
alpar@464
  1803
   %
alpar@464
  1804
   % If they want short, they certainly want long too.
alpar@464
  1805
   \ifsetshortcontentsaftertitlepage
alpar@464
  1806
     \shortcontents
alpar@464
  1807
     \contents
alpar@464
  1808
     \global\let\shortcontents = \relax
alpar@464
  1809
     \global\let\contents = \relax
alpar@464
  1810
   \fi
alpar@464
  1811
   %
alpar@464
  1812
   \ifsetcontentsaftertitlepage
alpar@464
  1813
     \contents
alpar@464
  1814
     \global\let\contents = \relax
alpar@464
  1815
     \global\let\shortcontents = \relax
alpar@464
  1816
   \fi
alpar@464
  1817
}
alpar@464
  1818
alpar@464
  1819
\def\finishtitlepage{%
alpar@464
  1820
   \vskip4pt \hrule height 2pt width \hsize
alpar@464
  1821
   \vskip\titlepagebottomglue
alpar@464
  1822
   \finishedtitlepagetrue
alpar@464
  1823
}
alpar@464
  1824
alpar@464
  1825
%%% Set up page headings and footings.
alpar@464
  1826
alpar@464
  1827
\let\thispage=\folio
alpar@464
  1828
alpar@464
  1829
\newtoks\evenheadline    % headline on even pages
alpar@464
  1830
\newtoks\oddheadline     % headline on odd pages
alpar@464
  1831
\newtoks\evenfootline    % footline on even pages
alpar@464
  1832
\newtoks\oddfootline     % footline on odd pages
alpar@464
  1833
alpar@464
  1834
% Now make Tex use those variables
alpar@464
  1835
\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
alpar@464
  1836
                            \else \the\evenheadline \fi}}
alpar@464
  1837
\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
alpar@464
  1838
                            \else \the\evenfootline \fi}\HEADINGShook}
alpar@464
  1839
\let\HEADINGShook=\relax
alpar@464
  1840
alpar@464
  1841
% Commands to set those variables.
alpar@464
  1842
% For example, this is what  @headings on  does
alpar@464
  1843
% @evenheading @thistitle|@thispage|@thischapter
alpar@464
  1844
% @oddheading @thischapter|@thispage|@thistitle
alpar@464
  1845
% @evenfooting @thisfile||
alpar@464
  1846
% @oddfooting ||@thisfile
alpar@464
  1847
alpar@464
  1848
\def\evenheading{\parsearg\evenheadingxxx}
alpar@464
  1849
\def\oddheading{\parsearg\oddheadingxxx}
alpar@464
  1850
\def\everyheading{\parsearg\everyheadingxxx}
alpar@464
  1851
alpar@464
  1852
\def\evenfooting{\parsearg\evenfootingxxx}
alpar@464
  1853
\def\oddfooting{\parsearg\oddfootingxxx}
alpar@464
  1854
\def\everyfooting{\parsearg\everyfootingxxx}
alpar@464
  1855
alpar@464
  1856
{\catcode`\@=0 %
alpar@464
  1857
alpar@464
  1858
\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
alpar@464
  1859
\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
alpar@464
  1860
\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
alpar@464
  1861
alpar@464
  1862
\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
alpar@464
  1863
\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
alpar@464
  1864
\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
alpar@464
  1865
alpar@464
  1866
\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
alpar@464
  1867
alpar@464
  1868
\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
alpar@464
  1869
\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
alpar@464
  1870
\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
alpar@464
  1871
alpar@464
  1872
\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
alpar@464
  1873
\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
alpar@464
  1874
  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
alpar@464
  1875
  %
alpar@464
  1876
  % Leave some space for the footline.  Hopefully ok to assume
alpar@464
  1877
  % @evenfooting will not be used by itself.
alpar@464
  1878
  \global\advance\pageheight by -\baselineskip
alpar@464
  1879
  \global\advance\vsize by -\baselineskip
alpar@464
  1880
}
alpar@464
  1881
alpar@464
  1882
\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}}
alpar@464
  1883
%
alpar@464
  1884
}% unbind the catcode of @.
alpar@464
  1885
alpar@464
  1886
% @headings double      turns headings on for double-sided printing.
alpar@464
  1887
% @headings single      turns headings on for single-sided printing.
alpar@464
  1888
% @headings off         turns them off.
alpar@464
  1889
% @headings on          same as @headings double, retained for compatibility.
alpar@464
  1890
% @headings after       turns on double-sided headings after this page.
alpar@464
  1891
% @headings doubleafter turns on double-sided headings after this page.
alpar@464
  1892
% @headings singleafter turns on single-sided headings after this page.
alpar@464
  1893
% By default, they are off at the start of a document,
alpar@464
  1894
% and turned `on' after @end titlepage.
alpar@464
  1895
alpar@464
  1896
\def\headings #1 {\csname HEADINGS#1\endcsname}
alpar@464
  1897
alpar@464
  1898
\def\HEADINGSoff{
alpar@464
  1899
\global\evenheadline={\hfil} \global\evenfootline={\hfil}
alpar@464
  1900
\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
alpar@464
  1901
\HEADINGSoff
alpar@464
  1902
% When we turn headings on, set the page number to 1.
alpar@464
  1903
% For double-sided printing, put current file name in lower left corner,
alpar@464
  1904
% chapter name on inside top of right hand pages, document
alpar@464
  1905
% title on inside top of left hand pages, and page numbers on outside top
alpar@464
  1906
% edge of all pages.
alpar@464
  1907
\def\HEADINGSdouble{
alpar@464
  1908
\global\pageno=1
alpar@464
  1909
\global\evenfootline={\hfil}
alpar@464
  1910
\global\oddfootline={\hfil}
alpar@464
  1911
\global\evenheadline={\line{\folio\hfil\thistitle}}
alpar@464
  1912
\global\oddheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1913
\global\let\contentsalignmacro = \chapoddpage
alpar@464
  1914
}
alpar@464
  1915
\let\contentsalignmacro = \chappager
alpar@464
  1916
alpar@464
  1917
% For single-sided printing, chapter title goes across top left of page,
alpar@464
  1918
% page number on top right.
alpar@464
  1919
\def\HEADINGSsingle{
alpar@464
  1920
\global\pageno=1
alpar@464
  1921
\global\evenfootline={\hfil}
alpar@464
  1922
\global\oddfootline={\hfil}
alpar@464
  1923
\global\evenheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1924
\global\oddheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1925
\global\let\contentsalignmacro = \chappager
alpar@464
  1926
}
alpar@464
  1927
\def\HEADINGSon{\HEADINGSdouble}
alpar@464
  1928
alpar@464
  1929
\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
alpar@464
  1930
\let\HEADINGSdoubleafter=\HEADINGSafter
alpar@464
  1931
\def\HEADINGSdoublex{%
alpar@464
  1932
\global\evenfootline={\hfil}
alpar@464
  1933
\global\oddfootline={\hfil}
alpar@464
  1934
\global\evenheadline={\line{\folio\hfil\thistitle}}
alpar@464
  1935
\global\oddheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1936
\global\let\contentsalignmacro = \chapoddpage
alpar@464
  1937
}
alpar@464
  1938
alpar@464
  1939
\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
alpar@464
  1940
\def\HEADINGSsinglex{%
alpar@464
  1941
\global\evenfootline={\hfil}
alpar@464
  1942
\global\oddfootline={\hfil}
alpar@464
  1943
\global\evenheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1944
\global\oddheadline={\line{\thischapter\hfil\folio}}
alpar@464
  1945
\global\let\contentsalignmacro = \chappager
alpar@464
  1946
}
alpar@464
  1947
alpar@464
  1948
% Subroutines used in generating headings
alpar@464
  1949
% This produces Day Month Year style of output.
alpar@464
  1950
% Only define if not already defined, in case a txi-??.tex file has set
alpar@464
  1951
% up a different format (e.g., txi-cs.tex does this).
alpar@464
  1952
\ifx\today\undefined
alpar@464
  1953
\def\today{%
alpar@464
  1954
  \number\day\space
alpar@464
  1955
  \ifcase\month
alpar@464
  1956
  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
alpar@464
  1957
  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
alpar@464
  1958
  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
alpar@464
  1959
  \fi
alpar@464
  1960
  \space\number\year}
alpar@464
  1961
\fi
alpar@464
  1962
alpar@464
  1963
% @settitle line...  specifies the title of the document, for headings.
alpar@464
  1964
% It generates no output of its own.
alpar@464
  1965
\def\thistitle{\putwordNoTitle}
alpar@464
  1966
\def\settitle{\parsearg\settitlezzz}
alpar@464
  1967
\def\settitlezzz #1{\gdef\thistitle{#1}}
alpar@464
  1968
alpar@464
  1969
alpar@464
  1970
\message{tables,}
alpar@464
  1971
% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
alpar@464
  1972
alpar@464
  1973
% default indentation of table text
alpar@464
  1974
\newdimen\tableindent \tableindent=.8in
alpar@464
  1975
% default indentation of @itemize and @enumerate text
alpar@464
  1976
\newdimen\itemindent  \itemindent=.3in
alpar@464
  1977
% margin between end of table item and start of table text.
alpar@464
  1978
\newdimen\itemmargin  \itemmargin=.1in
alpar@464
  1979
alpar@464
  1980
% used internally for \itemindent minus \itemmargin
alpar@464
  1981
\newdimen\itemmax
alpar@464
  1982
alpar@464
  1983
% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
alpar@464
  1984
% these defs.
alpar@464
  1985
% They also define \itemindex
alpar@464
  1986
% to index the item name in whatever manner is desired (perhaps none).
alpar@464
  1987
alpar@464
  1988
\newif\ifitemxneedsnegativevskip
alpar@464
  1989
alpar@464
  1990
\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
alpar@464
  1991
alpar@464
  1992
\def\internalBitem{\smallbreak \parsearg\itemzzz}
alpar@464
  1993
\def\internalBitemx{\itemxpar \parsearg\itemzzz}
alpar@464
  1994
alpar@464
  1995
\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
alpar@464
  1996
\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
alpar@464
  1997
alpar@464
  1998
\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
alpar@464
  1999
\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
alpar@464
  2000
alpar@464
  2001
\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
alpar@464
  2002
                 \itemzzz {#1}}
alpar@464
  2003
alpar@464
  2004
\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
alpar@464
  2005
                 \itemzzz {#1}}
alpar@464
  2006
alpar@464
  2007
\def\itemzzz #1{\begingroup %
alpar@464
  2008
  \advance\hsize by -\rightskip
alpar@464
  2009
  \advance\hsize by -\tableindent
alpar@464
  2010
  \setbox0=\hbox{\itemfont{#1}}%
alpar@464
  2011
  \itemindex{#1}%
alpar@464
  2012
  \nobreak % This prevents a break before @itemx.
alpar@464
  2013
  %
alpar@464
  2014
  % If the item text does not fit in the space we have, put it on a line
alpar@464
  2015
  % by itself, and do not allow a page break either before or after that
alpar@464
  2016
  % line.  We do not start a paragraph here because then if the next
alpar@464
  2017
  % command is, e.g., @kindex, the whatsit would get put into the
alpar@464
  2018
  % horizontal list on a line by itself, resulting in extra blank space.
alpar@464
  2019
  \ifdim \wd0>\itemmax
alpar@464
  2020
    %
alpar@464
  2021
    % Make this a paragraph so we get the \parskip glue and wrapping,
alpar@464
  2022
    % but leave it ragged-right.
alpar@464
  2023
    \begingroup
alpar@464
  2024
      \advance\leftskip by-\tableindent
alpar@464
  2025
      \advance\hsize by\tableindent
alpar@464
  2026
      \advance\rightskip by0pt plus1fil
alpar@464
  2027
      \leavevmode\unhbox0\par
alpar@464
  2028
    \endgroup
alpar@464
  2029
    %
alpar@464
  2030
    % We're going to be starting a paragraph, but we don't want the
alpar@464
  2031
    % \parskip glue -- logically it's part of the @item we just started.
alpar@464
  2032
    \nobreak \vskip-\parskip
alpar@464
  2033
    %
alpar@464
  2034
    % Stop a page break at the \parskip glue coming up.  (Unfortunately
alpar@464
  2035
    % we can't prevent a possible page break at the following
alpar@464
  2036
    % \baselineskip glue.)  However, if what follows is an environment
alpar@464
  2037
    % such as @example, there will be no \parskip glue; then
alpar@464
  2038
    % the negative vskip we just would cause the example and the item to
alpar@464
  2039
    % crash together.  So we use this bizarre value of 10001 as a signal
alpar@464
  2040
    % to \aboveenvbreak to insert \parskip glue after all.
alpar@464
  2041
    % (Possibly there are other commands that could be followed by
alpar@464
  2042
    % @example which need the same treatment, but not section titles; or
alpar@464
  2043
    % maybe section titles are the only special case and they should be
alpar@464
  2044
    % penalty 10001...)
alpar@464
  2045
    \penalty 10001
alpar@464
  2046
    \endgroup
alpar@464
  2047
    \itemxneedsnegativevskipfalse
alpar@464
  2048
  \else
alpar@464
  2049
    % The item text fits into the space.  Start a paragraph, so that the
alpar@464
  2050
    % following text (if any) will end up on the same line.
alpar@464
  2051
    \noindent
alpar@464
  2052
    % Do this with kerns and \unhbox so that if there is a footnote in
alpar@464
  2053
    % the item text, it can migrate to the main vertical list and
alpar@464
  2054
    % eventually be printed.
alpar@464
  2055
    \nobreak\kern-\tableindent
alpar@464
  2056
    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
alpar@464
  2057
    \unhbox0
alpar@464
  2058
    \nobreak\kern\dimen0
alpar@464
  2059
    \endgroup
alpar@464
  2060
    \itemxneedsnegativevskiptrue
alpar@464
  2061
  \fi
alpar@464
  2062
}
alpar@464
  2063
alpar@464
  2064
\def\item{\errmessage{@item while not in a table}}
alpar@464
  2065
\def\itemx{\errmessage{@itemx while not in a table}}
alpar@464
  2066
\def\kitem{\errmessage{@kitem while not in a table}}
alpar@464
  2067
\def\kitemx{\errmessage{@kitemx while not in a table}}
alpar@464
  2068
\def\xitem{\errmessage{@xitem while not in a table}}
alpar@464
  2069
\def\xitemx{\errmessage{@xitemx while not in a table}}
alpar@464
  2070
alpar@464
  2071
% Contains a kludge to get @end[description] to work.
alpar@464
  2072
\def\description{\tablez{\dontindex}{1}{}{}{}{}}
alpar@464
  2073
alpar@464
  2074
% @table, @ftable, @vtable.
alpar@464
  2075
\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
alpar@464
  2076
{\obeylines\obeyspaces%
alpar@464
  2077
\gdef\tablex #1^^M{%
alpar@464
  2078
\tabley\dontindex#1        \endtabley}}
alpar@464
  2079
alpar@464
  2080
\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
alpar@464
  2081
{\obeylines\obeyspaces%
alpar@464
  2082
\gdef\ftablex #1^^M{%
alpar@464
  2083
\tabley\fnitemindex#1        \endtabley
alpar@464
  2084
\def\Eftable{\endgraf\afterenvbreak\endgroup}%
alpar@464
  2085
\let\Etable=\relax}}
alpar@464
  2086
alpar@464
  2087
\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
alpar@464
  2088
{\obeylines\obeyspaces%
alpar@464
  2089
\gdef\vtablex #1^^M{%
alpar@464
  2090
\tabley\vritemindex#1        \endtabley
alpar@464
  2091
\def\Evtable{\endgraf\afterenvbreak\endgroup}%
alpar@464
  2092
\let\Etable=\relax}}
alpar@464
  2093
alpar@464
  2094
\def\dontindex #1{}
alpar@464
  2095
\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
alpar@464
  2096
\def\vritemindex #1{\doind {vr}{\code{#1}}}%
alpar@464
  2097
alpar@464
  2098
{\obeyspaces %
alpar@464
  2099
\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
alpar@464
  2100
\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
alpar@464
  2101
alpar@464
  2102
\def\tablez #1#2#3#4#5#6{%
alpar@464
  2103
\aboveenvbreak %
alpar@464
  2104
\begingroup %
alpar@464
  2105
\def\Edescription{\Etable}% Necessary kludge.
alpar@464
  2106
\let\itemindex=#1%
alpar@464
  2107
\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
alpar@464
  2108
\ifnum 0#4>0 \tableindent=#4\mil \fi %
alpar@464
  2109
\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
alpar@464
  2110
\def\itemfont{#2}%
alpar@464
  2111
\itemmax=\tableindent %
alpar@464
  2112
\advance \itemmax by -\itemmargin %
alpar@464
  2113
\advance \leftskip by \tableindent %
alpar@464
  2114
\exdentamount=\tableindent
alpar@464
  2115
\parindent = 0pt
alpar@464
  2116
\parskip = \smallskipamount
alpar@464
  2117
\ifdim \parskip=0pt \parskip=2pt \fi%
alpar@464
  2118
\def\Etable{\endgraf\afterenvbreak\endgroup}%
alpar@464
  2119
\let\item = \internalBitem %
alpar@464
  2120
\let\itemx = \internalBitemx %
alpar@464
  2121
\let\kitem = \internalBkitem %
alpar@464
  2122
\let\kitemx = \internalBkitemx %
alpar@464
  2123
\let\xitem = \internalBxitem %
alpar@464
  2124
\let\xitemx = \internalBxitemx %
alpar@464
  2125
}
alpar@464
  2126
alpar@464
  2127
% This is the counter used by @enumerate, which is really @itemize
alpar@464
  2128
alpar@464
  2129
\newcount \itemno
alpar@464
  2130
alpar@464
  2131
\def\itemize{\parsearg\itemizezzz}
alpar@464
  2132
alpar@464
  2133
\def\itemizezzz #1{%
alpar@464
  2134
  \begingroup % ended by the @end itemize
alpar@464
  2135
  \itemizey {#1}{\Eitemize}
alpar@464
  2136
}
alpar@464
  2137
alpar@464
  2138
\def\itemizey#1#2{%
alpar@464
  2139
  \aboveenvbreak
alpar@464
  2140
  \itemmax=\itemindent
alpar@464
  2141
  \advance\itemmax by -\itemmargin
alpar@464
  2142
  \advance\leftskip by \itemindent
alpar@464
  2143
  \exdentamount=\itemindent
alpar@464
  2144
  \parindent=0pt
alpar@464
  2145
  \parskip=\smallskipamount
alpar@464
  2146
  \ifdim\parskip=0pt \parskip=2pt \fi
alpar@464
  2147
  \def#2{\endgraf\afterenvbreak\endgroup}%
alpar@464
  2148
  \def\itemcontents{#1}%
alpar@464
  2149
  % @itemize with no arg is equivalent to @itemize @bullet.
alpar@464
  2150
  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
alpar@464
  2151
  \let\item=\itemizeitem
alpar@464
  2152
}
alpar@464
  2153
alpar@464
  2154
% \splitoff TOKENS\endmark defines \first to be the first token in
alpar@464
  2155
% TOKENS, and \rest to be the remainder.
alpar@464
  2156
%
alpar@464
  2157
\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
alpar@464
  2158
alpar@464
  2159
% Allow an optional argument of an uppercase letter, lowercase letter,
alpar@464
  2160
% or number, to specify the first label in the enumerated list.  No
alpar@464
  2161
% argument is the same as `1'.
alpar@464
  2162
%
alpar@464
  2163
\def\enumerate{\parsearg\enumeratezzz}
alpar@464
  2164
\def\enumeratezzz #1{\enumeratey #1  \endenumeratey}
alpar@464
  2165
\def\enumeratey #1 #2\endenumeratey{%
alpar@464
  2166
  \begingroup % ended by the @end enumerate
alpar@464
  2167
  %
alpar@464
  2168
  % If we were given no argument, pretend we were given `1'.
alpar@464
  2169
  \def\thearg{#1}%
alpar@464
  2170
  \ifx\thearg\empty \def\thearg{1}\fi
alpar@464
  2171
  %
alpar@464
  2172
  % Detect if the argument is a single token.  If so, it might be a
alpar@464
  2173
  % letter.  Otherwise, the only valid thing it can be is a number.
alpar@464
  2174
  % (We will always have one token, because of the test we just made.
alpar@464
  2175
  % This is a good thing, since \splitoff doesn't work given nothing at
alpar@464
  2176
  % all -- the first parameter is undelimited.)
alpar@464
  2177
  \expandafter\splitoff\thearg\endmark
alpar@464
  2178
  \ifx\rest\empty
alpar@464
  2179
    % Only one token in the argument.  It could still be anything.
alpar@464
  2180
    % A ``lowercase letter'' is one whose \lccode is nonzero.
alpar@464
  2181
    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
alpar@464
  2182
    %   not equal to itself.
alpar@464
  2183
    % Otherwise, we assume it's a number.
alpar@464
  2184
    %
alpar@464
  2185
    % We need the \relax at the end of the \ifnum lines to stop TeX from
alpar@464
  2186
    % continuing to look for a <number>.
alpar@464
  2187
    %
alpar@464
  2188
    \ifnum\lccode\expandafter`\thearg=0\relax
alpar@464
  2189
      \numericenumerate % a number (we hope)
alpar@464
  2190
    \else
alpar@464
  2191
      % It's a letter.
alpar@464
  2192
      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
alpar@464
  2193
        \lowercaseenumerate % lowercase letter
alpar@464
  2194
      \else
alpar@464
  2195
        \uppercaseenumerate % uppercase letter
alpar@464
  2196
      \fi
alpar@464
  2197
    \fi
alpar@464
  2198
  \else
alpar@464
  2199
    % Multiple tokens in the argument.  We hope it's a number.
alpar@464
  2200
    \numericenumerate
alpar@464
  2201
  \fi
alpar@464
  2202
}
alpar@464
  2203
alpar@464
  2204
% An @enumerate whose labels are integers.  The starting integer is
alpar@464
  2205
% given in \thearg.
alpar@464
  2206
%
alpar@464
  2207
\def\numericenumerate{%
alpar@464
  2208
  \itemno = \thearg
alpar@464
  2209
  \startenumeration{\the\itemno}%
alpar@464
  2210
}
alpar@464
  2211
alpar@464
  2212
% The starting (lowercase) letter is in \thearg.
alpar@464
  2213
\def\lowercaseenumerate{%
alpar@464
  2214
  \itemno = \expandafter`\thearg
alpar@464
  2215
  \startenumeration{%
alpar@464
  2216
    % Be sure we're not beyond the end of the alphabet.
alpar@464
  2217
    \ifnum\itemno=0
alpar@464
  2218
      \errmessage{No more lowercase letters in @enumerate; get a bigger
alpar@464
  2219
                  alphabet}%
alpar@464
  2220
    \fi
alpar@464
  2221
    \char\lccode\itemno
alpar@464
  2222
  }%
alpar@464
  2223
}
alpar@464
  2224
alpar@464
  2225
% The starting (uppercase) letter is in \thearg.
alpar@464
  2226
\def\uppercaseenumerate{%
alpar@464
  2227
  \itemno = \expandafter`\thearg
alpar@464
  2228
  \startenumeration{%
alpar@464
  2229
    % Be sure we're not beyond the end of the alphabet.
alpar@464
  2230
    \ifnum\itemno=0
alpar@464
  2231
      \errmessage{No more uppercase letters in @enumerate; get a bigger
alpar@464
  2232
                  alphabet}
alpar@464
  2233
    \fi
alpar@464
  2234
    \char\uccode\itemno
alpar@464
  2235
  }%
alpar@464
  2236
}
alpar@464
  2237
alpar@464
  2238
% Call itemizey, adding a period to the first argument and supplying the
alpar@464
  2239
% common last two arguments.  Also subtract one from the initial value in
alpar@464
  2240
% \itemno, since @item increments \itemno.
alpar@464
  2241
%
alpar@464
  2242
\def\startenumeration#1{%
alpar@464
  2243
  \advance\itemno by -1
alpar@464
  2244
  \itemizey{#1.}\Eenumerate\flushcr
alpar@464
  2245
}
alpar@464
  2246
alpar@464
  2247
% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
alpar@464
  2248
% to @enumerate.
alpar@464
  2249
%
alpar@464
  2250
\def\alphaenumerate{\enumerate{a}}
alpar@464
  2251
\def\capsenumerate{\enumerate{A}}
alpar@464
  2252
\def\Ealphaenumerate{\Eenumerate}
alpar@464
  2253
\def\Ecapsenumerate{\Eenumerate}
alpar@464
  2254
alpar@464
  2255
% Definition of @item while inside @itemize.
alpar@464
  2256
alpar@464
  2257
\def\itemizeitem{%
alpar@464
  2258
\advance\itemno by 1
alpar@464
  2259
{\let\par=\endgraf \smallbreak}%
alpar@464
  2260
\ifhmode \errmessage{In hmode at itemizeitem}\fi
alpar@464
  2261
{\parskip=0in \hskip 0pt
alpar@464
  2262
\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
alpar@464
  2263
\vadjust{\penalty 1200}}%
alpar@464
  2264
\flushcr}
alpar@464
  2265
alpar@464
  2266
% @multitable macros
alpar@464
  2267
% Amy Hendrickson, 8/18/94, 3/6/96
alpar@464
  2268
%
alpar@464
  2269
% @multitable ... @end multitable will make as many columns as desired.
alpar@464
  2270
% Contents of each column will wrap at width given in preamble.  Width
alpar@464
  2271
% can be specified either with sample text given in a template line,
alpar@464
  2272
% or in percent of \hsize, the current width of text on page.
alpar@464
  2273
alpar@464
  2274
% Table can continue over pages but will only break between lines.
alpar@464
  2275
alpar@464
  2276
% To make preamble:
alpar@464
  2277
%
alpar@464
  2278
% Either define widths of columns in terms of percent of \hsize:
alpar@464
  2279
%   @multitable @columnfractions .25 .3 .45
alpar@464
  2280
%   @item ...
alpar@464
  2281
%
alpar@464
  2282
%   Numbers following @columnfractions are the percent of the total
alpar@464
  2283
%   current hsize to be used for each column. You may use as many
alpar@464
  2284
%   columns as desired.
alpar@464
  2285
alpar@464
  2286
alpar@464
  2287
% Or use a template:
alpar@464
  2288
%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
alpar@464
  2289
%   @item ...
alpar@464
  2290
%   using the widest term desired in each column.
alpar@464
  2291
%
alpar@464
  2292
% For those who want to use more than one line's worth of words in
alpar@464
  2293
% the preamble, break the line within one argument and it
alpar@464
  2294
% will parse correctly, i.e.,
alpar@464
  2295
%
alpar@464
  2296
%     @multitable {Column 1 template} {Column 2 template} {Column 3
alpar@464
  2297
%      template}
alpar@464
  2298
% Not:
alpar@464
  2299
%     @multitable {Column 1 template} {Column 2 template}
alpar@464
  2300
%      {Column 3 template}
alpar@464
  2301
alpar@464
  2302
% Each new table line starts with @item, each subsequent new column
alpar@464
  2303
% starts with @tab. Empty columns may be produced by supplying @tab's
alpar@464
  2304
% with nothing between them for as many times as empty columns are needed,
alpar@464
  2305
% ie, @tab@tab@tab will produce two empty columns.
alpar@464
  2306
alpar@464
  2307
% @item, @tab, @multitable or @end multitable do not need to be on their
alpar@464
  2308
% own lines, but it will not hurt if they are.
alpar@464
  2309
alpar@464
  2310
% Sample multitable:
alpar@464
  2311
alpar@464
  2312
%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
alpar@464
  2313
%   @item first col stuff @tab second col stuff @tab third col
alpar@464
  2314
%   @item
alpar@464
  2315
%   first col stuff
alpar@464
  2316
%   @tab
alpar@464
  2317
%   second col stuff
alpar@464
  2318
%   @tab
alpar@464
  2319
%   third col
alpar@464
  2320
%   @item first col stuff @tab second col stuff
alpar@464
  2321
%   @tab Many paragraphs of text may be used in any column.
alpar@464
  2322
%
alpar@464
  2323
%         They will wrap at the width determined by the template.
alpar@464
  2324
%   @item@tab@tab This will be in third column.
alpar@464
  2325
%   @end multitable
alpar@464
  2326
alpar@464
  2327
% Default dimensions may be reset by user.
alpar@464
  2328
% @multitableparskip is vertical space between paragraphs in table.
alpar@464
  2329
% @multitableparindent is paragraph indent in table.
alpar@464
  2330
% @multitablecolmargin is horizontal space to be left between columns.
alpar@464
  2331
% @multitablelinespace is space to leave between table items, baseline
alpar@464
  2332
%                                                            to baseline.
alpar@464
  2333
%   0pt means it depends on current normal line spacing.
alpar@464
  2334
%
alpar@464
  2335
\newskip\multitableparskip
alpar@464
  2336
\newskip\multitableparindent
alpar@464
  2337
\newdimen\multitablecolspace
alpar@464
  2338
\newskip\multitablelinespace
alpar@464
  2339
\multitableparskip=0pt
alpar@464
  2340
\multitableparindent=6pt
alpar@464
  2341
\multitablecolspace=12pt
alpar@464
  2342
\multitablelinespace=0pt
alpar@464
  2343
alpar@464
  2344
% Macros used to set up halign preamble:
alpar@464
  2345
%
alpar@464
  2346
\let\endsetuptable\relax
alpar@464
  2347
\def\xendsetuptable{\endsetuptable}
alpar@464
  2348
\let\columnfractions\relax
alpar@464
  2349
\def\xcolumnfractions{\columnfractions}
alpar@464
  2350
\newif\ifsetpercent
alpar@464
  2351
alpar@464
  2352
% #1 is the part of the @columnfraction before the decimal point, which
alpar@464
  2353
% is presumably either 0 or the empty string (but we don't check, we
alpar@464
  2354
% just throw it away).  #2 is the decimal part, which we use as the
alpar@464
  2355
% percent of \hsize for this column.
alpar@464
  2356
\def\pickupwholefraction#1.#2 {%
alpar@464
  2357
  \global\advance\colcount by 1
alpar@464
  2358
  \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}%
alpar@464
  2359
  \setuptable
alpar@464
  2360
}
alpar@464
  2361
alpar@464
  2362
\newcount\colcount
alpar@464
  2363
\def\setuptable#1{%
alpar@464
  2364
  \def\firstarg{#1}%
alpar@464
  2365
  \ifx\firstarg\xendsetuptable
alpar@464
  2366
    \let\go = \relax
alpar@464
  2367
  \else
alpar@464
  2368
    \ifx\firstarg\xcolumnfractions
alpar@464
  2369
      \global\setpercenttrue
alpar@464
  2370
    \else
alpar@464
  2371
      \ifsetpercent
alpar@464
  2372
         \let\go\pickupwholefraction
alpar@464
  2373
      \else
alpar@464
  2374
         \global\advance\colcount by 1
alpar@464
  2375
         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
alpar@464
  2376
                   % separator; typically that is always in the input, anyway.
alpar@464
  2377
         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
alpar@464
  2378
      \fi
alpar@464
  2379
    \fi
alpar@464
  2380
    \ifx\go\pickupwholefraction
alpar@464
  2381
      % Put the argument back for the \pickupwholefraction call, so
alpar@464
  2382
      % we'll always have a period there to be parsed.
alpar@464
  2383
      \def\go{\pickupwholefraction#1}%
alpar@464
  2384
    \else
alpar@464
  2385
      \let\go = \setuptable
alpar@464
  2386
    \fi%
alpar@464
  2387
  \fi
alpar@464
  2388
  \go
alpar@464
  2389
}
alpar@464
  2390
alpar@464
  2391
% @multitable ... @end multitable definitions:
alpar@464
  2392
%
alpar@464
  2393
\def\multitable{\parsearg\dotable}
alpar@464
  2394
\def\dotable#1{\bgroup
alpar@464
  2395
  \vskip\parskip
alpar@464
  2396
  \let\item=\crcrwithfootnotes
alpar@464
  2397
  % A \tab used to include \hskip1sp.  But then the space in a template
alpar@464
  2398
  % line is not enough.  That is bad.  So let's go back to just & until
alpar@464
  2399
  % we encounter the problem it was intended to solve again.  --karl,
alpar@464
  2400
  % nathan@acm.org, 20apr99.
alpar@464
  2401
  \let\tab=&%
alpar@464
  2402
  \let\startfootins=\startsavedfootnote
alpar@464
  2403
  \tolerance=9500
alpar@464
  2404
  \hbadness=9500
alpar@464
  2405
  \setmultitablespacing
alpar@464
  2406
  \parskip=\multitableparskip
alpar@464
  2407
  \parindent=\multitableparindent
alpar@464
  2408
  \overfullrule=0pt
alpar@464
  2409
  \global\colcount=0
alpar@464
  2410
  \def\Emultitable{%
alpar@464
  2411
    \global\setpercentfalse
alpar@464
  2412
    \crcrwithfootnotes\crcr
alpar@464
  2413
    \egroup\egroup
alpar@464
  2414
  }%
alpar@464
  2415
  %
alpar@464
  2416
  % To parse everything between @multitable and @item:
alpar@464
  2417
  \setuptable#1 \endsetuptable
alpar@464
  2418
  %
alpar@464
  2419
  % \everycr will reset column counter, \colcount, at the end of
alpar@464
  2420
  % each line. Every column entry will cause \colcount to advance by one.
alpar@464
  2421
  % The table preamble
alpar@464
  2422
  % looks at the current \colcount to find the correct column width.
alpar@464
  2423
  \everycr{\noalign{%
alpar@464
  2424
  %
alpar@464
  2425
  % \filbreak%% keeps underfull box messages off when table breaks over pages.
alpar@464
  2426
  % Maybe so, but it also creates really weird page breaks when the table
alpar@464
  2427
  % breaks over pages. Wouldn't \vfil be better?  Wait until the problem
alpar@464
  2428
  % manifests itself, so it can be fixed for real --karl.
alpar@464
  2429
    \global\colcount=0\relax}}%
alpar@464
  2430
  %
alpar@464
  2431
  % This preamble sets up a generic column definition, which will
alpar@464
  2432
  % be used as many times as user calls for columns.
alpar@464
  2433
  % \vtop will set a single line and will also let text wrap and
alpar@464
  2434
  % continue for many paragraphs if desired.
alpar@464
  2435
  \halign\bgroup&\global\advance\colcount by 1\relax
alpar@464
  2436
    \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
alpar@464
  2437
  %
alpar@464
  2438
  % In order to keep entries from bumping into each other
alpar@464
  2439
  % we will add a \leftskip of \multitablecolspace to all columns after
alpar@464
  2440
  % the first one.
alpar@464
  2441
  %
alpar@464
  2442
  % If a template has been used, we will add \multitablecolspace
alpar@464
  2443
  % to the width of each template entry.
alpar@464
  2444
  %
alpar@464
  2445
  % If the user has set preamble in terms of percent of \hsize we will
alpar@464
  2446
  % use that dimension as the width of the column, and the \leftskip
alpar@464
  2447
  % will keep entries from bumping into each other.  Table will start at
alpar@464
  2448
  % left margin and final column will justify at right margin.
alpar@464
  2449
  %
alpar@464
  2450
  % Make sure we don't inherit \rightskip from the outer environment.
alpar@464
  2451
  \rightskip=0pt
alpar@464
  2452
  \ifnum\colcount=1
alpar@464
  2453
    % The first column will be indented with the surrounding text.
alpar@464
  2454
    \advance\hsize by\leftskip
alpar@464
  2455
  \else
alpar@464
  2456
    \ifsetpercent \else
alpar@464
  2457
      % If user has not set preamble in terms of percent of \hsize
alpar@464
  2458
      % we will advance \hsize by \multitablecolspace.
alpar@464
  2459
      \advance\hsize by \multitablecolspace
alpar@464
  2460
    \fi
alpar@464
  2461
   % In either case we will make \leftskip=\multitablecolspace:
alpar@464
  2462
  \leftskip=\multitablecolspace
alpar@464
  2463
  \fi
alpar@464
  2464
  % Ignoring space at the beginning and end avoids an occasional spurious
alpar@464
  2465
  % blank line, when TeX decides to break the line at the space before the
alpar@464
  2466
  % box from the multistrut, so the strut ends up on a line by itself.
alpar@464
  2467
  % For example:
alpar@464
  2468
  % @multitable @columnfractions .11 .89
alpar@464
  2469
  % @item @code{#}
alpar@464
  2470
  % @tab Legal holiday which is valid in major parts of the whole country.
alpar@464
  2471
  % Is automatically provided with highlighting sequences respectively marking
alpar@464
  2472
  % characters.
alpar@464
  2473
  \noindent\ignorespaces##\unskip\multistrut}\cr
alpar@464
  2474
}
alpar@464
  2475
alpar@464
  2476
\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
alpar@464
  2477
% If so, do nothing. If not, give it an appropriate dimension based on
alpar@464
  2478
% current baselineskip.
alpar@464
  2479
\ifdim\multitablelinespace=0pt
alpar@464
  2480
\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
alpar@464
  2481
\global\advance\multitablelinespace by-\ht0
alpar@464
  2482
%% strut to put in table in case some entry doesn't have descenders,
alpar@464
  2483
%% to keep lines equally spaced
alpar@464
  2484
\let\multistrut = \strut
alpar@464
  2485
\else
alpar@464
  2486
%% FIXME: what is \box0 supposed to be?
alpar@464
  2487
\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
alpar@464
  2488
width0pt\relax} \fi
alpar@464
  2489
%% Test to see if parskip is larger than space between lines of
alpar@464
  2490
%% table. If not, do nothing.
alpar@464
  2491
%%        If so, set to same dimension as multitablelinespace.
alpar@464
  2492
\ifdim\multitableparskip>\multitablelinespace
alpar@464
  2493
\global\multitableparskip=\multitablelinespace
alpar@464
  2494
\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
alpar@464
  2495
                                      %% than skip between lines in the table.
alpar@464
  2496
\fi%
alpar@464
  2497
\ifdim\multitableparskip=0pt
alpar@464
  2498
\global\multitableparskip=\multitablelinespace
alpar@464
  2499
\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
alpar@464
  2500
                                      %% than skip between lines in the table.
alpar@464
  2501
\fi}
alpar@464
  2502
alpar@464
  2503
% In case a @footnote appears inside an alignment, save the footnote
alpar@464
  2504
% text to a box and make the \insert when a row of the table is
alpar@464
  2505
% finished.  Otherwise, the insertion is lost, it never migrates to the
alpar@464
  2506
% main vertical list.  --kasal, 22jan03.
alpar@464
  2507
%
alpar@464
  2508
\newbox\savedfootnotes
alpar@464
  2509
%
alpar@464
  2510
% \dotable \let's \startfootins to this, so that \dofootnote will call
alpar@464
  2511
% it instead of starting the insertion right away.
alpar@464
  2512
\def\startsavedfootnote{%
alpar@464
  2513
  \global\setbox\savedfootnotes = \vbox\bgroup
alpar@464
  2514
    \unvbox\savedfootnotes
alpar@464
  2515
}
alpar@464
  2516
\def\crcrwithfootnotes{%
alpar@464
  2517
  \crcr
alpar@464
  2518
  \ifvoid\savedfootnotes \else
alpar@464
  2519
    \noalign{\insert\footins{\box\savedfootnotes}}%
alpar@464
  2520
  \fi
alpar@464
  2521
}
alpar@464
  2522
alpar@464
  2523
\message{conditionals,}
alpar@464
  2524
% Prevent errors for section commands.
alpar@464
  2525
% Used in @ignore and in failing conditionals.
alpar@464
  2526
\def\ignoresections{%
alpar@464
  2527
  \let\appendix=\relax
alpar@464
  2528
  \let\appendixsec=\relax
alpar@464
  2529
  \let\appendixsection=\relax
alpar@464
  2530
  \let\appendixsubsec=\relax
alpar@464
  2531
  \let\appendixsubsection=\relax
alpar@464
  2532
  \let\appendixsubsubsec=\relax
alpar@464
  2533
  \let\appendixsubsubsection=\relax
alpar@464
  2534
  %\let\begin=\relax
alpar@464
  2535
  %\let\bye=\relax
alpar@464
  2536
  \let\centerchap=\relax
alpar@464
  2537
  \let\chapter=\relax
alpar@464
  2538
  \let\contents=\relax
alpar@464
  2539
  \let\section=\relax
alpar@464
  2540
  \let\smallbook=\relax
alpar@464
  2541
  \let\subsec=\relax
alpar@464
  2542
  \let\subsection=\relax
alpar@464
  2543
  \let\subsubsec=\relax
alpar@464
  2544
  \let\subsubsection=\relax
alpar@464
  2545
  \let\titlepage=\relax
alpar@464
  2546
  \let\top=\relax
alpar@464
  2547
  \let\unnumbered=\relax
alpar@464
  2548
  \let\unnumberedsec=\relax
alpar@464
  2549
  \let\unnumberedsection=\relax
alpar@464
  2550
  \let\unnumberedsubsec=\relax
alpar@464
  2551
  \let\unnumberedsubsection=\relax
alpar@464
  2552
  \let\unnumberedsubsubsec=\relax
alpar@464
  2553
  \let\unnumberedsubsubsection=\relax
alpar@464
  2554
}
alpar@464
  2555
alpar@464
  2556
% Ignore @ignore, @ifhtml, @ifinfo, and the like.
alpar@464
  2557
%
alpar@464
  2558
\def\direntry{\doignore{direntry}}
alpar@464
  2559
\def\documentdescriptionword{documentdescription}
alpar@464
  2560
\def\documentdescription{\doignore{documentdescription}}
alpar@464
  2561
\def\html{\doignore{html}}
alpar@464
  2562
\def\ifhtml{\doignore{ifhtml}}
alpar@464
  2563
\def\ifinfo{\doignore{ifinfo}}
alpar@464
  2564
\def\ifnottex{\doignore{ifnottex}}
alpar@464
  2565
\def\ifplaintext{\doignore{ifplaintext}}
alpar@464
  2566
\def\ifxml{\doignore{ifxml}}
alpar@464
  2567
\def\ignore{\doignore{ignore}}
alpar@464
  2568
\def\menu{\doignore{menu}}
alpar@464
  2569
\def\xml{\doignore{xml}}
alpar@464
  2570
alpar@464
  2571
% @dircategory CATEGORY  -- specify a category of the dir file
alpar@464
  2572
% which this file should belong to.  Ignore this in TeX.
alpar@464
  2573
\let\dircategory = \comment
alpar@464
  2574
alpar@464
  2575
% Ignore text until a line `@end #1', keeping track of nested conditionals.
alpar@464
  2576
%
alpar@464
  2577
% A count to remember the depth of nesting.
alpar@464
  2578
\newcount\doignorecount  \doignorecount = 0
alpar@464
  2579
alpar@464
  2580
\def\doignore#1{\begingroup
alpar@464
  2581
  % Don't complain about control sequences we have declared \outer.
alpar@464
  2582
  \ignoresections
alpar@464
  2583
  %
alpar@464
  2584
  % Make sure that spaces turn into tokens that match what \doignoretext wants.
alpar@464
  2585
  \catcode\spaceChar = 10
alpar@464
  2586
  %
alpar@464
  2587
  % Ignore braces, so mismatched braces don't cause trouble.
alpar@464
  2588
  \catcode`\{ = 9
alpar@464
  2589
  \catcode`\} = 9
alpar@464
  2590
  %
alpar@464
  2591
  % Count number of #1's that we've seen.
alpar@464
  2592
  \doignorecount = 0
alpar@464
  2593
  %
alpar@464
  2594
  % Swallow text until we reach the matching `@end #1'.
alpar@464
  2595
  \expandafter \dodoignore \csname#1\endcsname {#1}%
alpar@464
  2596
}
alpar@464
  2597
alpar@464
  2598
{ \catcode`@=11 % We want to use \ST@P which cannot appear in texinfo source.
alpar@464
  2599
  \obeylines %
alpar@464
  2600
  %
alpar@464
  2601
  \gdef\dodoignore#1#2{%
alpar@464
  2602
    % #1 contains, e.g., \ifinfo, a.k.a. @ifinfo.
alpar@464
  2603
    % #2 contains the string `ifinfo'.
alpar@464
  2604
    %
alpar@464
  2605
    % Define a command to find the next `@end #2', which must be on a line
alpar@464
  2606
    % by itself.
alpar@464
  2607
    \long\def\doignoretext##1^^M\end #2{\doignoretextyyy##1^^M#1\ST@P}%
alpar@464
  2608
    % And this command to find another #1 command, at the beginning of a
alpar@464
  2609
    % line.  (Otherwise, we would consider a line `@c @ifset', for
alpar@464
  2610
    % example, to count as an @ifset for nesting.)
alpar@464
  2611
    \long\def\doignoretextyyy##1^^M#1##2\ST@P{\doignoreyyy{##2}\ST@P}%
alpar@464
  2612
    %
alpar@464
  2613
    % And now expand that command.
alpar@464
  2614
    \obeylines %
alpar@464
  2615
    \doignoretext ^^M%
alpar@464
  2616
  }%
alpar@464
  2617
}
alpar@464
  2618
alpar@464
  2619
\def\doignoreyyy#1{%
alpar@464
  2620
  \def\temp{#1}%
alpar@464
  2621
  \ifx\temp\empty			% Nothing found.
alpar@464
  2622
    \let\next\doignoretextzzz
alpar@464
  2623
  \else					% Found a nested condition, ...
alpar@464
  2624
    \advance\doignorecount by 1
alpar@464
  2625
    \let\next\doignoretextyyy		% ..., look for another.
alpar@464
  2626
    % If we're here, #1 ends with \ifinfo (for example).
alpar@464
  2627
  \fi
alpar@464
  2628
  \next #1% the token \ST@P is present just after this macro.
alpar@464
  2629
}
alpar@464
  2630
alpar@464
  2631
% We have to swallow the remaining "\ST@P".
alpar@464
  2632
% 
alpar@464
  2633
\def\doignoretextzzz#1{%
alpar@464
  2634
  \ifnum\doignorecount = 0	% We have just found the outermost @end.
alpar@464
  2635
    \let\next\enddoignore
alpar@464
  2636
  \else				% Still inside a nested condition.
alpar@464
  2637
    \advance\doignorecount by -1
alpar@464
  2638
    \let\next\doignoretext      % Look for the next @end.
alpar@464
  2639
  \fi
alpar@464
  2640
  \next
alpar@464
  2641
}
alpar@464
  2642
alpar@464
  2643
% Finish off ignored text.
alpar@464
  2644
\def\enddoignore{\endgroup\ignorespaces}
alpar@464
  2645
alpar@464
  2646
alpar@464
  2647
% @set VAR sets the variable VAR to an empty value.
alpar@464
  2648
% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
alpar@464
  2649
%
alpar@464
  2650
% Since we want to separate VAR from REST-OF-LINE (which might be
alpar@464
  2651
% empty), we can't just use \parsearg; we have to insert a space of our
alpar@464
  2652
% own to delimit the rest of the line, and then take it out again if we
alpar@464
  2653
% didn't need it.  Make sure the catcode of space is correct to avoid
alpar@464
  2654
% losing inside @example, for instance.
alpar@464
  2655
%
alpar@464
  2656
\def\set{\begingroup\catcode` =10
alpar@464
  2657
  \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
alpar@464
  2658
  \parsearg\setxxx}
alpar@464
  2659
\def\setxxx#1{\setyyy#1 \endsetyyy}
alpar@464
  2660
\def\setyyy#1 #2\endsetyyy{%
alpar@464
  2661
  \def\temp{#2}%
alpar@464
  2662
  \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
alpar@464
  2663
  \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
alpar@464
  2664
  \fi
alpar@464
  2665
  \endgroup
alpar@464
  2666
}
alpar@464
  2667
% Can't use \xdef to pre-expand #2 and save some time, since \temp or
alpar@464
  2668
% \next or other control sequences that we've defined might get us into
alpar@464
  2669
% an infinite loop. Consider `@set foo @cite{bar}'.
alpar@464
  2670
\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}}
alpar@464
  2671
alpar@464
  2672
% @clear VAR clears (i.e., unsets) the variable VAR.
alpar@464
  2673
%
alpar@464
  2674
\def\clear{\parsearg\clearxxx}
alpar@464
  2675
\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
alpar@464
  2676
alpar@464
  2677
% @value{foo} gets the text saved in variable foo.
alpar@464
  2678
{
alpar@464
  2679
  \catcode`\_ = \active
alpar@464
  2680
  %
alpar@464
  2681
  % We might end up with active _ or - characters in the argument if
alpar@464
  2682
  % we're called from @code, as @code{@value{foo-bar_}}.  So \let any
alpar@464
  2683
  % such active characters to their normal equivalents.
alpar@464
  2684
  \gdef\value{\begingroup
alpar@464
  2685
    \catcode`\-=\other \catcode`\_=\other
alpar@464
  2686
    \indexbreaks \let_\normalunderscore
alpar@464
  2687
    \valuexxx}
alpar@464
  2688
}
alpar@464
  2689
\def\valuexxx#1{\expandablevalue{#1}\endgroup}
alpar@464
  2690
alpar@464
  2691
% We have this subroutine so that we can handle at least some @value's
alpar@464
  2692
% properly in indexes (we \let\value to this in \indexdummies).  Ones
alpar@464
  2693
% whose names contain - or _ still won't work, but we can't do anything
alpar@464
  2694
% about that.  The command has to be fully expandable (if the variable
alpar@464
  2695
% is set), since the result winds up in the index file.  This means that
alpar@464
  2696
% if the variable's value contains other Texinfo commands, it's almost
alpar@464
  2697
% certain it will fail (although perhaps we could fix that with
alpar@464
  2698
% sufficient work to do a one-level expansion on the result, instead of
alpar@464
  2699
% complete).
alpar@464
  2700
%
alpar@464
  2701
\def\expandablevalue#1{%
alpar@464
  2702
  \expandafter\ifx\csname SET#1\endcsname\relax
alpar@464
  2703
    {[No value for ``#1'']}%
alpar@464
  2704
    \message{Variable `#1', used in @value, is not set.}%
alpar@464
  2705
  \else
alpar@464
  2706
    \csname SET#1\endcsname
alpar@464
  2707
  \fi
alpar@464
  2708
}
alpar@464
  2709
alpar@464
  2710
% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
alpar@464
  2711
% with @set.
alpar@464
  2712
%
alpar@464
  2713
\def\ifset{\parsearg\doifset}
alpar@464
  2714
\def\doifset#1{%
alpar@464
  2715
  \expandafter\ifx\csname SET#1\endcsname\relax
alpar@464
  2716
    \let\next=\ifsetfail
alpar@464
  2717
  \else
alpar@464
  2718
    \let\next=\ifsetsucceed
alpar@464
  2719
  \fi
alpar@464
  2720
  \next
alpar@464
  2721
}
alpar@464
  2722
\def\ifsetsucceed{\conditionalsucceed{ifset}}
alpar@464
  2723
\def\ifsetfail{\doignore{ifset}}
alpar@464
  2724
\defineunmatchedend{ifset}
alpar@464
  2725
alpar@464
  2726
% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
alpar@464
  2727
% defined with @set, or has been undefined with @clear.
alpar@464
  2728
%
alpar@464
  2729
\def\ifclear{\parsearg\doifclear}
alpar@464
  2730
\def\doifclear#1{%
alpar@464
  2731
  \expandafter\ifx\csname SET#1\endcsname\relax
alpar@464
  2732
    \let\next=\ifclearsucceed
alpar@464
  2733
  \else
alpar@464
  2734
    \let\next=\ifclearfail
alpar@464
  2735
  \fi
alpar@464
  2736
  \next
alpar@464
  2737
}
alpar@464
  2738
\def\ifclearsucceed{\conditionalsucceed{ifclear}}
alpar@464
  2739
\def\ifclearfail{\doignore{ifclear}}
alpar@464
  2740
\defineunmatchedend{ifclear}
alpar@464
  2741
alpar@464
  2742
% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we
alpar@464
  2743
% read the text following, through the first @end iftex (etc.).  Make
alpar@464
  2744
% `@end iftex' (etc.) valid only after an @iftex.
alpar@464
  2745
%
alpar@464
  2746
\def\iftex{\conditionalsucceed{iftex}}
alpar@464
  2747
\def\ifnothtml{\conditionalsucceed{ifnothtml}}
alpar@464
  2748
\def\ifnotinfo{\conditionalsucceed{ifnotinfo}}
alpar@464
  2749
\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}}
alpar@464
  2750
\defineunmatchedend{iftex}
alpar@464
  2751
\defineunmatchedend{ifnothtml}
alpar@464
  2752
\defineunmatchedend{ifnotinfo}
alpar@464
  2753
\defineunmatchedend{ifnotplaintext}
alpar@464
  2754
alpar@464
  2755
% True conditional.  Since \set globally defines its variables, we can
alpar@464
  2756
% just start and end a group (to keep the @end definition undefined at
alpar@464
  2757
% the outer level).
alpar@464
  2758
%
alpar@464
  2759
\def\conditionalsucceed#1{\begingroup
alpar@464
  2760
  \expandafter\def\csname E#1\endcsname{\endgroup}%
alpar@464
  2761
}
alpar@464
  2762
alpar@464
  2763
% @defininfoenclose.
alpar@464
  2764
\let\definfoenclose=\comment
alpar@464
  2765
alpar@464
  2766
alpar@464
  2767
\message{indexing,}
alpar@464
  2768
% Index generation facilities
alpar@464
  2769
alpar@464
  2770
% Define \newwrite to be identical to plain tex's \newwrite
alpar@464
  2771
% except not \outer, so it can be used within \newindex.
alpar@464
  2772
{\catcode`\@=11
alpar@464
  2773
\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
alpar@464
  2774
alpar@464
  2775
% \newindex {foo} defines an index named foo.
alpar@464
  2776
% It automatically defines \fooindex such that
alpar@464
  2777
% \fooindex ...rest of line... puts an entry in the index foo.
alpar@464
  2778
% It also defines \fooindfile to be the number of the output channel for
alpar@464
  2779
% the file that accumulates this index.  The file's extension is foo.
alpar@464
  2780
% The name of an index should be no more than 2 characters long
alpar@464
  2781
% for the sake of vms.
alpar@464
  2782
%
alpar@464
  2783
\def\newindex#1{%
alpar@464
  2784
  \iflinks
alpar@464
  2785
    \expandafter\newwrite \csname#1indfile\endcsname
alpar@464
  2786
    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
alpar@464
  2787
  \fi
alpar@464
  2788
  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
alpar@464
  2789
    \noexpand\doindex{#1}}
alpar@464
  2790
}
alpar@464
  2791
alpar@464
  2792
% @defindex foo  ==  \newindex{foo}
alpar@464
  2793
%
alpar@464
  2794
\def\defindex{\parsearg\newindex}
alpar@464
  2795
alpar@464
  2796
% Define @defcodeindex, like @defindex except put all entries in @code.
alpar@464
  2797
%
alpar@464
  2798
\def\defcodeindex{\parsearg\newcodeindex}
alpar@464
  2799
%
alpar@464
  2800
\def\newcodeindex#1{%
alpar@464
  2801
  \iflinks
alpar@464
  2802
    \expandafter\newwrite \csname#1indfile\endcsname
alpar@464
  2803
    \openout \csname#1indfile\endcsname \jobname.#1
alpar@464
  2804
  \fi
alpar@464
  2805
  \expandafter\xdef\csname#1index\endcsname{%
alpar@464
  2806
    \noexpand\docodeindex{#1}}%
alpar@464
  2807
}
alpar@464
  2808
alpar@464
  2809
alpar@464
  2810
% @synindex foo bar    makes index foo feed into index bar.
alpar@464
  2811
% Do this instead of @defindex foo if you don't want it as a separate index.
alpar@464
  2812
%
alpar@464
  2813
% @syncodeindex foo bar   similar, but put all entries made for index foo
alpar@464
  2814
% inside @code.
alpar@464
  2815
%
alpar@464
  2816
\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
alpar@464
  2817
\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
alpar@464
  2818
alpar@464
  2819
% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
alpar@464
  2820
% #3 the target index (bar).
alpar@464
  2821
\def\dosynindex#1#2#3{%
alpar@464
  2822
  % Only do \closeout if we haven't already done it, else we'll end up
alpar@464
  2823
  % closing the target index.
alpar@464
  2824
  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
alpar@464
  2825
    % The \closeout helps reduce unnecessary open files; the limit on the
alpar@464
  2826
    % Acorn RISC OS is a mere 16 files.
alpar@464
  2827
    \expandafter\closeout\csname#2indfile\endcsname
alpar@464
  2828
    \expandafter\let\csname\donesynindex#2\endcsname = 1
alpar@464
  2829
  \fi
alpar@464
  2830
  % redefine \fooindfile:
alpar@464
  2831
  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
alpar@464
  2832
  \expandafter\let\csname#2indfile\endcsname=\temp
alpar@464
  2833
  % redefine \fooindex:
alpar@464
  2834
  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
alpar@464
  2835
}
alpar@464
  2836
alpar@464
  2837
% Define \doindex, the driver for all \fooindex macros.
alpar@464
  2838
% Argument #1 is generated by the calling \fooindex macro,
alpar@464
  2839
%  and it is "foo", the name of the index.
alpar@464
  2840
alpar@464
  2841
% \doindex just uses \parsearg; it calls \doind for the actual work.
alpar@464
  2842
% This is because \doind is more useful to call from other macros.
alpar@464
  2843
alpar@464
  2844
% There is also \dosubind {index}{topic}{subtopic}
alpar@464
  2845
% which makes an entry in a two-level index such as the operation index.
alpar@464
  2846
alpar@464
  2847
\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
alpar@464
  2848
\def\singleindexer #1{\doind{\indexname}{#1}}
alpar@464
  2849
alpar@464
  2850
% like the previous two, but they put @code around the argument.
alpar@464
  2851
\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
alpar@464
  2852
\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
alpar@464
  2853
alpar@464
  2854
% Take care of Texinfo commands that can appear in an index entry.
alpar@464
  2855
% Since there are some commands we want to expand, and others we don't,
alpar@464
  2856
% we have to laboriously prevent expansion for those that we don't.
alpar@464
  2857
%
alpar@464
  2858
\def\indexdummies{%
alpar@464
  2859
  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
alpar@464
  2860
  \def\ {\realbackslash\space }%
alpar@464
  2861
  % Need these in case \tex is in effect and \{ is a \delimiter again.
alpar@464
  2862
  % But can't use \lbracecmd and \rbracecmd because texindex assumes
alpar@464
  2863
  % braces and backslashes are used only as delimiters.
alpar@464
  2864
  \let\{ = \mylbrace
alpar@464
  2865
  \let\} = \myrbrace
alpar@464
  2866
  %
alpar@464
  2867
  % \definedummyword defines \#1 as \realbackslash #1\space, thus
alpar@464
  2868
  % effectively preventing its expansion.  This is used only for control
alpar@464
  2869
  % words, not control letters, because the \space would be incorrect
alpar@464
  2870
  % for control characters, but is needed to separate the control word
alpar@464
  2871
  % from whatever follows.
alpar@464
  2872
  %
alpar@464
  2873
  % For control letters, we have \definedummyletter, which omits the
alpar@464
  2874
  % space.
alpar@464
  2875
  %
alpar@464
  2876
  % These can be used both for control words that take an argument and
alpar@464
  2877
  % those that do not.  If it is followed by {arg} in the input, then
alpar@464
  2878
  % that will dutifully get written to the index (or wherever).
alpar@464
  2879
  %
alpar@464
  2880
  \def\definedummyword##1{%
alpar@464
  2881
    \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
alpar@464
  2882
  }%
alpar@464
  2883
  \def\definedummyletter##1{%
alpar@464
  2884
    \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
alpar@464
  2885
  }%
alpar@464
  2886
  %
alpar@464
  2887
  % Do the redefinitions.
alpar@464
  2888
  \commondummies
alpar@464
  2889
}
alpar@464
  2890
alpar@464
  2891
% For the aux file, @ is the escape character.  So we want to redefine
alpar@464
  2892
% everything using @ instead of \realbackslash.  When everything uses
alpar@464
  2893
% @, this will be simpler.
alpar@464
  2894
%
alpar@464
  2895
\def\atdummies{%
alpar@464
  2896
  \def\@{@@}%
alpar@464
  2897
  \def\ {@ }%
alpar@464
  2898
  \let\{ = \lbraceatcmd
alpar@464
  2899
  \let\} = \rbraceatcmd
alpar@464
  2900
  %
alpar@464
  2901
  % (See comments in \indexdummies.)
alpar@464
  2902
  \def\definedummyword##1{%
alpar@464
  2903
    \expandafter\def\csname ##1\endcsname{@##1\space}%
alpar@464
  2904
  }%
alpar@464
  2905
  \def\definedummyletter##1{%
alpar@464
  2906
    \expandafter\def\csname ##1\endcsname{@##1}%
alpar@464
  2907
  }%
alpar@464
  2908
  %
alpar@464
  2909
  % Do the redefinitions.
alpar@464
  2910
  \commondummies
alpar@464
  2911
}
alpar@464
  2912
alpar@464
  2913
% Called from \indexdummies and \atdummies.  \definedummyword and
alpar@464
  2914
% \definedummyletter must be defined first.
alpar@464
  2915
%
alpar@464
  2916
\def\commondummies{%
alpar@464
  2917
  %
alpar@464
  2918
  \normalturnoffactive
alpar@464
  2919
  %
alpar@464
  2920
  % Control letters and accents.
alpar@464
  2921
  \definedummyletter{_}%
alpar@464
  2922
  \definedummyletter{,}%
alpar@464
  2923
  \definedummyletter{"}%
alpar@464
  2924
  \definedummyletter{`}%
alpar@464
  2925
  \definedummyletter{'}%
alpar@464
  2926
  \definedummyletter{^}%
alpar@464
  2927
  \definedummyletter{~}%
alpar@464
  2928
  \definedummyletter{=}%
alpar@464
  2929
  \definedummyword{u}%
alpar@464
  2930
  \definedummyword{v}%
alpar@464
  2931
  \definedummyword{H}%
alpar@464
  2932
  \definedummyword{dotaccent}%
alpar@464
  2933
  \definedummyword{ringaccent}%
alpar@464
  2934
  \definedummyword{tieaccent}%
alpar@464
  2935
  \definedummyword{ubaraccent}%
alpar@464
  2936
  \definedummyword{udotaccent}%
alpar@464
  2937
  \definedummyword{dotless}%
alpar@464
  2938
  %
alpar@464
  2939
  % Other non-English letters.
alpar@464
  2940
  \definedummyword{AA}%
alpar@464
  2941
  \definedummyword{AE}%
alpar@464
  2942
  \definedummyword{L}%
alpar@464
  2943
  \definedummyword{OE}%
alpar@464
  2944
  \definedummyword{O}%
alpar@464
  2945
  \definedummyword{aa}%
alpar@464
  2946
  \definedummyword{ae}%
alpar@464
  2947
  \definedummyword{l}%
alpar@464
  2948
  \definedummyword{oe}%
alpar@464
  2949
  \definedummyword{o}%
alpar@464
  2950
  \definedummyword{ss}%
alpar@464
  2951
  %
alpar@464
  2952
  % Although these internal commands shouldn't show up, sometimes they do.
alpar@464
  2953
  \definedummyword{bf}%
alpar@464
  2954
  \definedummyword{gtr}%
alpar@464
  2955
  \definedummyword{hat}%
alpar@464
  2956
  \definedummyword{less}%
alpar@464
  2957
  \definedummyword{sf}%
alpar@464
  2958
  \definedummyword{sl}%
alpar@464
  2959
  \definedummyword{tclose}%
alpar@464
  2960
  \definedummyword{tt}%
alpar@464
  2961
  %
alpar@464
  2962
  % Texinfo font commands.
alpar@464
  2963
  \definedummyword{b}%
alpar@464
  2964
  \definedummyword{i}%
alpar@464
  2965
  \definedummyword{r}%
alpar@464
  2966
  \definedummyword{sc}%
alpar@464
  2967
  \definedummyword{t}%
alpar@464
  2968
  %
alpar@464
  2969
  \definedummyword{TeX}%
alpar@464
  2970
  \definedummyword{acronym}%
alpar@464
  2971
  \definedummyword{cite}%
alpar@464
  2972
  \definedummyword{code}%
alpar@464
  2973
  \definedummyword{command}%
alpar@464
  2974
  \definedummyword{dfn}%
alpar@464
  2975
  \definedummyword{dots}%
alpar@464
  2976
  \definedummyword{emph}%
alpar@464
  2977
  \definedummyword{env}%
alpar@464
  2978
  \definedummyword{file}%
alpar@464
  2979
  \definedummyword{kbd}%
alpar@464
  2980
  \definedummyword{key}%
alpar@464
  2981
  \definedummyword{math}%
alpar@464
  2982
  \definedummyword{option}%
alpar@464
  2983
  \definedummyword{samp}%
alpar@464
  2984
  \definedummyword{strong}%
alpar@464
  2985
  \definedummyword{uref}%
alpar@464
  2986
  \definedummyword{url}%
alpar@464
  2987
  \definedummyword{var}%
alpar@464
  2988
  \definedummyword{w}%
alpar@464
  2989
  %
alpar@464
  2990
  % Assorted special characters.
alpar@464
  2991
  \definedummyword{bullet}%
alpar@464
  2992
  \definedummyword{copyright}%
alpar@464
  2993
  \definedummyword{dots}%
alpar@464
  2994
  \definedummyword{enddots}%
alpar@464
  2995
  \definedummyword{equiv}%
alpar@464
  2996
  \definedummyword{error}%
alpar@464
  2997
  \definedummyword{expansion}%
alpar@464
  2998
  \definedummyword{minus}%
alpar@464
  2999
  \definedummyword{pounds}%
alpar@464
  3000
  \definedummyword{point}%
alpar@464
  3001
  \definedummyword{print}%
alpar@464
  3002
  \definedummyword{result}%
alpar@464
  3003
  %
alpar@464
  3004
  % Handle some cases of @value -- where the variable name does not
alpar@464
  3005
  % contain - or _, and the value does not contain any
alpar@464
  3006
  % (non-fully-expandable) commands.
alpar@464
  3007
  \let\value = \expandablevalue
alpar@464
  3008
  %
alpar@464
  3009
  % Normal spaces, not active ones.
alpar@464
  3010
  \unsepspaces
alpar@464
  3011
  %
alpar@464
  3012
  % No macro expansion.
alpar@464
  3013
  \turnoffmacros
alpar@464
  3014
}
alpar@464
  3015
alpar@464
  3016
% If an index command is used in an @example environment, any spaces
alpar@464
  3017
% therein should become regular spaces in the raw index file, not the
alpar@464
  3018
% expansion of \tie (\leavevmode \penalty \@M \ ).
alpar@464
  3019
{\obeyspaces
alpar@464
  3020
 \gdef\unsepspaces{\obeyspaces\let =\space}}
alpar@464
  3021
alpar@464
  3022
alpar@464
  3023
% \indexnofonts is used when outputting the strings to sort the index
alpar@464
  3024
% by, and when constructing control sequence names.  It eliminates all
alpar@464
  3025
% control sequences and just writes whatever the best ASCII sort string
alpar@464
  3026
% would be for a given command (usually its argument).
alpar@464
  3027
%
alpar@464
  3028
\def\indexdummytex{TeX}
alpar@464
  3029
\def\indexdummydots{...}
alpar@464
  3030
%
alpar@464
  3031
\def\indexnofonts{%
alpar@464
  3032
  \def\ { }%
alpar@464
  3033
  \def\@{@}%
alpar@464
  3034
  % how to handle braces?
alpar@464
  3035
  \def\_{\normalunderscore}%
alpar@464
  3036
  %
alpar@464
  3037
  \let\,=\asis
alpar@464
  3038
  \let\"=\asis
alpar@464
  3039
  \let\`=\asis
alpar@464
  3040
  \let\'=\asis
alpar@464
  3041
  \let\^=\asis
alpar@464
  3042
  \let\~=\asis
alpar@464
  3043
  \let\==\asis
alpar@464
  3044
  \let\u=\asis
alpar@464
  3045
  \let\v=\asis
alpar@464
  3046
  \let\H=\asis
alpar@464
  3047
  \let\dotaccent=\asis
alpar@464
  3048
  \let\ringaccent=\asis
alpar@464
  3049
  \let\tieaccent=\asis
alpar@464
  3050
  \let\ubaraccent=\asis
alpar@464
  3051
  \let\udotaccent=\asis
alpar@464
  3052
  \let\dotless=\asis
alpar@464
  3053
  %
alpar@464
  3054
  % Other non-English letters.
alpar@464
  3055
  \def\AA{AA}%
alpar@464
  3056
  \def\AE{AE}%
alpar@464
  3057
  \def\L{L}%
alpar@464
  3058
  \def\OE{OE}%
alpar@464
  3059
  \def\O{O}%
alpar@464
  3060
  \def\aa{aa}%
alpar@464
  3061
  \def\ae{ae}%
alpar@464
  3062
  \def\l{l}%
alpar@464
  3063
  \def\oe{oe}%
alpar@464
  3064
  \def\o{o}%
alpar@464
  3065
  \def\ss{ss}%
alpar@464
  3066
  \def\exclamdown{!}%
alpar@464
  3067
  \def\questiondown{?}%
alpar@464
  3068
  %
alpar@464
  3069
  % Don't no-op \tt, since it isn't a user-level command
alpar@464
  3070
  % and is used in the definitions of the active chars like <, >, |, etc.
alpar@464
  3071
  % Likewise with the other plain tex font commands.
alpar@464
  3072
  %\let\tt=\asis
alpar@464
  3073
  %
alpar@464
  3074
  % Texinfo font commands.
alpar@464
  3075
  \let\b=\asis
alpar@464
  3076
  \let\i=\asis
alpar@464
  3077
  \let\r=\asis
alpar@464
  3078
  \let\sc=\asis
alpar@464
  3079
  \let\t=\asis
alpar@464
  3080
  %
alpar@464
  3081
  \let\TeX=\indexdummytex
alpar@464
  3082
  \let\acronym=\asis
alpar@464
  3083
  \let\cite=\asis
alpar@464
  3084
  \let\code=\asis
alpar@464
  3085
  \let\command=\asis
alpar@464
  3086
  \let\dfn=\asis
alpar@464
  3087
  \let\dots=\indexdummydots
alpar@464
  3088
  \let\emph=\asis
alpar@464
  3089
  \let\env=\asis
alpar@464
  3090
  \let\file=\asis
alpar@464
  3091
  \let\kbd=\asis
alpar@464
  3092
  \let\key=\asis
alpar@464
  3093
  \let\math=\asis
alpar@464
  3094
  \let\option=\asis
alpar@464
  3095
  \let\samp=\asis
alpar@464
  3096
  \let\strong=\asis
alpar@464
  3097
  \let\uref=\asis
alpar@464
  3098
  \let\url=\asis
alpar@464
  3099
  \let\var=\asis
alpar@464
  3100
  \let\w=\asis
alpar@464
  3101
}
alpar@464
  3102
alpar@464
  3103
\let\indexbackslash=0  %overridden during \printindex.
alpar@464
  3104
\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
alpar@464
  3105
alpar@464
  3106
% For \ifx comparisons.
alpar@464
  3107
\def\emptymacro{\empty}
alpar@464
  3108
alpar@464
  3109
% Most index entries go through here, but \dosubind is the general case.
alpar@464
  3110
%
alpar@464
  3111
\def\doind#1#2{\dosubind{#1}{#2}\empty}
alpar@464
  3112
alpar@464
  3113
% Workhorse for all \fooindexes.
alpar@464
  3114
% #1 is name of index, #2 is stuff to put there, #3 is subentry --
alpar@464
  3115
% \empty if called from \doind, as we usually are.  The main exception
alpar@464
  3116
% is with defuns, which call us directly.
alpar@464
  3117
%
alpar@464
  3118
\def\dosubind#1#2#3{%
alpar@464
  3119
  % Put the index entry in the margin if desired.
alpar@464
  3120
  \ifx\SETmarginindex\relax\else
alpar@464
  3121
    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
alpar@464
  3122
  \fi
alpar@464
  3123
  {%
alpar@464
  3124
    \count255=\lastpenalty
alpar@464
  3125
    {%
alpar@464
  3126
      \indexdummies % Must do this here, since \bf, etc expand at this stage
alpar@464
  3127
      \escapechar=`\\
alpar@464
  3128
      {%
alpar@464
  3129
        \let\folio = 0% We will expand all macros now EXCEPT \folio.
alpar@464
  3130
        \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
alpar@464
  3131
        % so it will be output as is; and it will print as backslash.
alpar@464
  3132
        %
alpar@464
  3133
        % The main index entry text.
alpar@464
  3134
        \toks0 = {#2}%
alpar@464
  3135
        %
alpar@464
  3136
        % If third arg is present, precede it with space in sort key.
alpar@464
  3137
        \def\thirdarg{#3}%
alpar@464
  3138
        \ifx\thirdarg\emptymacro \else
alpar@464
  3139
           % If the third (subentry) arg is present, add it to the index
alpar@464
  3140
           % line to write.
alpar@464
  3141
          \toks0 = \expandafter{\the\toks0 \space #3}%
alpar@464
  3142
        \fi
alpar@464
  3143
        %
alpar@464
  3144
        % Process the index entry with all font commands turned off, to
alpar@464
  3145
        % get the string to sort by.
alpar@464
  3146
        {\indexnofonts
alpar@464
  3147
         \edef\temp{\the\toks0}% need full expansion
alpar@464
  3148
         \xdef\indexsorttmp{\temp}%
alpar@464
  3149
        }%
alpar@464
  3150
        %
alpar@464
  3151
        % Set up the complete index entry, with both the sort key and
alpar@464
  3152
        % the original text, including any font commands.  We write
alpar@464
  3153
        % three arguments to \entry to the .?? file (four in the
alpar@464
  3154
        % subentry case), texindex reduces to two when writing the .??s
alpar@464
  3155
        % sorted result.
alpar@464
  3156
        \edef\temp{%
alpar@464
  3157
          \write\csname#1indfile\endcsname{%
alpar@464
  3158
            \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
alpar@464
  3159
        }%
alpar@464
  3160
        %
alpar@464
  3161
        % If a skip is the last thing on the list now, preserve it
alpar@464
  3162
        % by backing up by \lastskip, doing the \write, then inserting
alpar@464
  3163
        % the skip again.  Otherwise, the whatsit generated by the
alpar@464
  3164
        % \write will make \lastskip zero.  The result is that sequences
alpar@464
  3165
        % like this:
alpar@464
  3166
        % @end defun
alpar@464
  3167
        % @tindex whatever
alpar@464
  3168
        % @defun ...
alpar@464
  3169
        % will have extra space inserted, because the \medbreak in the
alpar@464
  3170
        % start of the @defun won't see the skip inserted by the @end of
alpar@464
  3171
        % the previous defun.
alpar@464
  3172
        %
alpar@464
  3173
        % But don't do any of this if we're not in vertical mode.  We
alpar@464
  3174
        % don't want to do a \vskip and prematurely end a paragraph.
alpar@464
  3175
        %
alpar@464
  3176
        % Avoid page breaks due to these extra skips, too.
alpar@464
  3177
        %
alpar@464
  3178
        \iflinks
alpar@464
  3179
          \ifvmode
alpar@464
  3180
            \skip0 = \lastskip
alpar@464
  3181
            \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi
alpar@464
  3182
          \fi
alpar@464
  3183
          %
alpar@464
  3184
          \temp % do the write
alpar@464
  3185
          %
alpar@464
  3186
          \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi
alpar@464
  3187
        \fi
alpar@464
  3188
      }%
alpar@464
  3189
    }%
alpar@464
  3190
    \penalty\count255
alpar@464
  3191
  }%
alpar@464
  3192
}
alpar@464
  3193
alpar@464
  3194
% The index entry written in the file actually looks like
alpar@464
  3195
%  \entry {sortstring}{page}{topic}
alpar@464
  3196
% or
alpar@464
  3197
%  \entry {sortstring}{page}{topic}{subtopic}
alpar@464
  3198
% The texindex program reads in these files and writes files
alpar@464
  3199
% containing these kinds of lines:
alpar@464
  3200
%  \initial {c}
alpar@464
  3201
%     before the first topic whose initial is c
alpar@464
  3202
%  \entry {topic}{pagelist}
alpar@464
  3203
%     for a topic that is used without subtopics
alpar@464
  3204
%  \primary {topic}
alpar@464
  3205
%     for the beginning of a topic that is used with subtopics
alpar@464
  3206
%  \secondary {subtopic}{pagelist}
alpar@464
  3207
%     for each subtopic.
alpar@464
  3208
alpar@464
  3209
% Define the user-accessible indexing commands
alpar@464
  3210
% @findex, @vindex, @kindex, @cindex.
alpar@464
  3211
alpar@464
  3212
\def\findex {\fnindex}
alpar@464
  3213
\def\kindex {\kyindex}
alpar@464
  3214
\def\cindex {\cpindex}
alpar@464
  3215
\def\vindex {\vrindex}
alpar@464
  3216
\def\tindex {\tpindex}
alpar@464
  3217
\def\pindex {\pgindex}
alpar@464
  3218
alpar@464
  3219
\def\cindexsub {\begingroup\obeylines\cindexsub}
alpar@464
  3220
{\obeylines %
alpar@464
  3221
\gdef\cindexsub "#1" #2^^M{\endgroup %
alpar@464
  3222
\dosubind{cp}{#2}{#1}}}
alpar@464
  3223
alpar@464
  3224
% Define the macros used in formatting output of the sorted index material.
alpar@464
  3225
alpar@464
  3226
% @printindex causes a particular index (the ??s file) to get printed.
alpar@464
  3227
% It does not print any chapter heading (usually an @unnumbered).
alpar@464
  3228
%
alpar@464
  3229
\def\printindex{\parsearg\doprintindex}
alpar@464
  3230
\def\doprintindex#1{\begingroup
alpar@464
  3231
  \dobreak \chapheadingskip{10000}%
alpar@464
  3232
  %
alpar@464
  3233
  \smallfonts \rm
alpar@464
  3234
  \tolerance = 9500
alpar@464
  3235
  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
alpar@464
  3236
  \indexbreaks
alpar@464
  3237
  %
alpar@464
  3238
  % See if the index file exists and is nonempty.
alpar@464
  3239
  % Change catcode of @ here so that if the index file contains
alpar@464
  3240
  % \initial {@}
alpar@464
  3241
  % as its first line, TeX doesn't complain about mismatched braces
alpar@464
  3242
  % (because it thinks @} is a control sequence).
alpar@464
  3243
  \catcode`\@ = 11
alpar@464
  3244
  \openin 1 \jobname.#1s
alpar@464
  3245
  \ifeof 1
alpar@464
  3246
    % \enddoublecolumns gets confused if there is no text in the index,
alpar@464
  3247
    % and it loses the chapter title and the aux file entries for the
alpar@464
  3248
    % index.  The easiest way to prevent this problem is to make sure
alpar@464
  3249
    % there is some text.
alpar@464
  3250
    \putwordIndexNonexistent
alpar@464
  3251
  \else
alpar@464
  3252
    %
alpar@464
  3253
    % If the index file exists but is empty, then \openin leaves \ifeof
alpar@464
  3254
    % false.  We have to make TeX try to read something from the file, so
alpar@464
  3255
    % it can discover if there is anything in it.
alpar@464
  3256
    \read 1 to \temp
alpar@464
  3257
    \ifeof 1
alpar@464
  3258
      \putwordIndexIsEmpty
alpar@464
  3259
    \else
alpar@464
  3260
      % Index files are almost Texinfo source, but we use \ as the escape
alpar@464
  3261
      % character.  It would be better to use @, but that's too big a change
alpar@464
  3262
      % to make right now.
alpar@464
  3263
      \def\indexbackslash{\rawbackslashxx}%
alpar@464
  3264
      \catcode`\\ = 0
alpar@464
  3265
      \escapechar = `\\
alpar@464
  3266
      \begindoublecolumns
alpar@464
  3267
      \input \jobname.#1s
alpar@464
  3268
      \enddoublecolumns
alpar@464
  3269
    \fi
alpar@464
  3270
  \fi
alpar@464
  3271
  \closein 1
alpar@464
  3272
\endgroup}
alpar@464
  3273
alpar@464
  3274
% These macros are used by the sorted index file itself.
alpar@464
  3275
% Change them to control the appearance of the index.
alpar@464
  3276
alpar@464
  3277
\def\initial#1{{%
alpar@464
  3278
  % Some minor font changes for the special characters.
alpar@464
  3279
  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
alpar@464
  3280
  %
alpar@464
  3281
  % Remove any glue we may have, we'll be inserting our own.
alpar@464
  3282
  \removelastskip
alpar@464
  3283
  %
alpar@464
  3284
  % We like breaks before the index initials, so insert a bonus.
alpar@464
  3285
  \penalty -300
alpar@464
  3286
  %
alpar@464
  3287
  % Typeset the initial.  Making this add up to a whole number of
alpar@464
  3288
  % baselineskips increases the chance of the dots lining up from column
alpar@464
  3289
  % to column.  It still won't often be perfect, because of the stretch
alpar@464
  3290
  % we need before each entry, but it's better.
alpar@464
  3291
  %
alpar@464
  3292
  % No shrink because it confuses \balancecolumns.
alpar@464
  3293
  \vskip 1.67\baselineskip plus .5\baselineskip
alpar@464
  3294
  \leftline{\secbf #1}%
alpar@464
  3295
  \vskip .33\baselineskip plus .1\baselineskip
alpar@464
  3296
  %
alpar@464
  3297
  % Do our best not to break after the initial.
alpar@464
  3298
  \nobreak
alpar@464
  3299
}}
alpar@464
  3300
alpar@464
  3301
% This typesets a paragraph consisting of #1, dot leaders, and then #2
alpar@464
  3302
% flush to the right margin.  It is used for index and table of contents
alpar@464
  3303
% entries.  The paragraph is indented by \leftskip.
alpar@464
  3304
%
alpar@464
  3305
\def\entry#1#2{\begingroup
alpar@464
  3306
  %
alpar@464
  3307
  % Start a new paragraph if necessary, so our assignments below can't
alpar@464
  3308
  % affect previous text.
alpar@464
  3309
  \par
alpar@464
  3310
  %
alpar@464
  3311
  % Do not fill out the last line with white space.
alpar@464
  3312
  \parfillskip = 0in
alpar@464
  3313
  %
alpar@464
  3314
  % No extra space above this paragraph.
alpar@464
  3315
  \parskip = 0in
alpar@464
  3316
  %
alpar@464
  3317
  % Do not prefer a separate line ending with a hyphen to fewer lines.
alpar@464
  3318
  \finalhyphendemerits = 0
alpar@464
  3319
  %
alpar@464
  3320
  % \hangindent is only relevant when the entry text and page number
alpar@464
  3321
  % don't both fit on one line.  In that case, bob suggests starting the
alpar@464
  3322
  % dots pretty far over on the line.  Unfortunately, a large
alpar@464
  3323
  % indentation looks wrong when the entry text itself is broken across
alpar@464
  3324
  % lines.  So we use a small indentation and put up with long leaders.
alpar@464
  3325
  %
alpar@464
  3326
  % \hangafter is reset to 1 (which is the value we want) at the start
alpar@464
  3327
  % of each paragraph, so we need not do anything with that.
alpar@464
  3328
  \hangindent = 2em
alpar@464
  3329
  %
alpar@464
  3330
  % When the entry text needs to be broken, just fill out the first line
alpar@464
  3331
  % with blank space.
alpar@464
  3332
  \rightskip = 0pt plus1fil
alpar@464
  3333
  %
alpar@464
  3334
  % A bit of stretch before each entry for the benefit of balancing columns.
alpar@464
  3335
  \vskip 0pt plus1pt
alpar@464
  3336
  %
alpar@464
  3337
  % Start a ``paragraph'' for the index entry so the line breaking
alpar@464
  3338
  % parameters we've set above will have an effect.
alpar@464
  3339
  \noindent
alpar@464
  3340
  %
alpar@464
  3341
  % Insert the text of the index entry.  TeX will do line-breaking on it.
alpar@464
  3342
  #1%
alpar@464
  3343
  % The following is kludged to not output a line of dots in the index if
alpar@464
  3344
  % there are no page numbers.  The next person who breaks this will be
alpar@464
  3345
  % cursed by a Unix daemon.
alpar@464
  3346
  \def\tempa{{\rm }}%
alpar@464
  3347
  \def\tempb{#2}%
alpar@464
  3348
  \edef\tempc{\tempa}%
alpar@464
  3349
  \edef\tempd{\tempb}%
alpar@464
  3350
  \ifx\tempc\tempd\ \else%
alpar@464
  3351
    %
alpar@464
  3352
    % If we must, put the page number on a line of its own, and fill out
alpar@464
  3353
    % this line with blank space.  (The \hfil is overwhelmed with the
alpar@464
  3354
    % fill leaders glue in \indexdotfill if the page number does fit.)
alpar@464
  3355
    \hfil\penalty50
alpar@464
  3356
    \null\nobreak\indexdotfill % Have leaders before the page number.
alpar@464
  3357
    %
alpar@464
  3358
    % The `\ ' here is removed by the implicit \unskip that TeX does as
alpar@464
  3359
    % part of (the primitive) \par.  Without it, a spurious underfull
alpar@464
  3360
    % \hbox ensues.
alpar@464
  3361
    \ifpdf
alpar@464
  3362
      \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
alpar@464
  3363
    \else
alpar@464
  3364
      \ #2% The page number ends the paragraph.
alpar@464
  3365
    \fi
alpar@464
  3366
  \fi%
alpar@464
  3367
  \par
alpar@464
  3368
\endgroup}
alpar@464
  3369
alpar@464
  3370
% Like \dotfill except takes at least 1 em.
alpar@464
  3371
\def\indexdotfill{\cleaders
alpar@464
  3372
  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
alpar@464
  3373
alpar@464
  3374
\def\primary #1{\line{#1\hfil}}
alpar@464
  3375
alpar@464
  3376
\newskip\secondaryindent \secondaryindent=0.5cm
alpar@464
  3377
\def\secondary#1#2{{%
alpar@464
  3378
  \parfillskip=0in
alpar@464
  3379
  \parskip=0in
alpar@464
  3380
  \hangindent=1in
alpar@464
  3381
  \hangafter=1
alpar@464
  3382
  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
alpar@464
  3383
  \ifpdf
alpar@464
  3384
    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
alpar@464
  3385
  \else
alpar@464
  3386
    #2
alpar@464
  3387
  \fi
alpar@464
  3388
  \par
alpar@464
  3389
}}
alpar@464
  3390
alpar@464
  3391
% Define two-column mode, which we use to typeset indexes.
alpar@464
  3392
% Adapted from the TeXbook, page 416, which is to say,
alpar@464
  3393
% the manmac.tex format used to print the TeXbook itself.
alpar@464
  3394
\catcode`\@=11
alpar@464
  3395
alpar@464
  3396
\newbox\partialpage
alpar@464
  3397
\newdimen\doublecolumnhsize
alpar@464
  3398
alpar@464
  3399
\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
alpar@464
  3400
  % Grab any single-column material above us.
alpar@464
  3401
  \output = {%
alpar@464
  3402
    %
alpar@464
  3403
    % Here is a possibility not foreseen in manmac: if we accumulate a
alpar@464
  3404
    % whole lot of material, we might end up calling this \output
alpar@464
  3405
    % routine twice in a row (see the doublecol-lose test, which is
alpar@464
  3406
    % essentially a couple of indexes with @setchapternewpage off).  In
alpar@464
  3407
    % that case we just ship out what is in \partialpage with the normal
alpar@464
  3408
    % output routine.  Generally, \partialpage will be empty when this
alpar@464
  3409
    % runs and this will be a no-op.  See the indexspread.tex test case.
alpar@464
  3410
    \ifvoid\partialpage \else
alpar@464
  3411
      \onepageout{\pagecontents\partialpage}%
alpar@464
  3412
    \fi
alpar@464
  3413
    %
alpar@464
  3414
    \global\setbox\partialpage = \vbox{%
alpar@464
  3415
      % Unvbox the main output page.
alpar@464
  3416
      \unvbox\PAGE
alpar@464
  3417
      \kern-\topskip \kern\baselineskip
alpar@464
  3418
    }%
alpar@464
  3419
  }%
alpar@464
  3420
  \eject % run that output routine to set \partialpage
alpar@464
  3421
  %
alpar@464
  3422
  % Use the double-column output routine for subsequent pages.
alpar@464
  3423
  \output = {\doublecolumnout}%
alpar@464
  3424
  %
alpar@464
  3425
  % Change the page size parameters.  We could do this once outside this
alpar@464
  3426
  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
alpar@464
  3427
  % format, but then we repeat the same computation.  Repeating a couple
alpar@464
  3428
  % of assignments once per index is clearly meaningless for the
alpar@464
  3429
  % execution time, so we may as well do it in one place.
alpar@464
  3430
  %
alpar@464
  3431
  % First we halve the line length, less a little for the gutter between
alpar@464
  3432
  % the columns.  We compute the gutter based on the line length, so it
alpar@464
  3433
  % changes automatically with the paper format.  The magic constant
alpar@464
  3434
  % below is chosen so that the gutter has the same value (well, +-<1pt)
alpar@464
  3435
  % as it did when we hard-coded it.
alpar@464
  3436
  %
alpar@464
  3437
  % We put the result in a separate register, \doublecolumhsize, so we
alpar@464
  3438
  % can restore it in \pagesofar, after \hsize itself has (potentially)
alpar@464
  3439
  % been clobbered.
alpar@464
  3440
  %
alpar@464
  3441
  \doublecolumnhsize = \hsize
alpar@464
  3442
    \advance\doublecolumnhsize by -.04154\hsize
alpar@464
  3443
    \divide\doublecolumnhsize by 2
alpar@464
  3444
  \hsize = \doublecolumnhsize
alpar@464
  3445
  %
alpar@464
  3446
  % Double the \vsize as well.  (We don't need a separate register here,
alpar@464
  3447
  % since nobody clobbers \vsize.)
alpar@464
  3448
  \vsize = 2\vsize
alpar@464
  3449
}
alpar@464
  3450
alpar@464
  3451
% The double-column output routine for all double-column pages except
alpar@464
  3452
% the last.
alpar@464
  3453
%
alpar@464
  3454
\def\doublecolumnout{%
alpar@464
  3455
  \splittopskip=\topskip \splitmaxdepth=\maxdepth
alpar@464
  3456
  % Get the available space for the double columns -- the normal
alpar@464
  3457
  % (undoubled) page height minus any material left over from the
alpar@464
  3458
  % previous page.
alpar@464
  3459
  \dimen@ = \vsize
alpar@464
  3460
  \divide\dimen@ by 2
alpar@464
  3461
  \advance\dimen@ by -\ht\partialpage
alpar@464
  3462
  %
alpar@464
  3463
  % box0 will be the left-hand column, box2 the right.
alpar@464
  3464
  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
alpar@464
  3465
  \onepageout\pagesofar
alpar@464
  3466
  \unvbox255
alpar@464
  3467
  \penalty\outputpenalty
alpar@464
  3468
}
alpar@464
  3469
%
alpar@464
  3470
% Re-output the contents of the output page -- any previous material,
alpar@464
  3471
% followed by the two boxes we just split, in box0 and box2.
alpar@464
  3472
\def\pagesofar{%
alpar@464
  3473
  \unvbox\partialpage
alpar@464
  3474
  %
alpar@464
  3475
  \hsize = \doublecolumnhsize
alpar@464
  3476
  \wd0=\hsize \wd2=\hsize
alpar@464
  3477
  \hbox to\pagewidth{\box0\hfil\box2}%
alpar@464
  3478
}
alpar@464
  3479
%
alpar@464
  3480
% All done with double columns.
alpar@464
  3481
\def\enddoublecolumns{%
alpar@464
  3482
  \output = {%
alpar@464
  3483
    % Split the last of the double-column material.  Leave it on the
alpar@464
  3484
    % current page, no automatic page break.
alpar@464
  3485
    \balancecolumns
alpar@464
  3486
    %
alpar@464
  3487
    % If we end up splitting too much material for the current page,
alpar@464
  3488
    % though, there will be another page break right after this \output
alpar@464
  3489
    % invocation ends.  Having called \balancecolumns once, we do not
alpar@464
  3490
    % want to call it again.  Therefore, reset \output to its normal
alpar@464
  3491
    % definition right away.  (We hope \balancecolumns will never be
alpar@464
  3492
    % called on to balance too much material, but if it is, this makes
alpar@464
  3493
    % the output somewhat more palatable.)
alpar@464
  3494
    \global\output = {\onepageout{\pagecontents\PAGE}}%
alpar@464
  3495
  }%
alpar@464
  3496
  \eject
alpar@464
  3497
  \endgroup % started in \begindoublecolumns
alpar@464
  3498
  %
alpar@464
  3499
  % \pagegoal was set to the doubled \vsize above, since we restarted
alpar@464
  3500
  % the current page.  We're now back to normal single-column
alpar@464
  3501
  % typesetting, so reset \pagegoal to the normal \vsize (after the
alpar@464
  3502
  % \endgroup where \vsize got restored).
alpar@464
  3503
  \pagegoal = \vsize
alpar@464
  3504
}
alpar@464
  3505
%
alpar@464
  3506
% Called at the end of the double column material.
alpar@464
  3507
\def\balancecolumns{%
alpar@464
  3508
  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
alpar@464
  3509
  \dimen@ = \ht0
alpar@464
  3510
  \advance\dimen@ by \topskip
alpar@464
  3511
  \advance\dimen@ by-\baselineskip
alpar@464
  3512
  \divide\dimen@ by 2 % target to split to
alpar@464
  3513
  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
alpar@464
  3514
  \splittopskip = \topskip
alpar@464
  3515
  % Loop until we get a decent breakpoint.
alpar@464
  3516
  {%
alpar@464
  3517
    \vbadness = 10000
alpar@464
  3518
    \loop
alpar@464
  3519
      \global\setbox3 = \copy0
alpar@464
  3520
      \global\setbox1 = \vsplit3 to \dimen@
alpar@464
  3521
    \ifdim\ht3>\dimen@
alpar@464
  3522
      \global\advance\dimen@ by 1pt
alpar@464
  3523
    \repeat
alpar@464
  3524
  }%
alpar@464
  3525
  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
alpar@464
  3526
  \setbox0=\vbox to\dimen@{\unvbox1}%
alpar@464
  3527
  \setbox2=\vbox to\dimen@{\unvbox3}%
alpar@464
  3528
  %
alpar@464
  3529
  \pagesofar
alpar@464
  3530
}
alpar@464
  3531
\catcode`\@ = \other
alpar@464
  3532
alpar@464
  3533
alpar@464
  3534
\message{sectioning,}
alpar@464
  3535
% Chapters, sections, etc.
alpar@464
  3536
alpar@464
  3537
\newcount\chapno
alpar@464
  3538
\newcount\secno        \secno=0
alpar@464
  3539
\newcount\subsecno     \subsecno=0
alpar@464
  3540
\newcount\subsubsecno  \subsubsecno=0
alpar@464
  3541
alpar@464
  3542
% This counter is funny since it counts through charcodes of letters A, B, ...
alpar@464
  3543
\newcount\appendixno  \appendixno = `\@
alpar@464
  3544
% \def\appendixletter{\char\the\appendixno}
alpar@464
  3545
% We do the following for the sake of pdftex, which needs the actual
alpar@464
  3546
% letter in the expansion, not just typeset.
alpar@464
  3547
\def\appendixletter{%
alpar@464
  3548
  \ifnum\appendixno=`A A%
alpar@464
  3549
  \else\ifnum\appendixno=`B B%
alpar@464
  3550
  \else\ifnum\appendixno=`C C%
alpar@464
  3551
  \else\ifnum\appendixno=`D D%
alpar@464
  3552
  \else\ifnum\appendixno=`E E%
alpar@464
  3553
  \else\ifnum\appendixno=`F F%
alpar@464
  3554
  \else\ifnum\appendixno=`G G%
alpar@464
  3555
  \else\ifnum\appendixno=`H H%
alpar@464
  3556
  \else\ifnum\appendixno=`I I%
alpar@464
  3557
  \else\ifnum\appendixno=`J J%
alpar@464
  3558
  \else\ifnum\appendixno=`K K%
alpar@464
  3559
  \else\ifnum\appendixno=`L L%
alpar@464
  3560
  \else\ifnum\appendixno=`M M%
alpar@464
  3561
  \else\ifnum\appendixno=`N N%
alpar@464
  3562
  \else\ifnum\appendixno=`O O%
alpar@464
  3563
  \else\ifnum\appendixno=`P P%
alpar@464
  3564
  \else\ifnum\appendixno=`Q Q%
alpar@464
  3565
  \else\ifnum\appendixno=`R R%
alpar@464
  3566
  \else\ifnum\appendixno=`S S%
alpar@464
  3567
  \else\ifnum\appendixno=`T T%
alpar@464
  3568
  \else\ifnum\appendixno=`U U%
alpar@464
  3569
  \else\ifnum\appendixno=`V V%
alpar@464
  3570
  \else\ifnum\appendixno=`W W%
alpar@464
  3571
  \else\ifnum\appendixno=`X X%
alpar@464
  3572
  \else\ifnum\appendixno=`Y Y%
alpar@464
  3573
  \else\ifnum\appendixno=`Z Z%
alpar@464
  3574
  % The \the is necessary, despite appearances, because \appendixletter is
alpar@464
  3575
  % expanded while writing the .toc file.  \char\appendixno is not
alpar@464
  3576
  % expandable, thus it is written literally, thus all appendixes come out
alpar@464
  3577
  % with the same letter (or @) in the toc without it.
alpar@464
  3578
  \else\char\the\appendixno
alpar@464
  3579
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
alpar@464
  3580
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
alpar@464
  3581
alpar@464
  3582
% Each @chapter defines this as the name of the chapter.
alpar@464
  3583
% page headings and footings can use it.  @section does likewise.
alpar@464
  3584
\def\thischapter{}
alpar@464
  3585
\def\thissection{}
alpar@464
  3586
alpar@464
  3587
\newcount\absseclevel % used to calculate proper heading level
alpar@464
  3588
\newcount\secbase\secbase=0 % @raise/lowersections modify this count
alpar@464
  3589
alpar@464
  3590
% @raisesections: treat @section as chapter, @subsection as section, etc.
alpar@464
  3591
\def\raisesections{\global\advance\secbase by -1}
alpar@464
  3592
\let\up=\raisesections % original BFox name
alpar@464
  3593
alpar@464
  3594
% @lowersections: treat @chapter as section, @section as subsection, etc.
alpar@464
  3595
\def\lowersections{\global\advance\secbase by 1}
alpar@464
  3596
\let\down=\lowersections % original BFox name
alpar@464
  3597
alpar@464
  3598
% Choose a numbered-heading macro
alpar@464
  3599
% #1 is heading level if unmodified by @raisesections or @lowersections
alpar@464
  3600
% #2 is text for heading
alpar@464
  3601
\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
alpar@464
  3602
\ifcase\absseclevel
alpar@464
  3603
  \chapterzzz{#2}
alpar@464
  3604
\or
alpar@464
  3605
  \seczzz{#2}
alpar@464
  3606
\or
alpar@464
  3607
  \numberedsubseczzz{#2}
alpar@464
  3608
\or
alpar@464
  3609
  \numberedsubsubseczzz{#2}
alpar@464
  3610
\else
alpar@464
  3611
  \ifnum \absseclevel<0
alpar@464
  3612
    \chapterzzz{#2}
alpar@464
  3613
  \else
alpar@464
  3614
    \numberedsubsubseczzz{#2}
alpar@464
  3615
  \fi
alpar@464
  3616
\fi
alpar@464
  3617
\suppressfirstparagraphindent
alpar@464
  3618
}
alpar@464
  3619
alpar@464
  3620
% like \numhead, but chooses appendix heading levels
alpar@464
  3621
\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
alpar@464
  3622
\ifcase\absseclevel
alpar@464
  3623
  \appendixzzz{#2}
alpar@464
  3624
\or
alpar@464
  3625
  \appendixsectionzzz{#2}
alpar@464
  3626
\or
alpar@464
  3627
  \appendixsubseczzz{#2}
alpar@464
  3628
\or
alpar@464
  3629
  \appendixsubsubseczzz{#2}
alpar@464
  3630
\else
alpar@464
  3631
  \ifnum \absseclevel<0
alpar@464
  3632
    \appendixzzz{#2}
alpar@464
  3633
  \else
alpar@464
  3634
    \appendixsubsubseczzz{#2}
alpar@464
  3635
  \fi
alpar@464
  3636
\fi
alpar@464
  3637
\suppressfirstparagraphindent
alpar@464
  3638
}
alpar@464
  3639
alpar@464
  3640
% like \numhead, but chooses numberless heading levels
alpar@464
  3641
\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
alpar@464
  3642
\ifcase\absseclevel
alpar@464
  3643
  \unnumberedzzz{#2}
alpar@464
  3644
\or
alpar@464
  3645
  \unnumberedseczzz{#2}
alpar@464
  3646
\or
alpar@464
  3647
  \unnumberedsubseczzz{#2}
alpar@464
  3648
\or
alpar@464
  3649
  \unnumberedsubsubseczzz{#2}
alpar@464
  3650
\else
alpar@464
  3651
  \ifnum \absseclevel<0
alpar@464
  3652
    \unnumberedzzz{#2}
alpar@464
  3653
  \else
alpar@464
  3654
    \unnumberedsubsubseczzz{#2}
alpar@464
  3655
  \fi
alpar@464
  3656
\fi
alpar@464
  3657
\suppressfirstparagraphindent
alpar@464
  3658
}
alpar@464
  3659
alpar@464
  3660
% @chapter, @appendix, @unnumbered.
alpar@464
  3661
\def\thischaptername{No Chapter Title}
alpar@464
  3662
\outer\def\chapter{\parsearg\chapteryyy}
alpar@464
  3663
\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
alpar@464
  3664
\def\chapterzzz #1{%
alpar@464
  3665
  \secno=0 \subsecno=0 \subsubsecno=0
alpar@464
  3666
  \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}%
alpar@464
  3667
  \chapmacro {#1}{\the\chapno}%
alpar@464
  3668
  \gdef\thissection{#1}%
alpar@464
  3669
  \gdef\thischaptername{#1}%
alpar@464
  3670
  % We don't substitute the actual chapter name into \thischapter
alpar@464
  3671
  % because we don't want its macros evaluated now.
alpar@464
  3672
  \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
alpar@464
  3673
  \writetocentry{chap}{#1}{{\the\chapno}}
alpar@464
  3674
  \donoderef
alpar@464
  3675
  \global\let\section = \numberedsec
alpar@464
  3676
  \global\let\subsection = \numberedsubsec
alpar@464
  3677
  \global\let\subsubsection = \numberedsubsubsec
alpar@464
  3678
}
alpar@464
  3679
alpar@464
  3680
% we use \chapno to avoid indenting back
alpar@464
  3681
\def\appendixbox#1{%
alpar@464
  3682
  \setbox0 = \hbox{\putwordAppendix{} \the\chapno}%
alpar@464
  3683
  \hbox to \wd0{#1\hss}}
alpar@464
  3684
alpar@464
  3685
\outer\def\appendix{\parsearg\appendixyyy}
alpar@464
  3686
\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
alpar@464
  3687
\def\appendixzzz #1{%
alpar@464
  3688
  \secno=0 \subsecno=0 \subsubsecno=0
alpar@464
  3689
  \global\advance \appendixno by 1
alpar@464
  3690
  \message{\putwordAppendix\space \appendixletter}%
alpar@464
  3691
  \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}%
alpar@464
  3692
  \gdef\thissection{#1}%
alpar@464
  3693
  \gdef\thischaptername{#1}%
alpar@464
  3694
  \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
alpar@464
  3695
  \writetocentry{appendix}{#1}{{\appendixletter}}
alpar@464
  3696
  \appendixnoderef
alpar@464
  3697
  \global\let\section = \appendixsec
alpar@464
  3698
  \global\let\subsection = \appendixsubsec
alpar@464
  3699
  \global\let\subsubsection = \appendixsubsubsec
alpar@464
  3700
}
alpar@464
  3701
alpar@464
  3702
% @centerchap is like @unnumbered, but the heading is centered.
alpar@464
  3703
\outer\def\centerchap{\parsearg\centerchapyyy}
alpar@464
  3704
\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
alpar@464
  3705
alpar@464
  3706
% @top is like @unnumbered.
alpar@464
  3707
\outer\def\top{\parsearg\unnumberedyyy}
alpar@464
  3708
alpar@464
  3709
\outer\def\unnumbered{\parsearg\unnumberedyyy}
alpar@464
  3710
\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
alpar@464
  3711
\def\unnumberedzzz #1{%
alpar@464
  3712
  \secno=0 \subsecno=0 \subsubsecno=0
alpar@464
  3713
  %
alpar@464
  3714
  % This used to be simply \message{#1}, but TeX fully expands the
alpar@464
  3715
  % argument to \message.  Therefore, if #1 contained @-commands, TeX
alpar@464
  3716
  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
alpar@464
  3717
  % expanded @cite (which turns out to cause errors because \cite is meant
alpar@464
  3718
  % to be executed, not expanded).
alpar@464
  3719
  %
alpar@464
  3720
  % Anyway, we don't want the fully-expanded definition of @cite to appear
alpar@464
  3721
  % as a result of the \message, we just want `@cite' itself.  We use
alpar@464
  3722
  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
alpar@464
  3723
  % simply yielding the contents of <toks register>.  (We also do this for
alpar@464
  3724
  % the toc entries.)
alpar@464
  3725
  \toks0 = {#1}\message{(\the\toks0)}%
alpar@464
  3726
  %
alpar@464
  3727
  \unnumbchapmacro {#1}%
alpar@464
  3728
  \gdef\thischapter{#1}\gdef\thissection{#1}%
alpar@464
  3729
  \writetocentry{unnumbchap}{#1}{{\the\chapno}}
alpar@464
  3730
  \unnumbnoderef
alpar@464
  3731
  \global\let\section = \unnumberedsec
alpar@464
  3732
  \global\let\subsection = \unnumberedsubsec
alpar@464
  3733
  \global\let\subsubsection = \unnumberedsubsubsec
alpar@464
  3734
}
alpar@464
  3735
alpar@464
  3736
% Sections.
alpar@464
  3737
\outer\def\numberedsec{\parsearg\secyyy}
alpar@464
  3738
\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
alpar@464
  3739
\def\seczzz #1{%
alpar@464
  3740
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
alpar@464
  3741
  \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
alpar@464
  3742
  \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}}
alpar@464
  3743
  \donoderef
alpar@464
  3744
  \nobreak
alpar@464
  3745
}
alpar@464
  3746
alpar@464
  3747
\outer\def\appendixsection{\parsearg\appendixsecyyy}
alpar@464
  3748
\outer\def\appendixsec{\parsearg\appendixsecyyy}
alpar@464
  3749
\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
alpar@464
  3750
\def\appendixsectionzzz #1{%
alpar@464
  3751
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
alpar@464
  3752
  \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
alpar@464
  3753
  \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}}
alpar@464
  3754
  \appendixnoderef
alpar@464
  3755
  \nobreak
alpar@464
  3756
}
alpar@464
  3757
alpar@464
  3758
\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
alpar@464
  3759
\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
alpar@464
  3760
\def\unnumberedseczzz #1{%
alpar@464
  3761
  \plainsecheading {#1}\gdef\thissection{#1}%
alpar@464
  3762
  \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}}
alpar@464
  3763
  \unnumbnoderef
alpar@464
  3764
  \nobreak
alpar@464
  3765
}
alpar@464
  3766
alpar@464
  3767
% Subsections.
alpar@464
  3768
\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
alpar@464
  3769
\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
alpar@464
  3770
\def\numberedsubseczzz #1{%
alpar@464
  3771
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
alpar@464
  3772
  \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
alpar@464
  3773
  \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}}
alpar@464
  3774
  \donoderef
alpar@464
  3775
  \nobreak
alpar@464
  3776
}
alpar@464
  3777
alpar@464
  3778
\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
alpar@464
  3779
\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
alpar@464
  3780
\def\appendixsubseczzz #1{%
alpar@464
  3781
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
alpar@464
  3782
  \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
alpar@464
  3783
  \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}}
alpar@464
  3784
  \appendixnoderef
alpar@464
  3785
  \nobreak
alpar@464
  3786
}
alpar@464
  3787
alpar@464
  3788
\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
alpar@464
  3789
\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
alpar@464
  3790
\def\unnumberedsubseczzz #1{%
alpar@464
  3791
  \plainsubsecheading {#1}\gdef\thissection{#1}%
alpar@464
  3792
  \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}}
alpar@464
  3793
  \unnumbnoderef
alpar@464
  3794
  \nobreak
alpar@464
  3795
}
alpar@464
  3796
alpar@464
  3797
% Subsubsections.
alpar@464
  3798
\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
alpar@464
  3799
\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
alpar@464
  3800
\def\numberedsubsubseczzz #1{%
alpar@464
  3801
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
alpar@464
  3802
  \subsubsecheading {#1}
alpar@464
  3803
    {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
alpar@464
  3804
  \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
alpar@464
  3805
  \donoderef
alpar@464
  3806
  \nobreak
alpar@464
  3807
}
alpar@464
  3808
alpar@464
  3809
\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
alpar@464
  3810
\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
alpar@464
  3811
\def\appendixsubsubseczzz #1{%
alpar@464
  3812
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
alpar@464
  3813
  \subsubsecheading {#1}
alpar@464
  3814
    {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
alpar@464
  3815
  \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
alpar@464
  3816
  \appendixnoderef
alpar@464
  3817
  \nobreak
alpar@464
  3818
}
alpar@464
  3819
alpar@464
  3820
\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
alpar@464
  3821
\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
alpar@464
  3822
\def\unnumberedsubsubseczzz #1{%
alpar@464
  3823
  \plainsubsubsecheading {#1}\gdef\thissection{#1}%
alpar@464
  3824
  \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
alpar@464
  3825
  \unnumbnoderef
alpar@464
  3826
  \nobreak
alpar@464
  3827
}
alpar@464
  3828
alpar@464
  3829
% These are variants which are not "outer", so they can appear in @ifinfo.
alpar@464
  3830
% Actually, they should now be obsolete; ordinary section commands should work.
alpar@464
  3831
\def\infotop{\parsearg\unnumberedzzz}
alpar@464
  3832
\def\infounnumbered{\parsearg\unnumberedzzz}
alpar@464
  3833
\def\infounnumberedsec{\parsearg\unnumberedseczzz}
alpar@464
  3834
\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
alpar@464
  3835
\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
alpar@464
  3836
alpar@464
  3837
\def\infoappendix{\parsearg\appendixzzz}
alpar@464
  3838
\def\infoappendixsec{\parsearg\appendixseczzz}
alpar@464
  3839
\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
alpar@464
  3840
\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
alpar@464
  3841
alpar@464
  3842
\def\infochapter{\parsearg\chapterzzz}
alpar@464
  3843
\def\infosection{\parsearg\sectionzzz}
alpar@464
  3844
\def\infosubsection{\parsearg\subsectionzzz}
alpar@464
  3845
\def\infosubsubsection{\parsearg\subsubsectionzzz}
alpar@464
  3846
alpar@464
  3847
% These macros control what the section commands do, according
alpar@464
  3848
% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
alpar@464
  3849
% Define them by default for a numbered chapter.
alpar@464
  3850
\global\let\section = \numberedsec
alpar@464
  3851
\global\let\subsection = \numberedsubsec
alpar@464
  3852
\global\let\subsubsection = \numberedsubsubsec
alpar@464
  3853
alpar@464
  3854
% Define @majorheading, @heading and @subheading
alpar@464
  3855
alpar@464
  3856
% NOTE on use of \vbox for chapter headings, section headings, and such:
alpar@464
  3857
%       1) We use \vbox rather than the earlier \line to permit
alpar@464
  3858
%          overlong headings to fold.
alpar@464
  3859
%       2) \hyphenpenalty is set to 10000 because hyphenation in a
alpar@464
  3860
%          heading is obnoxious; this forbids it.
alpar@464
  3861
%       3) Likewise, headings look best if no \parindent is used, and
alpar@464
  3862
%          if justification is not attempted.  Hence \raggedright.
alpar@464
  3863
alpar@464
  3864
alpar@464
  3865
\def\majorheading{%
alpar@464
  3866
  {\advance\chapheadingskip by 10pt \chapbreak }%
alpar@464
  3867
  \parsearg\chapheadingzzz
alpar@464
  3868
}
alpar@464
  3869
alpar@464
  3870
\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
alpar@464
  3871
\def\chapheadingzzz #1{%
alpar@464
  3872
  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
alpar@464
  3873
                    \parindent=0pt\raggedright
alpar@464
  3874
                    \rm #1\hfill}}%
alpar@464
  3875
  \bigskip \par\penalty 200\relax
alpar@464
  3876
  \suppressfirstparagraphindent
alpar@464
  3877
}
alpar@464
  3878
alpar@464
  3879
% @heading, @subheading, @subsubheading.
alpar@464
  3880
\def\heading{\parsearg\doheading}
alpar@464
  3881
\def\subheading{\parsearg\dosubheading}
alpar@464
  3882
\def\subsubheading{\parsearg\dosubsubheading}
alpar@464
  3883
\def\doheading#1{\plainsecheading{#1}\suppressfirstparagraphindent}
alpar@464
  3884
\def\dosubheading#1{\plainsubsecheading{#1}\suppressfirstparagraphindent}
alpar@464
  3885
\def\dosubsubheading#1{\plainsubsubsecheading{#1}\suppressfirstparagraphindent}
alpar@464
  3886
alpar@464
  3887
% These macros generate a chapter, section, etc. heading only
alpar@464
  3888
% (including whitespace, linebreaking, etc. around it),
alpar@464
  3889
% given all the information in convenient, parsed form.
alpar@464
  3890
alpar@464
  3891
%%% Args are the skip and penalty (usually negative)
alpar@464
  3892
\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
alpar@464
  3893
alpar@464
  3894
\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
alpar@464
  3895
alpar@464
  3896
%%% Define plain chapter starts, and page on/off switching for it
alpar@464
  3897
% Parameter controlling skip before chapter headings (if needed)
alpar@464
  3898
alpar@464
  3899
\newskip\chapheadingskip
alpar@464
  3900
alpar@464
  3901
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
alpar@464
  3902
\def\chappager{\par\vfill\supereject}
alpar@464
  3903
\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
alpar@464
  3904
alpar@464
  3905
\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
alpar@464
  3906
alpar@464
  3907
\def\CHAPPAGoff{%
alpar@464
  3908
\global\let\contentsalignmacro = \chappager
alpar@464
  3909
\global\let\pchapsepmacro=\chapbreak
alpar@464
  3910
\global\let\pagealignmacro=\chappager}
alpar@464
  3911
alpar@464
  3912
\def\CHAPPAGon{%
alpar@464
  3913
\global\let\contentsalignmacro = \chappager
alpar@464
  3914
\global\let\pchapsepmacro=\chappager
alpar@464
  3915
\global\let\pagealignmacro=\chappager
alpar@464
  3916
\global\def\HEADINGSon{\HEADINGSsingle}}
alpar@464
  3917
alpar@464
  3918
\def\CHAPPAGodd{
alpar@464
  3919
\global\let\contentsalignmacro = \chapoddpage
alpar@464
  3920
\global\let\pchapsepmacro=\chapoddpage
alpar@464
  3921
\global\let\pagealignmacro=\chapoddpage
alpar@464
  3922
\global\def\HEADINGSon{\HEADINGSdouble}}
alpar@464
  3923
alpar@464
  3924
\CHAPPAGon
alpar@464
  3925
alpar@464
  3926
\def\CHAPFplain{
alpar@464
  3927
\global\let\chapmacro=\chfplain
alpar@464
  3928
\global\let\unnumbchapmacro=\unnchfplain
alpar@464
  3929
\global\let\centerchapmacro=\centerchfplain}
alpar@464
  3930
alpar@464
  3931
% Plain chapter opening.
alpar@464
  3932
% #1 is the text, #2 the chapter number or empty if unnumbered.
alpar@464
  3933
\def\chfplain#1#2{%
alpar@464
  3934
  \pchapsepmacro
alpar@464
  3935
  {%
alpar@464
  3936
    \chapfonts \rm
alpar@464
  3937
    \def\chapnum{#2}%
alpar@464
  3938
    \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
alpar@464
  3939
    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
alpar@464
  3940
          \hangindent = \wd0 \centerparametersmaybe
alpar@464
  3941
          \unhbox0 #1\par}%
alpar@464
  3942
  }%
alpar@464
  3943
  \nobreak\bigskip % no page break after a chapter title
alpar@464
  3944
  \nobreak
alpar@464
  3945
}
alpar@464
  3946
alpar@464
  3947
% Plain opening for unnumbered.
alpar@464
  3948
\def\unnchfplain#1{\chfplain{#1}{}}
alpar@464
  3949
alpar@464
  3950
% @centerchap -- centered and unnumbered.
alpar@464
  3951
\let\centerparametersmaybe = \relax
alpar@464
  3952
\def\centerchfplain#1{{%
alpar@464
  3953
  \def\centerparametersmaybe{%
alpar@464
  3954
    \advance\rightskip by 3\rightskip
alpar@464
  3955
    \leftskip = \rightskip
alpar@464
  3956
    \parfillskip = 0pt
alpar@464
  3957
  }%
alpar@464
  3958
  \chfplain{#1}{}%
alpar@464
  3959
}}
alpar@464
  3960
alpar@464
  3961
\CHAPFplain % The default
alpar@464
  3962
alpar@464
  3963
\def\unnchfopen #1{%
alpar@464
  3964
\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
alpar@464
  3965
                       \parindent=0pt\raggedright
alpar@464
  3966
                       \rm #1\hfill}}\bigskip \par\nobreak
alpar@464
  3967
}
alpar@464
  3968
alpar@464
  3969
\def\chfopen #1#2{\chapoddpage {\chapfonts
alpar@464
  3970
\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
alpar@464
  3971
\par\penalty 5000 %
alpar@464
  3972
}
alpar@464
  3973
alpar@464
  3974
\def\centerchfopen #1{%
alpar@464
  3975
\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
alpar@464
  3976
                       \parindent=0pt
alpar@464
  3977
                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
alpar@464
  3978
}
alpar@464
  3979
alpar@464
  3980
\def\CHAPFopen{
alpar@464
  3981
\global\let\chapmacro=\chfopen
alpar@464
  3982
\global\let\unnumbchapmacro=\unnchfopen
alpar@464
  3983
\global\let\centerchapmacro=\centerchfopen}
alpar@464
  3984
alpar@464
  3985
alpar@464
  3986
% Section titles.
alpar@464
  3987
\newskip\secheadingskip
alpar@464
  3988
\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
alpar@464
  3989
\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
alpar@464
  3990
\def\plainsecheading#1{\sectionheading{sec}{}{#1}}
alpar@464
  3991
alpar@464
  3992
% Subsection titles.
alpar@464
  3993
\newskip \subsecheadingskip
alpar@464
  3994
\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
alpar@464
  3995
\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
alpar@464
  3996
\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
alpar@464
  3997
alpar@464
  3998
% Subsubsection titles.
alpar@464
  3999
\let\subsubsecheadingskip = \subsecheadingskip
alpar@464
  4000
\let\subsubsecheadingbreak = \subsecheadingbreak
alpar@464
  4001
\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
alpar@464
  4002
\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
alpar@464
  4003
alpar@464
  4004
alpar@464
  4005
% Print any size section title.
alpar@464
  4006
%
alpar@464
  4007
% #1 is the section type (sec/subsec/subsubsec), #2 is the section
alpar@464
  4008
% number (maybe empty), #3 the text.
alpar@464
  4009
\def\sectionheading#1#2#3{%
alpar@464
  4010
  {%
alpar@464
  4011
    \expandafter\advance\csname #1headingskip\endcsname by \parskip
alpar@464
  4012
    \csname #1headingbreak\endcsname
alpar@464
  4013
  }%
alpar@464
  4014
  {%
alpar@464
  4015
    % Switch to the right set of fonts.
alpar@464
  4016
    \csname #1fonts\endcsname \rm
alpar@464
  4017
    %
alpar@464
  4018
    % Only insert the separating space if we have a section number.
alpar@464
  4019
    \def\secnum{#2}%
alpar@464
  4020
    \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
alpar@464
  4021
    %
alpar@464
  4022
    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
alpar@464
  4023
          \hangindent = \wd0 % zero if no section number
alpar@464
  4024
          \unhbox0 #3}%
alpar@464
  4025
  }%
alpar@464
  4026
  % Add extra space after the heading -- either a line space or a
alpar@464
  4027
  % paragraph space, whichever is more.  (Some people like to set
alpar@464
  4028
  % \parskip to large values for some reason.)  Don't allow stretch, though.
alpar@464
  4029
  \nobreak
alpar@464
  4030
  \ifdim\parskip>\normalbaselineskip
alpar@464
  4031
    \kern\parskip
alpar@464
  4032
  \else
alpar@464
  4033
    \kern\normalbaselineskip
alpar@464
  4034
  \fi
alpar@464
  4035
  \nobreak
alpar@464
  4036
}
alpar@464
  4037
alpar@464
  4038
alpar@464
  4039
\message{toc,}
alpar@464
  4040
% Table of contents.
alpar@464
  4041
\newwrite\tocfile
alpar@464
  4042
alpar@464
  4043
% Write an entry to the toc file, opening it if necessary.
alpar@464
  4044
% Called from @chapter, etc.  We supply {\folio} at the end of the
alpar@464
  4045
% argument, which will end up as the last argument to the \...entry macro.
alpar@464
  4046
%
alpar@464
  4047
% Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}}
alpar@464
  4048
% We open the .toc file for writing here instead of at @setfilename (or
alpar@464
  4049
% any other fixed time) so that @contents can be anywhere in the document.
alpar@464
  4050
%
alpar@464
  4051
\newif\iftocfileopened
alpar@464
  4052
\def\writetocentry#1#2#3{%
alpar@464
  4053
  \iftocfileopened\else
alpar@464
  4054
    \immediate\openout\tocfile = \jobname.toc
alpar@464
  4055
    \global\tocfileopenedtrue
alpar@464
  4056
  \fi
alpar@464
  4057
  %
alpar@464
  4058
  \iflinks
alpar@464
  4059
    \toks0 = {#2}%
alpar@464
  4060
    \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}%
alpar@464
  4061
    \temp
alpar@464
  4062
  \fi
alpar@464
  4063
  %
alpar@464
  4064
  % Tell \shipout to create a page destination if we're doing pdf, which
alpar@464
  4065
  % will be the target of the links in the table of contents.  We can't
alpar@464
  4066
  % just do it on every page because the title pages are numbered 1 and
alpar@464
  4067
  % 2 (the page numbers aren't printed), and so are the first two pages
alpar@464
  4068
  % of the document.  Thus, we'd have two destinations named `1', and
alpar@464
  4069
  % two named `2'.
alpar@464
  4070
  \ifpdf \pdfmakepagedesttrue \fi
alpar@464
  4071
}
alpar@464
  4072
alpar@464
  4073
\newskip\contentsrightmargin \contentsrightmargin=1in
alpar@464
  4074
\newcount\savepageno
alpar@464
  4075
\newcount\lastnegativepageno \lastnegativepageno = -1
alpar@464
  4076
alpar@464
  4077
% Finish up the main text and prepare to read what we've written
alpar@464
  4078
% to \tocfile.
alpar@464
  4079
%
alpar@464
  4080
\def\startcontents#1{%
alpar@464
  4081
   % If @setchapternewpage on, and @headings double, the contents should
alpar@464
  4082
   % start on an odd page, unlike chapters.  Thus, we maintain
alpar@464
  4083
   % \contentsalignmacro in parallel with \pagealignmacro.
alpar@464
  4084
   % From: Torbjorn Granlund <tege@matematik.su.se>
alpar@464
  4085
   \contentsalignmacro
alpar@464
  4086
   \immediate\closeout\tocfile
alpar@464
  4087
   %
alpar@464
  4088
   % Don't need to put `Contents' or `Short Contents' in the headline.
alpar@464
  4089
   % It is abundantly clear what they are.
alpar@464
  4090
   \unnumbchapmacro{#1}\def\thischapter{}%
alpar@464
  4091
   \savepageno = \pageno
alpar@464
  4092
   \begingroup                  % Set up to handle contents files properly.
alpar@464
  4093
      \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
alpar@464
  4094
      % We can't do this, because then an actual ^ in a section
alpar@464
  4095
      % title fails, e.g., @chapter ^ -- exponentiation.  --karl, 9jul97.
alpar@464
  4096
      %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
alpar@464
  4097
      \raggedbottom             % Worry more about breakpoints than the bottom.
alpar@464
  4098
      \advance\hsize by -\contentsrightmargin % Don't use the full line length.
alpar@464
  4099
      %
alpar@464
  4100
      % Roman numerals for page numbers.
alpar@464
  4101
      \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
alpar@464
  4102
}
alpar@464
  4103
alpar@464
  4104
alpar@464
  4105
% Normal (long) toc.
alpar@464
  4106
\def\contents{%
alpar@464
  4107
   \startcontents{\putwordTOC}%
alpar@464
  4108
     \openin 1 \jobname.toc
alpar@464
  4109
     \ifeof 1 \else
alpar@464
  4110
       \closein 1
alpar@464
  4111
       \input \jobname.toc
alpar@464
  4112
     \fi
alpar@464
  4113
     \vfill \eject
alpar@464
  4114
     \contentsalignmacro % in case @setchapternewpage odd is in effect
alpar@464
  4115
     \pdfmakeoutlines
alpar@464
  4116
   \endgroup
alpar@464
  4117
   \lastnegativepageno = \pageno
alpar@464
  4118
   \global\pageno = \savepageno
alpar@464
  4119
}
alpar@464
  4120
alpar@464
  4121
% And just the chapters.
alpar@464
  4122
\def\summarycontents{%
alpar@464
  4123
   \startcontents{\putwordShortTOC}%
alpar@464
  4124
      %
alpar@464
  4125
      \let\chapentry = \shortchapentry
alpar@464
  4126
      \let\appendixentry = \shortappendixentry
alpar@464
  4127
      \let\unnumbchapentry = \shortunnumberedentry
alpar@464
  4128
      % We want a true roman here for the page numbers.
alpar@464
  4129
      \secfonts
alpar@464
  4130
      \let\rm=\shortcontrm \let\bf=\shortcontbf
alpar@464
  4131
      \let\sl=\shortcontsl \let\tt=\shortconttt
alpar@464
  4132
      \rm
alpar@464
  4133
      \hyphenpenalty = 10000
alpar@464
  4134
      \advance\baselineskip by 1pt % Open it up a little.
alpar@464
  4135
      \def\secentry ##1##2##3##4{}
alpar@464
  4136
      \def\subsecentry ##1##2##3##4##5{}
alpar@464
  4137
      \def\subsubsecentry ##1##2##3##4##5##6{}
alpar@464
  4138
      \let\unnumbsecentry = \secentry
alpar@464
  4139
      \let\unnumbsubsecentry = \subsecentry
alpar@464
  4140
      \let\unnumbsubsubsecentry = \subsubsecentry
alpar@464
  4141
      \openin 1 \jobname.toc
alpar@464
  4142
      \ifeof 1 \else
alpar@464
  4143
        \closein 1
alpar@464
  4144
        \input \jobname.toc
alpar@464
  4145
      \fi
alpar@464
  4146
     \vfill \eject
alpar@464
  4147
     \contentsalignmacro % in case @setchapternewpage odd is in effect
alpar@464
  4148
   \endgroup
alpar@464
  4149
   \lastnegativepageno = \pageno
alpar@464
  4150
   \global\pageno = \savepageno
alpar@464
  4151
}
alpar@464
  4152
\let\shortcontents = \summarycontents
alpar@464
  4153
alpar@464
  4154
\ifpdf
alpar@464
  4155
  \pdfcatalog{/PageMode /UseOutlines}%
alpar@464
  4156
\fi
alpar@464
  4157
alpar@464
  4158
% These macros generate individual entries in the table of contents.
alpar@464
  4159
% The first argument is the chapter or section name.
alpar@464
  4160
% The last argument is the page number.
alpar@464
  4161
% The arguments in between are the chapter number, section number, ...
alpar@464
  4162
alpar@464
  4163
% Chapters, in the main contents.
alpar@464
  4164
\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
alpar@464
  4165
%
alpar@464
  4166
% Chapters, in the short toc.
alpar@464
  4167
% See comments in \dochapentry re vbox and related settings.
alpar@464
  4168
\def\shortchapentry#1#2#3{%
alpar@464
  4169
  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}%
alpar@464
  4170
}
alpar@464
  4171
alpar@464
  4172
% Appendices, in the main contents.
alpar@464
  4173
\def\appendixentry#1#2#3{%
alpar@464
  4174
  \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}}
alpar@464
  4175
%
alpar@464
  4176
% Appendices, in the short toc.
alpar@464
  4177
\let\shortappendixentry = \shortchapentry
alpar@464
  4178
alpar@464
  4179
% Typeset the label for a chapter or appendix for the short contents.
alpar@464
  4180
% The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter.
alpar@464
  4181
% We could simplify the code here by writing out an \appendixentry
alpar@464
  4182
% command in the toc file for appendices, instead of using \chapentry
alpar@464
  4183
% for both, but it doesn't seem worth it.
alpar@464
  4184
%
alpar@464
  4185
\newdimen\shortappendixwidth
alpar@464
  4186
%
alpar@464
  4187
\def\shortchaplabel#1{%
alpar@464
  4188
  % This space should be enough, since a single number is .5em, and the
alpar@464
  4189
  % widest letter (M) is 1em, at least in the Computer Modern fonts.
alpar@464
  4190
  % But use \hss just in case.
alpar@464
  4191
  % (This space doesn't include the extra space that gets added after
alpar@464
  4192
  % the label; that gets put in by \shortchapentry above.)
alpar@464
  4193
  \dimen0 = 1em
alpar@464
  4194
  \hbox to \dimen0{#1\hss}%
alpar@464
  4195
}
alpar@464
  4196
alpar@464
  4197
% Unnumbered chapters.
alpar@464
  4198
\def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}}
alpar@464
  4199
\def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}}
alpar@464
  4200
alpar@464
  4201
% Sections.
alpar@464
  4202
\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
alpar@464
  4203
\def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}}
alpar@464
  4204
alpar@464
  4205
% Subsections.
alpar@464
  4206
\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
alpar@464
  4207
\def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}}
alpar@464
  4208
alpar@464
  4209
% And subsubsections.
alpar@464
  4210
\def\subsubsecentry#1#2#3#4#5#6{%
alpar@464
  4211
  \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
alpar@464
  4212
\def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}}
alpar@464
  4213
alpar@464
  4214
% This parameter controls the indentation of the various levels.
alpar@464
  4215
\newdimen\tocindent \tocindent = 3pc
alpar@464
  4216
alpar@464
  4217
% Now for the actual typesetting. In all these, #1 is the text and #2 is the
alpar@464
  4218
% page number.
alpar@464
  4219
%
alpar@464
  4220
% If the toc has to be broken over pages, we want it to be at chapters
alpar@464
  4221
% if at all possible; hence the \penalty.
alpar@464
  4222
\def\dochapentry#1#2{%
alpar@464
  4223
   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
alpar@464
  4224
   \begingroup
alpar@464
  4225
     \chapentryfonts
alpar@464
  4226
     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
alpar@464
  4227
   \endgroup
alpar@464
  4228
   \nobreak\vskip .25\baselineskip plus.1\baselineskip
alpar@464
  4229
}
alpar@464
  4230
alpar@464
  4231
\def\dosecentry#1#2{\begingroup
alpar@464
  4232
  \secentryfonts \leftskip=\tocindent
alpar@464
  4233
  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
alpar@464
  4234
\endgroup}
alpar@464
  4235
alpar@464
  4236
\def\dosubsecentry#1#2{\begingroup
alpar@464
  4237
  \subsecentryfonts \leftskip=2\tocindent
alpar@464
  4238
  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
alpar@464
  4239
\endgroup}
alpar@464
  4240
alpar@464
  4241
\def\dosubsubsecentry#1#2{\begingroup
alpar@464
  4242
  \subsubsecentryfonts \leftskip=3\tocindent
alpar@464
  4243
  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
alpar@464
  4244
\endgroup}
alpar@464
  4245
alpar@464
  4246
% Final typesetting of a toc entry; we use the same \entry macro as for
alpar@464
  4247
% the index entries, but we want to suppress hyphenation here.  (We
alpar@464
  4248
% can't do that in the \entry macro, since index entries might consist
alpar@464
  4249
% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
alpar@464
  4250
\def\tocentry#1#2{\begingroup
alpar@464
  4251
  \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
alpar@464
  4252
  % Do not use \turnoffactive in these arguments.  Since the toc is
alpar@464
  4253
  % typeset in cmr, characters such as _ would come out wrong; we
alpar@464
  4254
  % have to do the usual translation tricks.
alpar@464
  4255
  \entry{#1}{#2}%
alpar@464
  4256
\endgroup}
alpar@464
  4257
alpar@464
  4258
% Space between chapter (or whatever) number and the title.
alpar@464
  4259
\def\labelspace{\hskip1em \relax}
alpar@464
  4260
alpar@464
  4261
\def\dopageno#1{{\rm #1}}
alpar@464
  4262
\def\doshortpageno#1{{\rm #1}}
alpar@464
  4263
alpar@464
  4264
\def\chapentryfonts{\secfonts \rm}
alpar@464
  4265
\def\secentryfonts{\textfonts}
alpar@464
  4266
\let\subsecentryfonts = \textfonts
alpar@464
  4267
\let\subsubsecentryfonts = \textfonts
alpar@464
  4268
alpar@464
  4269
alpar@464
  4270
\message{environments,}
alpar@464
  4271
% @foo ... @end foo.
alpar@464
  4272
alpar@464
  4273
% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
alpar@464
  4274
%
alpar@464
  4275
% Since these characters are used in examples, it should be an even number of
alpar@464
  4276
% \tt widths. Each \tt character is 1en, so two makes it 1em.
alpar@464
  4277
%
alpar@464
  4278
\def\point{$\star$}
alpar@464
  4279
\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
alpar@464
  4280
\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
alpar@464
  4281
\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
alpar@464
  4282
\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
alpar@464
  4283
alpar@464
  4284
% The @error{} command.
alpar@464
  4285
% Adapted from the TeXbook's \boxit.
alpar@464
  4286
%
alpar@464
  4287
\newbox\errorbox
alpar@464
  4288
%
alpar@464
  4289
{\tentt \global\dimen0 = 3em}% Width of the box.
alpar@464
  4290
\dimen2 = .55pt % Thickness of rules
alpar@464
  4291
% The text. (`r' is open on the right, `e' somewhat less so on the left.)
alpar@464
  4292
\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
alpar@464
  4293
%
alpar@464
  4294
\global\setbox\errorbox=\hbox to \dimen0{\hfil
alpar@464
  4295
   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
alpar@464
  4296
   \advance\hsize by -2\dimen2 % Rules.
alpar@464
  4297
   \vbox{
alpar@464
  4298
      \hrule height\dimen2
alpar@464
  4299
      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
alpar@464
  4300
         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
alpar@464
  4301
         \kern3pt\vrule width\dimen2}% Space to right.
alpar@464
  4302
      \hrule height\dimen2}
alpar@464
  4303
    \hfil}
alpar@464
  4304
%
alpar@464
  4305
\def\error{\leavevmode\lower.7ex\copy\errorbox}
alpar@464
  4306
alpar@464
  4307
% @tex ... @end tex    escapes into raw Tex temporarily.
alpar@464
  4308
% One exception: @ is still an escape character, so that @end tex works.
alpar@464
  4309
% But \@ or @@ will get a plain tex @ character.
alpar@464
  4310
alpar@464
  4311
\def\tex{\begingroup
alpar@464
  4312
  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
alpar@464
  4313
  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
alpar@464
  4314
  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
alpar@464
  4315
  \catcode `\%=14
alpar@464
  4316
  \catcode `\+=\other
alpar@464
  4317
  \catcode `\"=\other
alpar@464
  4318
  \catcode `\==\other
alpar@464
  4319
  \catcode `\|=\other
alpar@464
  4320
  \catcode `\<=\other
alpar@464
  4321
  \catcode `\>=\other
alpar@464
  4322
  \escapechar=`\\
alpar@464
  4323
  %
alpar@464
  4324
  \let\b=\ptexb
alpar@464
  4325
  \let\bullet=\ptexbullet
alpar@464
  4326
  \let\c=\ptexc
alpar@464
  4327
  \let\,=\ptexcomma
alpar@464
  4328
  \let\.=\ptexdot
alpar@464
  4329
  \let\dots=\ptexdots
alpar@464
  4330
  \let\equiv=\ptexequiv
alpar@464
  4331
  \let\!=\ptexexclam
alpar@464
  4332
  \let\i=\ptexi
alpar@464
  4333
  \let\indent=\ptexindent
alpar@464
  4334
  \let\{=\ptexlbrace
alpar@464
  4335
  \let\+=\tabalign
alpar@464
  4336
  \let\}=\ptexrbrace
alpar@464
  4337
  \let\/=\ptexslash
alpar@464
  4338
  \let\*=\ptexstar
alpar@464
  4339
  \let\t=\ptext
alpar@464
  4340
  %
alpar@464
  4341
  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
alpar@464
  4342
  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
alpar@464
  4343
  \def\@{@}%
alpar@464
  4344
\let\Etex=\endgroup}
alpar@464
  4345
alpar@464
  4346
% Define @lisp ... @end lisp.
alpar@464
  4347
% @lisp does a \begingroup so it can rebind things,
alpar@464
  4348
% including the definition of @end lisp (which normally is erroneous).
alpar@464
  4349
alpar@464
  4350
% Amount to narrow the margins by for @lisp.
alpar@464
  4351
\newskip\lispnarrowing \lispnarrowing=0.4in
alpar@464
  4352
alpar@464
  4353
% This is the definition that ^^M gets inside @lisp, @example, and other
alpar@464
  4354
% such environments.  \null is better than a space, since it doesn't
alpar@464
  4355
% have any width.
alpar@464
  4356
\def\lisppar{\null\endgraf}
alpar@464
  4357
alpar@464
  4358
% Make each space character in the input produce a normal interword
alpar@464
  4359
% space in the output.  Don't allow a line break at this space, as this
alpar@464
  4360
% is used only in environments like @example, where each line of input
alpar@464
  4361
% should produce a line of output anyway.
alpar@464
  4362
%
alpar@464
  4363
{\obeyspaces %
alpar@464
  4364
\gdef\sepspaces{\obeyspaces\let =\tie}}
alpar@464
  4365
alpar@464
  4366
% Define \obeyedspace to be our active space, whatever it is.  This is
alpar@464
  4367
% for use in \parsearg.
alpar@464
  4368
{\sepspaces%
alpar@464
  4369
\global\let\obeyedspace= }
alpar@464
  4370
alpar@464
  4371
% This space is always present above and below environments.
alpar@464
  4372
\newskip\envskipamount \envskipamount = 0pt
alpar@464
  4373
alpar@464
  4374
% Make spacing and below environment symmetrical.  We use \parskip here
alpar@464
  4375
% to help in doing that, since in @example-like environments \parskip
alpar@464
  4376
% is reset to zero; thus the \afterenvbreak inserts no space -- but the
alpar@464
  4377
% start of the next paragraph will insert \parskip.
alpar@464
  4378
%
alpar@464
  4379
\def\aboveenvbreak{{%
alpar@464
  4380
  % =10000 instead of <10000 because of a special case in \itemzzz, q.v.
alpar@464
  4381
  \ifnum \lastpenalty=10000 \else
alpar@464
  4382
    \advance\envskipamount by \parskip
alpar@464
  4383
    \endgraf
alpar@464
  4384
    \ifdim\lastskip<\envskipamount
alpar@464
  4385
      \removelastskip
alpar@464
  4386
      % it's not a good place to break if the last penalty was \nobreak
alpar@464
  4387
      % or better ...
alpar@464
  4388
      \ifnum\lastpenalty>10000 \else \penalty-50 \fi
alpar@464
  4389
      \vskip\envskipamount
alpar@464
  4390
    \fi
alpar@464
  4391
  \fi
alpar@464
  4392
}}
alpar@464
  4393
alpar@464
  4394
\let\afterenvbreak = \aboveenvbreak
alpar@464
  4395
alpar@464
  4396
% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
alpar@464
  4397
\let\nonarrowing=\relax
alpar@464
  4398
alpar@464
  4399
% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
alpar@464
  4400
% environment contents.
alpar@464
  4401
\font\circle=lcircle10
alpar@464
  4402
\newdimen\circthick
alpar@464
  4403
\newdimen\cartouter\newdimen\cartinner
alpar@464
  4404
\newskip\normbskip\newskip\normpskip\newskip\normlskip
alpar@464
  4405
\circthick=\fontdimen8\circle
alpar@464
  4406
%
alpar@464
  4407
\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
alpar@464
  4408
\def\ctr{{\hskip 6pt\circle\char'010}}
alpar@464
  4409
\def\cbl{{\circle\char'012\hskip -6pt}}
alpar@464
  4410
\def\cbr{{\hskip 6pt\circle\char'011}}
alpar@464
  4411
\def\carttop{\hbox to \cartouter{\hskip\lskip
alpar@464
  4412
        \ctl\leaders\hrule height\circthick\hfil\ctr
alpar@464
  4413
        \hskip\rskip}}
alpar@464
  4414
\def\cartbot{\hbox to \cartouter{\hskip\lskip
alpar@464
  4415
        \cbl\leaders\hrule height\circthick\hfil\cbr
alpar@464
  4416
        \hskip\rskip}}
alpar@464
  4417
%
alpar@464
  4418
\newskip\lskip\newskip\rskip
alpar@464
  4419
alpar@464
  4420
\def\cartouche{%
alpar@464
  4421
\par  % can't be in the midst of a paragraph.
alpar@464
  4422
\begingroup
alpar@464
  4423
        \lskip=\leftskip \rskip=\rightskip
alpar@464
  4424
        \leftskip=0pt\rightskip=0pt %we want these *outside*.
alpar@464
  4425
        \cartinner=\hsize \advance\cartinner by-\lskip
alpar@464
  4426
                          \advance\cartinner by-\rskip
alpar@464
  4427
        \cartouter=\hsize
alpar@464
  4428
        \advance\cartouter by 18.4pt % allow for 3pt kerns on either
alpar@464
  4429
%                                    side, and for 6pt waste from
alpar@464
  4430
%                                    each corner char, and rule thickness
alpar@464
  4431
        \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
alpar@464
  4432
        % Flag to tell @lisp, etc., not to narrow margin.
alpar@464
  4433
        \let\nonarrowing=\comment
alpar@464
  4434
        \vbox\bgroup
alpar@464
  4435
                \baselineskip=0pt\parskip=0pt\lineskip=0pt
alpar@464
  4436
                \carttop
alpar@464
  4437
                \hbox\bgroup
alpar@464
  4438
                        \hskip\lskip
alpar@464
  4439
                        \vrule\kern3pt
alpar@464
  4440
                        \vbox\bgroup
alpar@464
  4441
                                \hsize=\cartinner
alpar@464
  4442
                                \kern3pt
alpar@464
  4443
                                \begingroup
alpar@464
  4444
                                        \baselineskip=\normbskip
alpar@464
  4445
                                        \lineskip=\normlskip
alpar@464
  4446
                                        \parskip=\normpskip
alpar@464
  4447
                                        \vskip -\parskip
alpar@464
  4448
\def\Ecartouche{%
alpar@464
  4449
                                \endgroup
alpar@464
  4450
                                \kern3pt
alpar@464
  4451
                        \egroup
alpar@464
  4452
                        \kern3pt\vrule
alpar@464
  4453
                        \hskip\rskip
alpar@464
  4454
                \egroup
alpar@464
  4455
                \cartbot
alpar@464
  4456
        \egroup
alpar@464
  4457
\endgroup
alpar@464
  4458
}}
alpar@464
  4459
alpar@464
  4460
alpar@464
  4461
% This macro is called at the beginning of all the @example variants,
alpar@464
  4462
% inside a group.
alpar@464
  4463
\def\nonfillstart{%
alpar@464
  4464
  \aboveenvbreak
alpar@464
  4465
  \inENV % This group ends at the end of the body
alpar@464
  4466
  \hfuzz = 12pt % Don't be fussy
alpar@464
  4467
  \sepspaces % Make spaces be word-separators rather than space tokens.
alpar@464
  4468
  \let\par = \lisppar % don't ignore blank lines
alpar@464
  4469
  \obeylines % each line of input is a line of output
alpar@464
  4470
  \parskip = 0pt
alpar@464
  4471
  \parindent = 0pt
alpar@464
  4472
  \emergencystretch = 0pt % don't try to avoid overfull boxes
alpar@464
  4473
  % @cartouche defines \nonarrowing to inhibit narrowing
alpar@464
  4474
  % at next level down.
alpar@464
  4475
  \ifx\nonarrowing\relax
alpar@464
  4476
    \advance \leftskip by \lispnarrowing
alpar@464
  4477
    \exdentamount=\lispnarrowing
alpar@464
  4478
    \let\exdent=\nofillexdent
alpar@464
  4479
    \let\nonarrowing=\relax
alpar@464
  4480
  \fi
alpar@464
  4481
}
alpar@464
  4482
alpar@464
  4483
% Define the \E... control sequence only if we are inside the particular
alpar@464
  4484
% environment, so the error checking in \end will work.
alpar@464
  4485
%
alpar@464
  4486
% To end an @example-like environment, we first end the paragraph (via
alpar@464
  4487
% \afterenvbreak's vertical glue), and then the group.  That way we keep
alpar@464
  4488
% the zero \parskip that the environments set -- \parskip glue will be
alpar@464
  4489
% inserted at the beginning of the next paragraph in the document, after
alpar@464
  4490
% the environment.
alpar@464
  4491
%
alpar@464
  4492
\def\nonfillfinish{\afterenvbreak\endgroup}
alpar@464
  4493
alpar@464
  4494
% @lisp: indented, narrowed, typewriter font.
alpar@464
  4495
\def\lisp{\begingroup
alpar@464
  4496
  \nonfillstart
alpar@464
  4497
  \let\Elisp = \nonfillfinish
alpar@464
  4498
  \tt
alpar@464
  4499
  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
alpar@464
  4500
  \gobble       % eat return
alpar@464
  4501
}
alpar@464
  4502
alpar@464
  4503
% @example: Same as @lisp.
alpar@464
  4504
\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
alpar@464
  4505
alpar@464
  4506
% @smallexample and @smalllisp: use smaller fonts.
alpar@464
  4507
% Originally contributed by Pavel@xerox.
alpar@464
  4508
\def\smalllisp{\begingroup
alpar@464
  4509
  \def\Esmalllisp{\nonfillfinish\endgroup}%
alpar@464
  4510
  \def\Esmallexample{\nonfillfinish\endgroup}%
alpar@464
  4511
  \smallexamplefonts
alpar@464
  4512
  \lisp
alpar@464
  4513
}
alpar@464
  4514
\let\smallexample = \smalllisp
alpar@464
  4515
alpar@464
  4516
alpar@464
  4517
% @display: same as @lisp except keep current font.
alpar@464
  4518
%
alpar@464
  4519
\def\display{\begingroup
alpar@464
  4520
  \nonfillstart
alpar@464
  4521
  \let\Edisplay = \nonfillfinish
alpar@464
  4522
  \gobble
alpar@464
  4523
}
alpar@464
  4524
%
alpar@464
  4525
% @smalldisplay: @display plus smaller fonts.
alpar@464
  4526
%
alpar@464
  4527
\def\smalldisplay{\begingroup
alpar@464
  4528
  \def\Esmalldisplay{\nonfillfinish\endgroup}%
alpar@464
  4529
  \smallexamplefonts \rm
alpar@464
  4530
  \display
alpar@464
  4531
}
alpar@464
  4532
alpar@464
  4533
% @format: same as @display except don't narrow margins.
alpar@464
  4534
%
alpar@464
  4535
\def\format{\begingroup
alpar@464
  4536
  \let\nonarrowing = t
alpar@464
  4537
  \nonfillstart
alpar@464
  4538
  \let\Eformat = \nonfillfinish
alpar@464
  4539
  \gobble
alpar@464
  4540
}
alpar@464
  4541
%
alpar@464
  4542
% @smallformat: @format plus smaller fonts.
alpar@464
  4543
%
alpar@464
  4544
\def\smallformat{\begingroup
alpar@464
  4545
  \def\Esmallformat{\nonfillfinish\endgroup}%
alpar@464
  4546
  \smallexamplefonts \rm
alpar@464
  4547
  \format
alpar@464
  4548
}
alpar@464
  4549
alpar@464
  4550
% @flushleft (same as @format).
alpar@464
  4551
%
alpar@464
  4552
\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format}
alpar@464
  4553
alpar@464
  4554
% @flushright.
alpar@464
  4555
%
alpar@464
  4556
\def\flushright{\begingroup
alpar@464
  4557
  \let\nonarrowing = t
alpar@464
  4558
  \nonfillstart
alpar@464
  4559
  \let\Eflushright = \nonfillfinish
alpar@464
  4560
  \advance\leftskip by 0pt plus 1fill
alpar@464
  4561
  \gobble
alpar@464
  4562
}
alpar@464
  4563
alpar@464
  4564
alpar@464
  4565
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
alpar@464
  4566
% and narrows the margins.
alpar@464
  4567
%
alpar@464
  4568
\def\quotation{%
alpar@464
  4569
  \begingroup\inENV %This group ends at the end of the @quotation body
alpar@464
  4570
  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
alpar@464
  4571
  \parindent=0pt
alpar@464
  4572
  % We have retained a nonzero parskip for the environment, since we're
alpar@464
  4573
  % doing normal filling. So to avoid extra space below the environment...
alpar@464
  4574
  \def\Equotation{\parskip = 0pt \nonfillfinish}%
alpar@464
  4575
  %
alpar@464
  4576
  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
alpar@464
  4577
  \ifx\nonarrowing\relax
alpar@464
  4578
    \advance\leftskip by \lispnarrowing
alpar@464
  4579
    \advance\rightskip by \lispnarrowing
alpar@464
  4580
    \exdentamount = \lispnarrowing
alpar@464
  4581
    \let\nonarrowing = \relax
alpar@464
  4582
  \fi
alpar@464
  4583
}
alpar@464
  4584
alpar@464
  4585
alpar@464
  4586
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
alpar@464
  4587
% If we want to allow any <char> as delimiter,
alpar@464
  4588
% we need the curly braces so that makeinfo sees the @verb command, eg:
alpar@464
  4589
% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
alpar@464
  4590
%
alpar@464
  4591
% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
alpar@464
  4592
%
alpar@464
  4593
% [Knuth] p.344; only we need to do the other characters Texinfo sets
alpar@464
  4594
% active too.  Otherwise, they get lost as the first character on a
alpar@464
  4595
% verbatim line.
alpar@464
  4596
\def\dospecials{%
alpar@464
  4597
  \do\ \do\\\do\{\do\}\do\$\do\&%
alpar@464
  4598
  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
alpar@464
  4599
  \do\<\do\>\do\|\do\@\do+\do\"%
alpar@464
  4600
}
alpar@464
  4601
%
alpar@464
  4602
% [Knuth] p. 380
alpar@464
  4603
\def\uncatcodespecials{%
alpar@464
  4604
  \def\do##1{\catcode`##1=12}\dospecials}
alpar@464
  4605
%
alpar@464
  4606
% [Knuth] pp. 380,381,391
alpar@464
  4607
% Disable Spanish ligatures ?` and !` of \tt font
alpar@464
  4608
\begingroup
alpar@464
  4609
  \catcode`\`=\active\gdef`{\relax\lq}
alpar@464
  4610
\endgroup
alpar@464
  4611
%
alpar@464
  4612
% Setup for the @verb command.
alpar@464
  4613
%
alpar@464
  4614
% Eight spaces for a tab
alpar@464
  4615
\begingroup
alpar@464
  4616
  \catcode`\^^I=\active
alpar@464
  4617
  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
alpar@464
  4618
\endgroup
alpar@464
  4619
%
alpar@464
  4620
\def\setupverb{%
alpar@464
  4621
  \tt  % easiest (and conventionally used) font for verbatim
alpar@464
  4622
  \def\par{\leavevmode\endgraf}%
alpar@464
  4623
  \catcode`\`=\active
alpar@464
  4624
  \tabeightspaces
alpar@464
  4625
  % Respect line breaks,
alpar@464
  4626
  % print special symbols as themselves, and
alpar@464
  4627
  % make each space count
alpar@464
  4628
  % must do in this order:
alpar@464
  4629
  \obeylines \uncatcodespecials \sepspaces
alpar@464
  4630
}
alpar@464
  4631
alpar@464
  4632
% Setup for the @verbatim environment
alpar@464
  4633
%
alpar@464
  4634
% Real tab expansion
alpar@464
  4635
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
alpar@464
  4636
%
alpar@464
  4637
\def\starttabbox{\setbox0=\hbox\bgroup}
alpar@464
  4638
\begingroup
alpar@464
  4639
  \catcode`\^^I=\active
alpar@464
  4640
  \gdef\tabexpand{%
alpar@464
  4641
    \catcode`\^^I=\active
alpar@464
  4642
    \def^^I{\leavevmode\egroup
alpar@464
  4643
      \dimen0=\wd0 % the width so far, or since the previous tab
alpar@464
  4644
      \divide\dimen0 by\tabw
alpar@464
  4645
      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
alpar@464
  4646
      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
alpar@464
  4647
      \wd0=\dimen0 \box0 \starttabbox
alpar@464
  4648
    }%
alpar@464
  4649
  }
alpar@464
  4650
\endgroup
alpar@464
  4651
\def\setupverbatim{%
alpar@464
  4652
  % Easiest (and conventionally used) font for verbatim
alpar@464
  4653
  \tt
alpar@464
  4654
  \def\par{\leavevmode\egroup\box0\endgraf}%
alpar@464
  4655
  \catcode`\`=\active
alpar@464
  4656
  \tabexpand
alpar@464
  4657
  % Respect line breaks,
alpar@464
  4658
  % print special symbols as themselves, and
alpar@464
  4659
  % make each space count
alpar@464
  4660
  % must do in this order:
alpar@464
  4661
  \obeylines \uncatcodespecials \sepspaces
alpar@464
  4662
  \everypar{\starttabbox}%
alpar@464
  4663
}
alpar@464
  4664
alpar@464
  4665
% Do the @verb magic: verbatim text is quoted by unique
alpar@464
  4666
% delimiter characters.  Before first delimiter expect a
alpar@464
  4667
% right brace, after last delimiter expect closing brace:
alpar@464
  4668
%
alpar@464
  4669
%    \def\doverb'{'<char>#1<char>'}'{#1}
alpar@464
  4670
%
alpar@464
  4671
% [Knuth] p. 382; only eat outer {}
alpar@464
  4672
\begingroup
alpar@464
  4673
  \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12
alpar@464
  4674
  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
alpar@464
  4675
\endgroup
alpar@464
  4676
%
alpar@464
  4677
\def\verb{\begingroup\setupverb\doverb}
alpar@464
  4678
%
alpar@464
  4679
%
alpar@464
  4680
% Do the @verbatim magic: define the macro \doverbatim so that
alpar@464
  4681
% the (first) argument ends when '@end verbatim' is reached, ie:
alpar@464
  4682
%
alpar@464
  4683
%     \def\doverbatim#1@end verbatim{#1}
alpar@464
  4684
%
alpar@464
  4685
% For Texinfo it's a lot easier than for LaTeX,
alpar@464
  4686
% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
alpar@464
  4687
% we need not redefine '\', '{' and '}'.
alpar@464
  4688
%
alpar@464
  4689
% Inspired by LaTeX's verbatim command set [latex.ltx]
alpar@464
  4690
%% Include LaTeX hack for completeness -- never know
alpar@464
  4691
%% \begingroup
alpar@464
  4692
%% \catcode`|=0 \catcode`[=1
alpar@464
  4693
%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active
alpar@464
  4694
%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[
alpar@464
  4695
%% #1|endgroup|def|Everbatim[]|end[verbatim]]
alpar@464
  4696
%% |endgroup
alpar@464
  4697
%
alpar@464
  4698
\begingroup
alpar@464
  4699
  \catcode`\ =\active
alpar@464
  4700
  \obeylines %
alpar@464
  4701
  % ignore everything up to the first ^^M, that's the newline at the end
alpar@464
  4702
  % of the @verbatim input line itself.  Otherwise we get an extra blank
alpar@464
  4703
  % line in the output.
alpar@464
  4704
  \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}%
alpar@464
  4705
\endgroup
alpar@464
  4706
%
alpar@464
  4707
\def\verbatim{%
alpar@464
  4708
  \def\Everbatim{\nonfillfinish\endgroup}%
alpar@464
  4709
  \begingroup
alpar@464
  4710
    \nonfillstart
alpar@464
  4711
    \advance\leftskip by -\defbodyindent
alpar@464
  4712
    \begingroup\setupverbatim\doverbatim
alpar@464
  4713
}
alpar@464
  4714
alpar@464
  4715
% @verbatiminclude FILE - insert text of file in verbatim environment.
alpar@464
  4716
%
alpar@464
  4717
% Allow normal characters that we make active in the argument (a file name).
alpar@464
  4718
\def\verbatiminclude{%
alpar@464
  4719
  \begingroup
alpar@464
  4720
    \catcode`\\=\other
alpar@464
  4721
    \catcode`~=\other
alpar@464
  4722
    \catcode`^=\other
alpar@464
  4723
    \catcode`_=\other
alpar@464
  4724
    \catcode`|=\other
alpar@464
  4725
    \catcode`<=\other
alpar@464
  4726
    \catcode`>=\other
alpar@464
  4727
    \catcode`+=\other
alpar@464
  4728
    \parsearg\doverbatiminclude
alpar@464
  4729
}
alpar@464
  4730
\def\setupverbatiminclude{%
alpar@464
  4731
  \begingroup
alpar@464
  4732
    \nonfillstart
alpar@464
  4733
    \advance\leftskip by -\defbodyindent
alpar@464
  4734
    \begingroup\setupverbatim
alpar@464
  4735
}
alpar@464
  4736
%
alpar@464
  4737
\def\doverbatiminclude#1{%
alpar@464
  4738
     % Restore active chars for included file.
alpar@464
  4739
  \endgroup
alpar@464
  4740
  \begingroup
alpar@464
  4741
    \let\value=\expandablevalue
alpar@464
  4742
    \def\thisfile{#1}%
alpar@464
  4743
    \expandafter\expandafter\setupverbatiminclude\input\thisfile
alpar@464
  4744
  \endgroup
alpar@464
  4745
  \nonfillfinish
alpar@464
  4746
  \endgroup
alpar@464
  4747
}
alpar@464
  4748
alpar@464
  4749
% @copying ... @end copying.
alpar@464
  4750
% Save the text away for @insertcopying later.  Many commands won't be
alpar@464
  4751
% allowed in this context, but that's ok.
alpar@464
  4752
%
alpar@464
  4753
% We save the uninterpreted tokens, rather than creating a box.
alpar@464
  4754
% Saving the text in a box would be much easier, but then all the
alpar@464
  4755
% typesetting commands (@smallbook, font changes, etc.) have to be done
alpar@464
  4756
% beforehand -- and a) we want @copying to be done first in the source
alpar@464
  4757
% file; b) letting users define the frontmatter in as flexible order as
alpar@464
  4758
% possible is very desirable.
alpar@464
  4759
%
alpar@464
  4760
\def\copying{\begingroup
alpar@464
  4761
  % Define a command to swallow text until we reach `@end copying'.
alpar@464
  4762
  % \ is the escape char in this texinfo.tex file, so it is the
alpar@464
  4763
  % delimiter for the command; @ will be the escape char when we read
alpar@464
  4764
  % it, but that doesn't matter.
alpar@464
  4765
  \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}%
alpar@464
  4766
  %
alpar@464
  4767
  % We must preserve ^^M's in the input file; see \insertcopying below.
alpar@464
  4768
  \catcode`\^^M = \active
alpar@464
  4769
  \docopying
alpar@464
  4770
}
alpar@464
  4771
alpar@464
  4772
% What we do to finish off the copying text.
alpar@464
  4773
%
alpar@464
  4774
\def\enddocopying{\endgroup\ignorespaces}
alpar@464
  4775
alpar@464
  4776
% @insertcopying.  Here we must play games with ^^M's.  On the one hand,
alpar@464
  4777
% we need them to delimit commands such as `@end quotation', so they
alpar@464
  4778
% must be active.  On the other hand, we certainly don't want every
alpar@464
  4779
% end-of-line to be a \par, as would happen with the normal active
alpar@464
  4780
% definition of ^^M.  On the third hand, two ^^M's in a row should still
alpar@464
  4781
% generate a \par.
alpar@464
  4782
%
alpar@464
  4783
% Our approach is to make ^^M insert a space and a penalty1 normally;
alpar@464
  4784
% then it can also check if \lastpenalty=1.  If it does, then manually
alpar@464
  4785
% do \par.
alpar@464
  4786
%
alpar@464
  4787
% This messes up the normal definitions of @c[omment], so we redefine
alpar@464
  4788
% it.  Similarly for @ignore.  (These commands are used in the gcc
alpar@464
  4789
% manual for man page generation.)
alpar@464
  4790
%
alpar@464
  4791
% Seems pretty fragile, most line-oriented commands will presumably
alpar@464
  4792
% fail, but for the limited use of getting the copying text (which
alpar@464
  4793
% should be quite simple) inserted, we can hope it's ok.
alpar@464
  4794
%
alpar@464
  4795
{\catcode`\^^M=\active %
alpar@464
  4796
\gdef\insertcopying{\begingroup %
alpar@464
  4797
  \parindent = 0pt  % looks wrong on title page
alpar@464
  4798
  \def^^M{%
alpar@464
  4799
    \ifnum \lastpenalty=1 %
alpar@464
  4800
      \par %
alpar@464
  4801
    \else %
alpar@464
  4802
      \space \penalty 1 %
alpar@464
  4803
    \fi %
alpar@464
  4804
  }%
alpar@464
  4805
  %
alpar@464
  4806
  % Fix @c[omment] for catcode 13 ^^M's.
alpar@464
  4807
  \def\c##1^^M{\ignorespaces}%
alpar@464
  4808
  \let\comment = \c %
alpar@464
  4809
  %
alpar@464
  4810
  % Don't bother jumping through all the hoops that \doignore does, it
alpar@464
  4811
  % would be very hard since the catcodes are already set.
alpar@464
  4812
  \long\def\ignore##1\end ignore{\ignorespaces}%
alpar@464
  4813
  %
alpar@464
  4814
  \copyingtext %
alpar@464
  4815
\endgroup}%
alpar@464
  4816
}
alpar@464
  4817
alpar@464
  4818
\message{defuns,}
alpar@464
  4819
% @defun etc.
alpar@464
  4820
alpar@464
  4821
% Allow user to change definition object font (\df) internally
alpar@464
  4822
\def\setdeffont#1 {\csname DEF#1\endcsname}
alpar@464
  4823
alpar@464
  4824
\newskip\defbodyindent \defbodyindent=.4in
alpar@464
  4825
\newskip\defargsindent \defargsindent=50pt
alpar@464
  4826
\newskip\deflastargmargin \deflastargmargin=18pt
alpar@464
  4827
alpar@464
  4828
\newcount\parencount
alpar@464
  4829
alpar@464
  4830
% We want ()&[] to print specially on the defun line.
alpar@464
  4831
%
alpar@464
  4832
\def\activeparens{%
alpar@464
  4833
  \catcode`\(=\active \catcode`\)=\active
alpar@464
  4834
  \catcode`\&=\active
alpar@464
  4835
  \catcode`\[=\active \catcode`\]=\active
alpar@464
  4836
}
alpar@464
  4837
alpar@464
  4838
% Make control sequences which act like normal parenthesis chars.
alpar@464
  4839
\let\lparen = ( \let\rparen = )
alpar@464
  4840
alpar@464
  4841
{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
alpar@464
  4842
alpar@464
  4843
% Be sure that we always have a definition for `(', etc.  For example,
alpar@464
  4844
% if the fn name has parens in it, \boldbrax will not be in effect yet,
alpar@464
  4845
% so TeX would otherwise complain about undefined control sequence.
alpar@464
  4846
\global\let(=\lparen \global\let)=\rparen
alpar@464
  4847
\global\let[=\lbrack \global\let]=\rbrack
alpar@464
  4848
alpar@464
  4849
\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
alpar@464
  4850
\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
alpar@464
  4851
% This is used to turn on special parens
alpar@464
  4852
% but make & act ordinary (given that it's active).
alpar@464
  4853
\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr}
alpar@464
  4854
alpar@464
  4855
% Definitions of (, ) and & used in args for functions.
alpar@464
  4856
% This is the definition of ( outside of all parentheses.
alpar@464
  4857
\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested
alpar@464
  4858
  \global\advance\parencount by 1
alpar@464
  4859
}
alpar@464
  4860
%
alpar@464
  4861
% This is the definition of ( when already inside a level of parens.
alpar@464
  4862
\gdef\opnested{\char`\(\global\advance\parencount by 1 }
alpar@464
  4863
%
alpar@464
  4864
\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
alpar@464
  4865
  % also in that case restore the outer-level definition of (.
alpar@464
  4866
  \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
alpar@464
  4867
  \global\advance \parencount by -1 }
alpar@464
  4868
% If we encounter &foo, then turn on ()-hacking afterwards
alpar@464
  4869
\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
alpar@464
  4870
%
alpar@464
  4871
\gdef\normalparens{\boldbrax\let&=\ampnr}
alpar@464
  4872
} % End of definition inside \activeparens
alpar@464
  4873
%% These parens (in \boldbrax) actually are a little bolder than the
alpar@464
  4874
%% contained text.  This is especially needed for [ and ]
alpar@464
  4875
\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 }
alpar@464
  4876
\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 }
alpar@464
  4877
\let\ampnr = \&
alpar@464
  4878
\def\lbrb{{\bf\char`\[}}
alpar@464
  4879
\def\rbrb{{\bf\char`\]}}
alpar@464
  4880
alpar@464
  4881
% Active &'s sneak into the index arguments, so make sure it's defined.
alpar@464
  4882
{
alpar@464
  4883
  \catcode`& = \active
alpar@464
  4884
  \global\let& = \ampnr
alpar@464
  4885
}
alpar@464
  4886
alpar@464
  4887
% \defname, which formats the name of the @def (not the args).
alpar@464
  4888
% #1 is the function name.
alpar@464
  4889
% #2 is the type of definition, such as "Function".
alpar@464
  4890
%
alpar@464
  4891
\def\defname#1#2{%
alpar@464
  4892
  % How we'll output the type name.  Putting it in brackets helps
alpar@464
  4893
  % distinguish it from the body text that may end up on the next line
alpar@464
  4894
  % just below it.
alpar@464
  4895
  \ifempty{#2}%
alpar@464
  4896
    \def\defnametype{}%
alpar@464
  4897
  \else
alpar@464
  4898
    \def\defnametype{[\rm #2]}%
alpar@464
  4899
  \fi
alpar@464
  4900
  %
alpar@464
  4901
  % Get the values of \leftskip and \rightskip as they were outside the @def...
alpar@464
  4902
  \dimen2=\leftskip
alpar@464
  4903
  \advance\dimen2 by -\defbodyindent
alpar@464
  4904
  %
alpar@464
  4905
  % Figure out values for the paragraph shape.
alpar@464
  4906
  \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}%
alpar@464
  4907
  \dimen0=\hsize \advance \dimen0 by -\wd0  % compute size for first line
alpar@464
  4908
  \dimen1=\hsize \advance \dimen1 by -\defargsindent  % size for continuations
alpar@464
  4909
  \parshape 2 0in \dimen0 \defargsindent \dimen1
alpar@464
  4910
  %
alpar@464
  4911
  % Output arg 2 ("Function" or some such) but stuck inside a box of
alpar@464
  4912
  % width 0 so it does not interfere with linebreaking.
alpar@464
  4913
  \noindent
alpar@464
  4914
  %
alpar@464
  4915
  {% Adjust \hsize to exclude the ambient margins,
alpar@464
  4916
   % so that \rightline will obey them.
alpar@464
  4917
   \advance \hsize by -\dimen2
alpar@464
  4918
   \dimen3 = 0pt  % was -1.25pc
alpar@464
  4919
   \rlap{\rightline{\defnametype\kern\dimen3}}%
alpar@464
  4920
  }%
alpar@464
  4921
  %
alpar@464
  4922
  % Allow all lines to be underfull without complaint:
alpar@464
  4923
  \tolerance=10000 \hbadness=10000
alpar@464
  4924
  \advance\leftskip by -\defbodyindent
alpar@464
  4925
  \exdentamount=\defbodyindent
alpar@464
  4926
  {\df #1}\enskip        % output function name
alpar@464
  4927
  % \defunargs will be called next to output the arguments, if any.
alpar@464
  4928
}
alpar@464
  4929
alpar@464
  4930
% Common pieces to start any @def...
alpar@464
  4931
% #1 is the \E... control sequence to end the definition (which we define).
alpar@464
  4932
% #2 is the \...x control sequence (which our caller defines).
alpar@464
  4933
% #3 is the control sequence to process the header, such as \defunheader.
alpar@464
  4934
%
alpar@464
  4935
\def\parsebodycommon#1#2#3{%
alpar@464
  4936
  \begingroup\inENV
alpar@464
  4937
  % If there are two @def commands in a row, we'll have a \nobreak,
alpar@464
  4938
  % which is there to keep the function description together with its
alpar@464
  4939
  % header.  But if there's nothing but headers, we want to allow a
alpar@464
  4940
  % break after all.  Check for penalty 10002 (inserted by
alpar@464
  4941
  % \defargscommonending) instead of 10000, since the sectioning
alpar@464
  4942
  % commands insert a \penalty10000, and we don't want to allow a break
alpar@464
  4943
  % between a section heading and a defun.
alpar@464
  4944
  \ifnum\lastpenalty=10002 \penalty0 \fi
alpar@464
  4945
  \medbreak
alpar@464
  4946
  %
alpar@464
  4947
  % Define the \E... end token that this defining construct specifies
alpar@464
  4948
  % so that it will exit this group.
alpar@464
  4949
  \def#1{\endgraf\endgroup\medbreak}%
alpar@464
  4950
  %
alpar@464
  4951
  \parindent=0in
alpar@464
  4952
  \advance\leftskip by \defbodyindent
alpar@464
  4953
  \exdentamount=\defbodyindent
alpar@464
  4954
}
alpar@464
  4955
alpar@464
  4956
% Common part of the \...x definitions.
alpar@464
  4957
%
alpar@464
  4958
\def\defxbodycommon{%
alpar@464
  4959
  % As with \parsebodycommon above, allow line break if we have multiple
alpar@464
  4960
  % x headers in a row.  It's not a great place, though.
alpar@464
  4961
  \ifnum\lastpenalty=10000 \penalty1000 \fi
alpar@464
  4962
  %
alpar@464
  4963
  \begingroup\obeylines
alpar@464
  4964
}
alpar@464
  4965
alpar@464
  4966
% Process body of @defun, @deffn, @defmac, etc.
alpar@464
  4967
%
alpar@464
  4968
\def\defparsebody#1#2#3{%
alpar@464
  4969
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  4970
  \def#2{\defxbodycommon \activeparens \spacesplit#3}%
alpar@464
  4971
  \catcode\equalChar=\active
alpar@464
  4972
  \begingroup\obeylines\activeparens
alpar@464
  4973
  \spacesplit#3%
alpar@464
  4974
}
alpar@464
  4975
alpar@464
  4976
% #1, #2, #3 are the common arguments (see \parsebodycommon above).
alpar@464
  4977
% #4, delimited by the space, is the class name.
alpar@464
  4978
%
alpar@464
  4979
\def\defmethparsebody#1#2#3#4 {%
alpar@464
  4980
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  4981
  \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}%
alpar@464
  4982
  \begingroup\obeylines\activeparens
alpar@464
  4983
  % The \empty here prevents misinterpretation of a construct such as
alpar@464
  4984
  %   @deffn {whatever} {Enharmonic comma}
alpar@464
  4985
  % See comments at \deftpparsebody, although in our case we don't have
alpar@464
  4986
  % to remove the \empty afterwards, since it is empty.
alpar@464
  4987
  \spacesplit{#3{#4}}\empty
alpar@464
  4988
}
alpar@464
  4989
alpar@464
  4990
% Used for @deftypemethod and @deftypeivar.
alpar@464
  4991
% #1, #2, #3 are the common arguments (see \defparsebody).
alpar@464
  4992
% #4, delimited by a space, is the class name.
alpar@464
  4993
% #5 is the method's return type.
alpar@464
  4994
%
alpar@464
  4995
\def\deftypemethparsebody#1#2#3#4 #5 {%
alpar@464
  4996
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  4997
  \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}%
alpar@464
  4998
  \begingroup\obeylines\activeparens
alpar@464
  4999
  \spacesplit{#3{#4}{#5}}%
alpar@464
  5000
}
alpar@464
  5001
alpar@464
  5002
% Used for @deftypeop.  The change from \deftypemethparsebody is an
alpar@464
  5003
% extra argument at the beginning which is the `category', instead of it
alpar@464
  5004
% being the hardwired string `Method' or `Instance Variable'.  We have
alpar@464
  5005
% to account for this both in the \...x definition and in parsing the
alpar@464
  5006
% input at hand.  Thus also need a control sequence (passed as #5) for
alpar@464
  5007
% the \E... definition to assign the category name to.
alpar@464
  5008
%
alpar@464
  5009
\def\deftypeopparsebody#1#2#3#4#5 #6 {%
alpar@464
  5010
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5011
  \def#2##1 ##2 ##3 {\def#4{##1}%
alpar@464
  5012
    \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}%
alpar@464
  5013
  \begingroup\obeylines\activeparens
alpar@464
  5014
  \spacesplit{#3{#5}{#6}}%
alpar@464
  5015
}
alpar@464
  5016
alpar@464
  5017
% For @defop.
alpar@464
  5018
\def\defopparsebody #1#2#3#4#5 {%
alpar@464
  5019
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5020
  \def#2##1 ##2 {\def#4{##1}%
alpar@464
  5021
    \defxbodycommon \activeparens \spacesplit{#3{##2}}}%
alpar@464
  5022
  \begingroup\obeylines\activeparens
alpar@464
  5023
  \spacesplit{#3{#5}}%
alpar@464
  5024
}
alpar@464
  5025
alpar@464
  5026
% These parsing functions are similar to the preceding ones
alpar@464
  5027
% except that they do not make parens into active characters.
alpar@464
  5028
% These are used for "variables" since they have no arguments.
alpar@464
  5029
%
alpar@464
  5030
\def\defvarparsebody #1#2#3{%
alpar@464
  5031
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5032
  \def#2{\defxbodycommon \spacesplit#3}%
alpar@464
  5033
  \catcode\equalChar=\active
alpar@464
  5034
  \begingroup\obeylines
alpar@464
  5035
  \spacesplit#3%
alpar@464
  5036
}
alpar@464
  5037
alpar@464
  5038
% @defopvar.
alpar@464
  5039
\def\defopvarparsebody #1#2#3#4#5 {%
alpar@464
  5040
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5041
  \def#2##1 ##2 {\def#4{##1}%
alpar@464
  5042
    \defxbodycommon \spacesplit{#3{##2}}}%
alpar@464
  5043
  \begingroup\obeylines
alpar@464
  5044
  \spacesplit{#3{#5}}%
alpar@464
  5045
}
alpar@464
  5046
alpar@464
  5047
\def\defvrparsebody#1#2#3#4 {%
alpar@464
  5048
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5049
  \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}%
alpar@464
  5050
  \begingroup\obeylines
alpar@464
  5051
  \spacesplit{#3{#4}}%
alpar@464
  5052
}
alpar@464
  5053
alpar@464
  5054
% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
alpar@464
  5055
% type is just `struct', because we lose the braces in `{struct
alpar@464
  5056
% termios}' when \spacesplit reads its undelimited argument.  Sigh.
alpar@464
  5057
% \let\deftpparsebody=\defvrparsebody
alpar@464
  5058
%
alpar@464
  5059
% So, to get around this, we put \empty in with the type name.  That
alpar@464
  5060
% way, TeX won't find exactly `{...}' as an undelimited argument, and
alpar@464
  5061
% won't strip off the braces.
alpar@464
  5062
%
alpar@464
  5063
\def\deftpparsebody #1#2#3#4 {%
alpar@464
  5064
  \parsebodycommon{#1}{#2}{#3}%
alpar@464
  5065
  \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}%
alpar@464
  5066
  \begingroup\obeylines
alpar@464
  5067
  \spacesplit{\parsetpheaderline{#3{#4}}}\empty
alpar@464
  5068
}
alpar@464
  5069
alpar@464
  5070
% Fine, but then we have to eventually remove the \empty *and* the
alpar@464
  5071
% braces (if any).  That's what this does.
alpar@464
  5072
%
alpar@464
  5073
\def\removeemptybraces\empty#1\relax{#1}
alpar@464
  5074
alpar@464
  5075
% After \spacesplit has done its work, this is called -- #1 is the final
alpar@464
  5076
% thing to call, #2 the type name (which starts with \empty), and #3
alpar@464
  5077
% (which might be empty) the arguments.
alpar@464
  5078
%
alpar@464
  5079
\def\parsetpheaderline#1#2#3{%
alpar@464
  5080
  #1{\removeemptybraces#2\relax}{#3}%
alpar@464
  5081
}%
alpar@464
  5082
alpar@464
  5083
% Split up #2 (the rest of the input line) at the first space token.
alpar@464
  5084
% call #1 with two arguments:
alpar@464
  5085
%  the first is all of #2 before the space token,
alpar@464
  5086
%  the second is all of #2 after that space token.
alpar@464
  5087
% If #2 contains no space token, all of it is passed as the first arg
alpar@464
  5088
% and the second is passed as empty.
alpar@464
  5089
%
alpar@464
  5090
{\obeylines %
alpar@464
  5091
 \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}%
alpar@464
  5092
 \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{%
alpar@464
  5093
   \ifx\relax #3%
alpar@464
  5094
     #1{#2}{}%
alpar@464
  5095
   \else %
alpar@464
  5096
     #1{#2}{#3#4}%
alpar@464
  5097
   \fi}%
alpar@464
  5098
}
alpar@464
  5099
alpar@464
  5100
% Define @defun.
alpar@464
  5101
alpar@464
  5102
% This is called to end the arguments processing for all the @def... commands.
alpar@464
  5103
%
alpar@464
  5104
\def\defargscommonending{%
alpar@464
  5105
  \interlinepenalty = 10000
alpar@464
  5106
  \advance\rightskip by 0pt plus 1fil
alpar@464
  5107
  \endgraf
alpar@464
  5108
  \nobreak\vskip -\parskip
alpar@464
  5109
  \penalty 10002  % signal to \parsebodycommon.
alpar@464
  5110
}
alpar@464
  5111
alpar@464
  5112
% This expands the args and terminates the paragraph they comprise.
alpar@464
  5113
%
alpar@464
  5114
\def\defunargs#1{\functionparens \sl
alpar@464
  5115
% Expand, preventing hyphenation at `-' chars.
alpar@464
  5116
% Note that groups don't affect changes in \hyphenchar.
alpar@464
  5117
% Set the font temporarily and use \font in case \setfont made \tensl a macro.
alpar@464
  5118
{\tensl\hyphenchar\font=0}%
alpar@464
  5119
#1%
alpar@464
  5120
{\tensl\hyphenchar\font=45}%
alpar@464
  5121
\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi%
alpar@464
  5122
  \defargscommonending
alpar@464
  5123
}
alpar@464
  5124
alpar@464
  5125
\def\deftypefunargs #1{%
alpar@464
  5126
% Expand, preventing hyphenation at `-' chars.
alpar@464
  5127
% Note that groups don't affect changes in \hyphenchar.
alpar@464
  5128
% Use \boldbraxnoamp, not \functionparens, so that & is not special.
alpar@464
  5129
\boldbraxnoamp
alpar@464
  5130
\tclose{#1}% avoid \code because of side effects on active chars
alpar@464
  5131
  \defargscommonending
alpar@464
  5132
}
alpar@464
  5133
alpar@464
  5134
% Do complete processing of one @defun or @defunx line already parsed.
alpar@464
  5135
alpar@464
  5136
% @deffn Command forward-char nchars
alpar@464
  5137
alpar@464
  5138
\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
alpar@464
  5139
alpar@464
  5140
\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
alpar@464
  5141
\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
alpar@464
  5142
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5143
}
alpar@464
  5144
alpar@464
  5145
% @defun == @deffn Function
alpar@464
  5146
alpar@464
  5147
\def\defun{\defparsebody\Edefun\defunx\defunheader}
alpar@464
  5148
alpar@464
  5149
\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
alpar@464
  5150
\begingroup\defname {#1}{\putwordDeffunc}%
alpar@464
  5151
\defunargs {#2}\endgroup %
alpar@464
  5152
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5153
}
alpar@464
  5154
alpar@464
  5155
% @deftypefun int foobar (int @var{foo}, float @var{bar})
alpar@464
  5156
alpar@464
  5157
\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
alpar@464
  5158
alpar@464
  5159
% #1 is the data type.  #2 is the name and args.
alpar@464
  5160
\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
alpar@464
  5161
% #1 is the data type, #2 the name, #3 the args.
alpar@464
  5162
\def\deftypefunheaderx #1#2 #3\relax{%
alpar@464
  5163
\doind {fn}{\code{#2}}% Make entry in function index
alpar@464
  5164
\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}%
alpar@464
  5165
\deftypefunargs {#3}\endgroup %
alpar@464
  5166
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5167
}
alpar@464
  5168
alpar@464
  5169
% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
alpar@464
  5170
alpar@464
  5171
\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
alpar@464
  5172
alpar@464
  5173
% \defheaderxcond#1\relax$.$
alpar@464
  5174
% puts #1 in @code, followed by a space, but does nothing if #1 is null.
alpar@464
  5175
\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi}
alpar@464
  5176
alpar@464
  5177
% #1 is the classification.  #2 is the data type.  #3 is the name and args.
alpar@464
  5178
\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
alpar@464
  5179
% #1 is the classification, #2 the data type, #3 the name, #4 the args.
alpar@464
  5180
\def\deftypefnheaderx #1#2#3 #4\relax{%
alpar@464
  5181
\doind {fn}{\code{#3}}% Make entry in function index
alpar@464
  5182
\begingroup
alpar@464
  5183
\normalparens % notably, turn off `&' magic, which prevents
alpar@464
  5184
%               at least some C++ text from working
alpar@464
  5185
\defname {\defheaderxcond#2\relax$.$#3}{#1}%
alpar@464
  5186
\deftypefunargs {#4}\endgroup %
alpar@464
  5187
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5188
}
alpar@464
  5189
alpar@464
  5190
% @defmac == @deffn Macro
alpar@464
  5191
alpar@464
  5192
\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
alpar@464
  5193
alpar@464
  5194
\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
alpar@464
  5195
\begingroup\defname {#1}{\putwordDefmac}%
alpar@464
  5196
\defunargs {#2}\endgroup %
alpar@464
  5197
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5198
}
alpar@464
  5199
alpar@464
  5200
% @defspec == @deffn Special Form
alpar@464
  5201
alpar@464
  5202
\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
alpar@464
  5203
alpar@464
  5204
\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
alpar@464
  5205
\begingroup\defname {#1}{\putwordDefspec}%
alpar@464
  5206
\defunargs {#2}\endgroup %
alpar@464
  5207
\catcode\equalChar=\other % Turn off change made in \defparsebody
alpar@464
  5208
}
alpar@464
  5209
alpar@464
  5210
% @defop CATEGORY CLASS OPERATION ARG...
alpar@464
  5211
%
alpar@464
  5212
\def\defop #1 {\def\defoptype{#1}%
alpar@464
  5213
\defopparsebody\Edefop\defopx\defopheader\defoptype}
alpar@464
  5214
%
alpar@464
  5215
\def\defopheader#1#2#3{%
alpar@464
  5216
  \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry
alpar@464
  5217
  \begingroup
alpar@464
  5218
    \defname{#2}{\defoptype\ \putwordon\ #1}%
alpar@464
  5219
    \defunargs{#3}%
alpar@464
  5220
  \endgroup
alpar@464
  5221
}
alpar@464
  5222
alpar@464
  5223
% @deftypeop CATEGORY CLASS TYPE OPERATION ARG...
alpar@464
  5224
%
alpar@464
  5225
\def\deftypeop #1 {\def\deftypeopcategory{#1}%
alpar@464
  5226
  \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader
alpar@464
  5227
                       \deftypeopcategory}
alpar@464
  5228
%
alpar@464
  5229
% #1 is the class name, #2 the data type, #3 the operation name, #4 the args.
alpar@464
  5230
\def\deftypeopheader#1#2#3#4{%
alpar@464
  5231
  \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
alpar@464
  5232
  \begingroup
alpar@464
  5233
    \defname{\defheaderxcond#2\relax$.$#3}
alpar@464
  5234
            {\deftypeopcategory\ \putwordon\ \code{#1}}%
alpar@464
  5235
    \deftypefunargs{#4}%
alpar@464
  5236
  \endgroup
alpar@464
  5237
}
alpar@464
  5238
alpar@464
  5239
% @deftypemethod CLASS TYPE METHOD ARG...
alpar@464
  5240
%
alpar@464
  5241
\def\deftypemethod{%
alpar@464
  5242
  \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader}
alpar@464
  5243
%
alpar@464
  5244
% #1 is the class name, #2 the data type, #3 the method name, #4 the args.
alpar@464
  5245
\def\deftypemethodheader#1#2#3#4{%
alpar@464
  5246
  \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
alpar@464
  5247
  \begingroup
alpar@464
  5248
    \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}%
alpar@464
  5249
    \deftypefunargs{#4}%
alpar@464
  5250
  \endgroup
alpar@464
  5251
}
alpar@464
  5252
alpar@464
  5253
% @deftypeivar CLASS TYPE VARNAME
alpar@464
  5254
%
alpar@464
  5255
\def\deftypeivar{%
alpar@464
  5256
  \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader}
alpar@464
  5257
%
alpar@464
  5258
% #1 is the class name, #2 the data type, #3 the variable name.
alpar@464
  5259
\def\deftypeivarheader#1#2#3{%
alpar@464
  5260
  \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index
alpar@464
  5261
  \begingroup
alpar@464
  5262
    \defname{\defheaderxcond#2\relax$.$#3}
alpar@464
  5263
            {\putwordInstanceVariableof\ \code{#1}}%
alpar@464
  5264
    \defvarargs{#3}%
alpar@464
  5265
  \endgroup
alpar@464
  5266
}
alpar@464
  5267
alpar@464
  5268
% @defmethod == @defop Method
alpar@464
  5269
%
alpar@464
  5270
\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
alpar@464
  5271
%
alpar@464
  5272
% #1 is the class name, #2 the method name, #3 the args.
alpar@464
  5273
\def\defmethodheader#1#2#3{%
alpar@464
  5274
  \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index
alpar@464
  5275
  \begingroup
alpar@464
  5276
    \defname{#2}{\putwordMethodon\ \code{#1}}%
alpar@464
  5277
    \defunargs{#3}%
alpar@464
  5278
  \endgroup
alpar@464
  5279
}
alpar@464
  5280
alpar@464
  5281
% @defcv {Class Option} foo-class foo-flag
alpar@464
  5282
alpar@464
  5283
\def\defcv #1 {\def\defcvtype{#1}%
alpar@464
  5284
\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
alpar@464
  5285
alpar@464
  5286
\def\defcvarheader #1#2#3{%
alpar@464
  5287
  \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry
alpar@464
  5288
  \begingroup
alpar@464
  5289
    \defname{#2}{\defcvtype\ \putwordof\ #1}%
alpar@464
  5290
    \defvarargs{#3}%
alpar@464
  5291
  \endgroup
alpar@464
  5292
}
alpar@464
  5293
alpar@464
  5294
% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME
alpar@464
  5295
%
alpar@464
  5296
\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
alpar@464
  5297
%
alpar@464
  5298
\def\defivarheader#1#2#3{%
alpar@464
  5299
  \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index
alpar@464
  5300
  \begingroup
alpar@464
  5301
    \defname{#2}{\putwordInstanceVariableof\ #1}%
alpar@464
  5302
    \defvarargs{#3}%
alpar@464
  5303
  \endgroup
alpar@464
  5304
}
alpar@464
  5305
alpar@464
  5306
% @defvar
alpar@464
  5307
% First, define the processing that is wanted for arguments of @defvar.
alpar@464
  5308
% This is actually simple: just print them in roman.
alpar@464
  5309
% This must expand the args and terminate the paragraph they make up
alpar@464
  5310
\def\defvarargs #1{\normalparens #1%
alpar@464
  5311
  \defargscommonending
alpar@464
  5312
}
alpar@464
  5313
alpar@464
  5314
% @defvr Counter foo-count
alpar@464
  5315
alpar@464
  5316
\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
alpar@464
  5317
alpar@464
  5318
\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
alpar@464
  5319
\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
alpar@464
  5320
alpar@464
  5321
% @defvar == @defvr Variable
alpar@464
  5322
alpar@464
  5323
\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
alpar@464
  5324
alpar@464
  5325
\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
alpar@464
  5326
\begingroup\defname {#1}{\putwordDefvar}%
alpar@464
  5327
\defvarargs {#2}\endgroup %
alpar@464
  5328
}
alpar@464
  5329
alpar@464
  5330
% @defopt == @defvr {User Option}
alpar@464
  5331
alpar@464
  5332
\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
alpar@464
  5333
alpar@464
  5334
\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
alpar@464
  5335
\begingroup\defname {#1}{\putwordDefopt}%
alpar@464
  5336
\defvarargs {#2}\endgroup %
alpar@464
  5337
}
alpar@464
  5338
alpar@464
  5339
% @deftypevar int foobar
alpar@464
  5340
alpar@464
  5341
\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
alpar@464
  5342
alpar@464
  5343
% #1 is the data type.  #2 is the name, perhaps followed by text that
alpar@464
  5344
% is actually part of the data type, which should not be put into the index.
alpar@464
  5345
\def\deftypevarheader #1#2{%
alpar@464
  5346
\dovarind#2 \relax% Make entry in variables index
alpar@464
  5347
\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}%
alpar@464
  5348
  \defargscommonending
alpar@464
  5349
\endgroup}
alpar@464
  5350
\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}}
alpar@464
  5351
alpar@464
  5352
% @deftypevr {Global Flag} int enable
alpar@464
  5353
alpar@464
  5354
\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
alpar@464
  5355
alpar@464
  5356
\def\deftypevrheader #1#2#3{\dovarind#3 \relax%
alpar@464
  5357
\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1}
alpar@464
  5358
  \defargscommonending
alpar@464
  5359
\endgroup}
alpar@464
  5360
alpar@464
  5361
% Now define @deftp
alpar@464
  5362
% Args are printed in bold, a slight difference from @defvar.
alpar@464
  5363
alpar@464
  5364
\def\deftpargs #1{\bf \defvarargs{#1}}
alpar@464
  5365
alpar@464
  5366
% @deftp Class window height width ...
alpar@464
  5367
alpar@464
  5368
\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
alpar@464
  5369
alpar@464
  5370
\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
alpar@464
  5371
\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
alpar@464
  5372
alpar@464
  5373
% These definitions are used if you use @defunx (etc.)
alpar@464
  5374
% anywhere other than immediately after a @defun or @defunx.
alpar@464
  5375
%
alpar@464
  5376
\def\defcvx#1 {\errmessage{@defcvx in invalid context}}
alpar@464
  5377
\def\deffnx#1 {\errmessage{@deffnx in invalid context}}
alpar@464
  5378
\def\defivarx#1 {\errmessage{@defivarx in invalid context}}
alpar@464
  5379
\def\defmacx#1 {\errmessage{@defmacx in invalid context}}
alpar@464
  5380
\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}}
alpar@464
  5381
\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
alpar@464
  5382
\def\defopx#1 {\errmessage{@defopx in invalid context}}
alpar@464
  5383
\def\defspecx#1 {\errmessage{@defspecx in invalid context}}
alpar@464
  5384
\def\deftpx#1 {\errmessage{@deftpx in invalid context}}
alpar@464
  5385
\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}}
alpar@464
  5386
\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}}
alpar@464
  5387
\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}}
alpar@464
  5388
\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}}
alpar@464
  5389
\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}}
alpar@464
  5390
\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}}
alpar@464
  5391
\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}}
alpar@464
  5392
\def\defunx#1 {\errmessage{@defunx in invalid context}}
alpar@464
  5393
\def\defvarx#1 {\errmessage{@defvarx in invalid context}}
alpar@464
  5394
\def\defvrx#1 {\errmessage{@defvrx in invalid context}}
alpar@464
  5395
alpar@464
  5396
alpar@464
  5397
\message{macros,}
alpar@464
  5398
% @macro.
alpar@464
  5399
alpar@464
  5400
% To do this right we need a feature of e-TeX, \scantokens,
alpar@464
  5401
% which we arrange to emulate with a temporary file in ordinary TeX.
alpar@464
  5402
\ifx\eTeXversion\undefined
alpar@464
  5403
 \newwrite\macscribble
alpar@464
  5404
 \def\scanmacro#1{%
alpar@464
  5405
   \begingroup \newlinechar`\^^M
alpar@464
  5406
   % Undo catcode changes of \startcontents and \doprintindex
alpar@464
  5407
   \catcode`\@=0 \catcode`\\=\other \escapechar=`\@
alpar@464
  5408
   % Append \endinput to make sure that TeX does not see the ending newline.
alpar@464
  5409
   \toks0={#1\endinput}%
alpar@464
  5410
   \immediate\openout\macscribble=\jobname.tmp
alpar@464
  5411
   \immediate\write\macscribble{\the\toks0}%
alpar@464
  5412
   \immediate\closeout\macscribble
alpar@464
  5413
   \let\xeatspaces\eatspaces
alpar@464
  5414
   \input \jobname.tmp
alpar@464
  5415
   \endgroup
alpar@464
  5416
}
alpar@464
  5417
\else
alpar@464
  5418
\def\scanmacro#1{%
alpar@464
  5419
\begingroup \newlinechar`\^^M
alpar@464
  5420
% Undo catcode changes of \startcontents and \doprintindex
alpar@464
  5421
\catcode`\@=0 \catcode`\\=\other \escapechar=`\@
alpar@464
  5422
\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup}
alpar@464
  5423
\fi
alpar@464
  5424
alpar@464
  5425
\newcount\paramno   % Count of parameters
alpar@464
  5426
\newtoks\macname    % Macro name
alpar@464
  5427
\newif\ifrecursive  % Is it recursive?
alpar@464
  5428
\def\macrolist{}    % List of all defined macros in the form
alpar@464
  5429
                    % \do\macro1\do\macro2...
alpar@464
  5430
alpar@464
  5431
% Utility routines.
alpar@464
  5432
% Thisdoes \let #1 = #2, except with \csnames.
alpar@464
  5433
\def\cslet#1#2{%
alpar@464
  5434
\expandafter\expandafter
alpar@464
  5435
\expandafter\let
alpar@464
  5436
\expandafter\expandafter
alpar@464
  5437
\csname#1\endcsname
alpar@464
  5438
\csname#2\endcsname}
alpar@464
  5439
alpar@464
  5440
% Trim leading and trailing spaces off a string.
alpar@464
  5441
% Concepts from aro-bend problem 15 (see CTAN).
alpar@464
  5442
{\catcode`\@=11
alpar@464
  5443
\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
alpar@464
  5444
\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
alpar@464
  5445
\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
alpar@464
  5446
\def\unbrace#1{#1}
alpar@464
  5447
\unbrace{\gdef\trim@@@ #1 } #2@{#1}
alpar@464
  5448
}
alpar@464
  5449
alpar@464
  5450
% Trim a single trailing ^^M off a string.
alpar@464
  5451
{\catcode`\^^M=\other \catcode`\Q=3%
alpar@464
  5452
\gdef\eatcr #1{\eatcra #1Q^^MQ}%
alpar@464
  5453
\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
alpar@464
  5454
\gdef\eatcrb#1Q#2Q{#1}%
alpar@464
  5455
}
alpar@464
  5456
alpar@464
  5457
% Macro bodies are absorbed as an argument in a context where
alpar@464
  5458
% all characters are catcode 10, 11 or 12, except \ which is active
alpar@464
  5459
% (as in normal texinfo). It is necessary to change the definition of \.
alpar@464
  5460
alpar@464
  5461
% It's necessary to have hard CRs when the macro is executed. This is
alpar@464
  5462
% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
alpar@464
  5463
% body, and then making it the \newlinechar in \scanmacro.
alpar@464
  5464
alpar@464
  5465
\def\macrobodyctxt{%
alpar@464
  5466
  \catcode`\~=\other
alpar@464
  5467
  \catcode`\^=\other
alpar@464
  5468
  \catcode`\_=\other
alpar@464
  5469
  \catcode`\|=\other
alpar@464
  5470
  \catcode`\<=\other
alpar@464
  5471
  \catcode`\>=\other
alpar@464
  5472
  \catcode`\+=\other
alpar@464
  5473
  \catcode`\{=\other
alpar@464
  5474
  \catcode`\}=\other
alpar@464
  5475
  \catcode`\@=\other
alpar@464
  5476
  \catcode`\^^M=\other
alpar@464
  5477
  \usembodybackslash}
alpar@464
  5478
alpar@464
  5479
\def\macroargctxt{%
alpar@464
  5480
  \catcode`\~=\other
alpar@464
  5481
  \catcode`\^=\other
alpar@464
  5482
  \catcode`\_=\other
alpar@464
  5483
  \catcode`\|=\other
alpar@464
  5484
  \catcode`\<=\other
alpar@464
  5485
  \catcode`\>=\other
alpar@464
  5486
  \catcode`\+=\other
alpar@464
  5487
  \catcode`\@=\other
alpar@464
  5488
  \catcode`\\=\other}
alpar@464
  5489
alpar@464
  5490
% \mbodybackslash is the definition of \ in @macro bodies.
alpar@464
  5491
% It maps \foo\ => \csname macarg.foo\endcsname => #N
alpar@464
  5492
% where N is the macro parameter number.
alpar@464
  5493
% We define \csname macarg.\endcsname to be \realbackslash, so
alpar@464
  5494
% \\ in macro replacement text gets you a backslash.
alpar@464
  5495
alpar@464
  5496
{\catcode`@=0 @catcode`@\=@active
alpar@464
  5497
 @gdef@usembodybackslash{@let\=@mbodybackslash}
alpar@464
  5498
 @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
alpar@464
  5499
}
alpar@464
  5500
\expandafter\def\csname macarg.\endcsname{\realbackslash}
alpar@464
  5501
alpar@464
  5502
\def\macro{\recursivefalse\parsearg\macroxxx}
alpar@464
  5503
\def\rmacro{\recursivetrue\parsearg\macroxxx}
alpar@464
  5504
alpar@464
  5505
\def\macroxxx#1{%
alpar@464
  5506
  \getargs{#1}%           now \macname is the macname and \argl the arglist
alpar@464
  5507
  \ifx\argl\empty       % no arguments
alpar@464
  5508
     \paramno=0%
alpar@464
  5509
  \else
alpar@464
  5510
     \expandafter\parsemargdef \argl;%
alpar@464
  5511
  \fi
alpar@464
  5512
  \if1\csname ismacro.\the\macname\endcsname
alpar@464
  5513
     \message{Warning: redefining \the\macname}%
alpar@464
  5514
  \else
alpar@464
  5515
     \expandafter\ifx\csname \the\macname\endcsname \relax
alpar@464
  5516
     \else \errmessage{Macro name \the\macname\space already defined}\fi
alpar@464
  5517
     \global\cslet{macsave.\the\macname}{\the\macname}%
alpar@464
  5518
     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
alpar@464
  5519
     % Add the macroname to \macrolist
alpar@464
  5520
     \toks0 = \expandafter{\macrolist\do}%
alpar@464
  5521
     \xdef\macrolist{\the\toks0
alpar@464
  5522
       \expandafter\noexpand\csname\the\macname\endcsname}%
alpar@464
  5523
  \fi
alpar@464
  5524
  \begingroup \macrobodyctxt
alpar@464
  5525
  \ifrecursive \expandafter\parsermacbody
alpar@464
  5526
  \else \expandafter\parsemacbody
alpar@464
  5527
  \fi}
alpar@464
  5528
alpar@464
  5529
\def\unmacro{\parsearg\dounmacro}
alpar@464
  5530
\def\dounmacro#1{%
alpar@464
  5531
  \if1\csname ismacro.#1\endcsname
alpar@464
  5532
    \global\cslet{#1}{macsave.#1}%
alpar@464
  5533
    \global\expandafter\let \csname ismacro.#1\endcsname=0%
alpar@464
  5534
    % Remove the macro name from \macrolist:
alpar@464
  5535
    \begingroup
alpar@464
  5536
      \expandafter\let\csname#1\endcsname \relax
alpar@464
  5537
      \let\do\unmacrodo
alpar@464
  5538
      \xdef\macrolist{\macrolist}%
alpar@464
  5539
    \endgroup
alpar@464
  5540
  \else
alpar@464
  5541
    \errmessage{Macro #1 not defined}%
alpar@464
  5542
  \fi
alpar@464
  5543
}
alpar@464
  5544
alpar@464
  5545
% Called by \do from \dounmacro on each macro.  The idea is to omit any
alpar@464
  5546
% macro definitions that have been changed to \relax.
alpar@464
  5547
%
alpar@464
  5548
\def\unmacrodo#1{%
alpar@464
  5549
  \ifx#1\relax
alpar@464
  5550
    % remove this
alpar@464
  5551
  \else
alpar@464
  5552
    \noexpand\do \noexpand #1%
alpar@464
  5553
  \fi
alpar@464
  5554
}
alpar@464
  5555
alpar@464
  5556
% This makes use of the obscure feature that if the last token of a
alpar@464
  5557
% <parameter list> is #, then the preceding argument is delimited by
alpar@464
  5558
% an opening brace, and that opening brace is not consumed.
alpar@464
  5559
\def\getargs#1{\getargsxxx#1{}}
alpar@464
  5560
\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
alpar@464
  5561
\def\getmacname #1 #2\relax{\macname={#1}}
alpar@464
  5562
\def\getmacargs#1{\def\argl{#1}}
alpar@464
  5563
alpar@464
  5564
% Parse the optional {params} list.  Set up \paramno and \paramlist
alpar@464
  5565
% so \defmacro knows what to do.  Define \macarg.blah for each blah
alpar@464
  5566
% in the params list, to be ##N where N is the position in that list.
alpar@464
  5567
% That gets used by \mbodybackslash (above).
alpar@464
  5568
alpar@464
  5569
% We need to get `macro parameter char #' into several definitions.
alpar@464
  5570
% The technique used is stolen from LaTeX:  let \hash be something
alpar@464
  5571
% unexpandable, insert that wherever you need a #, and then redefine
alpar@464
  5572
% it to # just before using the token list produced.
alpar@464
  5573
%
alpar@464
  5574
% The same technique is used to protect \eatspaces till just before
alpar@464
  5575
% the macro is used.
alpar@464
  5576
alpar@464
  5577
\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
alpar@464
  5578
        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
alpar@464
  5579
\def\parsemargdefxxx#1,{%
alpar@464
  5580
  \if#1;\let\next=\relax
alpar@464
  5581
  \else \let\next=\parsemargdefxxx
alpar@464
  5582
    \advance\paramno by 1%
alpar@464
  5583
    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
alpar@464
  5584
        {\xeatspaces{\hash\the\paramno}}%
alpar@464
  5585
    \edef\paramlist{\paramlist\hash\the\paramno,}%
alpar@464
  5586
  \fi\next}
alpar@464
  5587
alpar@464
  5588
% These two commands read recursive and nonrecursive macro bodies.
alpar@464
  5589
% (They're different since rec and nonrec macros end differently.)
alpar@464
  5590
alpar@464
  5591
\long\def\parsemacbody#1@end macro%
alpar@464
  5592
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
alpar@464
  5593
\long\def\parsermacbody#1@end rmacro%
alpar@464
  5594
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
alpar@464
  5595
alpar@464
  5596
% This defines the macro itself. There are six cases: recursive and
alpar@464
  5597
% nonrecursive macros of zero, one, and many arguments.
alpar@464
  5598
% Much magic with \expandafter here.
alpar@464
  5599
% \xdef is used so that macro definitions will survive the file
alpar@464
  5600
% they're defined in; @include reads the file inside a group.
alpar@464
  5601
\def\defmacro{%
alpar@464
  5602
  \let\hash=##% convert placeholders to macro parameter chars
alpar@464
  5603
  \ifrecursive
alpar@464
  5604
    \ifcase\paramno
alpar@464
  5605
    % 0
alpar@464
  5606
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5607
        \noexpand\scanmacro{\temp}}%
alpar@464
  5608
    \or % 1
alpar@464
  5609
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5610
         \bgroup\noexpand\macroargctxt
alpar@464
  5611
         \noexpand\braceorline
alpar@464
  5612
         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
alpar@464
  5613
      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
alpar@464
  5614
         \egroup\noexpand\scanmacro{\temp}}%
alpar@464
  5615
    \else % many
alpar@464
  5616
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5617
         \bgroup\noexpand\macroargctxt
alpar@464
  5618
         \noexpand\csname\the\macname xx\endcsname}%
alpar@464
  5619
      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
alpar@464
  5620
          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
alpar@464
  5621
      \expandafter\expandafter
alpar@464
  5622
      \expandafter\xdef
alpar@464
  5623
      \expandafter\expandafter
alpar@464
  5624
        \csname\the\macname xxx\endcsname
alpar@464
  5625
          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
alpar@464
  5626
    \fi
alpar@464
  5627
  \else
alpar@464
  5628
    \ifcase\paramno
alpar@464
  5629
    % 0
alpar@464
  5630
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5631
        \noexpand\norecurse{\the\macname}%
alpar@464
  5632
        \noexpand\scanmacro{\temp}\egroup}%
alpar@464
  5633
    \or % 1
alpar@464
  5634
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5635
         \bgroup\noexpand\macroargctxt
alpar@464
  5636
         \noexpand\braceorline
alpar@464
  5637
         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
alpar@464
  5638
      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
alpar@464
  5639
        \egroup
alpar@464
  5640
        \noexpand\norecurse{\the\macname}%
alpar@464
  5641
        \noexpand\scanmacro{\temp}\egroup}%
alpar@464
  5642
    \else % many
alpar@464
  5643
      \expandafter\xdef\csname\the\macname\endcsname{%
alpar@464
  5644
         \bgroup\noexpand\macroargctxt
alpar@464
  5645
         \expandafter\noexpand\csname\the\macname xx\endcsname}%
alpar@464
  5646
      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
alpar@464
  5647
          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
alpar@464
  5648
      \expandafter\expandafter
alpar@464
  5649
      \expandafter\xdef
alpar@464
  5650
      \expandafter\expandafter
alpar@464
  5651
      \csname\the\macname xxx\endcsname
alpar@464
  5652
      \paramlist{%
alpar@464
  5653
          \egroup
alpar@464
  5654
          \noexpand\norecurse{\the\macname}%
alpar@464
  5655
          \noexpand\scanmacro{\temp}\egroup}%
alpar@464
  5656
    \fi
alpar@464
  5657
  \fi}
alpar@464
  5658
alpar@464
  5659
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
alpar@464
  5660
alpar@464
  5661
% \braceorline decides whether the next nonwhitespace character is a
alpar@464
  5662
% {.  If so it reads up to the closing }, if not, it reads the whole
alpar@464
  5663
% line.  Whatever was read is then fed to the next control sequence
alpar@464
  5664
% as an argument (by \parsebrace or \parsearg)
alpar@464
  5665
\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
alpar@464
  5666
\def\braceorlinexxx{%
alpar@464
  5667
  \ifx\nchar\bgroup\else
alpar@464
  5668
    \expandafter\parsearg
alpar@464
  5669
  \fi \next}
alpar@464
  5670
alpar@464
  5671
% We mant to disable all macros during \shipout so that they are not
alpar@464
  5672
% expanded by \write.
alpar@464
  5673
\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
alpar@464
  5674
  \edef\next{\macrolist}\expandafter\endgroup\next}
alpar@464
  5675
alpar@464
  5676
alpar@464
  5677
% @alias.
alpar@464
  5678
% We need some trickery to remove the optional spaces around the equal
alpar@464
  5679
% sign.  Just make them active and then expand them all to nothing.
alpar@464
  5680
\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx}
alpar@464
  5681
\def\aliasxxx #1{\aliasyyy#1\relax}
alpar@464
  5682
\def\aliasyyy #1=#2\relax{\ignoreactivespaces
alpar@464
  5683
\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=%
alpar@464
  5684
           \expandafter\noexpand\csname#2\endcsname}%
alpar@464
  5685
\expandafter\endgroup\next}
alpar@464
  5686
alpar@464
  5687
alpar@464
  5688
\message{cross references,}
alpar@464
  5689
% @xref etc.
alpar@464
  5690
alpar@464
  5691
\newwrite\auxfile
alpar@464
  5692
alpar@464
  5693
\newif\ifhavexrefs    % True if xref values are known.
alpar@464
  5694
\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
alpar@464
  5695
alpar@464
  5696
% @inforef is relatively simple.
alpar@464
  5697
\def\inforef #1{\inforefzzz #1,,,,**}
alpar@464
  5698
\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
alpar@464
  5699
  node \samp{\ignorespaces#1{}}}
alpar@464
  5700
alpar@464
  5701
% @node's job is to define \lastnode.
alpar@464
  5702
\def\node{\ENVcheck\parsearg\nodezzz}
alpar@464
  5703
\def\nodezzz#1{\nodexxx #1,\finishnodeparse}
alpar@464
  5704
\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}}
alpar@464
  5705
\let\nwnode=\node
alpar@464
  5706
\let\lastnode=\relax
alpar@464
  5707
alpar@464
  5708
% The sectioning commands (@chapter, etc.) call these.
alpar@464
  5709
\def\donoderef{%
alpar@464
  5710
  \ifx\lastnode\relax\else
alpar@464
  5711
    \expandafter\expandafter\expandafter\setref{\lastnode}%
alpar@464
  5712
      {Ysectionnumberandtype}%
alpar@464
  5713
    \global\let\lastnode=\relax
alpar@464
  5714
  \fi
alpar@464
  5715
}
alpar@464
  5716
\def\unnumbnoderef{%
alpar@464
  5717
  \ifx\lastnode\relax\else
alpar@464
  5718
    \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}%
alpar@464
  5719
    \global\let\lastnode=\relax
alpar@464
  5720
  \fi
alpar@464
  5721
}
alpar@464
  5722
\def\appendixnoderef{%
alpar@464
  5723
  \ifx\lastnode\relax\else
alpar@464
  5724
    \expandafter\expandafter\expandafter\setref{\lastnode}%
alpar@464
  5725
      {Yappendixletterandtype}%
alpar@464
  5726
    \global\let\lastnode=\relax
alpar@464
  5727
  \fi
alpar@464
  5728
}
alpar@464
  5729
alpar@464
  5730
alpar@464
  5731
% @anchor{NAME} -- define xref target at arbitrary point.
alpar@464
  5732
%
alpar@464
  5733
\newcount\savesfregister
alpar@464
  5734
\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
alpar@464
  5735
\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
alpar@464
  5736
\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
alpar@464
  5737
alpar@464
  5738
% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
alpar@464
  5739
% anchor), namely NAME-title (the corresponding @chapter/etc. name),
alpar@464
  5740
% NAME-pg (the page number), and NAME-snt (section number and type).
alpar@464
  5741
% Called from \foonoderef.
alpar@464
  5742
%
alpar@464
  5743
% We have to set \indexdummies so commands such as @code in a section
alpar@464
  5744
% title aren't expanded.  It would be nicer not to expand the titles in
alpar@464
  5745
% the first place, but there's so many layers that that is hard to do.
alpar@464
  5746
%
alpar@464
  5747
% Likewise, use \turnoffactive so that punctuation chars such as underscore
alpar@464
  5748
% and backslash work in node names.
alpar@464
  5749
%
alpar@464
  5750
\def\setref#1#2{{%
alpar@464
  5751
  \atdummies
alpar@464
  5752
  \pdfmkdest{#1}%
alpar@464
  5753
  %
alpar@464
  5754
  \turnoffactive
alpar@464
  5755
  \dosetq{#1-title}{Ytitle}%
alpar@464
  5756
  \dosetq{#1-pg}{Ypagenumber}%
alpar@464
  5757
  \dosetq{#1-snt}{#2}%
alpar@464
  5758
}}
alpar@464
  5759
alpar@464
  5760
% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
alpar@464
  5761
% the node name, #2 the name of the Info cross-reference, #3 the printed
alpar@464
  5762
% node name, #4 the name of the Info file, #5 the name of the printed
alpar@464
  5763
% manual.  All but the node name can be omitted.
alpar@464
  5764
%
alpar@464
  5765
\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
alpar@464
  5766
\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
alpar@464
  5767
\def\ref#1{\xrefX[#1,,,,,,,]}
alpar@464
  5768
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
alpar@464
  5769
  \unsepspaces
alpar@464
  5770
  \def\printedmanual{\ignorespaces #5}%
alpar@464
  5771
  \def\printednodename{\ignorespaces #3}%
alpar@464
  5772
  \setbox1=\hbox{\printedmanual}%
alpar@464
  5773
  \setbox0=\hbox{\printednodename}%
alpar@464
  5774
  \ifdim \wd0 = 0pt
alpar@464
  5775
    % No printed node name was explicitly given.
alpar@464
  5776
    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
alpar@464
  5777
      % Use the node name inside the square brackets.
alpar@464
  5778
      \def\printednodename{\ignorespaces #1}%
alpar@464
  5779
    \else
alpar@464
  5780
      % Use the actual chapter/section title appear inside
alpar@464
  5781
      % the square brackets.  Use the real section title if we have it.
alpar@464
  5782
      \ifdim \wd1 > 0pt
alpar@464
  5783
        % It is in another manual, so we don't have it.
alpar@464
  5784
        \def\printednodename{\ignorespaces #1}%
alpar@464
  5785
      \else
alpar@464
  5786
        \ifhavexrefs
alpar@464
  5787
          % We know the real title if we have the xref values.
alpar@464
  5788
          \def\printednodename{\refx{#1-title}{}}%
alpar@464
  5789
        \else
alpar@464
  5790
          % Otherwise just copy the Info node name.
alpar@464
  5791
          \def\printednodename{\ignorespaces #1}%
alpar@464
  5792
        \fi%
alpar@464
  5793
      \fi
alpar@464
  5794
    \fi
alpar@464
  5795
  \fi
alpar@464
  5796
  %
alpar@464
  5797
  % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
alpar@464
  5798
  % insert empty discretionaries after hyphens, which means that it will
alpar@464
  5799
  % not find a line break at a hyphen in a node names.  Since some manuals
alpar@464
  5800
  % are best written with fairly long node names, containing hyphens, this
alpar@464
  5801
  % is a loss.  Therefore, we give the text of the node name again, so it
alpar@464
  5802
  % is as if TeX is seeing it for the first time.
alpar@464
  5803
  \ifpdf
alpar@464
  5804
    \leavevmode
alpar@464
  5805
    \getfilename{#4}%
alpar@464
  5806
    {\turnoffactive \otherbackslash
alpar@464
  5807
     \ifnum\filenamelength>0
alpar@464
  5808
       \startlink attr{/Border [0 0 0]}%
alpar@464
  5809
         goto file{\the\filename.pdf} name{#1}%
alpar@464
  5810
     \else
alpar@464
  5811
       \startlink attr{/Border [0 0 0]}%
alpar@464
  5812
         goto name{#1}%
alpar@464
  5813
     \fi
alpar@464
  5814
    }%
alpar@464
  5815
    \linkcolor
alpar@464
  5816
  \fi
alpar@464
  5817
  %
alpar@464
  5818
  \ifdim \wd1 > 0pt
alpar@464
  5819
    \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}%
alpar@464
  5820
  \else
alpar@464
  5821
    % _ (for example) has to be the character _ for the purposes of the
alpar@464
  5822
    % control sequence corresponding to the node, but it has to expand
alpar@464
  5823
    % into the usual \leavevmode...\vrule stuff for purposes of
alpar@464
  5824
    % printing. So we \turnoffactive for the \refx-snt, back on for the
alpar@464
  5825
    % printing, back off for the \refx-pg.
alpar@464
  5826
    {\turnoffactive \otherbackslash
alpar@464
  5827
     % Only output a following space if the -snt ref is nonempty; for
alpar@464
  5828
     % @unnumbered and @anchor, it won't be.
alpar@464
  5829
     \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
alpar@464
  5830
     \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
alpar@464
  5831
    }%
alpar@464
  5832
    % output the `[mynode]' via a macro.
alpar@464
  5833
    \xrefprintnodename\printednodename
alpar@464
  5834
    %
alpar@464
  5835
    % But we always want a comma and a space:
alpar@464
  5836
    ,\space
alpar@464
  5837
    %
alpar@464
  5838
    % output the `page 3'.
alpar@464
  5839
    \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
alpar@464
  5840
  \fi
alpar@464
  5841
  \endlink
alpar@464
  5842
\endgroup}
alpar@464
  5843
alpar@464
  5844
% This macro is called from \xrefX for the `[nodename]' part of xref
alpar@464
  5845
% output.  It's a separate macro only so it can be changed more easily,
alpar@464
  5846
% since not square brackets don't work in some documents.  Particularly
alpar@464
  5847
% one that Bob is working on :).
alpar@464
  5848
%
alpar@464
  5849
\def\xrefprintnodename#1{[#1]}
alpar@464
  5850
alpar@464
  5851
% \dosetq is called from \setref to do the actual \write (\iflinks).
alpar@464
  5852
%
alpar@464
  5853
\def\dosetq#1#2{%
alpar@464
  5854
  {\let\folio=0%
alpar@464
  5855
   \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}%
alpar@464
  5856
   \iflinks \next \fi
alpar@464
  5857
  }%
alpar@464
  5858
}
alpar@464
  5859
alpar@464
  5860
% \internalsetq{foo}{page} expands into
alpar@464
  5861
%   CHARACTERS @xrdef{foo}{...expansion of \page...}
alpar@464
  5862
\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}}
alpar@464
  5863
alpar@464
  5864
% Things to be expanded by \internalsetq.
alpar@464
  5865
%
alpar@464
  5866
\def\Ypagenumber{\folio}
alpar@464
  5867
\def\Ytitle{\thissection}
alpar@464
  5868
\def\Ynothing{}
alpar@464
  5869
\def\Ysectionnumberandtype{%
alpar@464
  5870
  \ifnum\secno=0
alpar@464
  5871
    \putwordChapter@tie \the\chapno
alpar@464
  5872
  \else \ifnum\subsecno=0
alpar@464
  5873
    \putwordSection@tie \the\chapno.\the\secno
alpar@464
  5874
  \else \ifnum\subsubsecno=0
alpar@464
  5875
    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
alpar@464
  5876
  \else
alpar@464
  5877
    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
alpar@464
  5878
  \fi\fi\fi
alpar@464
  5879
}
alpar@464
  5880
alpar@464
  5881
\def\Yappendixletterandtype{%
alpar@464
  5882
  \ifnum\secno=0
alpar@464
  5883
     \putwordAppendix@tie @char\the\appendixno{}%
alpar@464
  5884
  \else \ifnum\subsecno=0
alpar@464
  5885
     \putwordSection@tie @char\the\appendixno.\the\secno
alpar@464
  5886
  \else \ifnum\subsubsecno=0
alpar@464
  5887
    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
alpar@464
  5888
  \else
alpar@464
  5889
    \putwordSection@tie
alpar@464
  5890
      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
alpar@464
  5891
  \fi\fi\fi
alpar@464
  5892
}
alpar@464
  5893
alpar@464
  5894
% Use TeX 3.0's \inputlineno to get the line number, for better error
alpar@464
  5895
% messages, but if we're using an old version of TeX, don't do anything.
alpar@464
  5896
%
alpar@464
  5897
\ifx\inputlineno\thisisundefined
alpar@464
  5898
  \let\linenumber = \empty % Pre-3.0.
alpar@464
  5899
\else
alpar@464
  5900
  \def\linenumber{\the\inputlineno:\space}
alpar@464
  5901
\fi
alpar@464
  5902
alpar@464
  5903
% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
alpar@464
  5904
% If its value is nonempty, SUFFIX is output afterward.
alpar@464
  5905
%
alpar@464
  5906
\def\refx#1#2{%
alpar@464
  5907
  {%
alpar@464
  5908
    \indexnofonts
alpar@464
  5909
    \otherbackslash
alpar@464
  5910
    \expandafter\global\expandafter\let\expandafter\thisrefX
alpar@464
  5911
      \csname X#1\endcsname
alpar@464
  5912
  }%
alpar@464
  5913
  \ifx\thisrefX\relax
alpar@464
  5914
    % If not defined, say something at least.
alpar@464
  5915
    \angleleft un\-de\-fined\angleright
alpar@464
  5916
    \iflinks
alpar@464
  5917
      \ifhavexrefs
alpar@464
  5918
        \message{\linenumber Undefined cross reference `#1'.}%
alpar@464
  5919
      \else
alpar@464
  5920
        \ifwarnedxrefs\else
alpar@464
  5921
          \global\warnedxrefstrue
alpar@464
  5922
          \message{Cross reference values unknown; you must run TeX again.}%
alpar@464
  5923
        \fi
alpar@464
  5924
      \fi
alpar@464
  5925
    \fi
alpar@464
  5926
  \else
alpar@464
  5927
    % It's defined, so just use it.
alpar@464
  5928
    \thisrefX
alpar@464
  5929
  \fi
alpar@464
  5930
  #2% Output the suffix in any case.
alpar@464
  5931
}
alpar@464
  5932
alpar@464
  5933
% This is the macro invoked by entries in the aux file.
alpar@464
  5934
%
alpar@464
  5935
\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname}
alpar@464
  5936
alpar@464
  5937
% Read the last existing aux file, if any.  No error if none exists.
alpar@464
  5938
\def\readauxfile{\begingroup
alpar@464
  5939
  \catcode`\^^@=\other
alpar@464
  5940
  \catcode`\^^A=\other
alpar@464
  5941
  \catcode`\^^B=\other
alpar@464
  5942
  \catcode`\^^C=\other
alpar@464
  5943
  \catcode`\^^D=\other
alpar@464
  5944
  \catcode`\^^E=\other
alpar@464
  5945
  \catcode`\^^F=\other
alpar@464
  5946
  \catcode`\^^G=\other
alpar@464
  5947
  \catcode`\^^H=\other
alpar@464
  5948
  \catcode`\^^K=\other
alpar@464
  5949
  \catcode`\^^L=\other
alpar@464
  5950
  \catcode`\^^N=\other
alpar@464
  5951
  \catcode`\^^P=\other
alpar@464
  5952
  \catcode`\^^Q=\other
alpar@464
  5953
  \catcode`\^^R=\other
alpar@464
  5954
  \catcode`\^^S=\other
alpar@464
  5955
  \catcode`\^^T=\other
alpar@464
  5956
  \catcode`\^^U=\other
alpar@464
  5957
  \catcode`\^^V=\other
alpar@464
  5958
  \catcode`\^^W=\other
alpar@464
  5959
  \catcode`\^^X=\other
alpar@464
  5960
  \catcode`\^^Z=\other
alpar@464
  5961
  \catcode`\^^[=\other
alpar@464
  5962
  \catcode`\^^\=\other
alpar@464
  5963
  \catcode`\^^]=\other
alpar@464
  5964
  \catcode`\^^^=\other
alpar@464
  5965
  \catcode`\^^_=\other
alpar@464
  5966
  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
alpar@464
  5967
  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
alpar@464
  5968
  % supported in the main text, it doesn't seem desirable.  Furthermore,
alpar@464
  5969
  % that is not enough: for node names that actually contain a ^
alpar@464
  5970
  % character, we would end up writing a line like this: 'xrdef {'hat
alpar@464
  5971
  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
alpar@464
  5972
  % argument, and \hat is not an expandable control sequence.  It could
alpar@464
  5973
  % all be worked out, but why?  Either we support ^^ or we don't.
alpar@464
  5974
  %
alpar@464
  5975
  % The other change necessary for this was to define \auxhat:
alpar@464
  5976
  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
alpar@464
  5977
  % and then to call \auxhat in \setq.
alpar@464
  5978
  %
alpar@464
  5979
  \catcode`\^=\other
alpar@464
  5980
  %
alpar@464
  5981
  % Special characters.  Should be turned off anyway, but...
alpar@464
  5982
  \catcode`\~=\other
alpar@464
  5983
  \catcode`\[=\other
alpar@464
  5984
  \catcode`\]=\other
alpar@464
  5985
  \catcode`\"=\other
alpar@464
  5986
  \catcode`\_=\other
alpar@464
  5987
  \catcode`\|=\other
alpar@464
  5988
  \catcode`\<=\other
alpar@464
  5989
  \catcode`\>=\other
alpar@464
  5990
  \catcode`\$=\other
alpar@464
  5991
  \catcode`\#=\other
alpar@464
  5992
  \catcode`\&=\other
alpar@464
  5993
  \catcode`\%=\other
alpar@464
  5994
  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
alpar@464
  5995
  %
alpar@464
  5996
  % Make the characters 128-255 be printing characters
alpar@464
  5997
  {%
alpar@464
  5998
    \count 1=128
alpar@464
  5999
    \def\loop{%
alpar@464
  6000
      \catcode\count 1=\other
alpar@464
  6001
      \advance\count 1 by 1
alpar@464
  6002
      \ifnum \count 1<256 \loop \fi
alpar@464
  6003
    }%
alpar@464
  6004
  }%
alpar@464
  6005
  %
alpar@464
  6006
  % Turn off \ as an escape so we do not lose on
alpar@464
  6007
  % entries which were dumped with control sequences in their names.
alpar@464
  6008
  % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^
alpar@464
  6009
  % Reference to such entries still does not work the way one would wish,
alpar@464
  6010
  % but at least they do not bomb out when the aux file is read in.
alpar@464
  6011
  \catcode`\\=\other
alpar@464
  6012
  %
alpar@464
  6013
  % @ is our escape character in .aux files.
alpar@464
  6014
  \catcode`\{=1
alpar@464
  6015
  \catcode`\}=2
alpar@464
  6016
  \catcode`\@=0
alpar@464
  6017
  %
alpar@464
  6018
  \openin 1 \jobname.aux
alpar@464
  6019
  \ifeof 1 \else
alpar@464
  6020
    \closein 1
alpar@464
  6021
    \input \jobname.aux
alpar@464
  6022
    \global\havexrefstrue
alpar@464
  6023
  \fi
alpar@464
  6024
  % Open the new aux file.  TeX will close it automatically at exit.
alpar@464
  6025
  \openout\auxfile=\jobname.aux
alpar@464
  6026
\endgroup}
alpar@464
  6027
alpar@464
  6028
alpar@464
  6029
% Footnotes.
alpar@464
  6030
alpar@464
  6031
\newcount \footnoteno
alpar@464
  6032
alpar@464
  6033
% The trailing space in the following definition for supereject is
alpar@464
  6034
% vital for proper filling; pages come out unaligned when you do a
alpar@464
  6035
% pagealignmacro call if that space before the closing brace is
alpar@464
  6036
% removed. (Generally, numeric constants should always be followed by a
alpar@464
  6037
% space to prevent strange expansion errors.)
alpar@464
  6038
\def\supereject{\par\penalty -20000\footnoteno =0 }
alpar@464
  6039
alpar@464
  6040
% @footnotestyle is meaningful for info output only.
alpar@464
  6041
\let\footnotestyle=\comment
alpar@464
  6042
alpar@464
  6043
\let\ptexfootnote=\footnote
alpar@464
  6044
alpar@464
  6045
{\catcode `\@=11
alpar@464
  6046
%
alpar@464
  6047
% Auto-number footnotes.  Otherwise like plain.
alpar@464
  6048
\gdef\footnote{%
alpar@464
  6049
  \let\indent=\ptexindent
alpar@464
  6050
  \global\advance\footnoteno by \@ne
alpar@464
  6051
  \edef\thisfootno{$^{\the\footnoteno}$}%
alpar@464
  6052
  %
alpar@464
  6053
  % In case the footnote comes at the end of a sentence, preserve the
alpar@464
  6054
  % extra spacing after we do the footnote number.
alpar@464
  6055
  \let\@sf\empty
alpar@464
  6056
  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
alpar@464
  6057
  %
alpar@464
  6058
  % Remove inadvertent blank space before typesetting the footnote number.
alpar@464
  6059
  \unskip
alpar@464
  6060
  \thisfootno\@sf
alpar@464
  6061
  \dofootnote
alpar@464
  6062
}%
alpar@464
  6063
alpar@464
  6064
% Don't bother with the trickery in plain.tex to not require the
alpar@464
  6065
% footnote text as a parameter.  Our footnotes don't need to be so general.
alpar@464
  6066
%
alpar@464
  6067
% Oh yes, they do; otherwise, @ifset and anything else that uses
alpar@464
  6068
% \parseargline fail inside footnotes because the tokens are fixed when
alpar@464
  6069
% the footnote is read.  --karl, 16nov96.
alpar@464
  6070
%
alpar@464
  6071
% The start of the footnote looks usually like this:
alpar@464
  6072
\gdef\startfootins{\insert\footins\bgroup}
alpar@464
  6073
%
alpar@464
  6074
% ... but this macro is redefined inside @multitable.
alpar@464
  6075
%
alpar@464
  6076
\gdef\dofootnote{%
alpar@464
  6077
  \startfootins
alpar@464
  6078
  % We want to typeset this text as a normal paragraph, even if the
alpar@464
  6079
  % footnote reference occurs in (for example) a display environment.
alpar@464
  6080
  % So reset some parameters.
alpar@464
  6081
  \hsize=\pagewidth
alpar@464
  6082
  \interlinepenalty\interfootnotelinepenalty
alpar@464
  6083
  \splittopskip\ht\strutbox % top baseline for broken footnotes
alpar@464
  6084
  \splitmaxdepth\dp\strutbox
alpar@464
  6085
  \floatingpenalty\@MM
alpar@464
  6086
  \leftskip\z@skip
alpar@464
  6087
  \rightskip\z@skip
alpar@464
  6088
  \spaceskip\z@skip
alpar@464
  6089
  \xspaceskip\z@skip
alpar@464
  6090
  \parindent\defaultparindent
alpar@464
  6091
  %
alpar@464
  6092
  \smallfonts \rm
alpar@464
  6093
  %
alpar@464
  6094
  % Because we use hanging indentation in footnotes, a @noindent appears
alpar@464
  6095
  % to exdent this text, so make it be a no-op.  makeinfo does not use
alpar@464
  6096
  % hanging indentation so @noindent can still be needed within footnote
alpar@464
  6097
  % text after an @example or the like (not that this is good style).
alpar@464
  6098
  \let\noindent = \relax
alpar@464
  6099
  %
alpar@464
  6100
  % Hang the footnote text off the number.  Use \everypar in case the
alpar@464
  6101
  % footnote extends for more than one paragraph.
alpar@464
  6102
  \everypar = {\hang}%
alpar@464
  6103
  \textindent{\thisfootno}%
alpar@464
  6104
  %
alpar@464
  6105
  % Don't crash into the line above the footnote text.  Since this
alpar@464
  6106
  % expands into a box, it must come within the paragraph, lest it
alpar@464
  6107
  % provide a place where TeX can split the footnote.
alpar@464
  6108
  \footstrut
alpar@464
  6109
  \futurelet\next\fo@t
alpar@464
  6110
}
alpar@464
  6111
}%end \catcode `\@=11
alpar@464
  6112
alpar@464
  6113
% @| inserts a changebar to the left of the current line.  It should
alpar@464
  6114
% surround any changed text.  This approach does *not* work if the
alpar@464
  6115
% change spans more than two lines of output.  To handle that, we would
alpar@464
  6116
% have adopt a much more difficult approach (putting marks into the main
alpar@464
  6117
% vertical list for the beginning and end of each change).
alpar@464
  6118
%
alpar@464
  6119
\def\|{%
alpar@464
  6120
  % \vadjust can only be used in horizontal mode.
alpar@464
  6121
  \leavevmode
alpar@464
  6122
  %
alpar@464
  6123
  % Append this vertical mode material after the current line in the output.
alpar@464
  6124
  \vadjust{%
alpar@464
  6125
    % We want to insert a rule with the height and depth of the current
alpar@464
  6126
    % leading; that is exactly what \strutbox is supposed to record.
alpar@464
  6127
    \vskip-\baselineskip
alpar@464
  6128
    %
alpar@464
  6129
    % \vadjust-items are inserted at the left edge of the type.  So
alpar@464
  6130
    % the \llap here moves out into the left-hand margin.
alpar@464
  6131
    \llap{%
alpar@464
  6132
      %
alpar@464
  6133
      % For a thicker or thinner bar, change the `1pt'.
alpar@464
  6134
      \vrule height\baselineskip width1pt
alpar@464
  6135
      %
alpar@464
  6136
      % This is the space between the bar and the text.
alpar@464
  6137
      \hskip 12pt
alpar@464
  6138
    }%
alpar@464
  6139
  }%
alpar@464
  6140
}
alpar@464
  6141
alpar@464
  6142
% For a final copy, take out the rectangles
alpar@464
  6143
% that mark overfull boxes (in case you have decided
alpar@464
  6144
% that the text looks ok even though it passes the margin).
alpar@464
  6145
%
alpar@464
  6146
\def\finalout{\overfullrule=0pt}
alpar@464
  6147
alpar@464
  6148
% @image.  We use the macros from epsf.tex to support this.
alpar@464
  6149
% If epsf.tex is not installed and @image is used, we complain.
alpar@464
  6150
%
alpar@464
  6151
% Check for and read epsf.tex up front.  If we read it only at @image
alpar@464
  6152
% time, we might be inside a group, and then its definitions would get
alpar@464
  6153
% undone and the next image would fail.
alpar@464
  6154
\openin 1 = epsf.tex
alpar@464
  6155
\ifeof 1 \else
alpar@464
  6156
  \closein 1
alpar@464
  6157
  % Do not bother showing banner with epsf.tex v2.7k (available in
alpar@464
  6158
  % doc/epsf.tex and on ctan).
alpar@464
  6159
  \def\epsfannounce{\toks0 = }%
alpar@464
  6160
  \input epsf.tex
alpar@464
  6161
\fi
alpar@464
  6162
%
alpar@464
  6163
% We will only complain once about lack of epsf.tex.
alpar@464
  6164
\newif\ifwarnednoepsf
alpar@464
  6165
\newhelp\noepsfhelp{epsf.tex must be installed for images to
alpar@464
  6166
  work.  It is also included in the Texinfo distribution, or you can get
alpar@464
  6167
  it from ftp://tug.org/tex/epsf.tex.}
alpar@464
  6168
%
alpar@464
  6169
\def\image#1{%
alpar@464
  6170
  \ifx\epsfbox\undefined
alpar@464
  6171
    \ifwarnednoepsf \else
alpar@464
  6172
      \errhelp = \noepsfhelp
alpar@464
  6173
      \errmessage{epsf.tex not found, images will be ignored}%
alpar@464
  6174
      \global\warnednoepsftrue
alpar@464
  6175
    \fi
alpar@464
  6176
  \else
alpar@464
  6177
    \imagexxx #1,,,,,\finish
alpar@464
  6178
  \fi
alpar@464
  6179
}
alpar@464
  6180
%
alpar@464
  6181
% Arguments to @image:
alpar@464
  6182
% #1 is (mandatory) image filename; we tack on .eps extension.
alpar@464
  6183
% #2 is (optional) width, #3 is (optional) height.
alpar@464
  6184
% #4 is (ignored optional) html alt text.
alpar@464
  6185
% #5 is (ignored optional) extension.
alpar@464
  6186
% #6 is just the usual extra ignored arg for parsing this stuff.
alpar@464
  6187
\newif\ifimagevmode
alpar@464
  6188
\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
alpar@464
  6189
  \catcode`\^^M = 5     % in case we're inside an example
alpar@464
  6190
  \normalturnoffactive  % allow _ et al. in names
alpar@464
  6191
  % If the image is by itself, center it.
alpar@464
  6192
  \ifvmode
alpar@464
  6193
    \imagevmodetrue
alpar@464
  6194
    \nobreak\bigskip
alpar@464
  6195
    % Usually we'll have text after the image which will insert
alpar@464
  6196
    % \parskip glue, so insert it here too to equalize the space
alpar@464
  6197
    % above and below.
alpar@464
  6198
    \nobreak\vskip\parskip
alpar@464
  6199
    \nobreak
alpar@464
  6200
    \line\bgroup\hss
alpar@464
  6201
  \fi
alpar@464
  6202
  %
alpar@464
  6203
  % Output the image.
alpar@464
  6204
  \ifpdf
alpar@464
  6205
    \dopdfimage{#1}{#2}{#3}%
alpar@464
  6206
  \else
alpar@464
  6207
    % \epsfbox itself resets \epsf?size at each figure.
alpar@464
  6208
    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
alpar@464
  6209
    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
alpar@464
  6210
    \epsfbox{#1.eps}%
alpar@464
  6211
  \fi
alpar@464
  6212
  %
alpar@464
  6213
  \ifimagevmode \hss \egroup \bigbreak \fi  % space after the image
alpar@464
  6214
\endgroup}
alpar@464
  6215
alpar@464
  6216
alpar@464
  6217
\message{localization,}
alpar@464
  6218
% and i18n.
alpar@464
  6219
alpar@464
  6220
% @documentlanguage is usually given very early, just after
alpar@464
  6221
% @setfilename.  If done too late, it may not override everything
alpar@464
  6222
% properly.  Single argument is the language abbreviation.
alpar@464
  6223
% It would be nice if we could set up a hyphenation file here.
alpar@464
  6224
%
alpar@464
  6225
\def\documentlanguage{\parsearg\dodocumentlanguage}
alpar@464
  6226
\def\dodocumentlanguage#1{%
alpar@464
  6227
  \tex % read txi-??.tex file in plain TeX.
alpar@464
  6228
  % Read the file if it exists.
alpar@464
  6229
  \openin 1 txi-#1.tex
alpar@464
  6230
  \ifeof1
alpar@464
  6231
    \errhelp = \nolanghelp
alpar@464
  6232
    \errmessage{Cannot read language file txi-#1.tex}%
alpar@464
  6233
    \let\temp = \relax
alpar@464
  6234
  \else
alpar@464
  6235
    \def\temp{\input txi-#1.tex }%
alpar@464
  6236
  \fi
alpar@464
  6237
  \temp
alpar@464
  6238
  \endgroup
alpar@464
  6239
}
alpar@464
  6240
\newhelp\nolanghelp{The given language definition file cannot be found or
alpar@464
  6241
is empty.  Maybe you need to install it?  In the current directory
alpar@464
  6242
should work if nowhere else does.}
alpar@464
  6243
alpar@464
  6244
alpar@464
  6245
% @documentencoding should change something in TeX eventually, most
alpar@464
  6246
% likely, but for now just recognize it.
alpar@464
  6247
\let\documentencoding = \comment
alpar@464
  6248
alpar@464
  6249
alpar@464
  6250
% Page size parameters.
alpar@464
  6251
%
alpar@464
  6252
\newdimen\defaultparindent \defaultparindent = 15pt
alpar@464
  6253
alpar@464
  6254
\chapheadingskip = 15pt plus 4pt minus 2pt
alpar@464
  6255
\secheadingskip = 12pt plus 3pt minus 2pt
alpar@464
  6256
\subsecheadingskip = 9pt plus 2pt minus 2pt
alpar@464
  6257
alpar@464
  6258
% Prevent underfull vbox error messages.
alpar@464
  6259
\vbadness = 10000
alpar@464
  6260
alpar@464
  6261
% Don't be so finicky about underfull hboxes, either.
alpar@464
  6262
\hbadness = 2000
alpar@464
  6263
alpar@464
  6264
% Following George Bush, just get rid of widows and orphans.
alpar@464
  6265
\widowpenalty=10000
alpar@464
  6266
\clubpenalty=10000
alpar@464
  6267
alpar@464
  6268
% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
alpar@464
  6269
% using an old version of TeX, don't do anything.  We want the amount of
alpar@464
  6270
% stretch added to depend on the line length, hence the dependence on
alpar@464
  6271
% \hsize.  We call this whenever the paper size is set.
alpar@464
  6272
%
alpar@464
  6273
\def\setemergencystretch{%
alpar@464
  6274
  \ifx\emergencystretch\thisisundefined
alpar@464
  6275
    % Allow us to assign to \emergencystretch anyway.
alpar@464
  6276
    \def\emergencystretch{\dimen0}%
alpar@464
  6277
  \else
alpar@464
  6278
    \emergencystretch = .15\hsize
alpar@464
  6279
  \fi
alpar@464
  6280
}
alpar@464
  6281
alpar@464
  6282
% Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
alpar@464
  6283
% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8)
alpar@464
  6284
% physical page width.
alpar@464
  6285
%
alpar@464
  6286
% We also call \setleading{\textleading}, so the caller should define
alpar@464
  6287
% \textleading.  The caller should also set \parskip.
alpar@464
  6288
%
alpar@464
  6289
\def\internalpagesizes#1#2#3#4#5#6#7#8{%
alpar@464
  6290
  \voffset = #3\relax
alpar@464
  6291
  \topskip = #6\relax
alpar@464
  6292
  \splittopskip = \topskip
alpar@464
  6293
  %
alpar@464
  6294
  \vsize = #1\relax
alpar@464
  6295
  \advance\vsize by \topskip
alpar@464
  6296
  \outervsize = \vsize
alpar@464
  6297
  \advance\outervsize by 2\topandbottommargin
alpar@464
  6298
  \pageheight = \vsize
alpar@464
  6299
  %
alpar@464
  6300
  \hsize = #2\relax
alpar@464
  6301
  \outerhsize = \hsize
alpar@464
  6302
  \advance\outerhsize by 0.5in
alpar@464
  6303
  \pagewidth = \hsize
alpar@464
  6304
  %
alpar@464
  6305
  \normaloffset = #4\relax
alpar@464
  6306
  \bindingoffset = #5\relax
alpar@464
  6307
  %
alpar@464
  6308
  \ifpdf
alpar@464
  6309
    \pdfpageheight #7\relax
alpar@464
  6310
    \pdfpagewidth #8\relax
alpar@464
  6311
  \fi
alpar@464
  6312
  %
alpar@464
  6313
  \setleading{\textleading}
alpar@464
  6314
  %
alpar@464
  6315
  \parindent = \defaultparindent
alpar@464
  6316
  \setemergencystretch
alpar@464
  6317
}
alpar@464
  6318
alpar@464
  6319
% @letterpaper (the default).
alpar@464
  6320
\def\letterpaper{{\globaldefs = 1
alpar@464
  6321
  \parskip = 3pt plus 2pt minus 1pt
alpar@464
  6322
  \textleading = 13.2pt
alpar@464
  6323
  %
alpar@464
  6324
  % If page is nothing but text, make it come out even.
alpar@464
  6325
  \internalpagesizes{46\baselineskip}{6in}%
alpar@464
  6326
                    {\voffset}{.25in}%
alpar@464
  6327
                    {\bindingoffset}{36pt}%
alpar@464
  6328
                    {11in}{8.5in}%
alpar@464
  6329
}}
alpar@464
  6330
alpar@464
  6331
% Use @smallbook to reset parameters for 7x9.5 (or so) format.
alpar@464
  6332
\def\smallbook{{\globaldefs = 1
alpar@464
  6333
  \parskip = 2pt plus 1pt
alpar@464
  6334
  \textleading = 12pt
alpar@464
  6335
  %
alpar@464
  6336
  \internalpagesizes{7.5in}{5in}%
alpar@464
  6337
                    {\voffset}{.25in}%
alpar@464
  6338
                    {\bindingoffset}{16pt}%
alpar@464
  6339
                    {9.25in}{7in}%
alpar@464
  6340
  %
alpar@464
  6341
  \lispnarrowing = 0.3in
alpar@464
  6342
  \tolerance = 700
alpar@464
  6343
  \hfuzz = 1pt
alpar@464
  6344
  \contentsrightmargin = 0pt
alpar@464
  6345
  \defbodyindent = .5cm
alpar@464
  6346
}}
alpar@464
  6347
alpar@464
  6348
% Use @afourpaper to print on European A4 paper.
alpar@464
  6349
\def\afourpaper{{\globaldefs = 1
alpar@464
  6350
  \parskip = 3pt plus 2pt minus 1pt
alpar@464
  6351
  \textleading = 13.2pt
alpar@464
  6352
  %
alpar@464
  6353
  % Double-side printing via postscript on Laserjet 4050
alpar@464
  6354
  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
alpar@464
  6355
  % To change the settings for a different printer or situation, adjust
alpar@464
  6356
  % \normaloffset until the front-side and back-side texts align.  Then
alpar@464
  6357
  % do the same for \bindingoffset.  You can set these for testing in
alpar@464
  6358
  % your texinfo source file like this:
alpar@464
  6359
  % @tex
alpar@464
  6360
  % \global\normaloffset = -6mm
alpar@464
  6361
  % \global\bindingoffset = 10mm
alpar@464
  6362
  % @end tex
alpar@464
  6363
  \internalpagesizes{51\baselineskip}{160mm}
alpar@464
  6364
                    {\voffset}{\hoffset}%
alpar@464
  6365
                    {\bindingoffset}{44pt}%
alpar@464
  6366
                    {297mm}{210mm}%
alpar@464
  6367
  %
alpar@464
  6368
  \tolerance = 700
alpar@464
  6369
  \hfuzz = 1pt
alpar@464
  6370
  \contentsrightmargin = 0pt
alpar@464
  6371
  \defbodyindent = 5mm
alpar@464
  6372
}}
alpar@464
  6373
alpar@464
  6374
% Use @afivepaper to print on European A5 paper.
alpar@464
  6375
% From romildo@urano.iceb.ufop.br, 2 July 2000.
alpar@464
  6376
% He also recommends making @example and @lisp be small.
alpar@464
  6377
\def\afivepaper{{\globaldefs = 1
alpar@464
  6378
  \parskip = 2pt plus 1pt minus 0.1pt
alpar@464
  6379
  \textleading = 12.5pt
alpar@464
  6380
  %
alpar@464
  6381
  \internalpagesizes{160mm}{120mm}%
alpar@464
  6382
                    {\voffset}{\hoffset}%
alpar@464
  6383
                    {\bindingoffset}{8pt}%
alpar@464
  6384
                    {210mm}{148mm}%
alpar@464
  6385
  %
alpar@464
  6386
  \lispnarrowing = 0.2in
alpar@464
  6387
  \tolerance = 800
alpar@464
  6388
  \hfuzz = 1.2pt
alpar@464
  6389
  \contentsrightmargin = 0pt
alpar@464
  6390
  \defbodyindent = 2mm
alpar@464
  6391
  \tableindent = 12mm
alpar@464
  6392
}}
alpar@464
  6393
alpar@464
  6394
% A specific text layout, 24x15cm overall, intended for A4 paper.
alpar@464
  6395
\def\afourlatex{{\globaldefs = 1
alpar@464
  6396
  \afourpaper
alpar@464
  6397
  \internalpagesizes{237mm}{150mm}%
alpar@464
  6398
                    {\voffset}{4.6mm}%
alpar@464
  6399
                    {\bindingoffset}{7mm}%
alpar@464
  6400
                    {297mm}{210mm}%
alpar@464
  6401
  %
alpar@464
  6402
  % Must explicitly reset to 0 because we call \afourpaper.
alpar@464
  6403
  \globaldefs = 0
alpar@464
  6404
}}
alpar@464
  6405
alpar@464
  6406
% Use @afourwide to print on A4 paper in landscape format.
alpar@464
  6407
\def\afourwide{{\globaldefs = 1
alpar@464
  6408
  \afourpaper
alpar@464
  6409
  \internalpagesizes{241mm}{165mm}%
alpar@464
  6410
                    {\voffset}{-2.95mm}%
alpar@464
  6411
                    {\bindingoffset}{7mm}%
alpar@464
  6412
                    {297mm}{210mm}%
alpar@464
  6413
  \globaldefs = 0
alpar@464
  6414
}}
alpar@464
  6415
alpar@464
  6416
% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
alpar@464
  6417
% Perhaps we should allow setting the margins, \topskip, \parskip,
alpar@464
  6418
% and/or leading, also. Or perhaps we should compute them somehow.
alpar@464
  6419
%
alpar@464
  6420
\def\pagesizes{\parsearg\pagesizesxxx}
alpar@464
  6421
\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish}
alpar@464
  6422
\def\pagesizesyyy#1,#2,#3\finish{{%
alpar@464
  6423
  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
alpar@464
  6424
  \globaldefs = 1
alpar@464
  6425
  %
alpar@464
  6426
  \parskip = 3pt plus 2pt minus 1pt
alpar@464
  6427
  \setleading{\textleading}%
alpar@464
  6428
  %
alpar@464
  6429
  \dimen0 = #1
alpar@464
  6430
  \advance\dimen0 by \voffset
alpar@464
  6431
  %
alpar@464
  6432
  \dimen2 = \hsize
alpar@464
  6433
  \advance\dimen2 by \normaloffset
alpar@464
  6434
  %
alpar@464
  6435
  \internalpagesizes{#1}{\hsize}%
alpar@464
  6436
                    {\voffset}{\normaloffset}%
alpar@464
  6437
                    {\bindingoffset}{44pt}%
alpar@464
  6438
                    {\dimen0}{\dimen2}%
alpar@464
  6439
}}
alpar@464
  6440
alpar@464
  6441
% Set default to letter.
alpar@464
  6442
%
alpar@464
  6443
\letterpaper
alpar@464
  6444
alpar@464
  6445
alpar@464
  6446
\message{and turning on texinfo input format.}
alpar@464
  6447
alpar@464
  6448
% Define macros to output various characters with catcode for normal text.
alpar@464
  6449
\catcode`\"=\other
alpar@464
  6450
\catcode`\~=\other
alpar@464
  6451
\catcode`\^=\other
alpar@464
  6452
\catcode`\_=\other
alpar@464
  6453
\catcode`\|=\other
alpar@464
  6454
\catcode`\<=\other
alpar@464
  6455
\catcode`\>=\other
alpar@464
  6456
\catcode`\+=\other
alpar@464
  6457
\catcode`\$=\other
alpar@464
  6458
\def\normaldoublequote{"}
alpar@464
  6459
\def\normaltilde{~}
alpar@464
  6460
\def\normalcaret{^}
alpar@464
  6461
\def\normalunderscore{_}
alpar@464
  6462
\def\normalverticalbar{|}
alpar@464
  6463
\def\normalless{<}
alpar@464
  6464
\def\normalgreater{>}
alpar@464
  6465
\def\normalplus{+}
alpar@464
  6466
\def\normaldollar{$}%$ font-lock fix
alpar@464
  6467
alpar@464
  6468
% This macro is used to make a character print one way in ttfont
alpar@464
  6469
% where it can probably just be output, and another way in other fonts,
alpar@464
  6470
% where something hairier probably needs to be done.
alpar@464
  6471
%
alpar@464
  6472
% #1 is what to print if we are indeed using \tt; #2 is what to print
alpar@464
  6473
% otherwise.  Since all the Computer Modern typewriter fonts have zero
alpar@464
  6474
% interword stretch (and shrink), and it is reasonable to expect all
alpar@464
  6475
% typewriter fonts to have this, we can check that font parameter.
alpar@464
  6476
%
alpar@464
  6477
\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
alpar@464
  6478
alpar@464
  6479
% Same as above, but check for italic font.  Actually this also catches
alpar@464
  6480
% non-italic slanted fonts since it is impossible to distinguish them from
alpar@464
  6481
% italic fonts.  But since this is only used by $ and it uses \sl anyway
alpar@464
  6482
% this is not a problem.
alpar@464
  6483
\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
alpar@464
  6484
alpar@464
  6485
% Turn off all special characters except @
alpar@464
  6486
% (and those which the user can use as if they were ordinary).
alpar@464
  6487
% Most of these we simply print from the \tt font, but for some, we can
alpar@464
  6488
% use math or other variants that look better in normal text.
alpar@464
  6489
alpar@464
  6490
\catcode`\"=\active
alpar@464
  6491
\def\activedoublequote{{\tt\char34}}
alpar@464
  6492
\let"=\activedoublequote
alpar@464
  6493
\catcode`\~=\active
alpar@464
  6494
\def~{{\tt\char126}}
alpar@464
  6495
\chardef\hat=`\^
alpar@464
  6496
\catcode`\^=\active
alpar@464
  6497
\def^{{\tt \hat}}
alpar@464
  6498
alpar@464
  6499
\catcode`\_=\active
alpar@464
  6500
\def_{\ifusingtt\normalunderscore\_}
alpar@464
  6501
% Subroutine for the previous macro.
alpar@464
  6502
\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
alpar@464
  6503
alpar@464
  6504
\catcode`\|=\active
alpar@464
  6505
\def|{{\tt\char124}}
alpar@464
  6506
\chardef \less=`\<
alpar@464
  6507
\catcode`\<=\active
alpar@464
  6508
\def<{{\tt \less}}
alpar@464
  6509
\chardef \gtr=`\>
alpar@464
  6510
\catcode`\>=\active
alpar@464
  6511
\def>{{\tt \gtr}}
alpar@464
  6512
\catcode`\+=\active
alpar@464
  6513
\def+{{\tt \char 43}}
alpar@464
  6514
\catcode`\$=\active
alpar@464
  6515
\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
alpar@464
  6516
alpar@464
  6517
% Set up an active definition for =, but don't enable it most of the time.
alpar@464
  6518
{\catcode`\==\active
alpar@464
  6519
\global\def={{\tt \char 61}}}
alpar@464
  6520
alpar@464
  6521
\catcode`+=\active
alpar@464
  6522
\catcode`\_=\active
alpar@464
  6523
alpar@464
  6524
% If a .fmt file is being used, characters that might appear in a file
alpar@464
  6525
% name cannot be active until we have parsed the command line.
alpar@464
  6526
% So turn them off again, and have \everyjob (or @setfilename) turn them on.
alpar@464
  6527
% \otherifyactive is called near the end of this file.
alpar@464
  6528
\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
alpar@464
  6529
alpar@464
  6530
\catcode`\@=0
alpar@464
  6531
alpar@464
  6532
% \rawbackslashxx outputs one backslash character in current font,
alpar@464
  6533
% as in \char`\\.
alpar@464
  6534
\global\chardef\rawbackslashxx=`\\
alpar@464
  6535
alpar@464
  6536
% \rawbackslash defines an active \ to do \rawbackslashxx.
alpar@464
  6537
% \otherbackslash defines an active \ to be a literal `\' character with
alpar@464
  6538
% catcode other.
alpar@464
  6539
{\catcode`\\=\active
alpar@464
  6540
 @gdef@rawbackslash{@let\=@rawbackslashxx}
alpar@464
  6541
 @gdef@otherbackslash{@let\=@realbackslash}
alpar@464
  6542
}
alpar@464
  6543
alpar@464
  6544
% \realbackslash is an actual character `\' with catcode other.
alpar@464
  6545
{\catcode`\\=\other @gdef@realbackslash{\}}
alpar@464
  6546
alpar@464
  6547
% \normalbackslash outputs one backslash in fixed width font.
alpar@464
  6548
\def\normalbackslash{{\tt\rawbackslashxx}}
alpar@464
  6549
alpar@464
  6550
\catcode`\\=\active
alpar@464
  6551
alpar@464
  6552
% Used sometimes to turn off (effectively) the active characters
alpar@464
  6553
% even after parsing them.
alpar@464
  6554
@def@turnoffactive{%
alpar@464
  6555
  @let"=@normaldoublequote
alpar@464
  6556
  @let\=@realbackslash
alpar@464
  6557
  @let~=@normaltilde
alpar@464
  6558
  @let^=@normalcaret
alpar@464
  6559
  @let_=@normalunderscore
alpar@464
  6560
  @let|=@normalverticalbar
alpar@464
  6561
  @let<=@normalless
alpar@464
  6562
  @let>=@normalgreater
alpar@464
  6563
  @let+=@normalplus
alpar@464
  6564
  @let$=@normaldollar %$ font-lock fix
alpar@464
  6565
}
alpar@464
  6566
alpar@464
  6567
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
alpar@464
  6568
% the literal character `\'.  (Thus, \ is not expandable when this is in
alpar@464
  6569
% effect.)
alpar@464
  6570
%
alpar@464
  6571
@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
alpar@464
  6572
alpar@464
  6573
% Make _ and + \other characters, temporarily.
alpar@464
  6574
% This is canceled by @fixbackslash.
alpar@464
  6575
@otherifyactive
alpar@464
  6576
alpar@464
  6577
% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
alpar@464
  6578
% That is what \eatinput is for; after that, the `\' should revert to printing
alpar@464
  6579
% a backslash.
alpar@464
  6580
%
alpar@464
  6581
@gdef@eatinput input texinfo{@fixbackslash}
alpar@464
  6582
@global@let\ = @eatinput
alpar@464
  6583
alpar@464
  6584
% On the other hand, perhaps the file did not have a `\input texinfo'. Then
alpar@464
  6585
% the first `\{ in the file would cause an error. This macro tries to fix
alpar@464
  6586
% that, assuming it is called before the first `\' could plausibly occur.
alpar@464
  6587
% Also back turn on active characters that might appear in the input
alpar@464
  6588
% file name, in case not using a pre-dumped format.
alpar@464
  6589
%
alpar@464
  6590
@gdef@fixbackslash{%
alpar@464
  6591
  @ifx\@eatinput @let\ = @normalbackslash @fi
alpar@464
  6592
  @catcode`+=@active
alpar@464
  6593
  @catcode`@_=@active
alpar@464
  6594
}
alpar@464
  6595
alpar@464
  6596
% Say @foo, not \foo, in error messages.
alpar@464
  6597
@escapechar = `@@
alpar@464
  6598
alpar@464
  6599
% These look ok in all fonts, so just make them not special.
alpar@464
  6600
@catcode`@& = @other
alpar@464
  6601
@catcode`@# = @other
alpar@464
  6602
@catcode`@% = @other
alpar@464
  6603
alpar@464
  6604
@c Set initial fonts.
alpar@464
  6605
@textfonts
alpar@464
  6606
@rm
alpar@464
  6607
alpar@464
  6608
alpar@464
  6609
@c Local variables:
alpar@464
  6610
@c eval: (add-hook 'write-file-hooks 'time-stamp)
alpar@464
  6611
@c page-delimiter: "^\\\\message"
alpar@464
  6612
@c time-stamp-start: "def\\\\texinfoversion{"
alpar@464
  6613
@c time-stamp-format: "%:y-%02m-%02d.%02H"
alpar@464
  6614
@c time-stamp-end: "}"
alpar@464
  6615
@c End: