% texinfo.tex -- TeX macros to handle Texinfo files.
%
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
\def\texinfoversion{1999-09-25.10}
%
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
% Free Software Foundation, Inc.
%
% This texinfo.tex file is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
% published by the Free Software Foundation; either version 2, or (at
% your option) any later version.
%
% This texinfo.tex file is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
% General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this texinfo.tex file; see the file COPYING. If not, write
% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
% Boston, MA 02111-1307, USA.
%
% In other words, you are welcome to use, share and improve this program.
% You are forbidden to forbid anyone else to use, share and improve
% what you give them. Help stamp out software-hoarding!
%
% Please try the latest version of texinfo.tex before submitting bug
% reports; you can get the latest version from:
% ftp://ftp.gnu.org/gnu/texinfo.tex
% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html)
% ftp://texinfo.org/tex/texinfo.tex
% ftp://us.ctan.org/macros/texinfo/texinfo.tex
% (and all CTAN mirrors, finger ctan@us.ctan.org for a list).
% /home/gd/gnu/doc/texinfo.tex on the GNU machines.
% The texinfo.tex in any given Texinfo distribution could well be out
% of date, so if that's what you're using, please check.
% Texinfo has a small home page at http://texinfo.org/.
%
% Send bug reports to bug-texinfo@gnu.org. Please include including a
% complete document in each bug report with which we can reproduce the
% problem. Patches are, of course, greatly appreciated.
%
% To process a Texinfo manual with TeX, it's most reliable to use the
% texi2dvi shell script that comes with the distribution. For a simple
% manual foo.texi, however, you can get away with this:
% tex foo.texi
% texindex foo.??
% tex foo.texi
% tex foo.texi
% dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps.
% The extra runs of TeX get the cross-reference information correct.
% Sometimes one run after texindex suffices, and sometimes you need more
% than two; texi2dvi does it as many times as necessary.
%
% It is possible to adapt texinfo.tex for other languages. You can get
% the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/.
\message{Loading texinfo [version \texinfoversion]:}
% If in a .fmt file, print the version number
% and turn on active characters that we couldn't do earlier because
% they might have appeared in the input file name.
\everyjob{\message{[Texinfo version \texinfoversion]}%
\catcode`+=\active \catcode`\_=\active}
% Save some parts of plain tex whose names we will redefine.
\let\ptexb=\b
\let\ptexbullet=\bullet
\let\ptexc=\c
\let\ptexcomma=\,
\let\ptexdot=\.
\let\ptexdots=\dots
\let\ptexend=\end
\let\ptexequiv=\equiv
\let\ptexexclam=\!
\let\ptexi=\i
\let\ptexlbrace=\{
\let\ptexrbrace=\}
\let\ptexstar=\*
\let\ptext=\t
% We never want plain's outer \+ definition in Texinfo.
% For @tex, we can use \tabalign.
\let\+ = \relax
\message{Basics,}
\chardef\other=12
% If this character appears in an error message or help string, it
% starts a new line in the output.
\newlinechar = `^^J
% Set up fixed words for English if not already set.
\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
\ifx\putwordin\undefined \gdef\putwordin{in}\fi
\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
\ifx\putwordof\undefined \gdef\putwordof{of}\fi
\ifx\putwordon\undefined \gdef\putwordon{on}\fi
\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
%
\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
%
\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi
\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi
% Ignore a token.
%
\def\gobble#1{}
\hyphenation{ap-pen-dix}
\hyphenation{mini-buf-fer mini-buf-fers}
\hyphenation{eshell}
\hyphenation{white-space}
% Margin to add to right of even pages, to left of odd pages.
\newdimen \bindingoffset
\newdimen \normaloffset
\newdimen\pagewidth \newdimen\pageheight
% Sometimes it is convenient to have everything in the transcript file
% and nothing on the terminal. We don't just call \tracingall here,
% since that produces some useless output on the terminal.
%
\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
\ifx\eTeXversion\undefined
\def\loggingall{\tracingcommands2 \tracingstats2
\tracingpages1 \tracingoutput1 \tracinglostchars1
\tracingmacros2 \tracingparagraphs1 \tracingrestores1
\showboxbreadth\maxdimen\showboxdepth\maxdimen
}%
\else
\def\loggingall{\tracingcommands3 \tracingstats2
\tracingpages1 \tracingoutput1 \tracinglostchars1
\tracingmacros2 \tracingparagraphs1 \tracingrestores1
\tracingscantokens1 \tracingassigns1 \tracingifs1
\tracinggroups1 \tracingnesting2
\showboxbreadth\maxdimen\showboxdepth\maxdimen
}%
\fi
% For @cropmarks command.
% Do @cropmarks to get crop marks.
%
\newif\ifcropmarks
\let\cropmarks = \cropmarkstrue
%
% Dimensions to add cropmarks at corners.
% Added by P. A. MacKay, 12 Nov. 1986
%
\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
\newdimen\cornerlong \cornerlong=1pc
\newdimen\cornerthick \cornerthick=.3pt
\newdimen\topandbottommargin \topandbottommargin=.75in
% Main output routine.
\chardef\PAGE = 255
\output = {\onepageout{\pagecontents\PAGE}}
\newbox\headlinebox
\newbox\footlinebox
% \onepageout takes a vbox as an argument. Note that \pagecontents
% does insertions, but you have to call it yourself.
\def\onepageout#1{%
\ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
%
\ifodd\pageno \advance\hoffset by \bindingoffset
\else \advance\hoffset by -\bindingoffset\fi
%
% Do this outside of the \shipout so @code etc. will be expanded in
% the headline as they should be, not taken literally (outputting ''code).
\setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
\setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
%
{%
% Have to do this stuff outside the \shipout because we want it to
% take effect in \write's, yet the group defined by the \vbox ends
% before the \shipout runs.
%
\escapechar = `\\ % use backslash in output files.
\indexdummies % don't expand commands in the output.
\normalturnoffactive % \ in index entries must not stay \, e.g., if
% the page break happens to be in the middle of an example.
\shipout\vbox{%
\ifcropmarks \vbox to \outervsize\bgroup
\hsize = \outerhsize
\vskip-\topandbottommargin
\vtop to0pt{%
\line{\ewtop\hfil\ewtop}%
\nointerlineskip
\line{%
\vbox{\moveleft\cornerthick\nstop}%
\hfill
\vbox{\moveright\cornerthick\nstop}%
}%
\vss}%
\vskip\topandbottommargin
\line\bgroup
\hfil % center the page within the outer (page) hsize.
\ifodd\pageno\hskip\bindingoffset\fi
\vbox\bgroup
\fi
%
\unvbox\headlinebox
\pagebody{#1}%
\ifdim\ht\footlinebox > 0pt
% Only leave this space if the footline is nonempty.
% (We lessened \vsize for it in \oddfootingxxx.)
% The \baselineskip=24pt in plain's \makefootline has no effect.
\vskip 2\baselineskip
\unvbox\footlinebox
\fi
%
\ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi
%
\ifcropmarks
\egroup % end of \vbox\bgroup
\hfil\egroup % end of (centering) \line\bgroup
\vskip\topandbottommargin plus1fill minus1fill
\boxmaxdepth = \cornerthick
\vbox to0pt{\vss
\line{%
\vbox{\moveleft\cornerthick\nsbot}%
\hfill
\vbox{\moveright\cornerthick\nsbot}%
}%
\nointerlineskip
\line{\ewbot\hfil\ewbot}%
}%
\egroup % \vbox from first cropmarks clause
\fi
}% end of \shipout\vbox
}% end of group with \turnoffactive
\advancepageno
\ifnum\outputpenalty>-20000 \else\dosupereject\fi
}
\newinsert\margin \dimen\margin=\maxdimen
\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
{\catcode`\@ =11
\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
% marginal hacks, juha@viisa.uucp (Juha Takala)
\ifvoid\margin\else % marginal info is present
\rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
\dimen@=\dp#1 \unvbox#1
\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
}
% Here are the rules for the cropmarks. Note that they are
% offset so that the space between them is truly \outerhsize or \outervsize
% (P. A. MacKay, 12 November, 1986)
%
\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
\def\nstop{\vbox
{\hrule height\cornerthick depth\cornerlong width\cornerthick}}
\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
\def\nsbot{\vbox
{\hrule height\cornerlong depth\cornerthick width\cornerthick}}
% Parse an argument, then pass it to #1. The argument is the rest of
% the input line (except we remove a trailing comment). #1 should be a
% macro which expects an ordinary undelimited TeX argument.
%
\def\parsearg#1{%
\let\next = #1%
\begingroup
\obeylines
\futurelet\temp\parseargx
}
% If the next token is an obeyed space (from an @example environment or
% the like), remove it and recurse. Otherwise, we're done.
\def\parseargx{%
% \obeyedspace is defined far below, after the definition of \sepspaces.
\ifx\obeyedspace\temp
\expandafter\parseargdiscardspace
\else
\expandafter\parseargline
\fi
}
% Remove a single space (as the delimiter token to the macro call).
{\obeyspaces %
\gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
{\obeylines %
\gdef\parseargline#1^^M{%
\endgroup % End of the group started in \parsearg.
%
% First remove any @c comment, then any @comment.
% Result of each macro is put in \toks0.
\argremovec #1\c\relax %
\expandafter\argremovecomment \the\toks0 \comment\relax %
%
% Call the caller's macro, saved as \next in \parsearg.
\expandafter\next\expandafter{\the\toks0}%
}%
}
% Since all \c{,omment} does is throw away the argument, we can let TeX
% do that for us. The \relax here is matched by the \relax in the call
% in \parseargline; it could be more or less anything, its purpose is
% just to delimit the argument to the \c.
\def\argremovec#1\c#2\relax{\toks0 = {#1}}
\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
% @end itemize @c foo
% will have two active spaces as part of the argument with the
% `itemize'. Here we remove all active spaces from #1, and assign the
% result to \toks0.
%
% This loses if there are any *other* active characters besides spaces
% in the argument -- _ ^ +, for example -- since they get expanded.
% Fortunately, Texinfo does not define any such commands. (If it ever
% does, the catcode of the characters in questionwill have to be changed
% here.) But this means we cannot call \removeactivespaces as part of
% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
% that \parsearg gets might well have any character at all in it.
%
\def\removeactivespaces#1{%
\begingroup
\ignoreactivespaces
\edef\temp{#1}%
\global\toks0 = \expandafter{\temp}%
\endgroup
}
% Change the active space to expand to nothing.
%
\begingroup
\obeyspaces
\gdef\ignoreactivespaces{\obeyspaces\let =\empty}
\endgroup
\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
%% These are used to keep @begin/@end levels from running away
%% Call \inENV within environments (after a \begingroup)
\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
\def\ENVcheck{%
\ifENV\errmessage{Still within an environment; press RETURN to continue}
\endgroup\fi} % This is not perfect, but it should reduce lossage
% @begin foo is the same as @foo, for now.
\newhelp\EMsimple{Press RETURN to continue.}
\outer\def\begin{\parsearg\beginxxx}
\def\beginxxx #1{%
\expandafter\ifx\csname #1\endcsname\relax
{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
\csname #1\endcsname\fi}
% @end foo executes the definition of \Efoo.
%
\def\end{\parsearg\endxxx}
\def\endxxx #1{%
\removeactivespaces{#1}%
\edef\endthing{\the\toks0}%
%
\expandafter\ifx\csname E\endthing\endcsname\relax
\expandafter\ifx\csname \endthing\endcsname\relax
% There's no \foo, i.e., no ``environment'' foo.
\errhelp = \EMsimple
\errmessage{Undefined command `@end \endthing'}%
\else
\unmatchedenderror\endthing
\fi
\else
% Everything's ok; the right environment has been started.
\csname E\endthing\endcsname
\fi
}
% There is an environment #1, but it hasn't been started. Give an error.
%
\def\unmatchedenderror#1{%
\errhelp = \EMsimple
\errmessage{This `@end #1' doesn't have a matching `@#1'}%
}
% Define the control sequence \E#1 to give an unmatched @end error.
%
\def\defineunmatchedend#1{%
|