%% Intercept grammar typesetting and replace the vertical bar with the
%% maths-font version.
-\let\@@grammar\grammar
-\def\grammar{\def\textbar{\hbox{$|$}}\@@grammar}
+\let\@@syn@shorts\syn@shorts
+\def\syn@shorts{\def\textbar{\hbox{$|$}}\@@syn@shorts}
%% Collect super- and subscripts. (Note that underscores are active for the
%% most part.) When we're done, end maths mode if we entered it
%%%--------------------------------------------------------------------------
%%% Environment for setting programs.
+%% Save `\kill' so that `longtable' won't clobber it.
+\let\prog@@kill\kill
+
%% Main guts of `prog' and `nprog'.
-\def\@prog{\let\prog@@cr\@tabcr\let\@tabcr\@progcr\codeface\tabbing}
+\def\@prog{%
+ \let\prog@@cr\@tabcr%
+ \let\@tabcr\@progcr%
+ \let\kill\prog@@kill%
+ \codeface%
+ \tabbing%
+}
%% Newlines: called by `\\' within a `prog'.
%%
%% Show a backslash by the right-hand margin; for multiline macros etc.
\def\macsl{\`\textbackslash\hskip\leftmargin}
+%% \maplist{THING}{{ITEM}...}: Invoke THING{ITEM} for each ITEM in turn.
+\def\maplist#1#2{\map@i{#1}#2\q@}
+\def\map@i#1{\def\next@{\map@ii{#1}}\futurelet\ch@\next@}
+\def\map@ii#1{\ifx\ch@\q@\expandafter\@gobble%
+ \else\def\next@{\map@iii{#1}}\expandafter\next@\fi}
+\def\map@iii#1#2{#1{#2}\map@i{#1}}
+
+%% \crossproduct{THING}{{LIST}...} where each LIST is {ITEM}...
+%% For each possible way of selecting one ITEM from each LIST, in order,
+%% invoke THING{{ITEM}...}
+\toksdef\cprod@new=0
+\toksdef\cprod@old=2
+\toksdef\cprod@head=4
+\toksdef\cprod@tail=6
+\def\crossproduct#1#2{%
+ \cprod@new{{}}%
+ \maplist{\cprod@f{#1}}{#2}%
+ \cprod@head{#1}%
+ \edef\next@{\noexpand\maplist{\the\cprod@head}{\the\cprod@new}}
+ \next@%
+}
+\def\cprod@f#1#2{%
+ \cprod@old\cprod@new\cprod@new{}%
+ \maplist\cprod@g{#2}%
+}
+\def\cprod@g#1{%
+ \cprod@head{#1}%
+ \expandafter\maplist\expandafter\cprod@h\expandafter{\the\cprod@old}%
+}
+\def\cprod@h#1{%
+ \cprod@tail{#1}%
+ \cprod@new\expandafter{\the\expandafter\cprod@new\expandafter{%
+ \the\expandafter\cprod@tail\the\cprod@head}}%
+}
+
%%%--------------------------------------------------------------------------
%%% Machinery for describing functions, etc.
%% Category-kind methods for plain categories.
\@namedef{descargs/plain}#1{#1{}}
-\@namedef{desclabel/plain}#1#2#3{#1:\@mod@dispatch{modlabel}{#2}{#3}}
+\@namedef{desclabel/plain}#1#2#3{#2:\@mod@dispatch{modlabel}{#1}{#3}}
\@namedef{descindex/plain}#1#2#3{%
- \@mod@dispatch{modindex}{#2}{#3}!%
- \protect\describecategoryname[#2]{#1}%
+ \@mod@dispatch{modindex}{#1}{#3}!%
+ \protect\describecategoryname[#1]{#2}%
}
%% Category-kind methods for `method' categories. Collect an extra argument
}
\@namedef{descargs/method}#1#2{#1{{#2}}}
\@namedef{desclabel/method}#1#2#3#4%
- {#1:\@mod@dispatch{modlabel}{#2}{#3}(#4)}
+ {#2:\@mod@dispatch{modlabel}{#1}{#4}(#3)}
\@namedef{descindex/method}#1#2#3#4{%
- \@mod@dispatch{modindex}{#2}{#3}!%
- \protect\describecategoryname[#2]{#1}%
- \protect\fmtspecs{ specialized at }{#4}%
+ \@mod@dispatch{modindex}{#1}{#4}!%
+ \protect\describecategoryname[#1]{#2}%
+ \protect\fmtspecs{ specialized at }{#3}%
}
%% Some magic strings.
#1{setf}{#2}{#3}{#5}{#4}}
%% \dhead[MOD]{CAT}{...}...[NAME]{SYNOPSIS}
+%% \dhead*[MOD]{CAT}{...}...[NAME]{SYNOPSIS}
%%
%% Typeset a description head. Use this within the first argument of
%% `describe*'; see `describe' for the details.
+%%
+%% With `*', don't set labels or add items to the index.
\newif\if@dheadfirst
-\def\dhead{\parse@dhd\dhead@}
+\newif\if@dheadindex
+\def\dhead{\@ifstar%
+ {\parse@dhd{\global\@dheadindexfalse\dhead@}}%
+ {\parse@dhd{\global\@dheadindextrue\dhead@}}}
\def\dhead@#1#2#3#4#5{% {MOD}{CAT}{{...}...}{NAME}{SYNOPSIS}
\if@dheadfirst\global\@dheadfirstfalse\else\relax\\*[\smallskipamount]\fi%
- \phantomsection%
- {\let\protect\@empty\let\@uscore\relax%
- \edef\temp@{\@desc@dispatch{desclabel}{#2}{#2}{#1}{#4}#3}%
- \def\@uscore{_\@gobble}\expandafter\message\expandafter{\temp@}%
- \def\@uscore{-\@gobble}\expandafter\label\expandafter{\temp@}}%
- {\begingroup\lccode`\~=`\_\lowercase{\endgroup\def~{_}}%
- \protected@edef\@tempa##1{%
- \noexpand\index{\@desc@dispatch{descindex}{#2}{#2}{#1}{#4}#3##1}}%
- \toks@\expandafter{\@tempa{|)}}%
- \toks\tw@\expandafter{\after@desc}%
- \xdef\after@desc{\the\toks\tw@\the\toks@}%
- \@tempa{|(}}%
+ \if@dheadindex%
+ \phantomsection%
+ {\let\protect\@empty\let\@uscore\relax%
+ \edef\temp@{\@desc@dispatch{desclabel}{#2}{#1}{#2}#3{#4}}%
+ \def\@uscore{_\@gobble}\expandafter\message\expandafter{\temp@}%
+ \def\@uscore{-\@gobble}\expandafter\label\expandafter{\temp@}}%
+ {\begingroup\lccode`\~=`\_\lowercase{\endgroup\def~{_}}%
+ \protected@edef\@tempa##1{%
+ \noexpand\index{\@desc@dispatch{descindex}{#2}{#1}{#2}#3{#4}##1}}%
+ \toks@\expandafter{\@tempa{|)}}%
+ \toks\tw@\expandafter{\after@desc}%
+ \xdef\after@desc{\the\toks\tw@\the\toks@}%
+ \@tempa{|(}}%
+ \fi%
\rlap{\hb@xt@\linewidth{\hfil\normalfont\bfseries
[\describecategoryname[#1]{#2}]}}%
#5%
%%
%% * `:NAME': defaults MOD to `kwd'.
\def\describe{\parse@dhd\desc@}
-\def\desc@#1#2#3#4#5{\desc@begin{\dhead@{#1}{#2}{#3}{#4}{#5}}}
+\def\desc@#1#2#3#4#5{%
+ \global\@dheadindextrue%
+ \desc@begin{\dhead@{#1}{#2}{#3}{#4}{#5}}%
+}
\let\enddescribe\desc@end
%% \begin{describe*}
\@namedef{describe*}#1{\desc@begin{#1}}
\expandafter\let\csname enddescribe*\endcsname\desc@end
-%% \descref{CAT}{...}...{LABEL}[TEXT]
-%% \descref*{CAT}{...}...{LABEL}
+%% \parse@dlbl{NEXT}[MOD]{CAT}{...}...{LABEL}
+%%
+%% Parse a description label, and call
+%%
+%% NEXT{MOD}{CAT}{{...}...}{LABEL}
+%%
+%% This handles defaulting the MOD correctly, based on the LABEL text. See
+%% `\descref' for the details.
+\def\parse@dlbl#1{\@ifnextchar[{\parse@dlbl@a{#1}}{\parse@dlbl@c{#1}}}
+\def\parse@dlbl@a#1[#2]#3{\@desc@dispatch{descargs}{#3}{#1{#2}{#3}}}
+\def\parse@dlbl@c#1#2%
+ {\@desc@dispatch{descargs}{#2}{\parse@dlbl@cb{#1}{#2}}}
+\def\parse@dlbl@cb#1#2#3#4{%
+ \def\temp@##1##2*##3\q@{\def\temp@{##1##3}}\temp@#4*\q@%
+ \ifx\temp@\@starstar\def\next@{#1{muffs}{#2}{#3}{#4}}%
+ \else\def\temp@##1##2\q@{\def\temp@{##1}}\temp@#4\q@%
+ \if:\temp@\def\next@{#1{kwd}{#2}{#3}{#4}}
+ \else\def\next@{#1{plain}{#2}{#3}{#4}}\fi\fi%
+ \next@%
+}
+
+%% \descref[MOD]{CAT}{...}...{LABEL}[TEXT]
+%% \descref*[MOD]{CAT}{...}...{LABEL}
%%
%% Typesets a cross-reference to a described thing. The CAT names the
%% category of thing being described, and the LABEL names the specific thing.
%% The {...}... are any additional arguments required by the category's kind
%% (e.g., method specializers).
%%
-%% The precise rules for how the LABEL matches the name in the description
-%% depend on the description's modifier:
+%% The MOD is the modifier to apply, similar (but subtly different from) to
+%% the `describe' environment. If omitted, it will usually default to
+%% `plain', but in the absence of a NAME, some kinds of synopses are
+%% recognized specially:
%%
-%% * `plain', `muffs', and `kwd': the LABEL is the same as the NAME.
-%% * `setf': the LABEL should be `setf/NAME'.
+%% * `*NAME*': defaults MOD to `muffs'.
+%%
+%% * `:NAME': defaults MOD to `kwd'.
+%%
+%% (`setf' is /not/ specially detected here. Write an explicit `setf'
+%% modifier if necessary, because it's no more typing.)
%%
%% Usually a page-number cross-reference is included, so as to help readers
%% of a dead-tree copy; this is suppressed by the `*' version.
\def\descref{\@ifstar%
- {\descref@i{}\@gobble{}}%
- {\descref@i{ (}{\noexpand\autopageref}{)}}}
-\def\descref@i#1#2#3#4#5{\@ifnextchar@preserve[%
- {\descref@ii{#1}{#2}{#3}{#4}{#5}}%
- {\descref@iii{#1}{#2}{#3}{#4}{#5}{}}}
-\def\descref@ii#1#2#3#4#5[#6]{\descref@iii{#1}{#2}{#3}{#4}{#5}{ #6}}
-\def\descref@iii#1#2#3#4#5#6{%
+ {\parse@dlbl{\descref@i\relax\@gobble\relax}}%
+ {\parse@dlbl{\descref@i{ (}\autopageref)}}}
+\def\descref@i#1#2#3#4#5#6#7{\@ifnextchar@preserve[%
+ % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL}
+ {\descref@ii{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
+ {\descref@iii{#1}{#2}{#3}{#4}{#5}{#6}{#7}{}}}
+\def\descref@ii#1#2#3#4#5#6#7[#8]%
+ % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL}[AFTER]
+ {\descref@iii{#1}{#2}{#3}{#4}{#5}{#6}{#7}{ #8}}
+\def\descref@iii#1#2#3#4#5#6#7#8{%
+ % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL}{AFTER}
\begingroup%
- \let\protect\@empty%
- \def\@uscore{-\@gobble}%
- \edef\@tempa##1{%
- \endgroup%
- \noexpand\hyperref[#4:#5]%
- ##1%
- #2{#4:#5}%
- }%
- \@tempa{{\code{#5}}#6#1}#3%
+ \let\protect\@empty\def\@uscore{-\@gobble}%
+ \edef\temp@{\@desc@dispatch{desclabel}{#5}{#4}{#5}#6{#7}}%
+ \edef\next@##1##2##3{\endgroup%
+ \noexpand\hyperref[\temp@]{##1}##2{\temp@}##3}%
+ \next@{\code{#7}}{#8#1#2}{#3}%
+}
+
+%% \descindex[MOD]{CAT}{...}...{LABEL}[SUFFIX]
+%%
+%% Set a label and index entry here, as if for a description. The CAT names
+%% the category of thing being described, and the LABEL names the specific
+%% thing, as for `\descref'. The {...}... are any additional arguments
+%% required by the category's kind (e.g., method specializers). The MOD is
+%% the modifier to apply; see `\descref' for the details.
+%%
+%% The SUFFIX is appended to the index-entry text; by default it is empty.
+%% Useful values are `|(' and `|)' to set ranges.
+\def\descindex{\parse@dlbl\descindex@i}
+\def\descindex@i#1#2#3#4{\@ifnextchar[%
+ {\descindex@ii{#1}{#2}{#3}{#4}}%
+ {\descindex@ii{#1}{#2}{#3}{#4}[]}}
+\def\descindex@ii#1#2#3#4[#5]{%
+ {\begingroup\lccode`\~=`\_\lowercase{\endgroup\def~{_}}%
+ \protected@edef\@tempa{%
+ \noexpand\index{\@desc@dispatch{descindex}{#2}{#1}{#2}#3{#4}#5}}%
+ \@tempa}%
+}
+
+%% \desclabel[MOD]{CAT}{...}...{LABEL}[INDEX-SUFFIX]
+%%
+%% Set a label and index entry here, as if for a description. The CAT names
+%% the category of thing being described, and the LABEL names the specific
+%% thing, as for `\descref'. The {...}... are any additional arguments
+%% required by the category's kind (e.g., method specializers). The MOD is
+%% the modifier to apply; see `\descref' for the details.
+%%
+%% This will also add an index entry, as for `\descindex'; the INDEX-SUFFIX
+%% argument has the same effect as its SUFFIX argument.
+\def\desclabel{\parse@dlbl\desclabel@i}
+\def\desclabel@i#1#2#3#4{%
+ \begingroup%
+ \let\protect\@empty\def\@uscore{-\@gobble}%
+ \edef\@tempa{\@desc@dispatch{desclabel}{#2}{#1}{#2}#3{#4}}%
+ \phantomsection\label{\@tempa}%
+ \endgroup%
+ \descindex@i{#1}{#2}{#3}{#4}%
}
%% Description categories.