6948 lines
218 KiB
Raw Permalink Normal View History

2020-07-01 12:06:53 +00:00
% 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
% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 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
% 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.
% As a special exception, when this file is read by TeX when processing
% a Texinfo source document, you may use the result without
% restriction. (This has been our intent since Texinfo was invented.)
% Please try the latest version of texinfo.tex before submitting bug
% reports; you can get the latest version from:
% (the Texinfo home page), or
% (and all CTAN mirrors, see
% The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check.
% Send bug reports to 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; this makes
% The extra TeX runs 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, to some
% extent. You can get the existing language-specific files from the
% full Texinfo distribution.
% The GNU Texinfo home page is
\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}
% We never want plain's \outer definition of \+ in Texinfo.
% For @tex, we can use \tabalign.
\let\+ = \relax
% Save some plain tex macros whose names we will redefine.
% If this character appears in an error message or help string, it
% starts a new line in the output.
\newlinechar = `^^J
% Use TeX 3.0's \inputlineno to get the line number, for better error
% messages, but if we're using an old version of TeX, don't do anything.
\let\linenumber = \empty % Pre-3.0.
% 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\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
% In some macros, we cannot use the `\? notation---the left quote is
% in some cases the escape char.
\chardef\colonChar = `\:
\chardef\commaChar = `\,
\chardef\dotChar = `\.
\chardef\exclamChar= `\!
\chardef\questChar = `\?
\chardef\semiChar = `\;
\chardef\underChar = `\_
\chardef\spaceChar = `\ %
\chardef\spacecat = 10
% Ignore a token.
% The following is used inside several \edef's.
% Hyphenation fixes.
Flor-i-da Ghost-script Ghost-view Mac-OS ap-pen-dix bit-map bit-maps
data-base data-bases eshell fall-ing half-way long-est man-u-script
man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
par-a-digms rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
stand-alone strong-est time-stamp time-stamps which-ever white-space
wide-spread wrap-around
% Margin to add to right of even pages, to left of odd pages.
\newdimen\pagewidth \newdimen\pageheight
% For a final copy, take out the rectangles
% that mark overfull boxes (in case you have decided
% that the text looks ok even though it passes the margin).
% @| inserts a changebar to the left of the current line. It should
% surround any changed text. This approach does *not* work if the
% change spans more than two lines of output. To handle that, we would
% have adopt a much more difficult approach (putting marks into the main
% vertical list for the beginning and end of each change).
% \vadjust can only be used in horizontal mode.
% Append this vertical mode material after the current line in the output.
% We want to insert a rule with the height and depth of the current
% leading; that is exactly what \strutbox is supposed to record.
% \vadjust-items are inserted at the left edge of the type. So
% the \llap here moves out into the left-hand margin.
% For a thicker or thinner bar, change the `1pt'.
\vrule height\baselineskip width1pt
% This is the space between the bar and the text.
\hskip 12pt
% 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. We also make
% some effort to order the tracing commands to reduce output in the log
% file; cf. trace.sty in LaTeX.
\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
\tracinglostchars2 % 2 gives us more in etex
\showboxbreadth\maxdimen \showboxdepth\maxdimen
\ifx\eTeXversion\undefined\else % etex gives us more logging
\tracingcommands3 % 3 gives us more in etex
% add check for \lastpenalty to plain's definitions. If the last thing
% we did was a \nobreak, we don't want to insert more space.
% For @cropmarks command.
% Do @cropmarks to get crop marks.
\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}}
% \onepageout takes a vbox as an argument. Note that \pagecontents
% does insertions, but you have to call it yourself.
\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.
% Do this early so pdf references go to the beginning of the page.
\ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
\ifcropmarks \vbox to \outervsize\bgroup
\hsize = \outerhsize
\vtop to0pt{%
\hfil % center the page within the outer (page) hsize.
\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
\egroup % end of \vbox\bgroup
\hfil\egroup % end of (centering) \line\bgroup
\vskip\topandbottommargin plus1fill minus1fill
\boxmaxdepth = \cornerthick
\vbox to0pt{\vss
\egroup % \vbox from first cropmarks clause
}% end of \shipout\vbox
}% end of group with \normalturnoffactive
\ifnum\outputpenalty>-20000 \else\dosupereject\fi
\newinsert\margin \dimen\margin=\maxdimen
\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
{\catcode`\@ =11
% 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}
{\hrule height\cornerthick depth\cornerlong width\cornerthick}}
\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
{\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.
\parseargline\empty% Insert the \empty token, see \finishparsearg below.
{\obeylines %
\endgroup % End of the group started in \parsearg.
\argremovecomment #1\comment\ArgTerm%
% First remove any @comment, then any @c comment.
\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
% \argremovec might leave us with trailing space, e.g.,
% @end itemize @c foo
% This space token undergoes the same procedure and is eventually removed
% by \finishparsearg.
\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
% We cannot use \next here, as it holds the macro to run;
% thus we reuse \temp.
% Put the space token in:
\temp#1 #3\ArgTerm
% If a _delimited_ argument is enclosed in braces, they get stripped; so
% to get _exactly_ the rest of the line, we had to prevent such situation.
% We prepended an \empty token at the very beginning and we expand it now,
% just before passing the control to \next.
% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
% either the null string, or it ends with \^^M---thus there is no danger
% that a pair of braces would be stripped.
% But first, we have to remove the trailing space token.
\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
% \parseargdef\foo{...}
% is roughly equivalent to
% \def\foo{\parsearg\Xfoo}
% \def\Xfoo#1{...}
% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
% favourite TeX trick. --kasal, 16nov03
\expandafter \doparseargdef \csname\string#1\endcsname #1%
% Several utility definitions with active space:
\gdef\obeyedspace{ }
% Make each space character in the input produce a normal interword
% space in the output. Don't allow a line break at this space, as this
% is used only in environments like @example, where each line of input
% should produce a line of output anyway.
\gdef\sepspaces{\obeyspaces\let =\tie}
% If an index command is used in an @example environment, any spaces
% therein should become regular spaces in the raw index file, not the
% expansion of \tie (\leavevmode \penalty \@M \ ).
\gdef\unsepspaces{\let =\space}
\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
% Define the framework for environments in texinfo.tex. It's used like this:
% \envdef\foo{...}
% \def\Efoo{...}
% It's the responsibility of \envdef to insert \begingroup before the
% actual body; @end closes the group after calling \Efoo. \envdef also
% defines \thisenv, so the current environment is known; @end checks
% whether the environment name matches. The \checkenv macro can also be
% used to check whether the current environment is the one expected.
% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
% are not treated as enviroments; they don't open a group. (The
% implementation of @end takes care not to call \endgroup in this
% special case.)
% At runtime, environments start with this:
% initialize
% ... but they get defined via ``\envdef\foo{...}'':
% Check whether we're in the right environment:
% Evironment mismatch, #1 expected:
\errhelp = \EMsimple
\errmessage{This command can appear only \inenvironment\temp,
not \inenvironment\thisenv}%
out of any environment%
in environment \expandafter\string#1%
% @end foo executes the definition of \Efoo.
% But first, it executes a specialized version of \checkenv
\if 1\csname iscond.#1\endcsname
% The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
\csname E#1\endcsname
\newhelp\EMsimple{Press RETURN to continue.}
%% Simple single-character @ commands
% @@ prints an @
% Kludge this until the fonts are right (grr).
% This is turned off because it was never documented
% and you can use @w{...} around a quote to suppress ligatures.
%% Define @` and @' to be the same as ` and '
%% but suppressing ligatures.
% Used to generate quoted braces.
\def\mylbrace {{\tt\char123}}
\def\myrbrace {{\tt\char125}}
% Definitions to produce \{ and \} commands for indices,
% and @{ and @} for the aux file.
\catcode`\{ = \other \catcode`\} = \other
\catcode`\[ = 1 \catcode`\] = 2
\catcode`\! = 0 \catcode`\\ = \other
% @comma{} to avoid , parsing problems.
\let\comma = ,
% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
\let\, = \c
\let\dotaccent = \.
\def\ringaccent#1{{\accent23 #1}}
\let\tieaccent = \t
\let\ubaraccent = \b
\let\udotaccent = \d
% Other special characters: @questiondown @exclamdown @ordf @ordm
% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
% Dotless i and dotless j, used for accents.
\ifx\temp\imacro \ptexi
\else\ifx\temp\jmacro \j
\else \errmessage{@dotless can be used only with i or j}%
% The \TeX{} logo, as in plain, but resetting the spacing so that a
% period following counts as ending a sentence. (Idea found in latex.)
\edef\TeX{\TeX \spacefactor=3000 }
% @LaTeX{} logo. Not quite the same results as the definition in
% latex.ltx, since we use a different font for the raised A; it's most
% convenient for us to use an explicitly smaller font, rather than using
% the \scriptstyle font (since we don't reset \scriptstyle and
% \scriptscriptstyle).
\vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
% Be sure we're in horizontal mode when doing a tie, since we make space
% equivalent to this in @example-like environments. Otherwise, a space
% at the beginning of a line will start with \penalty -- and
% since \penalty is valid in vertical mode, we'd end up putting the
% penalty on the vertical list instead of in the new paragraph.
{\catcode`@ = 11
% Avoid using \@M directly, because that causes trouble
% if the definition is written into an index file.
\global\let\tiepenalty = \@M
\gdef\tie{\leavevmode\penalty\tiepenalty\ }
% @: forces normal size whitespace following.
\def\:{\spacefactor=1000 }
% @* forces a line break.
% @/ allows a line break.
% @. is an end-of-sentence period.
\def\.{.\spacefactor=3000 }
% @! is an end-of-sentence bang.
\def\!{!\spacefactor=3000 }
% @? is an end-of-sentence query.
\def\?{?\spacefactor=3000 }
% @w prevents a word break. Without the \leavevmode, @w at the
% beginning of a paragraph, when TeX is still in vertical mode, would
% produce a whole line of output instead of starting the paragraph.
% @group ... @end group forces ... to be all on one page, by enclosing
% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
% to keep its height that of a normal line. According to the rules for
% \topskip (p.114 of the TeXbook), the glue inserted is
% max (\topskip - \ht (first item), 0). If that height is large,
% therefore, no glue is inserted, and the space between the headline and
% the text is small, which looks bad.
% Another complication is that the group might be very large. This can
% cause the glue on the previous page to be unduly stretched, because it
% does not have much material. In this case, it's better to add an
% explicit \vfill so that the extra space is at the bottom. The
% threshold for doing this is if the group is more than \vfilllimit
% percent of a page (\vfilllimit can be changed inside of @tex).
\ifnum\catcode`\^^M=\active \else
\errhelp = \groupinvalidhelp
\errmessage{@group invalid in context where filling is enabled}%
\setbox\groupbox = \vtop\bgroup
% Do @comment since we are called inside an environment such as
% @example, where each end-of-line in the input causes an
% end-of-line in the output. We don't want the end-of-line after
% the `@group' to put extra space in the output. Since @group
% should appear on a line by itself (according to the Texinfo
% manual), we don't worry about eating any user text.
% The \vtop produces a box with normal height and large depth; thus, TeX puts
% \baselineskip glue before it, and (when the next line of text is done)
% \lineskip glue after it. Thus, space below is not quite equal to space
% above. But it's pretty close.
% To get correct interline space between the last line of the group
% and the first line afterwards, we have to propagate \prevdepth.
\endgraf % Not \par, as it may have been set to \lisppar.
\global\dimen1 = \prevdepth
\egroup % End the \vtop.
% \dimen0 is the vertical size of the group's box.
\dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
% \dimen2 is how much space is left on the page (more or less).
\dimen2 = \pageheight \advance\dimen2 by -\pagetotal
% if the group doesn't fit on the current page, and it's a big big
% group, force a page break.
\ifdim \dimen0 > \dimen2
\ifdim \pagetotal < \vfilllimit\pageheight
\prevdepth = \dimen1
% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
% message, so this ends up printing `@group can only ...'.
group can only be used in environments such as @example,^^J%
where each line of input produces a line of output.}
% @need space-in-mils
% forces a page break if there is not space-in-mils remaining.
\newdimen\mil \mil=0.001in
% Old definition--didn't work.
%\parseargdef\need{\par %
%% This method tries to make TeX break the page naturally
%% if the depth of the box does not fit.
%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
% Ensure vertical mode, so we don't make a big box in the middle of a
% paragraph.
% If the @need value is less than one line space, it's useless.
\dimen0 = #1\mil
\dimen2 = \ht\strutbox
\advance\dimen2 by \dp\strutbox
\ifdim\dimen0 > \dimen2
% Do a \strut just to make the height of this box be normal, so the
% normal leading is inserted relative to the preceding line.
% And a page break here is fine.
\vtop to #1\mil{\strut\vfil}%
% TeX does not even consider page breaks if a penalty added to the
% main vertical list is 10000 or more. But in order to see if the
% empty box we just added fits on the page, we must make it consider
% page breaks. On the other hand, we don't want to actually break the
% page after the empty box. So we use a penalty of 9999.
% There is an extremely small chance that TeX will actually break the
% page at this \penalty, if there are no other feasible breakpoints in
% sight. (If the user is using lots of big @group commands, which
% almost-but-not-quite fill up a page, TeX will have a hard time doing
% good page breaking, for example.) However, I could not construct an
% example where a page broke at this \penalty; if it happens in a real
% document, then we can reconsider our strategy.
% Back up by the size of the box, whether we did a page break or not.
\kern -#1\mil
% Do not allow a page break right after this kern.
% @br forces paragraph break (and is undocumented).
\let\br = \par
% @page forces the start of a new page.
% @exdent text....
% outputs text on separate line in roman font, starting at standard page margin
% This records the amount of indent in the innermost environment.
% That's how much \exdent should take out.
% This defn is used inside fill environments such as @defun.
\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
% This defn is used inside nofill environments such as @example.
\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
% paragraph. For more general purposes, use the \margin insertion
% class. WHICH is `l' or `r'.
\newskip\inmarginspacing \inmarginspacing=1cm
\vtop to \strutdepth{%
% if you have multiple lines of stuff to put here, you'll need to
% make the vbox yourself of the appropriate size.
\llap{\ignorespaces #2\hskip\inmarginspacing}%
\rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
\def\inleftmargin{\doinmargin l}
\def\inrightmargin{\doinmargin r}
% @inmargin{TEXT [, RIGHT-TEXT]}
% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
% else use TEXT for both).
\def\inmargin#1{\parseinmargin #1,,\finish}
\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
\setbox0 = \hbox{\ignorespaces #2}%
\ifdim\wd0 > 0pt
\def\lefttext{#1}% have both texts
\def\lefttext{#1}% have only one text
\def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
% @include file insert text of that file as input.
\def\temp{\input #1 }%
\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
\def\errthisfilestackempty{\errmessage{Internal error:
the stack of filenames is empty.}}
% @center line
% outputs that line, centered.
\next{\hfil \ignorespaces#1\unskip \hfil}%
\advance\hsize by -\leftskip
\advance\hsize by -\rightskip
\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
% @sp n outputs n lines of vertical space
\parseargdef\sp{\vskip #1\baselineskip}
% @comment ...line which is ignored...
% @c is the same as @comment
% @ignore ... @end ignore is another way to write a comment
\def\comment{\begingroup \catcode`\^^M=\other%
\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
% @paragraphindent NCHARS
% We'll use ems for NCHARS, close enough.
% NCHARS can also be the word `asis' or `none'.
% We cannot feasibly implement @paragraphindent asis, though.
\def\asisword{asis} % no translation, these are keywords
\defaultparindent = 0pt
\defaultparindent = #1em
\parindent = \defaultparindent
% @exampleindent NCHARS
% We'll use ems for NCHARS like @paragraphindent.
% It seems @exampleindent asis isn't necessary, but
% I preserve it to make it similar to @paragraphindent.
\lispnarrowing = 0pt
\lispnarrowing = #1em
% @firstparagraphindent WORD
% If WORD is `none', then suppress indentation of the first paragraph
% after a section heading. If WORD is `insert', then do indent at such
% paragraphs.
% The paragraph indentation is suppressed or not by calling
% \suppressfirstparagraphindent, which the sectioning commands do.
% We switch the definition of this back and forth according to WORD.
% By default, we suppress indentation.
\let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
\let\suppressfirstparagraphindent = \relax
\errhelp = \EMsimple
\errmessage{Unknown @firstparagraphindent option `\temp'}%
% Here is how we actually suppress indentation. Redefine \everypar to
% \kern backwards by \parindent, and then reset itself to empty.
% We also make \indent itself not actually do anything until the next
% paragraph.
\global\everypar = {%
\kern -\parindent
\global \let \indent = \ptexindent
\global \let \noindent = \ptexnoindent
\global \everypar = {}%
% @asis just yields its argument. Used with @table, for example.
% @math outputs its argument in math mode.
% One complication: _ usually means subscripts, but it could also mean
% an actual _ character, as in @math{@var{some_variable} + 1}. So make
% _ active, and distinguish by seeing if the current family is \slfam,
% which is what @var uses.
\catcode\underChar = \active
\def_{\ifnum\fam=\slfam \_\else\sb\fi}%
% Another complication: we want \\ (and @\) to output a \ character.
% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
% this is not advertised and we don't care. Texinfo does not
% otherwise define @\.
% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
\let\\ = \mathbackslash
\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
% Some active characters (such as <) are spaced differently in math.
% We have to reset their definitions in case the @math was an argument
% to a command which sets the catcodes (such as @item or @section).
\catcode`^ = \active
\catcode`< = \active
\catcode`> = \active
\catcode`+ = \active
\let^ = \ptexhat
\let< = \ptexless
\let> = \ptexgtr
\let+ = \ptexplus
% @bullet and @minus need the same treatment as @math, just above.
% @dots{} outputs an ellipsis using the current font.
% We do .5em per period so that it has the same spacing in a typewriter
% font as three actual period characters.
\hbox to 1.5em{%
\hskip 0pt plus 0.25fil
\hskip 0pt plus 0.5fil
% @enddots{} is an end-of-sentence ellipsis.
% @comma{} is so commas can be inserted into text without messing up
% Texinfo's parsing.
\let\comma = ,
% @refill is a no-op.
% If working on a large document in chapters, it is convenient to
% be able to disable indexing, cross-referencing, and contents, for test runs.
% This is done with @novalidate (before @setfilename).
\newif\iflinks \linkstrue % by default we want the aux files.
\let\novalidate = \linksfalse
% @setfilename is done at the beginning of every texinfo file.
% So open here the files we need to have open while reading the input.
% This makes it possible to make a .fmt file for texinfo.
\fixbackslash % Turn off hack to swallow `\input texinfo'.
% Open the new aux file. TeX will close it automatically at exit.
\fi % \openindices needs to do some work in any case.
\let\setfilename=\comment % Ignore extra @setfilename cmds.
% If texinfo.cnf is present on the system, read it.
% Useful for site-wide @afourpaper, etc.
\openin 1 texinfo.cnf
\ifeof 1 \else \input texinfo.cnf \fi
\closein 1
\comment % Ignore the actual filename.
% Called from \setfilename.
% @bye.
% adobe `portable' document format
\let\pdfmkdest = \gobble
\let\pdfurl = \gobble
\let\endlink = \relax
\let\linkcolor = \relax
\let\pdfmakeoutlines = \relax
\pdfoutput = 1
\input pdfcolor
\pdfcatalog{/PageMode /UseOutlines}%
% without \immediate, pdftex seg faults when the same image is
% included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
\ifnum\pdftexversion < 14
\ifx\empty\imagewidth\else width \imagewidth \fi
\ifx\empty\imageheight\else height \imageheight \fi
\ifnum\pdftexversion < 14 \else
\pdfrefximage \pdflastximage
% We have to set dummies so commands such as @code in a section title
% aren't expanded.
\pdfdest name{#1} xyz%
\let\linkcolor = \Blue % was Cyan, but that seems light?
% Adding outlines to PDF; macros for calculating structure of outlines
% come from Petr Olsak
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
\else \csname#1\endcsname \fi}
\advance\tempnum by 1
% #1 is the section text. #2 is the pdf expression for the number
% of subentries (or empty, for subsubsections). #3 is the node
% text, which might be empty if this toc entry had no
% corresponding node. #4 is the page number.
% Generate a link to the node text if that exists; else, use the
% page number. We could generate a destination for the section
% text in the case where a section has no node, but it doesn't
% seem worthwhile, since most documents are normally structured.
\ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
\pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
% Thanh's hack / proper braces in bookmarks
\edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
% Read toc silently, to get counts of subentries for \pdfoutline.
% use \def rather than \let here because we redefine \chapentry et
% al. a second time, below.