summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/xdoc/xdoc2.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/xdoc/xdoc2.dtx')
-rw-r--r--macros/latex/contrib/xdoc/xdoc2.dtx5166
1 files changed, 5166 insertions, 0 deletions
diff --git a/macros/latex/contrib/xdoc/xdoc2.dtx b/macros/latex/contrib/xdoc/xdoc2.dtx
new file mode 100644
index 0000000000..c0d4a22d3d
--- /dev/null
+++ b/macros/latex/contrib/xdoc/xdoc2.dtx
@@ -0,0 +1,5166 @@
+% \CheckSum{2952}
+%
+% \iffalse meta-comment
+%
+% This file may be distributed and/or modified under the conditions
+% of the LaTeX Project Public License, either version 1.2 of this
+% license or (at your option) any later version. The latest version
+% of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.2 or later is part of all distributions of LaTeX
+% version 1999/12/01 or later.
+%
+% Copyright 2000 2001 2002 Lars Hellstr\"om
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{array,longtable}
+
+\makeatletter
+\IfFileExists{xdoc2.sty}{%
+ \usepackage[dolayout]{xdoc2}
+ \NewMacroEnvironment{xrefcmd}{\XD@grab@harmless\relax}{1}%
+ {\MacroFont##1 \normalfont XXR-command}%
+ {\XDMainIndex{%
+ \levelsorted{##1 (XXR-command)}{\texttt{##1} (XXR-command)}%
+ }%
+ \XDMainIndex{%
+ \levelsame{XXR-commands:}\levelsorted{##1}{\texttt{##1}}%
+ }}%
+ {{##1}{XXR-command \texttt{##1}}}%
+ {}%
+ \@namedef{XD@harmless\string\Bslash}{%
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname XD@harmless@92\endcsname}%
+ \XD@harmless@
+ }%
+ \IfFileExists{docidx2e.sty}{%
+ \usepackage{docidx2e}%
+ \AtEndDocument{%
+ \typeout{*********************************}%
+ \typeout{* Use docindex.ist when sorting *}%
+ \typeout{* xdoc2.idx and xdoc2.glo. \@spaces\space*}%
+ \typeout{*********************************}%
+ }%
+ }%
+}{%
+ \newenvironment{option}[1]{\trivlist\item[]}{\endtrivlist}%
+ \newenvironment{xrefcmd}[1]{\trivlist\item[]}{\endtrivlist}%
+ \@ifpackagelater{doc}{2000/05/20}{}{%
+ \let\XD@fragile@meta=\meta
+ \def\meta{%
+ \ifx \protect\@typeset@protect
+ \expandafter\futurelet \expandafter\@let@token
+ \expandafter\XD@fragile@meta
+ \else
+ \noexpand\meta
+ \fi
+ }%
+ }%
+}
+\makeatother
+
+\providecommand\describecsfamily[1]{%
+ \leavevmode
+ \GenericDescribePrint{\MacroFont\Bslash#1}%
+ \ignorespaces
+}
+\providecommand\describeoption[1]{%
+ \leavevmode
+ \GenericDescribePrint{\MacroFont#1 \normalfont option}%
+ \ignorespaces
+}
+\providecommand\GenericDescribePrint[1]{%
+ \marginpar{\raggedleft\strut #1}%
+}
+\providecommand\Bslash{\bslash}
+\providecommand\DoNotIndexBy[1]{}
+\DoNotIndexBy{@}
+\DoNotIndexBy{@@}
+\DoNotIndexBy{XD@}
+
+\DeclareRobustCommand\package[1]{\textsf{#1}}
+\DeclareRobustCommand\LaTeXplus{\LaTeXe$*$}
+\newcommand\B{\penalty\exhyphenpenalty}
+\ProvideTextCommandDefault\textminus{\textendash}
+
+\hfuzz=15pt
+
+\AlsoImplementation
+\setcounter{IndexColumns}{2}
+
+\CodelineIndex
+\EnableCrossrefs
+\RecordChanges
+
+\begin{document}
+
+\DocInput{xdoc2.dtx}
+
+\PrintChanges
+\PrintIndex
+
+\end{document}
+%</driver>
+% \fi
+%
+% \title{The \package{xdoc} package --- experimental reimplementations
+% of features from \package{doc}, second~prototype}
+% \author{Lars Hellstr\"om^^A
+% \thanks{E-mail: \texttt{Lars.Hellstrom@math.umu.se}}}
+% \date{2003/07/07}
+% \maketitle
+%
+% \DoNotIndex{\,,\-,\/,\ ,\#,\%,\&,\\,\^,\|}
+% \DoNotIndex{\@addtoreset,\@auxout,\@bsphack,\@cclv,\@ctrerr}
+% \DoNotIndex{\@eha,\@empty,\@esphack,\@evenfoot}
+% \DoNotIndex{\@firstofone,\@firstoftwo,\@for}
+% \DoNotIndex{\@gobble,\@gobblefour,\@gobbletwo}
+% \DoNotIndex{\@ifclassloaded,\@ifdefinable,\@ifpackagewith,\@ifundefined}
+% \DoNotIndex{\@input,\@latexerr,\@mainaux,\@mparswitchtrue}
+% \DoNotIndex{\@namedef,\@nameuse,\@ne,\@next,\@nil,\@oddfoot,\@partaux}
+% \DoNotIndex{\@partlist,\@secondoftwo,\@sptoken}
+% \DoNotIndex{\@tempswafalse,\@tempswatrue,\@totalleftmargin}
+% \DoNotIndex{\@typeset@protect,\@unexpandable@protect}
+% \DoNotIndex{\@vobeyspaces,\@writeckpt,\@xxxii}
+% \DoNotIndex{\active,\addto@hook,\addtolength,\advance,\AtBeginDocument}
+% \DoNotIndex{\baselineskip,\begingroup,\bgroup,\box,\boxmaxdepth}
+% \DoNotIndex{\catcode,\char,\clearpage,\closeout,\color@begingroup}
+% \DoNotIndex{\color@endgroup,\copy,\csname}
+% \DoNotIndex{\deadcycles,\DeclareOption,\DeclareRobustCommand,\def}
+% \DoNotIndex{\discretionary,\divide,\do@space,\dp}
+% \DoNotIndex{\edef,\egroup,\else,\em,\endcsname,\endgroup,\ensuremath}
+% \DoNotIndex{\escapechar,\everypar,\expandafter}
+% \DoNotIndex{\fi,\font,\footnotesize,\frenchspacing,\futurelet}
+% \DoNotIndex{\g@addto@macro,\gdef,\global}
+% \DoNotIndex{\hb@xt@,\hbox,\hfill,\hss,\ht,\hyphenchar}
+% \DoNotIndex{\if,\if@filesw,\if@inlabel,\if@mparswitch,\if@partsw}
+% \DoNotIndex{\if@reversemargin,\if@tempswa,\ifcase,\ifcat,\iffalse}
+% \DoNotIndex{\ifmmode,\ifnum,\ifodd,\iftrue,\ifx,\ignorespaces}
+% \DoNotIndex{\immediate,\include,\indexentry,\input,\inputlineno,\item}
+% \DoNotIndex{\itshape,\kern}
+% \DoNotIndex{\labelsep,\langle,\language,\leavevmode,\let,\long,\loop}
+% \DoNotIndex{\m@ne,\m@ta,\makelabel,\marginpar,\marginparsep,\maxdimen}
+% \DoNotIndex{\MessageBreak,\multiply}
+% \DoNotIndex{\NeedsTeXFormat,\newcommand,\newdimen,\newlanguage}
+% \DoNotIndex{\nfss@text,\noexpand,\normalfont,\normalmarginpar,\number}
+% \DoNotIndex{\obeyspaces,\openout,\or}
+% \DoNotIndex{\PackageError,\PackageInfo,\PackageWarning}
+% \DoNotIndex{\PackageWarningNoLine,\pagestyle,\paperwidth,\parbox,\part}
+% \DoNotIndex{\ProcessOptions,\protect,\protected@edef,\protected@write}
+% \DoNotIndex{\protected@xdef,\ProvidesPackage}
+% \DoNotIndex{\raggedleft,\raggedright,\rangle,\relax,\renewcommand}
+% \DoNotIndex{\repeat,\RequirePackage}
+% \DoNotIndex{\setbox,\setlength,\sixt@@n,\space,\string,\strut,\strutbox}
+% \DoNotIndex{\textasciicircum,\textasciitilde,\textbackslash,\textbar}
+% \DoNotIndex{\textbf,\textbraceleft,\textbraceright,\textdollar}
+% \DoNotIndex{\textgreater,\textless,\textquotedbl,\textquoteleft}
+% \DoNotIndex{\textquoteright,\texttt,\textunderscore,\textvisiblespace}
+% \DoNotIndex{\textwidth,\the,\topsep,\trivlist,\tw@}
+% \DoNotIndex{\uccode,\unhbox,\unrestored@protected@xdef,\unvbox}
+% \DoNotIndex{\uppercase}
+% \DoNotIndex{\vbox,\vss,\vtop,\write,\xdef,\z@}
+%
+% \changes{prot1}{2000/06/15}{Started writing first prototype. (LH)}
+% \changes{prot2}{2000/07/13}{Began work on the second prototype. (LH)}
+%
+% \begin{abstract}
+% The \package{xdoc} package contains reimplementations of some of
+% the features found in the standard \LaTeX\ \package{doc}
+% package~\cite{doc} by Mittelbach \emph{et~al. }The ultimate goals
+% for these reimplementations are that the commands should be better,
+% easily configurable, and be easy to extend, but this is only a
+% second prototype implementation and nothing in it is guaranteed to
+% be the same in the third prototype.\footnote{But there are no
+% guarantees there will ever be a third prototype either.}
+% \end{abstract}
+%
+% \tableofcontents
+%
+%
+% \section{Usage}
+%
+% When I began working on this package I thought that there would be no
+% need for a usage section (at least on the prototype stage)---either you
+% are interested in using the new features and then you might just as
+% well read the descriptions of the commands in the implementation part
+% of this document (they are written as specifications of what the
+% commands do), or else you can simply insert a |\usepackage|\B|{xdoc2}|
+% in the preamble and see how things work a little better than when you
+% simply use \package{doc}---but with some features it became natural
+% to introduce incompatible changes and some new features ought to be
+% mentioned. Hence I wrote a short section on usage after all.
+%
+% It is my intention that this document will eventually evolve into the
+% source for a package \package{xdoc}\footnote{The name \package{doc2}
+% has also been discussed; we'll see when we get there.} which will
+% either build on the \package{doc} package and provide better
+% implementations of many of its features, or replace it completely,
+% but this document is still only the source for a prototype for that
+% package. As I believe that the need for some improvement in this area
+% is rather large however, I have decided to release this prototype so
+% that other people can use it in their documents or create packages that
+% are based on it. In doing so, one must of course bear in mind that this
+% prototype needs not be compatible with the final \package{xdoc}
+% package, and to overcome most incompatibility problems I therefore
+% release it under the variant name \package{xdoc2}. This way, documents
+% based on this prototype can still be typeset using the package they
+% were written for long after the next \package{xdoc} prototype (or final
+% version) is released.
+%
+% Thus although this document frequently speaks of \package{xdoc}, you
+% might just as well read it as \package{xdoc2}.
+%
+%
+% \subsection{Changes to old features}
+%
+% Whereas \package{doc} more or less assumes that all pages have the
+% same layout, \package{xdoc} takes measures to ensure that the
+% \package{doc} features support two-sided document designs. If the
+% left margin has been widened to better accommodate long macro names
+% however (like for example the \package{ltxdoc} document class does),
+% then you may find that the outer margin on right (odd) pages is too
+% narrow for printing macro names in. The remedy for this is the
+% \GenericDescribePrint{\MacroFont dolayout \normalfont option}^^A
+% \SortIndex{dolayout}{\texttt{dolayout} option\encapchar
+% usage}\texttt{dolayout} option; in two-sided mode it causes
+% \package{xdoc} to recompute the |\oddsidemargin| so that the outer
+% margin has the same size on right pages as it previously did on left
+% pages. In documents which are not processed in two-sided mode the
+% \texttt{dolayout} option has no effect.
+%
+% |\DocInput| has been changed to not make percent a comment character
+% upon return unless it was before the |\DocInput|. This makes |\DocInput|
+% nestable and I recommend that \texttt{.dtx} files which input other
+% \texttt{.dtx} files use |\DocInput| for this.
+%
+% The |\DocInclude| command, which is defined by the \package{ltxdoc}
+% document class rather than \package{doc}, is also by default
+% redefined in an incompatible manner by \package{xdoc}, but you can
+% stop \package{xdoc} from making incompatible changes if you pass it the
+% option \GenericDescribePrint{\MacroFont olddocinclude \normalfont
+% option}\SortIndex{olddocinclude}{\texttt{olddocinclude} option^^A
+% \encapchar usage}\texttt{olddocinclude}. The main incompatibility
+% lies in that the default redefinition of |\DocInclude| behaves purely
+% as an |\include| command which |\DocInput|s a \texttt{.dtx} file rather
+% than merely |\input|ting a \texttt{.tex} file---you must pass the
+% \GenericDescribePrint{\MacroFont fileispart \normalfont option}^^A
+% \SortIndex{fileispart}{\texttt{fileispart} option\encapchar
+% usage}\texttt{fileispart} option to \package{xdoc} to get the |\part|
+% headings etc.\ for each new file---but there are also minor changes
+% in the appearance of these headings, in how page styles are set, and
+% in how the information presented in the page footer is obtained.
+%
+% Other changes are as far as I can tell minor and within the bounds of
+% expected behaviour, but code that relies on the implementation of some
+% feature in \package{doc} may of course behave differently or break
+% completely. Note in particular that the formats of the internal
+% \package{doc} variables |\saved@macroname|, |\macro@namepart|, and
+% |\index@excludelist| have changed completely (see
+% Section~\ref{Sec:Changes}, Subsection~\ref{Ssec:Scanning macrocode},
+% and Subsection~\ref{Ssec:Index-exclude} respectively)---hence any hack
+% involving one of these must be revised before it is used with
+% \package{xdoc}. These are however exceptions; in my experience the most
+% noticeable changes not listed above are that the index exclude
+% mechanism actually works for control sequences whose names consist of
+% a single non-letter and that symbols get sorted in a different order.
+%
+%
+% \subsection{Some notable new features}
+%
+% The main new feature is the \DescribeMacro\NewMacroEnvironment
+% |\NewMacroEnvironment| command, which defines a new \texttt{macro}-like
+% environment. The command offers complete control of the argument
+% structure, the formatting of the marginal heading, the code for making
+% index entries, and the change entry sorting and formatting, but the
+% syntax is too complex to explain here. Those who are interested in
+% using it should read Section~\ref{Sec:Macro-environments}. In
+% particular, Subsections~\ref{Ssec:Macro&environment}--^^A
+% \ref{Ssec:More macros} contain several examples of how it can be
+% used. In addition to using |\New|\-|Macro|\-|Environment| for
+% redefining the \DescribeEnv{macro}\texttt{macro} and
+% \DescribeEnv{environment}\texttt{environment} environments,
+% \package{xdoc} also defines an \DescribeEnv{option}\texttt{option}
+% environment (which is intended for document class and package
+% options) and a \DescribeEnv{switch}\texttt{switch} environment (which
+% is intended for switches defined using |\newif|; the argument should
+% not include the |\if|).
+%
+% There is also a companion command \DescribeMacro\NewDescribeCommand
+% |\NewDescribeCommand| which defines new commands similar to
+% |\Describe|\-|Macro| and |\Describe|\-|Env|. The syntax of
+% |\New|\-|Describe|\-|Command| is also too complex to explain here, so
+% I have to refer readers who want to use it to Section~^^A
+% \ref{Sec:Describing}. Two more commands which are defined in that
+% section are \DescribeMacro\describeoption|\describe|\-|option|, which
+% is the \texttt{describe}\dots\ companion of the \texttt{option}
+% environment, and \DescribeMacro\describecsfamily
+% |\describe|\-|cs|\-|family| which is meant for describing control
+% sequence families (see the table on page~\pageref{Tab:CS-families} for
+% examples of what I mean). The argument of this latter command is simply
+% the material you would put between |\csname| and |\endcsname|. Variant
+% parts are written as |\meta|\B\marg{text} and print as one would expect
+% them to (but notice that the \meta{text} is a moving argument) whereas
+% most other characters can be written verbatim without any special
+% quoting (but |\|, |{|, |}|, and |%| need quoting; see the comments to
+% the definition of |\describe|\-|cs|\-|family| for information on how
+% to do that).
+%
+% The \DescribeMacro\DoNotIndexBy|\DoNotIndexBy| command tells the
+% commands that make index entries for macros to ignore a certain
+% character sequence when the index entries are sorted. The
+% |\DoNotIndexBy| command takes one argument: the character sequence to
+% ignore. If |\DoNotIndexBy| is used more than once then the indexing
+% commands will look for, and if it finds it ignore, each of the
+% character sequences given to it, starting with the one specified last.
+%
+% It has already been mentioned that the |\DocInclude| command has been
+% changed. What has not been mentioned is its companion
+% \DescribeMacro\setfileinfo|\setfileinfo|,
+% which the partfiles should use for setting the date and version
+% information presented in the page footer, but that is explained in
+% detail in Subsection~\ref{Ssec:New DocInclude}.
+%
+% Finally there is a new variant of the |\changes| command which is
+% intended for changes that, although not limited to a single macro and
+% thus being ``general'' changes in the \package{doc} terminology, affect
+% only a few (probably widely dispersed) macros (or whatever). The basic
+% idea is that you can define a change with a specific version, date,
+% and text using the \DescribeMacro{\definechange}|\definechange| command
+% and then recall those parameters later using the
+% \DescribeMacro{\usechange}|\usechange| command. Primarily this ensures
+% that the entry texts are identical so that \package{makeindex} will
+% combine them into one entry, but it is also specified which macro
+% was changed at which page. See Section~\ref{Sec:Changes} for more
+% details. Another new feature concerning |\changes| is that there is
+% now support for sorting version numbers according to mathematical
+% order rather than ASCII order. Traditionally the version numbers
+% \texttt{2}, \texttt{11}, and \texttt{100} would have been sorted so
+% that \texttt{100}${}<{}$\texttt{11}${}<{}$\texttt{2}, but if they are
+% entered as \DescribeMacro{\uintver}|\uintver{2}|, |\uintver{11}|, and
+% |\uintver{100}| then they will be sorted as
+% \texttt{2}${}<{}$\texttt{11}${}<{}$\texttt{100}. The argument of
+% |\uintver| must be a \TeX\ \meta{number}.
+%
+% \medskip
+%
+% \package{xdoc} also contains several features which are of little use
+% as direct user commands, but which can simplify the definitions of other
+% commands. The foremost of these are the `harmless character strings',
+% which can be seen as a datatype for (short pieces of) verbatim text.
+% \TeX\ typesets a harmless character string in pretty much the same way
+% as the corresponding string of `other' tokens, but the harmless
+% character string can also be written to file and read back arbitrarily
+% many times without getting garbled, it doesn't make \package{makeindex}
+% choke, and it survives being fed to a |\protected@edef|. The most
+% important commands related to harmless character strings are
+% \DescribeMacro\PrintChar|\PrintChar|, which is used for representing
+% problematic characters, and \DescribeMacro\MakeHarmless|\MakeHarmless|,
+% which converts arbitrary \TeX\ code to the corresponding harmless
+% character string.
+%
+% The superfluity of indexing commands in \package{doc} has been
+% replaced by the single command \DescribeMacro\IndexEntry|\IndexEntry|,
+% which has been designed with the intention that it should provide a
+% clear interface between the user level macros and the index sorting
+% program. It takes three arguments: the index entry specification, the
+% name of the encapsulation scheme that should be used, and the number to
+% put in the index. The index entry specification is a sequence of
+% |\LevelSame| and\slash or |\LevelSorted| commands, which have the
+% respective syntaxes
+% \begin{quote}
+% \DescribeMacro\LevelSame|\LevelSame|\marg{text}\\
+% \DescribeMacro\LevelSorted|\LevelSorted|\marg{sort key}\marg{text}
+% \end{quote}
+% Each such command specifies one level of the index entry. In the case of
+% |\LevelSorted|, the \meta{text} is what will be written in the sorted
+% index at that level and \meta{sort key} is what the index-sorting
+% program should look at when sorting the entry (at that level). In the
+% case of |\LevelSame|, the \meta{text} is used both as sort key and
+% contents of entry in the sorted index. The first command is for the
+% topmost level and each subsequent command is for the next sublevel.
+% The complete description appears in Subsection~\ref{Ssec:IndexEntry}.
+%
+% \package{xdoc} also contains support for external cross-referencing
+% programs (see Subsection~\ref{Ssec:XXR} for details) and a system for
+% determining whether a piece of text falls on an even or an odd page
+% (see Section~\ref{Sec:Twoside} for details). I expect that the latter
+% system will eventually migrate out of \package{xdoc}, either to a
+% package of its own, or into oblivion because the \LaTeXplus\ output
+% routine makes it obsolete.
+%
+%
+% \subsection{The \package{docindex} package}
+%
+% As of prototype version 2.2, the \package{xdoc} package has a companion
+% package \package{docindex}~\cite{docindex} which provides improved
+% formatting of the index and list of changes. \package{xdoc} works fine
+% without \package{docindex}, however.
+%
+%
+% \subsection{A note on command names}
+%
+% The \package{doc} package defines several commands with mixed-case
+% names which (IMHO) should really have all-lower-case names (according
+% to the rule of thumb spelled out in \cite[Ssec.~2.4]{clsguide}) since
+% people use them in the capacity of being the author of a \texttt{.dtx}
+% file rather than in the capacity of being the writer of a class or
+% package. The names in question are
+% \begin{longtable}{ll}
+% \textbf{Name in \package{doc}}& \textbf{Better (?) name}\endhead
+% \cs{AlsoImplementation}& \cs{alsoimplementation}\\
+% \cs{CharacterTable}& \cs{charactertable}\\
+% \cs{CharTableChanges}& \cs{chartablechanges}\\
+% \cs{CheckModules}& \cs{checkmodules}\\
+% \cs{CheckSum}& \cs{checksum}\\
+% \cs{CodelineIndex}& \cs{codelineindex}\\
+% \texttt{CodelineNo} (counter)& \texttt{codelineno}\\
+% \cs{CodelineNumbered}& \cs{codelinenumbered}\\
+% \cs{DeleteShortVerb}& \cs{deleteshortverb}\\
+% \cs{DescribeEnv}& \cs{describeenv}\\
+% \cs{DescribeMacro}& \cs{describemacro}\\
+% \cs{DisableCrossrefs}& \cs{disablecrossrefs}\\
+% \cs{DocInput}& \cs{docinput}\\
+% \cs{DoNotIndex}& \cs{donotindex}\\
+% \cs{DontCheckModules}& \cs{dontcheckmodules}\\
+% \cs{EnableCrossrefs}& \cs{enablecrossrefs}\\
+% \cs{Finale}& \cs{finale}\\
+% \texttt{GlossaryColumns} (counter)& \texttt{glossarycolumns}\\
+% \cs{GlossaryPrologue}& \cs{glossaryprologue}\\
+% \texttt{IndexColumns} (counter)& \texttt{indexcolumns}\\
+% \cs{IndexInput}& \cs{indexinput}\\
+% \cs{IndexPrologue}& \cs{indexprologue}\\
+% \cs{MakePrivateLetters}& \cs{makeprivateletters}\\
+% \cs{MakeShortVerb}& \cs{makeshortverb}\\
+% \cs{OnlyDescription}& \cs{onlydescription}\\
+% \cs{PageIndex}& \cs{pageindex}\\
+% \cs{PrintChanges}& \cs{printchanges}\\
+% \cs{PrintIndex}& \cs{printindex}\\
+% \cs{RecordChanges}& \cs{recordchanges}\\
+% \cs{SortIndex}& \cs{sortindex}\\
+% \cs{SpecialEscapechar}& \cs{specialescapechar}\\
+% \texttt{StandardModuleDepth} (counter)& \texttt{standardmoduledepth}\\
+% \cs{StopEventually}& \cs{stopeventually}
+% \end{longtable}
+% \noindent With the exception for \texttt{CodelineNo},\footnote{Where I
+% recommend using \texttt{codelineno} instead of \texttt{CodelineNo},
+% \cs{PrintCodelineNo} instead of \cs{theCodelineNo}, and
+% \cs{thecodelineno} instead of \cs{number}\cs{c@CodelineNo}; see
+% Subsection~\ref{Ssec:CodelineNo}.} I haven't changed any of the
+% \package{doc} names in this \package{xdoc} prototype, nor introduced any
+% of the ``better names'' as alternatives, but I think the matter should
+% be given a bit of thought during the future development of
+% \package{doc}\slash \package{xdoc}.
+%
+% For completeness, I should also remark that there are several macros
+% that \package{doc} gives mixed-case names which I haven't listed above.
+% The logo command names have special capitalizing rules by tradition.
+% Some macros and named registers---for example |\Docstyle|\-|Parms|,
+% |\Index|\-|Parms|, |\Macro|\-|Font|, |\Macro|\-|Topsep|,
+% |\Make|\-|Percent|\-|Ignore|, and |\Print|\-|Macro|\-|Name|---are part
+% of the package or document class writer's interface to \package{doc},
+% although I cannot claim it to be obvious that for example
+% |\Index|\-|Parms| and the \texttt{IndexColumns} counter should belong
+% to different classes here (but several of these control sequences will
+% probably disappear from the interface in \LaTeXplus\ anyway, so the
+% problem isn't that important). The |\Special|\dots\B|Index| commands
+% (and their even more special variants, such as
+% |\Left|\-|Brace|\-|Index|) are internal commands rather than user level
+% commands. Finally there is the |\Get|\-|File|\-|Info| command, which I
+% doubt there is any point in having.
+%
+%
+% \StopEventually{}
+%
+%
+% \subsection{\package{docstrip} modules}
+%
+% The \package{docstrip} modules in \texttt{xdoc2.dtx} are:
+% \begin{description}
+% \item[\textsf{pkg}]
+% This module directive surrounds the code for the \package{xdoc}
+% package.
+% \item[\textsf{driver}]
+% The driver.
+% \item[\textsf{internals}]
+% This module contains an alternative replacement text for the
+% |\Print|\-|Visible|\-|Char| command that uses ``\LaTeX\ internal
+% character representation'' (i.e., as much as possible
+% encoding-specific commands---|\text|\textellipsis\ commands and
+% the like) rather than the primitive |\char| command for
+% typesetting visible characters.
+% It is provided as a separate module mainly for compability with
+% prototype version~2.0, as this alternative definition can (as of
+% prot.\,2.1) be chosen by passing the option
+% \describeoption{notrawchar}\texttt{notrawchar} to \package{xdoc}.
+% \item[\textsf{economical}]
+% There is little point in storing the harmless representations of
+% the 161 non-visible-ASCII characters as these representations are
+% always the same and can be formed on the fly whenever they are
+% needed. The \textsf{economical} modules contain some alternative
+% code which makes use of this fact to reduce the number of control
+% sequences used for storing the table of harmless representations.
+% The \Module{economical} module appears inside the \Module{pkg}
+% module.
+% \item[\textsf{xdoc2}]
+% This module contains code for compability with previous releases
+% of \package{xdoc2}. It will not be included in \package{xdoc3}
+% or \package{xdoc} (whichever is the next major version).
+% \item[\textsf{enccmds}]
+% This module contains the code for defining two \texttt{macro}-like
+% environments for encoding-specific commands. These are not included
+% in the \package{xdoc} package since so few \texttt{.dtx} files
+% define encoding-specific commands.
+% \item[\textsf{rsrccmd}]
+% Similar to the \textsf{enccmds} module, but demonstrates the
+% |\New|\-|Describe|\-|Command| command instead.
+% \item[\textsf{example}]
+% This surrounds some code which to \package{docstrip} looks like it
+% should be copied, but isn't meant to.
+% \end{description}
+%
+%
+%
+% \section{Initial stuff}
+%
+% First there's the usual |\NeedsTeXFormat| and |\ProvidesPackage|.
+% \begin{macrocode}
+%<*pkg>
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{xdoc2}[2003/07/06 prot2.5 doc reimplementation package]
+% \end{macrocode}
+%
+% \subsection*{Options}
+%
+% The first option has to do with the page layout.
+% Although \package{doc} itself doesn't modify any of the main layout
+% parameters, it is well known that using it does tend to restrict
+% one's choices in terms of document layout. In particular the
+% \texttt{macro} and \texttt{environment} environments require a rather
+% large left margin since they will otherwise print long macro names
+% partially outside the paper. It is furthermore hard to decrease the
+% |\textwidth| as it should be wide enough to contain about 70 columns of
+% |\MacroFont| text. Thus the only solution is to do as the
+% \package{ltxdoc}~\cite{ltxdoc} document class and enlarge the left
+% margin at the expense of the right.
+%
+% The resulting layout has a left--right asymmetry with the main galley
+% (the text rectangle) on the right and a very wide left margin (in
+% which marginal headings and marginal notes appears). Although this
+% layout is not uncommon in technical manuals, it is inappropriate for
+% two-sided designs since the vertical line at which the two pages of a
+% spread meet becomes the natural vertical symmetry axis for the entire
+% spread and it breaks this symmetry to let the left margin be the
+% widest on all pages. It would look better to always let the outer
+% margin be the largest.
+%
+% \begin{option}{dolayout}
+% \begin{macro}{\oddsidemargin}
+% The \texttt{dolayout} option modifies |\oddsidemargin| so that
+% spreads are symmetric around the center in two-sided mode. As size
+% of the outer margin is taken the size of the left margin on left
+% (even) pages, i.e., |\evensidemargin|${}+1\,\mathrm{in}$.
+%
+% In one-sided mode, the \texttt{dolayout} option does nothing.
+% \begin{macrocode}
+\DeclareOption{dolayout}{%
+ \if@twoside
+ \setlength\oddsidemargin{\paperwidth}
+ \addtolength\oddsidemargin{-\textwidth}
+ \addtolength\oddsidemargin{-\evensidemargin}
+ \addtolength\oddsidemargin{-2in}
+ \fi
+}
+% \end{macrocode}
+% \end{macro}\end{option}
+%
+% \begin{option}{olddocinclude}
+% \begin{option}{fileispart}
+% The \texttt{olddocinclude} and \texttt{fileispart} options are
+% related to the |\DocInclude| command defined by the \package{ltxdoc}
+% document class. Some of the code related to that command relies on
+% modifying the \package{doc} internal macro |\codeline@wrindex|, but
+% that has no effect with \package{xdoc} so in order to get the
+% expected results one has to reimplement the |\DocInclude| command as
+% well. The \texttt{olddocinclude} and \texttt{fileispart} options
+% control how this should be done.
+%
+% If the \texttt{olddocinclude} option is passed to \package{xdoc}
+% then only the parts of the implementation of |\DocInclude| which
+% must be altered to make the command work with the \package{xdoc}
+% implementation of indexing and cross-referencing are changed. These
+% redefinitions will furthermore only be made if the \package{ltxdoc}
+% document class has been loaded; nothing is done if the
+% \texttt{olddocinclude} option is passed and \package{ltxdoc} hasn't
+% been loaded. Passing the \texttt{olddocinclude} option can be
+% considered as requesting a ``compatibility mode'' for |\DocInclude|.
+%
+% If the \texttt{olddocinclude} option is not passed then the
+% |\DocInclude| command is reimplemented from scratch, regardless of
+% whether some definition of it has already been given or not. The
+% basis of this reimplementation is the observation that the
+% |\DocInclude| command of \package{ltxdoc} really does two quite
+% distinct things at once---it is an |\include| command which
+% |\DocInput|s files rather than |\input|ting them, but it also starts
+% a new |\part|, sets the pagestyle, and changes how the values of
+% some counters are typeset. This latter function is by default
+% disabled in the \package{xdoc} implementation of |\DocInclude|, but
+% passing the \texttt{fileispart} option enables it.
+%
+% There is no code for these two options here, as it is rather long;
+% instead that code appears in Section~\ref{Sec:DocInclude}. The
+% |\Pass|\-|Options|\-|To|\-|Package| commands make sure that these
+% options are registered as local options for \package{xdoc}, so that
+% one can test for them using |\@if|\-|package|\-|with| below.
+% \begin{macrocode}
+\DeclareOption{olddocinclude}{%
+ \PassOptionsToPackage{\CurrentOption}{xdoc2}%
+}
+\DeclareOption{fileispart}{%
+ \PassOptionsToPackage{\CurrentOption}{xdoc2}%
+}
+% \end{macrocode}
+% \end{option}\end{option}
+%
+% \changes{prot2.5}{2003/07/06}{Reregeristing options in case
+% they were global. (LH)}
+%
+% \begin{option}{notrawchar}
+% The \texttt{notrawchar} option controls how the |\PrintVisibleChar|
+% command is defined, and thereby what method is used for typesetting
+% visible characters in e.g.\ macro names. The default is to use the
+% |\char| primitive (which is better for \texttt{T1}-encoded fonts and
+% non-italic \texttt{OT1}-encoded typewriter fonts), but the
+% \texttt{notrawchar} option causes things to go via the ``\LaTeX\
+% internal character representation'' instead (which is necessary
+% for e.g.\ \texttt{OT1}-encoded non-typewriter fonts).
+%
+% There is no code for this option here; instead that code is found
+% in the definition of |\Print|\-|Visible|\-|Char|.
+% \begin{macrocode}
+\DeclareOption{notrawchar}{%
+ \PassOptionsToPackage{\CurrentOption}{xdoc2}%
+}
+% \end{macrocode}
+% \end{option}
+%
+%
+% Then options are processed.
+% \begin{macrocode}
+\ProcessOptions\relax
+% \end{macrocode}
+% And finally the \package{doc} package is loaded.
+% \begin{macrocode}
+\RequirePackage{doc}
+% \end{macrocode}
+%
+%
+% \section{Character strings}
+%
+% A source of much of the complexity in \package{doc} is that it has to
+% be able to deal with rather arbitrary strings of characters (mainly
+% the names of control sequences). Once the initial problems with
+% characters having troublesome catcodes have been overcome however, it
+% is usually no problem to manage such things in \TeX. \package{doc}
+% does however complicate things considerably by also putting these
+% things in the index and list of changes. Not only must they then be
+% formatted so that the \package{makeindex} program doesn't choke on
+% them, but they must also be wrapped up in code that allows \TeX\ to
+% make sense of them when they are read back. \package{doc} manages the
+% \package{makeindex} problems mainly by allowing the user to change what
+% characters are used as \package{makeindex} metacharacters and the
+% reading back problem by making abundant use of |\verb|.
+%
+% All this relies on that the author of a document is making sure that
+% the metacharacters aren't used for anything else. If for example the
+% |\verbatimchar| (by default |+|) is one of the ``private letters''
+% then names of control sequences containing that character will be
+% typeset incorrectly because the |\verb| used to typeset it is
+% terminated prematurely---control sequence names such as `|\lost+found|'
+% will be typeset as `|\lost|found+'. On top of that, one also has to
+% make sure that the font used for typesetting these |\verb| sections
+% contains all the characters needed.
+%
+% For \package{xdoc}, I have chosen a completely different approach.
+% Instead of allowing the strings (after they have converted to the
+% internal format) to contain \TeX\ character tokens with arbitrary
+% character codes, they may only contain \TeX\ character tokens which
+% are unproblematic---the normal catcode should be 11 (letter) or 12
+% (other), they should not be outside visible ASCII, and they may not
+% be one of the \package{makeindex} metacharacters. All other characters
+% are represented using a robust command which takes the character code
+% (in decimal) as the argument. This takes care of all ``moving
+% argument'' type problems that may occur.
+%
+% An important observation about these character strings is that
+% they are strings of \emph{input} characters. This means that rather
+% than using the characters in some special font for typesetting
+% control sequences like |\^^M| (recall that the |^^| substitutions
+% take place before tokenization), one should typeset them using only
+% visible ASCII characters. (After all, that's the only way they are
+% written in \TeX\ code.) The default definition is to typeset
+% invisible characters as precisely the |^^|-sequences that \TeX\
+% normally uses for these characters when they are written to a file.
+%
+%
+% \subsection{Typesetting problematic characters}
+%
+% \begin{macro}{\PrintChar}
+% \begin{macro}{\XD@threedignum}
+% The |\PrintChar| command has the syntax
+% \begin{quote}
+% |\PrintChar|\marg{8-bit number}
+% \end{quote}
+% where \meta{8-bit number} is a \TeX\ number in the range 0--255.
+% For arguments in the range 0--31, |\PrintChar| prints
+% `\textit{\ttfamily\string^\string^@}'--`\textit{\ttfamily
+% \string^\string^\string_}'. For an argument in the range 32--126,
+% |\PrintChar| calls |\Print|\-|Visible|\-|Char| which by default
+% simply does |\char| on that argument (but which can be redefined
+% if the font set-up requires it); in particular, |\PrintChar{32}|
+% should print a ``visible space'' character. |\PrintChar{127}| prints
+% `\textit{\ttfamily\string^\string^?}'. For arguments in the range
+% 128--255, |\PrintChar| prints
+% `\textit{\ttfamily\string^\string^80}'--`\textit{\ttfamily
+% \string^\string^ff}'.
+%
+% |\PrintChar| is robust. |\PrintChar| also has a special behaviour
+% when it is written to a file (when |\protect| is |\noexpand|): it
+% makes sure that the argument consists of three decimal digits, to
+% ensure external sorting gets it right.
+% \begin{macrocode}
+\@ifundefined{PrintChar}{}{%
+ \PackageInfo{xdoc2}{Redefining \protect\PrintChar}%
+}
+\def\PrintChar{%
+ \ifx \protect\@typeset@protect
+ \expandafter\XD@PrintChar
+ \else\ifx \protect\noexpand
+ \string\PrintChar
+ \expandafter\expandafter \expandafter\XD@threedignum
+ \else
+ \noexpand\PrintChar
+ \fi\fi
+}
+% \end{macrocode}
+%
+% |\XD@threedignum| does a |\number| on its argument, possibly prepends
+% a |0| or two, and wraps it all up in a ``group'' (the braces have
+% category other, not beginning and end of group).
+% \changes{prot2.1}{2000/11/15}{Braces inserted by
+% \cs{XD@threedignum} are given catcode other. (LH)}
+% \begin{macrocode}
+\edef\XD@threedignum#1{%
+ \string{%
+ \noexpand\ifnum #1<100 %
+ \noexpand\ifnum #1<10 0\noexpand\fi
+ 0%
+ \noexpand\fi
+ \noexpand\number#1%
+ \string}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\XD@PrintChar}
+% \begin{macro}{\InvisibleCharPrefix}
+% \begin{macro}{\InvisibleCharSuffix}
+% |\XD@PrintChar| manages the typesetting for |\PrintChar|. It
+% distinguishes between visible characters (code 32--126) and
+% invisible characters. The visible characters are typeset directly
+% using |\PrintVisibleChar|, whereas the invisible characters are
+% typeset as |^^|-sequences.
+%
+% The macros |\InvisibleCharPrefix| and |\InvisibleCharSuffix| begin
+% and end a |^^|-sequence. |\InvisibleCharPrefix| should print the
+% actual |^^|, but it may also for example select a new font for
+% the |^^|-sequence (such font changes are restored at the end of
+% |\XD@PrintChar|).
+% \begin{macrocode}
+\def\XD@PrintChar#1{%
+ \leavevmode
+ \begingroup
+ \count@=#1\relax
+ \ifnum \@xxxii>\count@
+ \advance \count@ 64%
+ \InvisibleCharPrefix
+ \PrintVisibleChar\count@
+ \InvisibleCharSuffix
+ \else\ifnum 127>\count@
+ \PrintVisibleChar\count@
+ \else
+ \InvisibleCharPrefix
+ \ifnum 127=\count@ \PrintVisibleChar{63}\else
+ \@tempcnta=\count@
+ \divide \count@ \sixt@@n
+ \@tempcntb=\count@
+ \multiply \count@ \sixt@@n
+ \advance \@tempcnta -\count@
+ \advance \@tempcntb \ifnum 9<\@tempcntb 87\else 48\fi
+ \advance \@tempcnta \ifnum 9<\@tempcnta 87\else 48\fi
+ \char\@tempcntb \char\@tempcnta
+ \fi
+ \InvisibleCharSuffix
+ \fi\fi
+ \endgroup
+}
+% \end{macrocode}
+% \begin{macrocode}
+\newcommand\InvisibleCharPrefix{%
+ \/\em
+ \PrintVisibleChar{`\^}\PrintVisibleChar{`\^}%
+}
+\newcommand\InvisibleCharSuffix{\/}
+% \end{macrocode}
+% There are some alternative methods for making hexadecimal numbers
+% which should perhaps be mentioned. The \LaTeX\ kernel contains a
+% macro |\hexnumber@| which uses |\ifcase| to produce one hexadecimal
+% digit, but that uses upper case letters, and things like `8E' look
+% extremely silly if the upper case letters doesn't line with the
+% digits. Applying |\meaning| to a \meta{chardef token} or
+% \meta{mathchardef token} expands to |\char"|\meta{hex} and
+% |\mathchar"|\meta{hex} respectively, where \meta{hex} is the
+% corresponding number in hexadecimal, but that too has upper case A--F
+% and leading zeros are removed.
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\PrintVisibleChar}
+% \changes{prot2.1}{2000/12/18}{Made it possible to select the
+% alternative defintion of \cs{PrintVisibleChar} through an
+% \package{xdoc} package option. (LH)}
+% The |\PrintVisibleChar| command should print the visible ASCII
+% character whose character code is given in the argument. There are
+% currently two definitions of this command: one which uses the \TeX\
+% primitive |\char| and one which goes via the ``\LaTeX\ internal
+% character representation'' for the character. By default
+% \package{xdoc} uses the former definition, but if \package{xdoc}
+% is passed the
+% \SortIndex{notrawchar}{\texttt{notrawchar} option\encapchar usage}
+% \texttt{notrawchar} option then it will use the latter.
+%
+% The reason there are two definitions is a deficiency in how the NFSS
+% encoding attribute has been assigned to fonts; even though the
+% encodings of Computer Modern Roman and Computer Modern Typewriter
+% are quite different, \LaTeXe\ uses the \texttt{OT1} encoding for
+% both. As a result of this, the \LaTeX\ internal representation will
+% in some important cases use characters from non-typewriter fonts
+% despite the fact that typewriter forms are immediately available.
+% Since the cases in which the |\char| primitive produces results as
+% least as good as those made through the \LaTeX\ internal
+% character representation includes those that the current font is
+% \texttt{T1}-encoded or an \texttt{OT1}-encoded nonitalic typewriter
+% font, the shorter |\char| primitive defintion has been made the
+% default.
+%
+% For compability with prototype version~2.0 of \package{xdoc}, the
+% replacement text for |\Print|\-|Visible|\-|Char| that uses \LaTeX\
+% internal character representation can alternatively be extracted by
+% \package{docstrip}ping \texttt{xdoc2.dtx} with the option
+% \Module{internals}.
+% \begin{macrocode}
+\@ifpackagewith{xdoc2}{notrawchar}{%
+ \newcommand\PrintVisibleChar[1]{%
+%</pkg>
+%<*pkg|internals>
+ \ifcase #1%
+ \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
+ \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
+ % "20
+ \textvisiblespace \or!\or\textquotedbl \or\#\or\textdollar
+ \or\%\or\&\or\textquoteright\or(\or)\or*\or+\or,\or-\or.\or/%
+ \or % "30
+ 0\or1\or2\or3\or4\or5\or6\or7\or8\or9\or:\or;\or
+ \textless\or=\or\textgreater\or?%
+ \or % "40
+ @\or A\or B\or C\or D\or E\or F\or G\or
+ H\or I\or J\or K\or L\or M\or N\or O%
+ \or % "50
+ P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\or [\or
+ \textbackslash \or]\or\textasciicircum \or\textunderscore
+ \or % "60
+ \textquoteleft \or a\or b\or c\or d\or e\or f\or g\or h\or
+ i\or j\or k\or l\or m\or n\or o%
+ \or % "70
+ p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\or
+ \textbraceleft \or\textbar \or\textbraceright \or
+ \textasciitilde
+ \fi
+ }%
+%</pkg|internals>
+%<*pkg>
+}{%
+ \newcommand\PrintVisibleChar[1]{\char #1\relax}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\Bslash}
+% It turns out that it is very common to say |\PrintChar{92}|
+% (backslash), so a macro which expands to that reduces typing.
+% \begin{macrocode}
+\newcommand\Bslash{\PrintChar{92}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Rendering character strings harmless}
+%
+% Replacing all problematic characters with |\PrintChar| calls certainly
+% makes the strings easier to manage, but actually making those
+% replacements is a rather complicated task. Therefore this subsection
+% contains the macros necessary for doing these replacements.
+%
+% The first problem is how to efficiently recognise the problematic
+% characters. A first solution which gets rather far is to mainly look
+% in the |\catcode| register for that character and keep the character
+% as it is if the category found there is 11 or 12, but replace it with
+% a |\PrintChar| command if the category is anything else. Two extra
+% tests can be performed to take care of invisible ASCII, and the
+% \package{makeindex} metacharacters can be cared for by locally
+% changing their catcodes for when the string is processed.
+% Unfortunately this doesn't work inside \texttt{macrocode}
+% environments (where one would like to use it for the macro
+% cross-referencing) since that environment changes the catcodes of
+% several characters from being problematic to being unproblematic and
+% vice versa.\footnote{As the entire \texttt{macrocode} environment is
+% tokenized by the expansion of \cs{xmacro@code} one could alternatively
+% solve this problem by reimplementing the \texttt{macrocode}
+% environment so that normal catcodes are in force when the contents are
+% being typeset.} As furthermore harmless character strings should be
+% possible to move to completely different parts of the document, the
+% test used for determining whether a character is problematic should
+% yield the same result throughout the document.
+%
+% Because of this, I have chosen a brute strength solution: build a
+% table (indexed by character code) that gives the harmless form of
+% every character. This table is stored in the
+% \describecsfamily{XD@harmless@\meta{code}}^^A
+% |\XD@harmless@|\meta{code} family of control sequences, where the
+% \meta{code} is in the range |0|--|255|. Assignments to this table are
+% global. In principle, the table should not change after the preamble,
+% but there is a command |\SetHarmState| which can be used at any time
+% for setting a single table entry. This could be useful for documents
+% which, like for example~\cite{fontinst}, have nonstandard settings of
+% |\catcode|s.
+%
+% \begin{macro}{\SetHarmState}
+% The |\SetHarmState| command takes three arguments:
+% \begin{quote}
+% |\SetHarmState|\marg{type}\marg{char}\marg{harm}
+% \end{quote}
+% \meta{char} is the character whose entry should be set. \meta{type}
+% is a flag which specifies what format \meta{char} is given in. If
+% \meta{type} is |\BooleanTrue| then \meta{char} is the \TeX\
+% \meta{number} of the table entry to set, and if \meta{type} is
+% |\BooleanFalse| then \meta{char} is something which expands to a
+% single character token whose entry should be set. The expansion is
+% carried out by an |\edef|, so it needs not be only one level.
+% \meta{harm} is |\BooleanTrue| if the character is problematic and
+% |\BooleanFalse| if it is not.
+%
+% The \meta{type} and \meta{harm} arguments are currently not subject
+% to any expansion. In the future they probably should be, but I
+% don't want to make assumptions about the actual definitions of
+% |\BooleanTrue| and |\BooleanFalse| at this point.
+% \begin{macrocode}
+\begingroup
+ \catcode\z@=12
+ \@ifdefinable\SetHarmState{
+ \gdef\SetHarmState#1#2#3{%
+ \begingroup
+ \ifx #1\BooleanTrue
+ \count@=#2\relax
+ \else
+ \protected@edef\@tempa{#2}%
+ \count@=\expandafter`\@tempa\relax
+ \fi
+ \ifx #3\BooleanTrue
+ \edef\@tempa{\noexpand\PrintChar{\the\count@}}%
+ \else
+ \uccode\z@=\count@
+ \uppercase{\def\@tempa{^^@}}%
+ \fi
+ \global\expandafter\let
+ \csname XD@harmless@\the\count@ \endcsname \@tempa
+ \endgroup
+ }%
+ }
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{trivlist}\item[]\leavevmode ^^A Just for the look of it
+% \GenericDescribePrint{\small\cs{XD@harmless@}\meta{code}}^^A
+% ^^A There should have been a "main" index entry here as well,
+% ^^A but generating that with \package{doc} commands is more than I
+% ^^A bother to do right now.
+% Initializing the |\XD@harmless@|\meta{code} table is a
+% straightforward exercise of |\loop| \dots\ |\repeat|.
+% \begin{macrocode}
+%<*!economical>
+\count@=\z@
+\loop
+ \expandafter\xdef \csname XD@harmless@\the\count@ \endcsname
+ {\noexpand\PrintChar{\the\count@}}%
+ \advance \count@ \@ne
+\ifnum 33>\count@ \repeat
+%</!economical>
+%<economical>\count@=\@xxxii
+\begingroup
+ \catcode\z@=12\relax
+ \@firstofone{%
+\endgroup
+ \loop
+ \if \ifnum 11=\catcode\count@ 1\else \ifnum 12=\catcode\count@
+ 1\else 0\fi\fi 1%
+ \uccode\z@=\count@
+ \uppercase{\def\@tempa{^^@}}%
+ \else
+ \edef\@tempa{\noexpand\PrintChar{\the\count@}}%
+ \fi
+ \global\expandafter\let
+ \csname XD@harmless@\the\count@ \endcsname \@tempa
+ \advance \count@ \@ne
+ \ifnum 127>\count@ \repeat
+}
+%<*!economical>
+\loop
+ \expandafter\xdef \csname XD@harmless@\the\count@ \endcsname
+ {\noexpand\PrintChar{\the\count@}}%
+\ifnum \@cclv>\count@
+ \advance \count@ \@ne
+\repeat
+%</!economical>
+% \end{macrocode}
+% Marking the \package{makeindex} metacharacters as harmful is
+% deferred until |\begin|\nolinebreak[2]|{document}|, since it is not
+% unreasonable that these are changed in the preamble.
+% \begin{macrocode}
+\AtBeginDocument{%
+ \SetHarmState\BooleanFalse\actualchar\BooleanTrue
+ \SetHarmState\BooleanFalse\encapchar\BooleanTrue
+ \SetHarmState\BooleanFalse\levelchar\BooleanTrue
+ \SetHarmState\BooleanFalse\quotechar\BooleanTrue
+}
+% \end{macrocode}
+% \package{doc}'s |\verbatimchar| is not harmful, since it isn't used
+% at all in \package{xdoc}.
+% \end{trivlist}
+%
+%
+% \begin{macro}{\MakeHarmless}
+% To render a character string harmless, you do
+% \begin{quote}
+% |\MakeHarmless|\marg{macro}\marg{string}
+% \end{quote}
+% This locally assigns to \meta{macro} the harmless character string
+% which corresponds to \meta{string}. During the conversion the converted
+% part of the string is stored in |\toks@|, but that is local to
+% |\MakeHarmless|.
+% \begin{macrocode}
+\def\MakeHarmless#1#2{%
+ \begingroup
+ \toks@={}%
+ \escapechar=`\\%
+ \XD@harmless@#2\XD@harmless@
+ \expandafter\endgroup \expandafter\def \expandafter#1%
+ \expandafter{\the\toks@}%
+}
+% \end{macrocode}
+%
+% \begin{macro}{\XD@harmless@iii}
+% \begin{macro}{\XD@harmless@iv}
+% \begin{macro}{\XD@harmless@v}
+% \changes{prot2}{2000/07/27}{Moved code for adding to \cs{toks@} here
+% and changed it to append the contents of \cs{XD@harmless@32}, not
+% necessarily a \cs{PrintChar}. (LH)}
+% \begin{macro}{\XD@harmless@vi}
+% What one has to be most careful about when rendering strings
+% harmless are the space tokens, since many of \TeX's primitives gladly
+% snatches an extra space (or more) where you don't want them to in
+% this case. Macro parameters can be particularly dangerous, as \TeX\
+% will skip any number of spaces while looking for the replacement
+% text for an undelimited macro argument. Therefore the algorithm for
+% rendering a character token harmless begins
+% (|\XD@|\B|harmless@iii|) with |\string|ing the next token in the
+% string---this preserves the character code and sets the category to
+% 12 for all characters except the ASCII space, which gets category 10
+% (space)---and then |\futurelet| is used to peek at the next token. If
+% it is a space token (|\XD@|\B|harmless@iv|) then the character code
+% is 32 and the actual space can be gobbled (|\XD@|\B|harmless@v|), and
+% if it isn't then the next token can be grabbed in an undelimited macro
+% argument (|\XD@|\B|harmless@vi|). In either case, the harmless form
+% is given by the |\XD@|\B|harmless@|\meta{code} table entry
+% (in |\XD@|\B|harmless@v| or |\XD@|\B|harmless@vi|).
+% \begin{macrocode}
+\def\XD@harmless@iii{%
+ \expandafter\futurelet \expandafter\@let@token
+ \expandafter\XD@harmless@iv \string
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@harmless@iv{%
+ \ifx \@let@token\@sptoken
+ \expandafter\XD@harmless@v
+ \else
+ \expandafter\XD@harmless@vi
+ \fi
+}
+% \end{macrocode}
+% ^^A Hack:
+% \begingroup
+% \expandafter\def \expandafter\MakePrivateLetters \expandafter{^^A
+% \MakePrivateLetters
+% \catcode`3=11
+% \catcode`2=11
+% }
+% \begin{macrocode}
+\begingroup
+ \catcode`3=\catcode`a
+ \catcode`2=\catcode`a
+ \@firstofone{\gdef\XD@harmless@v} {%
+ \toks@=\expandafter{\the \expandafter\toks@ \XD@harmless@32}%
+ \XD@harmless@
+ }
+\endgroup
+% \end{macrocode}
+% \endgroup
+% In the \Module{economical} (with hash table space) variant
+% implementation the |\XD@harmless@|\meta{code} table has entries only
+% for the characters in visible ASCII. Thus the harmless forms of
+% characters outside visible ASCII must be constructed on the fly.
+% \begin{macrocode}
+\def\XD@harmless@vi#1{%
+%<*economical>
+ \if \ifnum `#1<\@xxxii 1\else \ifnum `#1>126 1\else 0\fi\fi 1%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\PrintChar \expandafter{\number`#1}%
+ }%
+ \else
+%</economical>
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname XD@harmless@\number`#1\endcsname}%
+%<economical> \fi
+ \XD@harmless@
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@harmless@}
+% \begin{macro}{\XD@harmless@i}
+% \begin{macro}{\XD@harmless@ii}
+% But that is not all |\MakeHarmless| can do. In some cases (as for
+% example when one is describing a family of control sequences) one
+% might want to include things in the string that are not simply
+% characters, but more complex items---such as for example |\meta|
+% constructions like \meta{code}. To accommodate for this,
+% |\XD@harmless@| (which is the first step in converting a token)
+% always begins by checking whether the next token to render harmless
+% is a control sequence. If it is then it is checked (in
+% |\XD@harmless@ii|) whether the control sequence
+% \describecsfamily{XD@harmless\Bslash\meta{cs-name}}^^A
+% |\XD@harmless\|\meta{cs-name}, where \meta{cs-name} is the name
+% without |\| of the control sequence encountered, is defined. If it
+% isn't then the encountered control sequence is |\string|ed and
+% conversion continues as above, but if it is defined then the
+% encountered control sequence begins such a more complex item.
+% \begin{macrocode}
+\def\XD@harmless@{\futurelet\@let@token \XD@harmless@i}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@harmless@i{%
+ \ifcat \noexpand\@let@token \noexpand\XD@harmless@
+ \expandafter\XD@harmless@ii
+ \else
+ \expandafter\XD@harmless@iii
+ \fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@harmless@ii#1{%
+ \@ifundefined{XD@harmless\string#1}{%
+ \expandafter\XD@harmless@vi \string#1%
+ }{\csname XD@harmless\string#1\endcsname}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@harmless\XD@harmless@}
+% A control sequence |\XD@harmless\|\meta{cs-name} is responsible for
+% interpreting the string item that begins with the control sequence
+% |\|\meta{cs-name} and appending a harmless representation of it to
+% |\toks@|. Harmless representations should only contain robust
+% control sequences and they must not rely on changing any catcodes.
+% Normal |\XD@harmless\|\meta{cs-name} control sequences must also
+% end by inserting |\XD@harmless@| in front of what remains of the
+% string after the complex string item has been removed. This sees to
+% that the rest of the string is also rendered harmless. The only such
+% control sequence which does not insert |\XD@harmless@| is
+% |\XD@harmless\XD@harmless@|, but that is as it should be since
+% |\MakeHarmless| itself appends a |\XD@harmless@| to every character
+% string it should convert to mark the end of it.
+% \begin{macrocode}
+\expandafter\let
+ \csname XD@harmless\string\XD@harmless@\endcsname \@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\XD@harmless\PrintChar}
+% It is occasionally convenient to use a |\PrintChar| command as part
+% of a string that is to be rendered harmless instead of using the raw
+% character. The definition is very similar to that of
+% |\XD@harmless@vi|.
+% \begin{macrocode}
+\@namedef{XD@harmless\string\PrintChar}#1{%
+%<*economical>
+ \if \ifnum #1<\@xxxii 1\else \ifnum #1>126 1\else 0\fi\fi 1%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\PrintChar \expandafter{\number#1}%
+ }%
+ \else
+%</economical>
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname XD@harmless@\number#1\endcsname}%
+%<economical> \fi
+ \XD@harmless@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Interaction with mechanisms that make characters
+% problematic}
+%
+% If additional visible characters are made problematic after the
+% initial |\XD@harmless@|\meta{code} table is formed then problems may
+% indeed arise, because some character which is expected to be
+% unproblematic when read from (for example) an \texttt{.ind} file will
+% actually not be. In fortunate cases this will only lead to that
+% characters will print strangely or not at all, but it can quite
+% conceivably lead to errors that prevent further typesetting and it
+% should therefore be prevented if possible.
+%
+% Right now, I can think of two mechanisms that make characters
+% problematic, and both do that by making them active. One is the
+% shorthand mechanism of \package{babel}, but I think I'll delay
+% implementing any interaction with that until some later prototype; I
+% don't know it well enough and anyway I don't think it is that likely
+% to cause any problems. The other mechanism is the short verb mechanism
+% of \package{doc} itself, and this should be taken care of right away.
+%
+% The main difficulty is that the |\XD@harmless@|\meta{code} table should
+% be the same throughout the document body (otherwise you may get more
+% than one index entry for the same thing, with index references
+% arbitrarily distributed between the two) whereas short verb characters
+% can be made and deleted at any time. It would actually be wrong to
+% always have the |\XD@harmless@|\meta{code} table entry mirroring the
+% current state of the character! Instead a character will be considered
+% as problematic even if it is only made problematic temporarily (with
+% the exception for characters that are made problematic in
+% \texttt{verbatim} environments and the like---the index file isn't
+% being read in while those catcodes are active). Since it is impossible
+% to know in the beginning of a document whether a character will be made
+% a short verb character at some later point, the modifications to the
+% |\XD@harmless@|\meta{code} table that will be made because of short verb
+% characters will (at least partially) be based on which characters were
+% made short verbs on the previous run.
+%
+% \begin{macro}{\SetCharProblematic}
+% \changes{prot2}{2000/07/26}{Command added. (LH)}
+% The |\SetCharProblematic| command should be called by commands which
+% make a character problematic (e.g.\ makes it active) in the general
+% context (commands which make some character problematic only in some
+% very special context, such as the \texttt{verbatim} environment,
+% need not call |\Set|\-|Char|\-|Problematic|). The syntax is
+% \begin{quote}
+% |\SetCharProblematic|\marg{code}
+% \end{quote}
+% and it sets the ``harm state'' of the character whose code is
+% \meta{code} to problematic.
+%
+% When |\SetCharProblematic| is called in the preamble, it sets the
+% harm state on the current run. When it is called in the document
+% body however, it sets the harm state on the next run by writing a
+% |\SetHarmState| command to the \texttt{.aux} file. This is done to
+% ensure that the contents of the |\XD@harmless@|\meta{code} table
+% doesn't change during the body of a document.
+% \begin{macrocode}
+\newcommand\SetCharProblematic[1]{%
+ \SetHarmState\BooleanTrue{#1}\BooleanTrue
+}
+\AtBeginDocument{%
+ \gdef\SetCharProblematic#1{%
+ \if@filesw
+ \immediate\write\@auxout{\string\SetHarmState
+ \string\BooleanTrue {\number#1}\string\BooleanTrue}%
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\add@specials}
+% \changes{prot2}{2000/07/26}{Redefinition added. (LH)}
+% |\MakeShortVerb|'s call to |\SetCharProblematic| is put in the
+% |\add@|\B|specials| macro, which anyway already adds the character
+% to the |\dospecials| and |\@sanitize| lists. Only familiar
+% definitions of |\add@special| are changed.
+% \begin{macrocode}
+\def\@tempa#1{%
+ \rem@special{#1}%
+ \expandafter\gdef\expandafter\dospecials\expandafter
+ {\dospecials \do #1}%
+ \expandafter\gdef\expandafter\@sanitize\expandafter
+ {\@sanitize \@makeother #1}}
+\ifx \@tempa\add@special
+ \def\add@special#1{%
+ \rem@special{#1}%
+ \expandafter\gdef\expandafter\dospecials\expandafter
+ {\dospecials \do #1}%
+ \expandafter\gdef\expandafter\@sanitize\expandafter
+ {\@sanitize \@makeother #1}%
+ \SetCharProblematic{`#1}%
+ }
+\else
+ \PackageWarningNoLine{xdoc2}{Unfamiliar definition of
+ \protect\add@special;\MessageBreak the macro was not patched}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Indexing}
+% \label{Sec:Indexing}
+%
+% Each type of index entry \package{doc} produces is implemented through
+% a different indexing command.\footnote{Sometimes there are
+% even more than one command per entry type---the \cs{SpecialIndex},
+% \cs{LeftBraceIndex}, \cs{RightBraceIndex}, and \cs{PercentIndex}
+% commands all generate entries of the same type.} This might be
+% manageable when there are only \texttt{macro}s and
+% \texttt{environment}s to distinguish between, but it soon gets
+% unmanageable if more environments of this type are added. Therefore
+% all \package{xdoc} index entries are made with a single
+% command---|\IndexEntry|.
+%
+%
+% \subsection{New basic indexing commands}
+% \label{Ssec:IndexEntry}
+%
+% \begin{macro}{\IndexEntry}
+% \begin{macro}{\LevelSame}
+% \changes{prot2.1}{2000/11/18}{New name for \cs{levelsame}. (LH)}
+% \begin{macro}{\LevelSorted}
+% \changes{prot2.1}{2000/11/18}{New name for \cs{levelsorted}. (LH)}
+% \begin{macro}{\XD@if@index}
+% The |\IndexEntry| command writes one index entry to the \texttt{.idx}
+% file. It takes three arguments:
+% \begin{quote}
+% |\IndexEntry|\marg{entry text}\marg{encap}\marg{thenumber}
+% \end{quote}
+% The \meta{entry text} contains the text for the entry. It is a
+% nonempty sequence of commands in which each item is one of
+% \begin{quote}
+% |\LevelSame|\marg{text}\\
+% |\LevelSorted|\marg{sort key}\marg{text}
+% \end{quote}
+% Each such item specifies one level of the entry that is to be
+% written. In the case of |\LevelSorted|, the \meta{text} is what will
+% be written in the sorted index at that level and \meta{sort key} is
+% a key which the index-sorting program should use for sorting that
+% entry at that level. In the case of |\LevelSame|, the \meta{text} is
+% used both as sort key and contents of entry in the sorted index.
+% The first item is for the topmost level and each subsequent item is
+% for the next sublevel. The \meta{entry text} will be fully expanded
+% by the |\IndexEntry| command.
+%
+% \meta{thenumber} is the number (if any) that the index entry refers
+% to. It can consist of explicit characters, but it can also be a
+% |\the|\meta{counter} control sequence or a macro containing such
+% control sequences. \meta{thenumber} is fully expanded by the
+% |\IndexEntry| command, with the exception for occurrences of
+% |\thepage|---expansion of |\thepage| will instead be delayed until
+% the page is shipped out, so that the page numbers will be right.
+% \textbf{Note:} \meta{thenumber} must not contain any formatting that
+% will upset the index-sorting program. \package{doc}'s default
+% definition of |\theCodelineNo| contains such formatting, so one
+% must instead use |\thecodelineno| as \meta{thenumber} in that case.
+%
+% \meta{encap} is the name of the encapsulation scheme that should be
+% applied to \meta{thenumber}. All encapsulation schemes that have been
+% implemented instruct the index sorting program to wrap up
+% \meta{thenumber} in some code that gives it special formatting when
+% the sorted index is written, but one could also use the \meta{encap}
+% to specify `beginning of range' and `end of range' index entries.
+% Use \GenericDescribePrint{\small\texttt{none}}^^A
+% \SortIndex{none}{\texttt{none}\encapchar usage}\texttt{none} as
+% \meta{encap} if you don't want any special formatting.
+%
+% \textbf{Note:} |\IndexEntry| uses |\@tempa| internally, so you
+% cannot use that in argument \#2 or \#3. Using it in argument \#1
+% presents no problems, though.
+% \begin{macrocode}
+\newcommand\IndexEntry[3]{%
+ \@bsphack
+ \begingroup
+ \def\LevelSame##1{\levelchar##1}%
+ \def\LevelSorted##1##2{\levelchar##1\actualchar##2}%
+ \protected@edef\@tempa{#1}%
+ \protected@edef\@tempa{\expandafter\@gobble\@tempa\@empty}%
+ \@ifundefined{XD@idxencap@#2}{%
+ \PackageError{xdoc2}{Index entry encap `#2' unknown}\@eha
+ }{%
+ \XD@if@index{%
+ \csname XD@idxencap@#2\endcsname\@tempa{#3}%
+ }{}%
+ }%
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% |\IndexEntry| does (like |\index|) not contribute any material to the
+% current list if indices aren't being made.
+%
+% |\XD@if@index| is |\@firstoftwo| if index entries are being written
+% and |\@second|\-|of|\-|two| if they are not.
+% \begin{macrocode}
+\let\XD@if@index=\@secondoftwo
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% In \LaTeXplus, the \cs{IndexEntry} command should probably be
+% implemented using templates, e.g. the \meta{encap}s could be names of
+% instances.
+%
+% \begin{macro}{\levelsame}
+% \begin{macro}{\levelsorted}
+% These names were used for |\LevelSame| and |\LevelSorted|
+% respectively in prototype version~2.0, but the macros should belong
+% to the same capitalization class as |\IndexEntry| so their names
+% were changed in prototype version~2.1. The old names |\levelsame|
+% and |\levelsorted| will continue to work in \package{xdoc2}, though.
+% \begin{macrocode}
+%<*xdoc2>
+\newcommand*\levelsame{\LevelSame}
+\newcommand*\levelsorted{\LevelSorted}
+%</xdoc2>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \describecsfamily{XD@idxencap@\meta{encap}}^^A
+% Macros in the family |\XD@idxencap@|\meta{encap} takes two
+% arguments as follows
+% \begin{quote}
+% |\XD@idxencap@|\meta{encap}\,\marg{entry}\,\marg{thenumber}
+% \end{quote}
+% They should write an entry with the \meta{encap} encapsulation of the
+% \meta{thenumber} to the index file. They need not check whether index
+% generation is on or not, but they must be subject to the \LaTeX\ kernel
+% \texttt{@filesw} switch. They must expand both arguments fully at the
+% time of the command, with the exception for the control sequence
+% |\thepage|, which should not be expanded until the page on which the
+% write appears is output. Both these conditions are met if the macro
+% is implemented using |\protected@write|.
+%
+% \begin{macro}{\XD@idxencap@none}
+% \begin{macro}{\XD@idxencap@main}
+% \begin{macro}{\XD@idxencap@usage}
+% These macros implement the encapsulation schemes that are used in
+% \package{doc}.
+% \begin{macrocode}
+\def\XD@idxencap@none#1#2{%
+ \protected@write\@indexfile{}{\XD@index@keyword{#1}{#2}}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@idxencap@main#1#2{%
+ \protected@write\@indexfile{}%
+ {\XD@index@keyword{#1\encapchar main}{#2}}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@idxencap@usage#1#2{%
+ \protected@write\@indexfile{}%
+ {\XD@index@keyword{#1\encapchar usage}{#2}}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@index@keyword}
+% \changes{prot2.2}{2001/02/13}{Macro added and \meta{encap} macros
+% changed to use it. (LH)}
+% The |\XD@index@keyword| is a hook for changing the index entry
+% keyword (the text that is put in front of every index entry in the
+% \texttt{.idx} file). It is changed by e.g.\ the \package{docindex}
+% package~\cite{docindex}.
+% \begin{macrocode}
+\@ifundefined{XD@index@keyword}{%
+ \edef\XD@index@keyword{\@backslashchar indexentry}%
+}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\CodelineIndex}
+% \changes{prot2.1}{2000/10/08}{Using \cs{thecodelineno}. (LH)}
+% \begin{macro}{\PageIndex}
+% \begin{macro}{\TheXDIndexNumber}
+% The |\CodelineIndex| and |\PageIndex| commands do the same things as
+% in \package{doc}, but work with the \package{xdoc} internals instead
+% of the \package{doc} ones. |\TheXDIndexNumber| is used as
+% \meta{thenumber} argument to |\IndexEntry| by all indexing commands
+% that would have used |\special@index| in \package{doc}.
+% \begin{macrocode}
+\renewcommand\CodelineIndex{%
+ \makeindex
+ \let\XD@if@index=\@firstoftwo
+ \codeline@indextrue
+ \def\TheXDIndexNumber{\thecodelineno}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\renewcommand\PageIndex{%
+ \makeindex
+ \let\XD@if@index=\@firstoftwo
+ \codeline@indexfalse
+ \def\TheXDIndexNumber{\thepage}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\TheXDIndexNumber{??}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+%
+% \subsection{Making good sort keys}
+%
+% \changes{prot2.1}{2000/11/15}{Sort key making commands added. (LH)}
+% A common nuisance in \package{doc} indices is that many macros are
+% sorted by parts of the name that do not carry any interesting
+% information. In the \LaTeX\ kernel many macro names begin with a
+% silent |@|, whereas the names of private macros in many packages
+% (including this one) begin with some fixed abbreviation of the
+% package name. Since such prefixes usually are harder to remember than
+% the rest of the macro name, it is not uncommon that the index position
+% one thinks of first isn't the one where the macro actually is put.
+% Hence a mechanism for removing such annoying prefixes from the macro
+% names might be useful, and that is presicely what is defined below.
+%
+% The actual mechanism is based on having a set of macros called
+% \emph{operators} which operate on the harmless character string that
+% is to become the sort key. Each operator has a specific prefix string
+% which it tries to match against the beginning of the to-be sort key,
+% and if they match then the prefix is moved to the end of the sort key.
+% Automatically constructed operators (see below) have names of the form
+% \describecsfamily{XD@operatorA@\meta{prefix}}|\XD@operatorA@|^^A
+% \meta{prefix}, but operators can be given arbitrary names.
+%
+% \begin{macro}{\XD@operators@list}
+% The |\XD@operators@list| macro contains the list of all currently
+% active operators.
+% \begin{macrocode}
+\let\XD@operators@list\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% The operators do all their work at expand-time. When an operator
+% macro is expanded, it is in the context
+% \begin{quote}
+% \meta{operator} \meta{subsequent operators} |\@firstofone|
+% \meta{sort key text} |\@empty|
+% \end{quote}
+% There may not be any |\@empty|s or |\@firstofone|s amongst the
+% \meta{subsequent operators} or in the \meta{sort key text}. This should
+% expand to
+% \begin{quote}
+% \meta{subsequent operators} |\@firstofone| \meta{operated-on sort
+% key text} |\@empty|
+% \end{quote}
+% The purpose of the |\@firstofone| after the \meta{subsequent
+% operators} is to remove any spaces that some operator might have put
+% in front of the sort key. This happens if the entire sort key text has
+% been ignored by some operator.
+%
+% \begin{macro}{\MakeSortKey}
+% The |\MakeSortKey| command is called to make the acutal sort key.
+% The syntax of this command is
+% \begin{quote}
+% |\MakeSortKey|\marg{macro}\marg{text}\marg{extras}
+% \end{quote}
+% This locally defines \meta{macro} to be the sort key that the
+% currently active operators manufacture from \meta{text}. The
+% \meta{extras} argument can contain additional assignments needed for
+% handling macros with special harmless forms, such as |\meta|.
+% \begin{macrocode}
+\newcommand\MakeSortKey[3]{%
+ \begingroup
+ \def\PrintChar{\string\PrintChar\XD@threedignum}%
+ #3%
+ \unrestored@protected@xdef\@gtempa{#2}%
+ \endgroup
+ \protected@edef#1{%
+ \expandafter\XD@operators@list \expandafter\@firstofone
+ \@gtempa\@empty
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XD@make@operator}
+% The |\XD@make@operator| macro takes a harmless character sequence as
+% argument, constructs the corresponding operator, and returns the
+% operator control sequence in the |\toks@| token list register.
+%
+% More precisely, given a harmless character string \meta{string},
+% |\XD@make@operator| will construct a sequence of other tokens
+% \meta{text} from \meta{string} by replacing all |\PrintChar|
+% commands in the same way as |\MakeSortKey| does. Then it defines the
+% macro |\XD@operatorA@|\meta{text} to be
+% \begin{quote}
+% \raggedright \spaceskip=0.16666em
+% \#1\,|\@firstofone|\,\#2\,|\@empty| \ $\rightarrow$ \ %
+% |\XD@operatorB@|\meta{text} |\@firstofone| \#2
+% |\@firstofone| \meta{text} |\@firstofone| |\relax| \#1 |\@empty|
+% \end{quote}
+% and the macro |\XD@operatorB@|\meta{text} to do
+% \begin{quote}
+% \raggedright
+% \#1\,|\@firstofone|\,\meta{text}\,\#2\,|\@firstofone|\,\#3\,^^A
+% |\relax|\,\#4\,|\@empty| $\rightarrow$
+% \#4\,\( \left\{ \begin{array}{ll}
+% \mbox{\cs{@firstofone}\,\#2\,\textvisiblespace\,\meta{text}\,^^A
+% \cs{@empty}}& \mbox{if \#1 is empty}\\
+% \mbox{\#1\,\cs{@empty}}& \mbox{otherwise}
+% \end{array} \right.\)
+% \end{quote}
+%
+% \begin{macrocode}
+\def\XD@make@operator#1{%
+ \begingroup
+ \def\PrintChar{\string\PrintChar\XD@threedignum}%
+ \let\protect\@gobble
+ \xdef\@gtempa{#1}%
+ \endgroup
+ \expandafter\edef \csname XD@operatorA@\@gtempa\endcsname
+ ##1\@firstofone##2\@empty{%
+ \expandafter\noexpand \csname XD@operatorB@\@gtempa\endcsname
+ \noexpand\@firstofone ##2\noexpand\@firstofone \@gtempa
+ \noexpand\@firstofone \relax##1\noexpand\@empty
+ }%
+ \expandafter\edef \csname XD@operatorB@\@gtempa \expandafter\endcsname
+ \expandafter##\expandafter1\expandafter\@firstofone \@gtempa
+ ##2\@firstofone##3\relax##4\@empty{%
+ \noexpand\ifx $##1$%
+ \noexpand\expandafter \noexpand\@firstoftwo
+ \noexpand\else
+ \noexpand\expandafter \noexpand\@secondoftwo
+ \noexpand\fi{%
+ ##4\noexpand\@firstofone ##2 \@gtempa
+ }{##4##1}%
+ \noexpand\@empty
+ }%
+ \toks@=\expandafter{\csname XD@operatorA@\@gtempa\endcsname}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DoNotIndexBy}
+% The |\DoNotIndexBy| command has the syntax
+% \begin{quote}
+% |\DoNotIndexBy|\marg{morpheme}
+% \end{quote}
+% It causes the \meta{morpheme} to be put \emph{last} in the index
+% sort key for each macro name which begins by \meta{morpheme}. This
+% can be used to ignore e.g.\ ``silent'' |@|s at the beginning of a
+% macro name.
+% \begin{macrocode}
+\newcommand\DoNotIndexBy[1]{%
+ \MakeHarmless\@tempa{#1}%
+ \XD@make@operator\@tempa
+ \expandafter\def \expandafter\XD@operators@list \expandafter{%
+ \the\expandafter\toks@ \XD@operators@list
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{Reimplementations of \package{doc} indexing commands}
+%
+% The \package{doc} indexing commands aren't that interesting in
+% \package{xdoc}, since they take `raw' control sequences as
+% arguments rather than the harmless strings that the \package{xdoc}
+% commands will want to put in the index. But it can be instructive to
+% see how they would be implemented in this context.
+%
+% \begin{macro}{\SortIndex}
+% \changes{prot2.2}{2001/02/13}{Redefinition added. (LH)}
+% The |\SortIndex| takes a sort key and an entry text as argument, and
+% writes a one-level index entry for that.
+% \begin{macrocode}
+\renewcommand*\SortIndex[2]{%
+ \IndexEntry{\LevelSorted{#1}{#2}}{none}{\thepage}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SpecialIndex}
+% \begin{macro}{\SpecialMainIndex}
+% \begin{macro}{\SpecialUsageIndex}
+% The |\SpecialIndex|, |\SpecialMainIndex|, and |\SpecialUsageIndex|
+% commands take a control sequence (or more often something which looks
+% like a |\string|ed control sequence) as their only argument. The
+% entry text is that item verbatim, and the initial backslash is
+% ignored in sorting (|\Special|\-|Index| always ignores the first
+% character regardless of whether it is a backslash or not, the other
+% two checks first). |\Special|\-|Index| has \texttt{none} formatting,
+% |\Special|\-|Main|\-|Index| has \texttt{main} formatting, and
+% |\Special|\-|Usage|\-|Index| has \texttt{usage} formatting of the
+% index number.
+%
+% Although these definitions will (or at least are supposed to) yield
+% the same typeset results as the \package{doc} definitions in the
+% mainstream cases, I doubt that they will do so in all cases. At any
+% rate, they shouldn't perform worse.
+% \begin{macrocode}
+\renewcommand\SpecialIndex[1]{%
+ \expandafter\MakeHarmless \expandafter\@tempa
+ \expandafter{\string#1}%
+ \IndexEntry{%
+ \LevelSorted{%
+ \expandafter\XD@unbackslash \@tempa\@empty
+ }{\texttt{\@tempa}}%
+ }{none}{\TheXDIndexNumber}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\renewcommand\SpecialMainIndex[1]{%
+ \expandafter\MakeHarmless \expandafter\@tempa
+ \expandafter{\string#1}%
+ \IndexEntry{%
+ \LevelSorted{%
+ \expandafter\XD@unbackslash \@tempa\@empty
+ }{\texttt{\@tempa}}%
+ }{main}{\TheXDIndexNumber}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\renewcommand\SpecialUsageIndex[1]{%
+ \expandafter\MakeHarmless \expandafter\@tempa
+ \expandafter{\string#1}%
+ \IndexEntry{%
+ \LevelSorted{%
+ \expandafter\XD@unbackslash \@tempa\@empty
+ }{\texttt{\@tempa}}%
+ }{usage}{\thepage}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@unbackslash}
+% \begin{macro}{\XD@unbackslash@}
+% |\XD@unbackslash| is a utility macro which removes the first
+% character from a harmless character string if that character is a
+% backslash (i.e., if it is |\PrintChar{92}|). The \package{doc}
+% commands have traditionally used |\@gobble| for doing this, but the
+% \cs{@SpecialIndexHelper@} macro that was comparatively recently added
+% tries to do better.
+% \begin{macrocode}
+\def\XD@unbackslash#1{%
+ \ifx \PrintChar#1%
+ \expandafter\XD@unbackslash@
+ \else
+ \expandafter#1%
+ \fi
+}
+\def\XD@unbackslash@#1{\ifnum #1=92 \else \PrintChar{#1}\fi}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\SpecialMainEnvIndex}
+% \begin{macro}{\SpecialEnvIndex}
+% These are similar to the above, but \package{doc} thinks that the
+% arguments don't need any special care, and it produces two index
+% entries per command. |\Special|\-|Env|\-|Index| should really have
+% been called |\Special|\-|Usage|\-|Env|\-|Index|.
+% \begin{macrocode}
+\renewcommand\SpecialMainEnvIndex[1]{%
+ \IndexEntry{\LevelSorted{#1}{\texttt{#1} (environment)}}{main}%
+ {\TheXDIndexNumber}%
+ \IndexEntry{\LevelSame{environments:}\LevelSorted{#1}{\texttt{#1}}}%
+ {main}{\TheXDIndexNumber}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\renewcommand\SpecialEnvIndex[1]{%
+ \IndexEntry{\LevelSorted{#1}{\texttt{#1} (environment)}}{usage}%
+ {\thepage}%
+ \IndexEntry{\LevelSame{environments:}\LevelSorted{#1}{\texttt{#1}}}%
+ {usage}{\thepage}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\it@is@a}
+% \begin{macro}{\XD@special@index}
+% The |\it@is@a| macro is a specialized version of |\SpecialIndex|,
+% but the format of its argument is quite different. After full
+% expansion the argument will become a single category 12 token
+% (\meta{t}, say), and the control sequence for which an entry should
+% be made is |\|\meta{t}. \package{doc} uses |\it@is@a| for control
+% sequences with one-character names. Note: The following
+% definition should really have special code for the \Module{economical}
+% \package{docstrip} module, but I don't think that is necessary
+% since the \package{doc} macros which used |\it@is@a| will be
+% redefined so that they don't.
+%
+% |\XD@special@index| does the same thing as |\SpecialIndex|, but it
+% does it with \package{xdoc} datatypes---the argument must be a
+% harmless character string that does not include the initial escape
+% (backslash).
+% \changes{prot2.1}{2000/11/15}{Using \cs{MakeSortKey} to make the
+% sort key. (LH)}
+% \begin{macrocode}
+\def\it@is@a#1{%
+ \edef\@tempa{#1}%
+ \XD@special@index{\csname XD@harmless@\number
+ \expandafter`\@tempa\endcsname}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@special@index#1{%
+ \MakeSortKey\@tempa{#1}{}%
+ \IndexEntry{\LevelSorted{\@tempa}{\texttt{\Bslash#1}}}{none}%
+ {\TheXDIndexNumber}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\LeftBraceIndex}
+% \begin{macro}{\RightBraceIndex}
+% \begin{macro}{\PercentIndex}
+% \begin{macro}{\OldMakeIndex}
+% More specialised forms of |\SpecialIndex|. The |\OldMakeIndex|
+% command can safely be made a no-op.
+% \begin{macrocode}
+\renewcommand\LeftBraceIndex{\XD@special@index{\PrintChar{123}}}
+\renewcommand\RightBraceIndex{\XD@special@index{\PrintChar{125}}}
+\renewcommand\PercentIndex{\XD@special@index{\PrintChar{37}}}
+\let\OldMakeIndex\relax
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\@wrindex}
+% \changes{prot2.2}{2001/02/13}{Redefinition added. (LH)}
+% Finally, while we're at redefining indexing commands, let's redefine
+% |\@wrindex| as well to ensure that the index entry keyword is the
+% same for all indexing commands.
+% \begin{macrocode}
+\def\@wrindex#1{%
+ \protected@write\@indexfile{}{\XD@index@keyword{#1}{\thepage}}%
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Cross-referencing}
+%
+% \subsection{Scanning \texttt{macrocode} for \TeX\ control sequences}
+% \label{Ssec:Scanning macrocode}
+%
+% The cross-referencing mechanism in \package{doc} isn't problematic in
+% the same way as the indexing mechanism is, so one could pretty much
+% leave it as it is, but there are things that are better done
+% differently when the basic indexing commands are based on harmless
+% character strings. Rather than storing control sequence names (without
+% escape character) as sequences of category 11 tokens, they will be
+% stored as the equivalent harmless character strings.
+%
+% \begin{macro}{\macro@switch}
+% As in \package{doc}, |\macro@switch| determines whether the control
+% sequence name that follows consists of letters (call |\macro@name|)
+% or a single non-letter (call |\short@macro|). Unlike \package{doc},
+% \package{xdoc} accumulates the characters from a multiple-letter
+% control sequence name in a token register (|\@toks|), which is why
+% that is cleared here.
+% \begin{macrocode}
+\def\macro@switch{%
+ \ifcat\noexpand\next a%
+ \toks@={}%
+ \expandafter\macro@name
+ \else
+ \expandafter\short@macro
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\scan@macro}
+% Since |\macro@namepart| isn't used as in \package{doc}, I might as
+% well remove the command that cleared it from |\scan@macro|.
+% \begin{macrocode}
+\def\scan@macro{%
+ \special@escape@char
+ \step@checksum
+ \ifscan@allowed
+ \def\next{\futurelet\next\macro@switch}%
+ \else \let\next\@empty \fi
+ \next}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\short@macro}
+% This macro will be invoked (with a single character as parameter)
+% when a single-character macro name has been spotted whilst
+% scanning within the \texttt{macrocode} environment. It will produce
+% an index entry for that macro, unless that macro has been excluded
+% from indexing, and it will also typeset the character that
+% constitutes the name of the macro.
+% \begin{macrocode}
+\def\short@macro#1{%
+ \protected@edef\macro@namepart{%
+%<*economical>
+ \ifnum `#1<\@xxxii
+ \noexpand\PrintChar{\number`#1}%
+ \else\ifnum `#1>126
+ \noexpand\PrintChar{\number`#1}%
+ \else
+%</economical>
+ \csname XD@harmless@\number`#1\endcsname
+%<economical> \fi\fi
+ }%
+ \ifnot@excluded \XD@special@index{\macro@namepart}\fi
+% \end{macrocode}
+% The cross-referencing mechanism is disabled for when the actual
+% character is printed, as it could be the escape character. The index
+% entry must be generated before the character is printed to ensure
+% that no page break intervenes (recall that a |^^M| will start a new
+% line).
+% \begin{macrocode}
+ \scan@allowedfalse #1\scan@allowedtrue
+}
+% \end{macrocode}
+% \end{macro}
+%
+% There is one mechanism in |\TeX|'s control sequence tokenization that
+% |\short@|\B|macro| doesn't cover, and that is the |^^| sequence
+% substitution---|\^^M| is (with default catcodes) seen as the three
+% tokens |\^|, |^|, and |M|, not as the single control
+% sequence token that \TeX\ will make out of it. But this is the way it
+% is done in \package{doc}.
+%
+%
+% \begin{macro}{\macro@name}
+% \begin{macro}{\more@macroname}
+% \begin{macro}{\macro@finish}
+% Then there's the macros for assembling a control sequence name which
+% consists of one or more letters (category 11 tokens). (This includes
+% both the characters which are normally letters in the document and
+% those that are made letters by |\MakePrivateLetters|.) They're
+% pretty straightforward.
+% \begin{macrocode}
+\def\macro@name#1{%
+%<*economical>
+ \if \ifnum `#1<\@xxxii 1\else \ifnum `#1>126 1\else 0\fi\fi 1%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\PrintChar \expandafter{\number`#1}%
+ }%
+ \else
+%</economical>
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname XD@harmless@\number`#1\endcsname}%
+%<economical> \fi
+ \futurelet\next\more@macroname}
+% \end{macrocode}
+% \begin{macrocode}
+\def\more@macroname{%
+ \ifcat\noexpand\next a%
+ \expandafter\macro@name
+ \else
+ \macro@finish
+ \fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\macro@finish{%
+ \edef\macro@namepart{\the\toks@}%
+ \ifnot@excluded \XD@special@index{\macro@namepart}\fi
+ \macro@namepart
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+%
+%
+% \subsection{The index exclude list}
+% \label{Ssec:Index-exclude}
+%
+% The index exclude list mechanisms are not quite as simple to convert
+% for use with harmless character strings as the construction of macro
+% names are. This is because the trick used for searching the exclude
+% list for a certain string doesn't work if the string one is looking
+% for contains tokens with category 1 or 2 (beginning and end of group),
+% as the \meta{parameter text} of a |\def| cannot contain such tokens.
+% On the other hand the only groups that can appear in the harmless
+% character strings one will be looking for are the ones around the
+% argument of some |\PrintChar|, and these can easily be converted to
+% something else. Therefore an item in the index exclude list of
+% \package{xdoc} will have the format
+% \begin{quote}
+% |\do|\,\meta{string}
+% \end{quote}
+% where the \meta{string} is different from a harmless character string
+% only in that all |\PrintChar|\marg{num} have been replaced by
+% |\PrintChar|\parg{num}. The \meta{string} does not include an escape
+% character. The |\do| serves only to separate the item from the one
+% before, but it could in principle be used for other purposes as well
+% (such as in typesetting the entire exclude list).
+%
+% \begin{macro}{\XD@paren@PrintChar}
+% |\XD@paren@PrintChar| is a definition of |\PrintChar| which, when it
+% is used in an |\edef|, merely replaces the group around the argument
+% by a parenthesis and normalizes the number in the argument.
+% \changes{prot2.1}{2000/09/16}{\cs{number} added. (LH)}
+% \begin{macrocode}
+\def\XD@paren@PrintChar#1{\noexpand\PrintChar(\number#1)}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DoNotIndex}
+% \changes{prot2.1}{2000/09/16}{Also changing catcode of \%. (LH)}
+% \begin{macro}{\do@not@index}
+% \begin{macro}{\XD@do@not@index}
+% These are the macros which add elements to the index exclude list.
+% |\DoNotIndex| is pretty much as in \package{doc}, but I have added
+% resetting of the catcodes of `|,|' (since |\XD@do@not@index| relies
+% on it) and `|#|' (since it can otherwise mess things up for the
+% |\def\@tempa| in |\do@not@index|).
+% \begin{macrocode}
+\renewcommand\DoNotIndex{%
+ \begingroup
+ \MakePrivateLetters
+ \catcode`\#=12\catcode`\\=12\catcode`,=12\catcode`\%=12
+ \expandafter\endgroup \do@not@index
+}
+% \end{macrocode}
+%
+% |\do@not@index|, on the other hand, is quite different, as it more
+% or less has to convert the argument from the format used in
+% \package{doc} to that of \package{xdoc}. The bulk of the work is
+% done by |\XD@do@not@index|, which grabs one of the elements in the
+% argument of |\do@not@index| and converts it (minus the initial
+% backslash) to a harmless character string. That harmless character
+% string is then converted by |\XD@paren@PrintChar|, so that the
+% string can be searched for using |\expanded@notin|.
+%
+% The reason for using a special loop structure here, as opposed to
+% using for example |\@for|, is that one cannot use either of |\|
+% or |,| alone as item separators, as they may both be part of control
+% sequence names (consider for example |\DoNotIndex{\a,\\,\b,\,,\c}|),
+% but they should be sufficient when combined.
+%
+% The reason for storing new elements in |\toks@| until the end of
+% the loop and only then inserting them into the index exclude list
+% is speed; the index exclude list can get rather large, so you don't
+% want to expand it more often than you have to. I don't know if the
+% difference is noticeable, though.
+% \begin{macrocode}
+\begingroup
+ \catcode`\|=0
+ \catcode`\,=12
+ \catcode`\\=12
+% \end{macrocode}
+% \SpecialEscapechar{\|}
+% \begin{macrocode}
+ |gdef|do@not@index#1{%
+ |def|@tempa{#1}%
+ |ifx |@empty|@tempa |else
+ |toks@={}%
+ |expandafter|XD@do@not@index |@gobble #1,\|XD@do@not@index,\%
+ |fi
+ }
+ |gdef|XD@do@not@index#1,\{%
+ |ifx |XD@do@not@index#1%
+ |index@excludelist=|expandafter{%
+ |the|expandafter|index@excludelist |the|toks@
+ }%
+ |expandafter|@gobble
+ |else
+ |MakeHarmless|@tempa{#1}%
+ |begingroup
+ |let|PrintChar|XD@paren@PrintChar
+ |unrestored@protected@xdef|@gtempa{|noexpand|do|@tempa}%
+ |endgroup
+ |toks@=|expandafter{|the|expandafter|toks@ |@gtempa}%
+ |fi
+ |XD@do@not@index
+ }
+|endgroup
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\DoNotIndexHarmless}
+% The |\DoNotIndexHarmless| command takes a harmless character string
+% as argument and locally adds the control sequence whose name is that
+% character string to the index exclude list.
+% \begin{macrocode}
+\newcommand\DoNotIndexHarmless[1]{%
+ \begingroup
+ \let\PrintChar\XD@paren@PrintChar
+ \unrestored@protected@xdef\@gtempa{\noexpand\do#1}%
+ \endgroup
+ \index@excludelist=\expandafter{%
+ \the\expandafter\index@excludelist \@gtempa
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\index@excludelist}
+% In case the index exclude list is not empty, its contents are
+% converted to \package{xdoc} format.
+% \begin{macrocode}
+\edef\@tempa{\the\index@excludelist}
+\index@excludelist{}
+\ifx \@tempa\@empty \else
+ \def\@tempb#1,\@nil{\do@not@index{#1}}
+ \expandafter\@tempb \@tempa \@nil
+ \let\@tempa\@empty
+ \let\@tempb\@empty
+\fi
+% \end{macrocode}
+% The fact that the |\XD@|\B|harmless@|\B\meta{code} table has not
+% yet reached its final form means that some of these control sequences
+% listed in the exclude list might get a different form here than they
+% actually should, but there isn't much that can be done about that. It
+% is furthermore unusual that control sequence are given such names
+% that they would be affected by this.
+% \end{macro}
+%
+% \begin{macro}{\ifnot@excluded}
+% The |\ifnot@excluded| macro ultimately boils down to an
+% \texttt{if}, which evaluates to true if and only if the string in
+% |\macro@namepart| is not one of the items in the index exclude
+% list. Before |\expanded@notin| gets to carry out the actual test,
+% the |\PrintChar| calls in |\macro@namepart| are converted by
+% |\XD@paren@PrintChar| (it's OK to use an unprotected |\edef| for
+% this, since |\PrintChar| is the only control sequence that can
+% appear in |\macro@namepart|) so that |\expanded@notin| can be used
+% to test for its presence.
+% \begin{macrocode}
+\def\ifnot@excluded{%
+ \begingroup
+ \let\PrintChar\XD@paren@PrintChar
+ \edef\@tempa{\macro@namepart}%
+ \expandafter\endgroup \expandafter\expanded@notin
+ \expandafter{\expandafter\do \@tempa\do}%
+ {\the\index@excludelist}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{External cross-referencing}
+% \label{Ssec:XXR}
+%
+% (This subsection is a bit speculatory, but I think the structures it
+% describes may come in handy.)
+%
+% \changes{prot2}{2000/07/31}{I finally decided that it would be better
+% to make the XXR-commands look like comments to \TeX. (LH)}
+%
+% It's rather easy to write macros for scanning \TeX\ code for the names
+% of control sequences---just look for the escape (category 0)
+% character, and whatever follows is the name of a control sequence.
+% Doing the same thing for other languages may lay anywhere between
+% ``a~tricky exercise in advanced \TeX\ programming'' and ``possible in
+% theory'',\footnote{I.e., you know it can be implemented as a computer
+% program (in some language), you know that any computer program can be
+% translated to a Turing machine (or if you prefer that, expressed in
+% lambda calculus), and you know that a Turing machine can be emulated
+% by \TeX, but that's the closest thing to a solution you've managed to
+% come up with.} but in most cases the available solutions turn out to be
+% too complicated and\slash or slow to be of practical use. When that
+% happens, one might instead want to use some external piece of software
+% for doing the cross-referencing.
+%
+% The commands in this subsection implement basic support for such an
+% external cross-referencing program (or XXR,\footnote{Maybe not the
+% most logical name, but it looks much cooler than ECR.} for short). The
+% idea is that an XXR should communicate with \LaTeX\ like \BibTeX\
+% does---scan the \texttt{.aux} file (or files, if we're |\include|ing
+% things) for certain ``commands'' and use them to locate the files to
+% cross-reference, get parameter settings (like for example entries for
+% the index exclude list), and so on. It should then cross-reference the
+% file(s) and write the index entries in a suitable format to some file
+% (appending them to the \texttt{.idx} file is probably the easiest
+% solution). This way, it is (almost) as simple to use as the built-in
+% cross-referencing and the extra work for supporting it is (in
+% comparison to not supporting it) negligible.
+%
+% \begin{xrefcmd}{ExternalXRefMsg}
+% \begin{macro}{\SendExternalXRefMsg}
+% \changes{prot2}{2000/07/28}{Added \cs{if@filesw} test. (LH)}
+% It's hardly possible to predict all kinds of information that one
+% might want to give to an XXR, and neither can one assume that
+% there is only one XXR program that will read the \texttt{.aux}
+% file. A complicated project might involve code in several languages,
+% and each language might have its own XXR.
+% Therefore the general XXR-command (text in an \texttt{.aux} file which
+% is used for communicating information to an XXR) simply has the syntax
+% \begin{quote}
+% \verb*|%%ExternalXRefMsg |\marg{who}\verb*| |\marg{what}
+% \end{quote}
+% \meta{who} identifies the XXR this message is meant for. It must be
+% balanced text to \TeX\ and may not contain any whitespace, but can
+% otherwise be rather arbitrary. \meta{what} is the actual message. It
+% too must be balanced text to \TeX\ and it may not contain any
+% newlines, but it is otherwise arbitrary.
+% \index{whitespace restrictions}^^A
+% The reason for these restrictions on the contents of \meta{who} and
+% \meta{what} is that many (maybe even most) scripting languages
+% (which is what at least the \texttt{.aux}-scanning part of an
+% XXR will probably be written in) are much better at recognising
+% words on a line than they are at recognising a brace-delimited group.
+% By accepting these restrictions, one can make sure that all XXRs can
+% correctly determine whether a message is for them, even if they see
+% the \texttt{.aux} file as a sequence of lines composed of
+% whitespace-delimited words.
+%
+% |\SendExternalXRefMsg| is the basic command for writing
+% |ExternalXRefMsg|s to the \texttt{.aux} file, but it might be
+% recommendable that XXR writers provide users with a set of commands
+% that have more specific purposes. The syntax of the
+% |\Send|\-|External|\-|XRef|\-|Msg| command is (hardly surprising)
+% \begin{quote}
+% |\SendExternalXRefMsg|\marg{who}\marg{what}
+% \end{quote}
+% |\SendExternalXRefMsg| does a protected full expansion (like
+% |\protected@edef|) of its arguments at the time it is called.
+% \begin{macrocode}
+\newcommand\SendExternalXRefMsg[2]{%
+ \begingroup
+ \if@filesw
+ \let\protect\@unexpandable@protect
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefMsg {#1} {#2}}%
+ \fi
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}\end{xrefcmd}
+%
+% The remaining commands in this subsection address complications that
+% exist because of how \texttt{.dtx} files are generally written, and
+% thus constitutes difficulties that all XXRs will have to face.
+%
+% \begin{xrefcmd}{ExternalXRefFile}
+% The usual way to write \texttt{.dtx} files is to include a
+% driver---a~short piece of uncommented \LaTeX\ code which contains
+% the necessary preamble material and a document body which mainly
+% contains a |\DocInput| for the \texttt{.dtx} file itself---but it
+% is also usually understood that this driver may be copied to another
+% file if necessary and larger projects usually have a completely
+% separate driver file. Therefore an XXR cannot be expected to be
+% able to find the file(s) to cross-reference simply by changing
+% suffix on the name of the \texttt{.aux} file it reads its commands
+% from. A more intricate method must be used.
+%
+% To tell the XXR that ``here I input the file \dots'', one includes
+% an |External|\-|XRef|\-|File| XXR-command in the \texttt{.aux} file.
+% Its syntax is
+% \begin{quote}
+% \verb*|%%ExternalXRefFile |\marg{cmd}\verb*| |\marg{file}^^A
+% \verb*| |\marg{what}
+% \end{quote}
+% \meta{file} is the name (as given to |\input| or the like) of the
+% file to input. \meta{cmd} is either \texttt{begin} (begin of
+% \meta{file}) or \texttt{end} (end of \meta{file}). \meta{what} is a
+% declaration of what is in the file; XXRs should use it to determine
+% whether they should process this file or not. \meta{what} is empty
+% if all XXRs should process the file, but for example |\IndexInput|
+% will put \texttt{TeX} here to declare that the contents of this file
+% are \TeX\ code and only XXRs that cross-reference \TeX\ code need to
+% process this file.
+%
+% In connection to this, it should be mentioned that XXRs must also look
+% for (and act on) |\@input|\penalty\hyphenpenalty\marg{auxfile} commands
+% that |\include| or |\DocInclude| has written to the \texttt{.aux} file,
+% since these \meta{auxfile}s can also contain commands for the XXR
+% that should result in output to the same \texttt{.idx} file. In
+% particular, the |ExternalXRefFile| XXR-commands that are written
+% because of a |\DocInclude| will be written to such an \meta{auxfile}.
+% \end{xrefcmd}
+%
+% \begin{xrefcmd}{ExternalXRefSync}
+% Most XXRs will probably find it an unreasonable task to keep exact
+% track of all codelines in all documents, i.e., they will sometimes
+% think that a piece of code contains more or fewer numbered
+% codelines than it actually does. If for example a document contains
+% code such as\iffalse
+%<*example>
+% \fi
+%\begin{verbatim}
+%% \iffalse
+%% \begin{macrocode}
+%Etaoin Shrldu
+%% \end{macrocode}
+%% \fi
+%\end{verbatim}\iffalse
+%</example>
+%\fi
+% then all reasonable XXRs will probably be fooled into thinking that
+% the \texttt{Etaoin Shrldu} line is a numbered codeline. This would
+% of course be very bad if an XXR thought it should cross-reference
+% the contents of this line, but that shouldn't usually be a problem
+% since the specifications\footnote{I imagine these specifications
+% will consist of a list of \package{docstrip} options (modules),
+% possibly used in combination with restrictions on the names of
+% surrounding environments.} of what code should be cross-referenced
+% will probably make it clear that the above line should not be
+% cross-referenced. Code such as the above will still be problematic
+% however, as it will cause the XXR to believe that the
+% \texttt{codelineno} counter has another value on any following
+% line that is indexed than it actually has in the typeset
+% document. This will cause index entries to refer to another line
+% than it actually should.
+%
+% To overcome this, the |ExternalXRefSync| XXR-command can be used to
+% tell the XXR what the corresponding values of |\inputlineno| and
+% \texttt{codelineno} are. Its syntax is
+% \begin{quote}
+% \verb*|%%ExternalXRefSync |\marg{inputlineno}\verb*| |^^A
+% \marg{codelineno}
+% \end{quote}
+% where \meta{inputlineno} is the expansion of |\the\inputlineno| and
+% \meta{codelineno} is the expansion of |\thecodelineno|, both
+% expanded at the same point in the program. Note here that the first
+% line of a file is line number 1, that line number 0 is used to
+% denote ``just before the first line'', and that \texttt{codelineno}
+% gets increased immediately before the number is typeset (i.e.,
+% \texttt{codelineno} contains the number of the last numbered
+% codeline).
+% \end{xrefcmd}
+%
+% This doesn't support external cross-referencing by pages, since doing
+% that requires that the document outputs a lot more information to the
+% \texttt{.aux} file. In principle, one could put a |\mark|\penalty0
+% |{\thecodelineno}| in |\PrintCodelineNo| and a |\write| in the page
+% header which outputs to the \texttt{.aux} file which range of
+% codelines correspond to a given page, but the \LaTeXe\ sectioning
+% commands' use of marks tends to interfere with this. The \LaTeXplus\
+% package \package{xmarks} will probably solve that problem, though.
+%
+% \begin{macro}{\syncexternalxref}
+% \changes{prot2}{2000/07/28}{New name for \cs{SendExternalXRefSync}.
+% Also added \cs{if@filesw} test. (LH)}
+% ^^A Johann Sebastian Bach: 1685/03/21--1750/07/28
+% The |\syncexternalxref| command writes an |ExternalXRefSync|
+% XXR-command for the current line number and value of the
+% \texttt{codelineno} counter to \texttt{.aux} file. It is used for
+% synchronizing the numbered codeline counter that an XXR maintains with
+% the \texttt{codelineno} counter that is used for numbering codelines
+% in the typeset document after a piece of code in the document that
+% some XXR is likely to misinterpret. |\sync|\-|external|\-|xref|
+% shouldn't be used inside \texttt{macrocode} environments (or the
+% like) as they tend to read ahead in the file---instead it is best
+% placed shortly after such an environment. |\sync|\-|external|\-|xref|
+% has no arguments.
+% \begin{macrocode}
+\newcommand\syncexternalxref{%
+ \if@filesw
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefSync {\the\inputlineno} {\thecodelineno}%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{xrefcmd}{ExternalXRefWrap}
+% The |\DocInclude| command complicates matters for XXRs by redefining
+% things so that the \texttt{codelineno} counter only makes up a part
+% of the line numbers appearing in the index. The purpose of the
+% |External|\-|XRef|\-|Wrap| XXR-command is to inform XXRs about such
+% changes. The command
+% \begin{quote}
+% \verb*|%%ExternalXRefWrap {|\meta{prefix}\verb*|} {|^^A
+% \meta{suffix}|}|
+% \end{quote}
+% means that codeline numbers written to the index should have the form
+% \begin{quote}
+% \meta{prefix}\meta{codelineno}\meta{suffix}
+% \end{quote}
+% This setting takes effect from the next |External|\-|XRef|\-|Sync|
+% and stays in effect until the end of the document or until another
+% |External|\-|XRef|\-|Wrap| overrides it. The state at the beginning
+% of the document is to have both \meta{prefix} and \meta{suffix}
+% empty.
+% \end{xrefcmd}
+%
+%
+% \begin{macro}{\XD@input}
+% The |\XD@input| command is a version of |\input| which takes care
+% to inform XXRs that another file is being |\input|ted. Its syntax is
+% \begin{quote}
+% |\XD@input|\marg{file}\marg{what}
+% \end{quote}
+% where \meta{file} is the name of the file to |\input| and \meta{what}
+% is the contents of the file, as specified in
+% |External|\-|XRef|\-|File| commands.
+% \begin{macrocode}
+\def\XD@input#1#2{%
+ \if@filesw
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefFile {begin} {#1} {#2}%
+ }%
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefSync {0} {\thecodelineno}%
+ }%
+ \fi
+ \input{#1}%
+ \if@filesw
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefFile {end} {#1} {#2}%
+ }%
+ \immediate\write\@auxout{\@percentchar\@percentchar
+ ExternalXRefSync {\the\inputlineno} {\thecodelineno}%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInput}
+% The |\DocInput| command is redefined so that it writes
+% |External|\-|XRef|\-|File| and |External|\-|XRef|\-|Sync| XXR-commands
+% to the \texttt{.aux} file. Furthermore, with \package{xdoc} one
+% should always use the |\DocInput| command (or some command based on
+% it, like |\DocInclude|) for inputting a file where percent is an
+% `ignore' character---even when one such file inputs another. (Doing
+% that didn't work with the \package{doc} definition, as it always
+% called |\MakePercentComment| upon return, but the \package{xdoc}
+% definition contains code for dealing with that.)
+% \begin{macrocode}
+\renewcommand\DocInput[1]{%
+ \relax
+ \ifnum \catcode`\%=14
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi{%
+ \MakePercentIgnore\XD@input{#1}{}\MakePercentComment
+ }{\XD@input{#1}{}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\IndexInput}
+% The |\IndexInput| command also needs to be redefined to write
+% XXR-commands to the \texttt{.aux} file. It would
+% probably be enough here to write an |External|\-|XRef|\-|Sync|
+% after the file has been |\input| since no external
+% cross-referencing of |\IndexInput|ted files is needed, but I do the
+% more verbose variant here just to exemplify how these things would
+% look for other languages.
+% \begin{macrocode}
+\renewcommand\IndexInput[1]{%
+ \begingroup
+ \macro@code
+ \frenchspacing
+ \@vobeyspaces
+ \XD@input{#1}{TeX}%
+ \endmacrocode
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Two-sided printing}
+% \label{Sec:Twoside}
+%
+% The main problem one faces when reimplementing \package{doc} so that
+% the marginal material always appears in the outer margin in two-sided
+% documents is that the justification of \package{doc}'s marginal
+% material is asymmetric; it always extends outwards. This means that
+% the justification to use when typesetting the marginal material must
+% depend on whether it is to be put on a left or a right
+% page---something which cannot be determined for sure when the
+% material is typeset! This is a minor difficulty if the marginal material
+% is put in place using \LaTeX's |\marginpar| command, as that allows the
+% user to supply different versions of the marginal paragraph for left and
+% right margin placements. It is however a major difficulty if the
+% marginal material is displaced out into the margin from within the main
+% galley (like the \texttt{macro} environment of \package{doc} does),
+% since the output routine is never involved.
+%
+% Even though this difficulty provides arguments for using a |\marginpar|
+% mechanism for all text that is put in the margin, that will not be
+% done in \package{xdoc} (but maybe it will in some successor).
+% Instead \package{xdoc} contains a general mechanism which uses data
+% written to the \texttt{.aux} file for determining whether a piece of
+% text was put on an odd or even numbered page the \emph{last} time the
+% document was typeset. By the usual convergence of page breaks in a
+% \LaTeX\ document, this will eventually produce a typeset document
+% with the marginal material consistently in the outer margin.
+%
+% The mechanism works as follows. The places in the document (the
+% document source) at which it is necessary to determine whether
+% something is going to appear on an even (left) or an odd (right) page
+% are called ``page situations''\footnote{I know it's not a particularly
+% good name. Suggestions for better names are gracefully accepted.} or
+% just ``situations''. In each situation, a relatively simple test (is
+% the \texttt{page} counter currently even or odd?) which is right more
+% often than not is used as a first guess, and both the guess, the
+% placement actually used, and the correct answer (determined from the
+% value of \texttt{page} when the piece of text is shipped out) are
+% recorded in the \texttt{.aux} file. If the guess (for the current
+% situation) coincided with the correct answer the last time the
+% document was typeset then the guess determined now is used, otherwise
+% the opposite of the guess determined now is used. Finally, when at
+% |\end{document}| the \texttt{.aux} file is inputted to check for
+% changed labels, the placements used are also checked and the user is
+% given a suitable warning if there was an incorrect one.
+%
+% \begin{macro}{\IfOddPageSituation}
+% The |\IfOddPageSituation| macro is the user level test for whether
+% the current page situation appears on an odd or an even page. It
+% has the syntax
+% \begin{quote}
+% |\IfOddPageSituation|\marg{odd}\marg{even}
+% \end{quote}
+% and this will expand to \meta{odd} if the current situation is
+% expected to end up on an odd page (based on how correct it was to
+% look at the value of \texttt{page} last time) and to \meta{even}
+% otherwise. In single-sided mode, it always expands to \meta{even}.
+% In two-sided mode, |\IfOddPageSituation| is redefined for the new
+% situation each time |\StepPageSituation| is called.
+% \begin{macrocode}
+\let\IfOddPageSituation=\@secondoftwo
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\StepPageSituation}
+% \changes{prot2.1}{2000/12/19}{Now also setting
+% \cs{IfOddPageSituation}, instead of having that macro performing
+% the test each time it is used. This fixes a rarely occuring bug
+% which occurs when a page is shipped out between
+% \cs{StepPageSituation} and a corresponding
+% \cs{IfOddPageSituation}. (LH)}
+% \begin{macro}{\macro@cnt}
+% \begin{macro}{\XD@next@wrong}
+% \begin{macro}{\XD@wrongs@list}
+% The |\StepPageSituation| command is called to inform the page
+% situation mechanism that a new situation has begun. The rule for
+% when you need to use |\Step|\-|Page|\-|Situation| is simple: if you
+% use |\IfOdd|\-|Page|\-|Situation| in two places which may end up on
+% different pages, then there must be a |\Step|\-|Page|\-|Situation|
+% between them. There is no code which automatically calls
+% |\Step|\-|Page|\-|Situation|---not even |\clearpage| or other
+% macros which force page breaks do this---hence macros which use
+% the page situation mechanism must always call |\Step|\-|Page|\-^^A
+% |Situation| explicitly when a new situation begins.
+%
+% Since the |\macro@cnt| count register isn't used for stacking
+% marginal headings (``macro'' names) anymore (see below), it is
+% employed for enumerating page situation. |\XD@next@wrong| is a macro
+% which contains the number of the next situation in which the guess
+% was wrong last time. Unless |\XD@next@wrong|${}={}$|\macro@cnt|, the
+% guess was right last time. All assignments to |\macro@cnt| and
+% |\XD@next@wrong| are global.
+%
+% |\XD@wrongs@list| is a list of all the wrong guesses. It has the
+% syntax
+% \begin{quote}
+% |\@elt|\marg{guess no.}|\@elt|\marg{guess no.}\dots
+% |\@elt|\marg{guess no.}
+% \end{quote}
+% where the \meta{guess no.}s are the numbers of the wrong guesses, in
+% increasing order. The contents of |\XD@wrongs@list| are collected
+% when the \texttt{.aux} file is inputted at |\begin|\B|{document}|,
+% and they are removed again as \TeX\ passes the situation in the
+% document that they apply to. All assignments to |\XD@wrong@list| are
+% global.
+%
+% Calling |\StepPageSituation| increases |\macro@cnt| by one,
+% updates |\XD@|\B|next@|\B|wrong| and |\XD@|\B|wrong@|\B|list|
+% appropriately, and sets |\IfOdd|\B|Page|\B|Situation| to
+% |\@firstoftwo| or |\@secondoftwo| (whichever is correct for this
+% situation). |\@next| is a list management macro from the \LaTeX\
+% kernel.
+% \begin{macrocode}
+\if@twoside
+ \def\StepPageSituation{%
+ \global\advance \macro@cnt \@ne
+ \ifnum \XD@next@wrong<\macro@cnt
+ \global\@next\XD@next@wrong\XD@wrongs@list{}{%
+ \let\XD@next@wrong\maxdimen
+ }%
+ \fi
+ \ifnum \ifodd\c@page -\fi \@ne=%
+ \ifnum \XD@next@wrong=\macro@cnt -\fi \@ne
+ \global\let\IfOddPageSituation\@secondoftwo
+ \else
+ \global\let\IfOddPageSituation\@firstoftwo
+ \fi
+ }
+ \def\XD@next@wrong{-\maxdimen}
+ \let\XD@wrongs@list\@empty
+\else
+ \let\StepPageSituation=\relax
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+%
+% \begin{macro}{\RecordPageSituation}
+% The |\RecordPageSituation| command generates a |\write| whatsit node
+% which records the outcome of the current page situation. It is the
+% location of this whatsit node that determines on which page a
+% certain situation is considered to occur. If you don't execute this
+% macro for a certain page situation, the first guess will always be
+% used for that situation and no warnings will be given if that guess
+% is incorrect. In single-sided mode, this is a no-op (thus you should
+% better place it somewhere where it doesn't affect spacing).
+% Furthermore you must make sure that \TeX\ does not change the value
+% of the \texttt{page} counter between a |\StepPageSituation| and its
+% corresponding |\RecordPageSituation|, since the |\ifodd| test must
+% yield the same result in both cases.
+%
+% \begin{macrocode}
+\if@twoside
+ \def\RecordPageSituation{%
+ \if@filesw
+ \edef\@tempa{%
+ \string\XD@situation{\the\macro@cnt}{%
+ \ifodd\c@page 1\else 0\fi
+ }{\IfOddPageSituation{1}{0}}%
+ }%
+ \write\@auxout\expandafter{\@tempa{\ifodd\c@page 1\else 0\fi}}%
+ \fi
+ }%
+\else
+ \let\RecordPageSituation=\relax
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\XD@situation}
+% \changes{prot2}{2000/07/13}{Changed to allow multiple
+% \cs{XD@situation} commands for the same situation. This is
+% necessary for coping with documents which \cs{include} files. (LH)}
+% \changes{prot2}{2000/07/26}{Made redefinition at begin document
+% global. (LH)}
+% \begin{macro}{\XD@check@situation}
+% |\XD@situation| is the command that will be written to the
+% \texttt{.aux} file with the data about how the situation turned out.
+% Its syntax is
+% \begin{quote}
+% |\XD@situation|\marg{number}\marg{guess}\marg{did}\marg{correct}
+% \end{quote}
+% where \meta{number} is the number of the situation, and
+% \meta{guess}, \meta{did}, and \meta{correct} describe what the
+% guess, the actual action done, and what the correct action to do
+% respectively was. \meta{guess}, \meta{did}, and \meta{correct} are
+% either |0| (denoting even page) or |1| (denoting odd page).
+%
+% The definition for |\XD@situation| set here is the one which will
+% be in force when the \texttt{.aux} file is inputted at |\begin|\B
+% |{document}|; its purpose is to build the |\XD@wrongs@list|.
+% |\XD@check@situation| is the definition for |\XD@situation| which
+% will be in force when the \texttt{.aux} file is inputted at
+% |\end|\B|{document}|; its purpose is to check if anything was
+% incorrectly placed.
+%
+% The main problem |\XD@situation| has to face is that text in the
+% \texttt{.dvi} file needs not appear in exactly the same order as it
+% was typeset, and it is therefore possible that |\XD@situation|s in
+% the \texttt{.aux} file do not appear in increasing \meta{number}
+% order. Because of this, |\XD@situation| must sort the
+% |\XD@wrongs@list| while constructing it. The only reasonable
+% algorithm for this seems to be insertion sort, but as the items to
+% insert are almost surely almost sorted, a special check is done in
+% the beginning to see if that is the case. |\XD@next@wrong| is used
+% in this to store the number of the last item so far inserted into
+% the |\XD@wrongs@list|. By only assigning |\XD@next@wrong| locally
+% here, one is relieved of having to reset it in |\AtBeginDocument|
+% code.
+%
+% When sorting is actually applied, a new item |\@elt|\marg{insert}
+% is inserted through expanding the list. When doing that, the |\@elt|
+% macro has the syntax
+% \begin{quote}
+% |\@elt|\,\meta{flag}\,\marg{number}\,\meta{next}
+% \end{quote}
+% where \meta{flag} is |\BooleanTrue| or |\BooleanFalse|, \meta{number}
+% is the item that the |\@elt| belong to, and \meta{next} is either the
+% next |\@elt| or |\@gobble| (if this is the last). The \meta{flag}
+% specifies whether the item has been inserted; |\Boolean|\B|True| means
+% that it has. The above |\@elt|-sequence will expand to
+% \begin{quote}
+% |\noexpand|\,|\@elt|\,\marg{number}\,\meta{next}\,|\BooleanTrue|
+% \end{quote}
+% if \meta{flag} is |\BooleanTrue|, or \meta{flag} is |\BooleanFalse|
+% and \meta{number} is equal to \meta{insert}. It will expand to
+% \begin{quote}
+% |\noexpand|\,|\@elt|\,\marg{number}\,\meta{next}\,|\BooleanFalse|
+% \end{quote}
+% if \meta{flag} is |\BooleanFalse| and \meta{number} is less than
+% \meta{insert}. It expands to
+% \begin{quote}
+% |\noexpand|\,|\@elt|\,\marg{insert}\,|\noexpand|\,|\@elt|^^A
+% \,\marg{number}\\
+% \meta{next}\,|\BooleanTrue|
+% \end{quote}
+% if \meta{flag} is |\BooleanFalse| and \meta{number} is greater than
+% \meta{insert}.
+%
+% \begin{macrocode}
+\if@twoside
+ \def\XD@situation#1#2#3#4{%
+ \if #2#4\else
+ \ifnum #1<\XD@next@wrong
+ \begingroup
+ \def\@elt##1##2##3{%
+ \noexpand\@elt
+ \ifcase
+ \ifx ##1\BooleanTrue 0%
+ \else\ifnum ##2<#1 1%
+ \else\ifnum ##2>#1 2%
+ \else 0%
+ \fi\fi\fi
+ \space
+ {##2}\expandafter\@secondoftwo
+ \or
+ {##2}\expandafter\@firstoftwo
+ \else
+ {#1}\noexpand\@elt{##2}\expandafter\@secondoftwo
+ \fi{##3\BooleanFalse}{##3\BooleanTrue}%
+ }%
+ \xdef\XD@wrongs@list{%
+ \expandafter\expandafter \expandafter\@elt
+ \expandafter\@firstoftwo \expandafter\BooleanFalse
+ \XD@wrongs@list \@gobble
+ }%
+ \endgroup
+ \else\ifnum #1>\XD@next@wrong
+ \def\XD@next@wrong{#1}%
+ \expandafter\gdef \expandafter\XD@wrongs@list
+ \expandafter{\XD@wrongs@list \@elt{#1}}%
+ \fi\fi
+ \fi
+ }
+ \def\XD@check@situation#1#2#3#4{%
+ \if #3#4\else
+ \PackageWarningNoLine{xdoc2}{Page breaks may have changed.%
+ \MessageBreak Rerun to get marginal material right}%
+ \let\XD@situation\@gobblefour
+ \fi
+ }
+ \AtBeginDocument{\global\let\XD@situation\XD@check@situation}
+\else
+ \let\XD@situation\@gobblefour
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+%
+% \begin{macro}{\XD@set@situation}
+% \begin{macro}{\XD@write@situation@ckpt}
+% \begin{macro}{\cl@@ckpt}
+% The page situation counter |\macro@cnt| is closely related to the
+% \texttt{page} counter and it needs to be among the counters whose
+% values are recorded in |\include| checkpoints, since the enumeration
+% of situations will otherwise change when files are added to or
+% removed from the |\@partlist|. It is not sufficient to simply set
+% the value of |\macro@cnt| however; one must also advance to the
+% correct position in the |\XD@wrongs@list| list and set
+% |\XD@next@wrong| accordingly. The |\XD@set@situation| command has
+% the syntax
+% \begin{quote}
+% |\XD@set@situation|\marg{number}
+% \end{quote}
+% It sets |\macro@cnt| to \meta{number} and updates |\XD@wrongs@list|
+% and |\XD@|\B|next@|\B|wrong| accordingly.
+% \begin{macrocode}
+\if@twoside
+ \def\XD@set@situation#1{%
+ \global\macro@cnt=#1\relax
+ \loop \ifnum \XD@next@wrong<\macro@cnt
+ \global\@next\XD@next@wrong\XD@wrongs@list{}{%
+ \let\XD@next@wrong\maxdimen
+ }%
+ \repeat
+ }
+\else \let\XD@set@situation=\@gobble \fi
+% \end{macrocode}
+%
+% The |\XD@write@situation@ckpt| macro writes an |\XD@set@situation|
+% command to the \texttt{.aux} file in the way that |\@wckptelt|
+% writes |\setcounter| commands for normal counters. A problem for
+% |\XD@write@situation@ckpt| is that it will have to appear in a
+% macro which is regularly subjected to the |\xdef| in |\@cons|. For
+% that reason, it will simply expand to itself whenever |\@elt| isn't
+% |\@wckptelt|.
+% \begin{macrocode}
+\if@twoside
+ \def\XD@write@situation@ckpt{%
+ \ifx \@elt\@wckptelt
+ \immediate\write\@partaux{%
+ \string\XD@set@situation{\the\macro@cnt}%
+ }%
+ \else
+ \noexpand\XD@write@situation@ckpt
+ \fi
+ }
+ \expandafter\def \expandafter\cl@@ckpt
+ \expandafter{\cl@@ckpt \XD@write@situation@ckpt}
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+%
+%
+% \section{The list of changes}
+% \label{Sec:Changes}
+%
+% Reimplementations elsewhere have required a few modifications related
+% to the |\changes| command. There are a lot of other things that could
+% and perhaps should be done with these mechanisms, though.
+%
+% \begin{macro}{\saved@macroname}
+% The contents of the |\saved@macroname| macro now have the syntax
+% \begin{quote}
+% \marg{sort key}\marg{text}
+% \end{quote}
+% i.e., exactly like the argument sequence of |\LevelSorted|. It's not
+% fed to that macro right now, but it is not unlikely that it will in
+% the future. The default definition corresponds to the default
+% definition in \package{doc}.
+% \begin{macrocode}
+\def\saved@macroname{{ }{\generalname}}
+% \end{macrocode}
+% Unlike the case in \package{doc}, the formatting of the text in
+% |\saved@macroname| must be included.
+% \end{macro}
+%
+% \begin{macro}{\if@version@key@}
+% The |@version@key@| switch is used for supporting intelligent
+% sorting of version numbers. It is normally false, but at times
+% where the version number argument of |\changes| is being expanded
+% because it will be used as a sort key then it is true. This is used
+% by the |\uintver| macro. Assignments to this switch are as a rule
+% global, since it is never true for any longer time.
+% \changes{prot2.4}{2002/11/01}{Switch added. (LH)}
+% \begin{macrocode}
+\newif\if@version@key@
+\@version@key@false
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\uintver}
+% The |\uintver| command can be used in the \meta{version} argument
+% of |\changes| to ensure that (unsigned) integers are sorted in
+% mathematical rather than ASCII order by \package{makeindex}. Thus
+% if for example version |1.10| is later than version |1.9| then one
+% should write this as
+% \begin{quote}
+% |\changes{1.\uintver{10}}{|\dots
+% \end{quote}
+% The general syntax is
+% \begin{quote}
+% |\uintver|\marg{number}
+% \end{quote}
+% and this expands completely in \TeX's mouth.
+% \changes{prot2.4}{2002/11/01}{Command added. (LH)}
+%
+% The idea is that 0--9 are compared as 0--9, whereas 10--99 are
+% compared as A10--A99, 100--999 are compared as B100-B999, and so on.
+% The comparisons are correct up to 99999, but it could easily be
+% extended further.
+% \begin{macrocode}
+\newcommand*\uintver[1]{%
+ \if@version@key@
+ \ifnum #1>9
+ \ifnum #1<100
+ A%
+ \else\ifnum #1<\@m
+ B%
+ \else\ifnum #1<\@M
+ C%
+ \else
+ D%
+ \fi\fi\fi
+ \fi
+ \fi
+ \expandafter\@firstofone \expandafter{\number#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\changes@}
+% This |\changes@| is a simple redefinition of the \package{doc}
+% macro with the same name. The main difference is that all
+% formatting of the second entry level has been taken out---it is
+% supposed to be provided in |\saved@macroname|---but in addition to
+% that the date is being used as a third level sort key and |\uintver|
+% may be used in the version number to correct the data.
+% \changes{prot2.4}{2002/11/01}{Added support for \cs{uintver}. (LH)}
+%
+% The former makes more sense for projects where the date is
+% increased faster than the version number and it doesn't change
+% anything relevant in the remaining cases. The latter is necessary
+% if version numbers are assigned for example by CVS.
+% \begin{macrocode}
+\def\changes@#1#2#3{%
+ \global\@version@key@true
+ \protected@edef\@tempa{#1}%
+ \global\@version@key@false
+ \protected@edef\@tempa{%
+ \noexpand\glossary{%
+ \@tempa\actualchar#1\levelchar
+ \expandafter\@firstoftwo\saved@macroname\actualchar
+ \expandafter\@secondoftwo\saved@macroname:\levelchar
+ #2\actualchar#3%
+ }%
+ }%
+ \@tempa
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@wrglossary}
+% \changes{prot2.2}{2001/02/13}{Redefinition added. (LH)}
+% \begin{macro}{\XD@glossary@keyword}
+% \changes{prot2.2}{2001/02/13}{Macro added. (LH)}
+% The |\@wrglossary| macro is the one which actually writes entries
+% to the \texttt{.glo} file. It is redefined by \package{xdoc} to put
+% the contents of |\XD@glossary@keyword|, rather than a hardwired
+% |\glossaryentry|, in front of the glossary entry.
+% |\XD@glossary@keyword| is redefined by the \package{docindex}
+% package~\cite{docindex}.
+% \begin{macrocode}
+\def\@wrglossary#1{%
+ \protected@write\@glossaryfile{}%
+ {\XD@glossary@keyword{#1}{\thepage}}%
+ \endgroup
+ \@esphack
+}
+\@ifundefined{XD@glossary@keyword}{%
+ \edef\XD@glossary@keyword{\@backslashchar glossaryentry}%
+}{}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\definechange}
+% \begin{macro}{\XD@definechange}
+% The |\definechange| command has the syntax
+% \begin{quote}
+% |\definechange|\marg{name}\marg{version}\marg{date}\marg{text}
+% \end{quote}
+% The three last arguments are precisely like the arguments of
+% |\changes|, but |\definechange| doesn't write the change to the
+% \texttt{.glo} file; instead it stores them away as the ``named
+% change'' \meta{name}, for later use in the |\usechange| command.
+% \begin{macrocode}
+\newcommand\definechange{%
+ \begingroup\@sanitize
+ \catcode`\\\z@ \catcode`\ 10 \MakePercentIgnore
+ \expandafter\endgroup \XD@definechange
+}
+\def\XD@definechange#1#2#3#4{\@namedef{XD@ch-#1}{{#2}{#3}{#4}}}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% The named changes are stored in the
+% \describecsfamily{XD@ch-\meta{name}}|\XD@ch-|\meta{name} family of
+% control sequences. These are parameterless macros with replacement
+% texts of the form
+% \begin{quote}
+% \marg{version}\marg{date}\marg{text}
+% \end{quote}
+%
+% \begin{macro}{\usechange}
+% \begin{macro}{\XD@usechange}
+% \changes{prot2.4}{2002/11/01}{Added support for \cs{uintver}. (LH)}
+% To use a named change defined earlier, one of course uses the
+% command |\usechange|, which has the syntax
+% \begin{quote}
+% |\usechange|\marg{name}
+% \end{quote}
+% The effect of this is similar to that of a general |\changes|
+% (i.e., it appears outside all \texttt{macro}-like environments) with
+% the arguments specified in the |\definechange|, but this also
+% includes the macro (or whatever) name with the page number, using
+% the encapsulation mechanism in \package{makeindex}.
+% \begin{macrocode}
+\newcommand*\usechange[1]{%
+ \@ifundefined{XD@ch-#1}{%
+ \PackageError{xdoc2}{Named change `#1' undefined}\@eha
+ }{%
+ \expandafter\expandafter \expandafter\XD@usechange
+ \csname XD@ch-#1\endcsname
+ }%
+}
+\def\XD@usechange#1#2#3{%
+ \def\@tempa{{ }{\generalname}}%
+ \ifx \@tempa\saved@macroname
+ \let\@tempa\@empty
+ \else
+ \protected@edef\@tempa{%
+ \encapchar labelednumber%
+ {\expandafter\@secondoftwo\saved@macroname}%
+ }
+ \fi
+ \global\@version@key@true
+ \protected@edef\@tempb{#1}%
+ \global\@version@key@false
+ \glossary{%
+ \@tempb\actualchar #1\levelchar
+ \space\actualchar\generalname:\levelchar
+ #2\actualchar#3\@tempa
+ }%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\labelednumber}
+% The |\labelednumber| macro belongs to the same category as the
+% |\main| and |\usage| macros, but it takes an extra argument. The
+% syntax is
+% \begin{quote}
+% |\labelednumber|\marg{extra}\marg{number}
+% \end{quote}
+% which typesets as
+% \begin{quote}
+% \meta{number} (\meta{extra})
+% \end{quote}
+% \begin{macrocode}
+\newcommand*\labelednumber[2]{#2\nolinebreak[2] (#1)}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{\texttt{macro}-like environments}
+% \label{Sec:Macro-environments}
+%
+% There are several reasons one might want to improve the \texttt{macro}
+% and \texttt{environment} environments.
+% \begin{itemize}
+% \item
+% The code in them cannot be reused if you want to define other
+% things than \TeX\ macros or \LaTeX\ environments. (During the
+% last year or so, I have defined \texttt{macro}-like environments
+% for over a dozen different things.)
+% \item
+% They always put the macro\slash environment name to the left of
+% the current column. This is inappropriate for two-sided printing,
+% as there should be a symmetry over an entire spread in that case.
+% \item
+% The vertical extent of a macro\slash environment name must not
+% exceed that of the |\strut|, since they will otherwise overprint
+% each other when stacked. In particular this makes it impossible to
+% make line breaks in macro names---something which would otherwise
+% be of interest in projects (such as for example \cite{fontinst})
+% where some names are very long and obvious breakpoints are
+% available.
+% \end{itemize}
+% (I'm quite sure there are more things that have annoyed me, but I can't
+% remember which they are right now.) The redefinitions below take care
+% of the all these problems.
+%
+%
+% \subsection{Grabbing arguments}
+%
+% A special feature of the \texttt{macro}-like environments is that (at
+% least some) of their arguments must be given rather special treatment.
+% This special treatment usually consists of making temporary |\catcode|
+% changes for the time these arguments are tokenized---since the standard
+% |\catcode|s for some important characters tend to be unsatisfactory in
+% these cases---but there are other possibilities as well. For that
+% reason, the \package{xdoc} package employs a mechanism that is very
+% similar to that used in the Mittelbach--Rowley--Carlisle
+% \package{xparse} package~\cite{xparse}, although it does not share
+% any code with that. I call this mechanism the argument grabber.
+%
+% The heart of the argument grabber is the macro |\XD@grab@arguments|,
+% which has the following syntax:
+% \begin{quote}
+% |\XD@grab@arguments|\marg{call}\marg{grabber sequence}^^A
+% \meta{arguments to grab}
+% \end{quote}
+% \meta{call} is something which will eventually be placed in front of
+% all the arguments grabbed. It can simply be a single macro, but it
+% can also contain some arguments for that macro. \meta{grabber sequence}
+% is a sequence of grabbers. A \emph{grabber} is typically a macro which
+% grabs the next argument and stores it in a token list together with the
+% arguments that were grabbed before. A grabber could however be some
+% more complex piece of code that performs a similar action.
+%
+% \begin{table}
+% \begin{minipage}{\columnwidth}
+% \begin{center}\small
+% \begin{tabular}{lll>{\raggedright}p{0.3\linewidth}}
+% \textbf{Grabber}& \textbf{Arg.\ type}&
+% \textbf{Catcodes\footnote[1]{Catcode settings key:
+% --- = no change, PL = changes made by \cs{MakePrivateLetters},
+% OB = set the catcode of backslash to ordinary.}}&
+% \textbf{Post-processing}\tabularnewline
+% |\XD@grab@marg|& Mandatory& ---& None\tabularnewline
+% |\XD@grab@oarg|& Optional& ---& None\tabularnewline
+% |\XD@grab@sarg|\marg{char}& 1-char optional&
+% ---& Returns |\BooleanTrue| if the character was present
+% and |\BooleanFalse| otherwise.\tabularnewline
+% |\XD@grab@withprivate|& Mandatory& PL& None\tabularnewline
+% |\XD@grab@asmacro|\footnote[2]{This grabber is probably obsolete;
+% it is included because it grabs the argument in precisely the
+% way that the \texttt{macro} environment of \package{doc} does.}&
+% Mandatory& OB+PL& None\tabularnewline
+% |\XD@grab@harmless|\meta{proc}& Mandatory& ---&
+% |\MakeHarmless| followed by \meta{proc}\tabularnewline
+% |\XD@grab@harmless@oarg|& Optional& ---&
+% |\MakeHarmless|\tabularnewline
+% \multicolumn{3}{l}{\cs{XD@grab@harmless@asmacro}}\tabularnewline
+% & Mandatory& OB+PL&
+% |\MakeHarmless| followed by |\XD@unbackslash|\tabularnewline
+% |\XD@grab@harmless@cs|& Mandatory\footnote[3]{The argument is
+% normally precisely one control sequence.}& PL&
+% |\string| whilst |\escapechar| is set to \textminus1,
+% followed by |\MakeHarmless|\tabularnewline
+% \multicolumn{3}{l}{^^A
+% \cs{XD@grab@harmless@withprivate}\marg{proc}}\\
+% & Mandatory& PL& |\MakeHarmless| followed by \meta{proc}
+% \end{tabular}
+% \end{center}
+% \end{minipage}
+%
+% \caption{Grabbers currently defined by \package{xdoc}}
+% \label{Tab:Grabbers}
+% \end{table}
+%
+% When arguments are being grabbed, the \meta{call} is stored in |\toks@|
+% and the arguments are appended to |\toks@| as they are grabbed. For
+% that reason, a grabber may not itself call |\XD@grab@arguments|, nor
+% may it use a command defined through \package{xparse}'s
+% |\Declare|\-|Document|\-|Command| or anything else which uses this
+% token register in a bad way.
+%
+% When a grabber is expanded, it is in the context
+% \begin{quote}
+% \meta{grabber}\,\meta{following grabbers}\,|\XD@endgrab|\penalty0
+% \thinspace\meta{ungrabbed arguments}
+% \end{quote}
+% After it has grabbed its argument, everything of the above should be
+% put back except for the \meta{grabber} and the argument it grabbed.
+% The argument itself should be wrapped in a group and appended to
+% |\toks@|.
+%
+% \textbf{Note:} In prototype~2 the format in which the argument grabber
+% returns the grabbed arguments was changed so that it can now be
+% unified with argument grabbing mechanisms of \package{xparse}. I
+% think this should be done some time in the future, but for the moment
+% it seems best not to rely on \LaTeXplus\ packages like \package{xparse}.
+%
+% \begin{macro}{\XD@grab@arguments}
+% \begin{macro}{\XD@endgrab}
+% \changes{prot2}{2000/07/13}{The grabbed arguments are no longer
+% returned wrapped up in a group. There is no longer a need for
+% storing the base call separately in \cs{toks}\,\texttt{2}. (LH)}
+% The |\XD@grab@arguments| and |\XD@endgrab| macros set up and finish
+% off argument grabbing.
+% \begin{macrocode}
+\def\XD@grab@arguments#1#2{%
+ \toks@={#1}%
+ #2\XD@endgrab
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\XD@endgrab{\the\toks@}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\XD@grab@marg}
+% A grabber for ordinary arguments, like the \texttt{m} arguments of
+% \package{xparse}.
+% \begin{macrocode}
+\long\def\XD@grab@marg#1\XD@endgrab#2{%
+ \addto@hook\toks@{{#2}}%
+ #1\XD@endgrab
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XD@grab@oarg}
+% \begin{macro}{\XD@grab@oarg@}
+% A grabber for optional arguments (\texttt{o} arguments in
+% \package{xparse}). It looks ahead for an optional argument and
+% grabs that argument if there was one. If it doesn't find anything
+% which looks like an optional argument (i.e., if the next character
+% isn't a |[|), then the grabber will not grab anything (although it
+% may have tokenized the next argument), but it will still append
+% |\NoValue| to |\toks@|.
+%
+% \begin{macrocode}
+\def\XD@grab@oarg#1\XD@endgrab{%
+ \@ifnextchar[{\XD@grab@oarg@{#1}}{%
+ \addto@hook\toks@\NoValue
+ #1\XD@endgrab
+ }%
+}
+% \end{macrocode}
+% |\XD@grab@oarg@| is a helper to remove the brackets around the
+% optional argument.
+% \begin{macrocode}
+\long\def\XD@grab@oarg@#1[#2]{%
+ \addto@hook\toks@{{#2}}%
+ #1\XD@endgrab
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\XD@grab@sarg}
+% A grabber for `star'-type arguments (\texttt{s} arguments in
+% \package{xparse}). The syntax is
+% \begin{quote}
+% |\XD@grab@sarg|\marg{char}
+% \end{quote}
+% It looks ahead to see if the next character is the \meta{char}. In
+% that case it gobbles it and adds a |\BooleanTrue| to the grabbed
+% arguments, otherwise it adds a |\BooleanFalse| to the grabbed
+% arguments.
+% \changes{prot2.3}{2001/11/03}{Macro added. (LH)}
+% \begin{macrocode}
+\def\XD@grab@sarg#1#2\XD@endgrab{%
+ \@ifnextchar#1{%
+ \addto@hook\toks@\BooleanTrue
+ \@firstoftwo{#2\XD@endgrab}%
+ }{%
+ \addto@hook\toks@\BooleanFalse
+ #2\XD@endgrab
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XD@grab@withprivate}
+% |\XD@grab@withprivate| is like |\XD@grab@marg| but grabs the
+% argument when the catcodes are as set by |\MakePrivateLetters|.
+% \begin{macrocode}
+\def\XD@grab@withprivate{%
+ \begingroup\MakePrivateLetters\relax\expandafter\endgroup
+ \XD@grab@marg
+}
+% \end{macrocode}
+% To think about: Perhaps things like |\XD@grab@withprivate| should
+% rather be considered a modifier for a grabber? Instead of having
+% |\XD@grab@withprivate| be the entire grabber, one could let the
+% grabber be something like
+% \begin{quote}
+% |\XD@grab@withprivate\XD@grab@marg|
+% \end{quote}
+% where the |\XD@grab@withprivate| should only expand to
+% \begin{quote}
+% |\begingroup\MakePrivateLetters\relax\expandafter\endgroup|
+% \end{quote}
+% \end{macro}
+%
+% \begin{macro}{\XD@grab@asmacro}
+% |\XD@grab@asmacro| is very similar to |\XD@grab@withprivate|, but it
+% sees to that the catcode settings are exactly those used by
+% \package{doc}'s \texttt{macro} environment.
+% \begin{macrocode}
+\def\XD@grab@asmacro{%
+ \begingroup
+ \catcode`\\=12 \MakePrivateLetters\relax
+ \expandafter\endgroup
+ \XD@grab@marg
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XD@grab@harmless}
+% \begin{macro}{\XD@grab@harmless@oarg}
+% \changes{prot2.1}{2000/09/30}{Macro added. (LH)}
+% \begin{macro}{\XD@grab@harmless@oarg@}
+% \changes{prot2.1}{2000/09/30}{Macro added. (LH)}
+% The |\XD@grab@harmless| grabber grabs one mandatory argument and
+% converts it to a harmless character string, which it contributes to
+% the list of arguments. The syntax is
+% \begin{quote}
+% |\XD@grab@harmless|\marg{post-processing}
+% \end{quote}
+% where \meta{post-processing} are commands that will be performed
+% after the grabbed argument has been made harmless, but before it is
+% contributed to the list of arguments. Thus the
+% \meta{post-processing} can modify the argument some more, but
+% \meta{post-processing} can just as well be empty.
+% \begin{macrocode}
+\def\XD@grab@harmless#1#2\XD@endgrab#3{%
+ \MakeHarmless\@tempa{#3}%
+ #1%
+ \toks@=\expandafter{\the\expandafter\toks@ \expandafter{\@tempa}}%
+ #2\XD@endgrab
+}
+% \end{macrocode}
+%
+% The |\XD@grab@harmless@oarg| grabber grabs one optional argument and
+% converts it to a harmless character string. This string is
+% contributed to the list of arguments if the optional argument, or
+% else the token |\NoValue| is contributed instead.
+% \begin{macrocode}
+\def\XD@grab@harmless@oarg#1\XD@endgrab{%
+ \@ifnextchar[{\XD@grab@harmless@oarg@{#1}}{%
+ \addto@hook\toks@\NoValue
+ #1\XD@endgrab
+ }%
+}
+% \end{macrocode}
+% |\XD@grab@harmless@oarg@| is a helper to remove the brackets around
+% the optional argument.
+% \begin{macrocode}
+\long\def\XD@grab@harmless@oarg@#1[#2]{%
+ \MakeHarmless\@tempa{#2}%
+ \toks@=\expandafter{\the\expandafter\toks@ \expandafter{\@tempa}}%
+ #1\XD@endgrab
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@grab@harmless@asmacro}
+% \begin{macro}{\XD@grab@harmless@cs}
+% \begin{macro}{\XD@grab@harmless@cs@}
+% The |\XD@grab@harmless@asmacro| grabber combines the features of
+% |\XD@grab@|\B|asmacro| and |\XD@grab@harmless|, since when the
+% argument to grab is tokenized the catcode of |\| is set to 12 and
+% the catcode assignments in |\MakePrivateLetters| are made. Then the
+% grabbed argument is converted to a harmless character sequence, and
+% finally the first character is removed if it is a backslash.
+% \begin{macrocode}
+\def\XD@grab@harmless@asmacro{%
+ \begingroup
+ \catcode`\\=12 \MakePrivateLetters\relax
+ \expandafter\endgroup
+ \XD@grab@harmless{%
+ \protected@edef\@tempa{%
+ \expandafter\XD@unbackslash\@tempa\@empty
+ }%
+ }%
+}
+% \end{macrocode}
+%
+% The |\XD@grab@harmless@cs| grabber is for use with commands like
+% \package{doc}'s |\Describe|\-|Macro|, which take an actual control
+% sequence as the argument. It grabs one argument while having
+% catcodes changed as indicated by |\Make|\-|Private|\-|Letters|,
+% |\string|s the argument while |\escapechar| is |-1| (so that there
+% is no escape character inserted), and continues as
+% |\XD@grab@harmless|.
+% \begin{macrocode}
+\def\XD@grab@harmless@cs{%
+ \begingroup
+ \MakePrivateLetters\relax
+ \expandafter\endgroup \XD@grab@harmless@cs@
+}
+% \end{macrocode}
+% \begin{macrocode}
+\long\def\XD@grab@harmless@cs@#1\XD@endgrab#2{%
+ \begingroup
+ \escapechar=\m@ne
+ \expandafter\endgroup
+ \expandafter\MakeHarmless \expandafter\@tempa
+ \expandafter{\string#2}%
+ \toks@=\expandafter{\the\expandafter\toks@ \expandafter{\@tempa}}%
+ #1\XD@endgrab
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\XD@grab@harmless@withprivate}
+% |\XD@grab@harmless@withprivate| is like |\XD@grab@harmless| but
+% grabs the argument when the catcodes are as set by
+% |\Make|\-|Private|\-|Letters|.
+% Like |\XD@|\B|grab@|\B|harmless|, |\XD@grab@|\B|harmless@|\B
+% |withprivate| takes an argument which can contain code that
+% modifies the harmless character string after it has been formed.
+% \begin{macrocode}
+\def\XD@grab@harmless@withprivate{%
+ \begingroup\MakePrivateLetters\relax\expandafter\endgroup
+ \XD@grab@harmless
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{The \cs{XD@m@cro} and \cs{NewMacroEnvironment} commands}
+%
+% In \package{doc} the macro that contains most of the code for the
+% \texttt{macro} and \texttt{environment} environments is called
+% |\m@cro@|. In \package{xdoc} the corresponding macro is |\XD@m@cro|.
+%
+% At this point, it is helpful to recall what |\m@cro@| actually does.
+% It can be summarized in the following four points:
+% \begin{itemize}
+% \item It starts a |\trivlist|.\footnote{Seriously, can someone
+% explain to me why it seems just about every non-math \LaTeX\
+% environment that doesn't start a \cs{list} starts a \cs{trivlist}?
+% What good does all these \cs{trivlist}s do? Is it (a)~that people
+% just like the basic design, (b)~that there's some deep technical
+% reason, or (c)~that people in general doesn't have a clue but all
+% other environments do that so it's best to include it just in
+% case?}
+% \item It prints the name of the macro\slash environment that is
+% about to be defined in the margin.
+% \item It writes an index entry (and inhibits cross-referencing of
+% the macro inside the environment).
+% \item It sets |\saved@macroname| to the name of the macro\slash
+% environment (for use by |\changes|).
+% \end{itemize}
+%
+% The first and fourth points are simple, and commands for the third
+% were defined in Section~\ref{Sec:Indexing}, but the second point
+% needs a few helper macros.
+%
+%
+% \begin{macro}{\XDStackItemLabels}
+% \changes{prot2}{2000/07/28}{Made it work like a \cs{vtop} (but hide
+% the height) if \cs{XD@macro@dimen} is \texttt{-}\cs{maxdimen}.
+% (LH)}
+% \begin{macro}{\XD@macro@dimen}
+% The |\XDStackItemLabels| macro is a definition of |\makelabel| which
+% is used in the \texttt{macro}-like environments for stacking the
+% names printed by subsequent environments under each other. It makes
+% a box which has zero height and depth (it should have zero width as
+% well, but that is left as a restriction on the argument) and the
+% printed names will be stacked if the reference points of the
+% subsequent boxes generated by |\XD|\-|Stack|\-|Item|\-|Labels|
+% coincide.
+%
+% |\XD@macro@dimen| (always assigned globally) stores the vertical
+% distance from the reference point of the box that
+% |\XD|\-|Stack|\-|Item|\-|Labels| makes to the (bottommost) baseline
+% of the previous printed name. |\XD@macro@dimen| is updated by each
+% new |\XD|\-|Stack|\-|Item|\-|Labels|. The baseline of the next printed
+% name will be put one |\baselineskip| lower than that of the previous
+% printed name, except for when |\XD@macro@dimen| is |-\maxdimen| (see
+% below). To avoid that printed names clash into each other, this
+% additional |\baselineskip| is generated as normal interline glue
+% where the upper box has the same depth as a strut and the new value
+% of |\XD@macro@dimen| is measured in such a way that the printed
+% name's depth below the nominal baseline will not exceed the depth of
+% a strut (that's what the |\boxmaxdepth| assignment is for).
+% When |\XD@macro@dimen| is |-\maxdimen| the (topmost) baseline of the
+% printed name will instead go through the reference point of the box.
+% This case is intended for the first item label in a stack.
+%
+% The reason |\everypar| is cleared is that that is where the list
+% environments put the commands which actually insert the item label
+% into the paragraph. If that code gets executed inside |\makelabel|,
+% the list environments get seriously confused with not at all nice
+% consequences.
+% \begin{macrocode}
+\def\XDStackItemLabels#1{%
+ \setbox\z@=\vbox{%
+ \ifdim \XD@macro@dimen=-\maxdimen
+ \setbox\z@=\vtop{%
+ \color@begingroup
+ \everypar={}%
+ #1%
+ \color@endgroup
+ }%
+ \kern-\ht\z@
+ \unvbox\z@
+ \else
+ \color@begingroup
+ \everypar={}%
+ \kern\XD@macro@dimen
+ \setbox\z@=\copy\strutbox \ht\z@=\z@ \box\z@
+ #1%
+ \color@endgroup
+ \fi
+ \boxmaxdepth=\dp\strutbox
+ }%
+ \global\XD@macro@dimen=\ht\z@
+ \vtop to\z@{\unvbox\z@ \vss}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\newdimen\XD@macro@dimen
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\XDToMargin}
+% \changes{prot2.1}{2000/11/26}{New name for \cs{XD@to@margin}. (LH)}
+% The |\XDToMargin| macro takes one argument, which is assumed to be
+% some horizontal material, and puts that material in a |\hbox| of
+% width zero, horizontally shifted out into the the outer margin, in
+% such a way that longer arguments extend further out. |\marginparsep|
+% is used as the distance between the argument and the main galley. All
+% these placements assume that the |\hbox| will be put |\labelsep| to
+% the left of the beginning of a nonindented paragraph, since that is
+% where it will be put by the |\item| of a |\trivlist|.
+%
+% A question is where the margin should be considered to start if the
+% |\@total|\-|left|\-|margin| isn't zero. The corresponding
+% \package{doc} action would be to consider the margin as everything
+% outside the |\linewidth| width, but I don't think that would be
+% appropriate here (especially not since \package{doc} always puts the
+% codeline numbers at the edge of the |\textwidth| width).
+% \begin{macrocode}
+\newcommand\XDToMargin[1]{%
+ \hb@xt@\z@{%
+ \IfOddPageSituation{%
+ \dimen@=-\@totalleftmargin
+ \advance \dimen@ \labelsep
+ \advance \dimen@ \textwidth
+ \advance \dimen@ \marginparsep
+ \kern\dimen@
+ }\hss
+ #1%
+ \IfOddPageSituation\hss{%
+ \dimen@=\@totalleftmargin
+ \advance \dimen@ -\labelsep
+ \advance \dimen@ \marginparsep
+ \kern\dimen@
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XDParToMargin}
+% The |\XDParToMargin| command is in syntax and use similar to the
+% |\XDToMargin| command, but it will try to linebreak an argument
+% that is too long rather than letting it extend outside the paper.
+%
+% The implementation first tries to break the argument without
+% considering justification or positioning, but with a rather high
+% |\linepenalty|. If the result of that try is a single line paragraph
+% then |\XDToMargin| will be called to actually typeset the argument.
+% Otherwise the argument is typeset as a paragraph which gets
+% displaced out into the outer margin by giving |\leftskip| and
+% |\rightskip| nonzero natural widths. The practical line width in
+% the paragraph is the |\marginparwidth|, but the hboxes containing
+% the individual lines will have width zero. The first line of the
+% paragraph will be set flush outwards, the last line of the paragraph
+% will be set flush inwards, and the remaining lines will be centered.
+%
+% \changes{prot2.1}{2000/11/26}{Command added. (LH)}
+% \begin{macrocode}
+\newcommand\XDParToMargin[1]{%
+ \parindent=\z@
+ \setbox\z@=\vbox{%
+ \leftskip=\z@skip
+ \rightskip=\z@\@plus 1fil%
+ \parfillskip=\z@skip
+ \hsize=\marginparwidth
+ \linepenalty=1000%
+ \color@begingroup
+ \noindent\ignorespaces #1\@@par
+ \color@endgroup
+ \expandafter}%
+ \expandafter\ifnum \the\prevgraf<\tw@
+ \XDToMargin{#1}%
+ \else
+ \hsize=\z@
+ \leftskip=\z@ \@plus \marginparwidth
+ \rightskip=\leftskip
+ \IfOddPageSituation{%
+ \dimen@=-\@totalleftmargin
+ \advance \dimen@ \labelsep
+ \advance \dimen@ \textwidth
+ \advance \dimen@ \marginparsep
+ \advance \leftskip \dimen@
+ \advance \rightskip -\dimen@ \@minus \p@
+ \advance \rightskip -\marginparwidth
+ \parfillskip=\z@ \@plus 1fil%
+ }{%
+ \dimen@=\@totalleftmargin
+ \advance \dimen@ -\labelsep
+ \advance \dimen@ \marginparsep
+ \advance \leftskip -\dimen@ \@minus \p@
+ \advance \leftskip -\marginparwidth
+ \advance \rightskip \dimen@
+ \parfillskip=\z@ \@plus -\marginparwidth%
+ }
+ \noindent\nobreak\hskip\parfillskip
+ \ignorespaces #1\@@par
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% In the following I exploit the implementation of the |\item| command
+% in a slightly hackish way. Instead of starting a new paragraph with
+% the item label (which is what one at first would believe |\item|
+% does), |\item| actually puts the label in the box |\@labels| register,
+% and stores code in |\everypar| that inserts that box into the new
+% paragraph. Therefore I can make sure that various |\write| whatsits
+% that need to be as the same page as an |\item| label will be there by
+% adding them to the contents of the |\@labels| box. This seems more
+% reliable to me than putting them on the vertical list followed by a
+% |\nobreak| as \package{doc} does, but that would probably work as
+% well.
+%
+% [A funny thing in that which confused me a while was the question of
+% whether the |\box| command that inserts the box into the paragraph and
+% simultaneously clears the register acted globally or locally. It turns
+% out that the question was ill-posed, as the distinction between local
+% and global assignments is determined by what restore items they put
+% on \TeX's save stack. The |\box| command doesn't put anything there,
+% so the assignment it makes will essentially appear at the same
+% grouping level as the |\setbox| command that set the contents of the
+% box register. As all |\setbox|es for the |\@labels| box register are
+% global, the box register will be globally void after |\box\@labels|.]
+%
+%
+% \begin{macro}{\XD@m@cro}
+% \changes{prot2}{2000/07/24}{Put the \meta{changes} argument before
+% the \meta{assign} argument. Executing the \meta{assign} code
+% after the \meta{changes} \cs{edef}. Changed the descriptions of
+% these arguments a little. (LH)}
+% \changes{prot2.1}{2000/11/26}{Removed \cs{XDToMargin} from the
+% argument of \cs{item}. It should now be included in \#1
+% instead. (LH)}
+% This is the workhorse of all the \texttt{macro}-like environments.
+% It calls |\trivlist| and sets related parameters, prints the
+% ``macro'' name in the proper place, updates the representation of
+% the ``macro'' name that |\changes| will use, and writes appropriate
+% index entries (possibly making temporary changes in
+% cross-referencing). Exactly what these tasks consist of can vary
+% quite a lot between different \texttt{macro}-like environments, and
+% therefore the |\XD@m@cro| macro has the following syntax:
+% \begin{quote}
+% |\XD@m@cro|\marg{print}\marg{index}\marg{changes}\marg{assign}
+% \end{quote}
+% \meta{print}, \meta{index}, and \meta{assign} are simply the
+% commands for printing the ``macro'' name as it should appear in the
+% margin, generating the index entries for this \texttt{macro}-like
+% environment, and making whatever additional local assignments that
+% are needed for this environment (usually a couple of
+% |\Do|\-|Not|\-|Index|\-|Harmless| commands, if anything at all)
+% respectively. At the time \meta{index} is executed,
+% \texttt{codelineno} holds the number of the \emph{next} codeline.
+% \meta{changes}, finally, is code that will be put in the context
+% \begin{quote}
+% |\protected@edef\saved@macroname{|\meta{changes}|}|
+% \end{quote}
+% to set the |\saved@macroname| macro (for |\changes|).
+% \begin{macrocode}
+\def\XD@m@cro#1#2#3#4{%
+ \topsep\MacroTopsep
+ \trivlist
+ \global\setbox\@labels=\hbox{%
+ \unhbox\@labels
+ \if@inlabel \else
+ \global\XD@macro@dimen=-\maxdimen
+ \StepPageSituation
+ \RecordPageSituation
+ \fi
+ \advance \c@codelineno \@ne
+ #2%
+ }%
+ \let\makelabel\XDStackItemLabels
+ \item[#1]%
+ \protected@edef\saved@macroname{#3}%
+ #4%
+ \ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+%
+% In the first \package{xdoc} prototype, the \texttt{macro}-like
+% environments were implemented so that each new environment only used
+% two control sequences (|\|\meta{env} and |\end|\meta{env}), which is
+% the absolute minimum. This implementation worked fine for
+% single argument environments, but the number of helper macros that
+% would have to be introduced to deal with multiple argument
+% environments exceeded what could be considered reasonable. Therefore
+% the second prototype claims a third control sequence for the
+% implementation of a \texttt{macro}-like environment \meta{env}, namely
+% |\\|\meta{env}, which is also used by normal \LaTeXe\ environments
+% which take an optional argument.
+%
+% It should also be mentioned that the implementation in the first
+% prototype required that most of the code in |\|\meta{env} had to be
+% written in a very special way. Instead of using the |#|\meta{digit}
+% notation for the arguments and write straightforward \LaTeX\ code, one
+% had to express everything using macros which operate on arguments ``up
+% ahead'' (immediately after the code you can specify). This curious
+% coding model made it out of the question to create a class designer
+% interface for defining new \texttt{macro}-like environments, but in
+% the second \package{xdoc} prototype it is quite simple to do something
+% of that sort: the command name is |\New|\-|Macro|\-|Environment|.
+%
+% \begin{macro}{\NewMacroEnvironment}
+% \changes{prot2}{2000/07/13}{Command added. (LH)}
+% \changes{prot2}{2000/07/24}{Changed syntax in conformity with the
+% syntax change in \cs{XD@m@cro}. (LH)}
+% \changes{prot2.1}{2000/11/26}{Introduced star form with different
+% semanics for the \meta{print} argument. This uses the helper
+% macros \cs{XD@NewMacroEnvironment} and
+% \cs{XD@NewMacroEnvironment@}. (LH)}
+% \begin{macro}{\XD@NewMacroEnvironment}
+% \begin{macro}{\XD@NewMacroEnvironment@}
+% The |\NewMacroEnvironment| command is used for defining new
+% \texttt{macro}-like environments. It has the syntaxes
+% \begin{quote}
+% |\NewMacroEnvironment|\marg{name}\marg{grabbers}\marg{numargs}\\
+% \vadjust{}\hfill\marg{unjust-print}\marg{index}\marg{changes}^^A
+% \marg{assign}\\
+% |\NewMacroEnvironment*|\marg{name}\marg{grabbers}\marg{numargs}\\
+% \vadjust{}\hfill\marg{print}\marg{index}\marg{changes}\marg{assign}
+% \end{quote}
+% where \meta{name} is the name of the environment to define,
+% \meta{grabbers} is a sequence of argument grabbers, \meta{numargs}
+% is the number of arguments that the grabbers will grab, and
+% \meta{print}, \meta{index}, \meta{changes}, and \meta{assign} are
+% code that will be put in the respective arguments of |\XD@m@cro|.
+% In the four last arguments, argument specifiers |#1| to
+% |#|\meta{numargs} inclusive can be used do mean the arguments that
+% were grabbed by the sequence of grabbers.
+%
+% The argument grabbers that are currently made available by the
+% \package{xdoc} package are listed in Table~\ref{Tab:Grabbers} on
+% page~\pageref{Tab:Grabbers}.
+%
+% The \meta{print} code will be executed while \TeX\ is in internal
+% vertical mode and it should put one or several hboxes of width zero
+% onto the vertical list. The contents of these boxes should be some
+% amount of text which will appear displaced out into the outer margin
+% on the page when the reference point of the box appears |\labelsep|
+% to the left of the left edge of the line. The easiest way of
+% achieveing this is to use a \meta{print} of the form
+% \begin{quote}
+% |\XDToMargin|\marg{unjust-print}
+% \end{quote}
+% and this is exactly what the non-star form of |\NewMacroEnvironment|
+% does by default.
+%
+% \begin{macrocode}
+\newcommand\NewMacroEnvironment{%
+ \@ifstar\XD@NewMacroEnvironment\XD@NewMacroEnvironment@
+}
+\def\XD@NewMacroEnvironment@#1#2#3#4{%
+ \XD@NewMacroEnvironment{#1}{#2}{#3}{\XDToMargin{#4}}%
+}
+\def\XD@NewMacroEnvironment#1#2#3#4#5#6#7{%
+ \expandafter\@ifdefinable\csname#1\endcsname{%
+ \expandafter\def \csname#1\expandafter\endcsname
+ \expandafter{\expandafter\XD@grab@arguments
+ \csname\@backslashchar#1\endcsname{#2}}%
+ \let\l@ngrel@x\relax
+ \expandafter\@yargdef \csname\@backslashchar#1\endcsname \@ne
+ {#3}{\XD@m@cro{#4}{#5}{#6}{#7}}%
+ \expandafter\let \csname end#1\endcsname \endtrivlist
+ }%
+}
+% \end{macrocode}
+% The \meta{grabbers} argument---in which one specifies a list of
+% internal macros---is not how the interface should really look, but I
+% think it will have to do for now. The final interface will probably
+% use something like the argument specifications of
+% |\Declare|\-|Document|\-|Command|, but there is little point in
+% implementing that before \package{xparse} has gotten its final form.
+% \end{macro}\end{macro}\end{macro}
+%
+% The macro |\@yargdef| used above should perhaps be checked so that its
+% syntax hasn't changed, but since |\@yargdef| quite recently
+% (\texttt{ltdefn.dtx} v\,1.3c, 1999/01/18) was completely reimplemented
+% without any change in the syntax (despite the fact that the syntax is
+% afterwards rather peculiar), I think it can be assumed that the syntax
+% will not change in \LaTeXe.
+%
+%
+%
+% \subsection{Reimplementing \texttt{macro} and \texttt{environment}}
+% \label{Ssec:Macro&environment}
+%
+% Well, then how does one reimplement the \texttt{macro} and
+% \texttt{environment} environments using |\XD@m@cro|? We shall soon
+% see, but first it is convenient to define a utility macro.
+%
+% \changes{prot2}{2000/07/14}{Lots of utility macros were removed:
+% \cs{XDWrapText}, \cs{XDAltWrapText}, \cs{XDSortAndText},
+% \cs{MultipleApply}, \cs{ApplicableUsageIndex}, and
+% \cs{XD@index@family}. (LH)}
+%
+% \begin{macro}{\XDMainIndex}
+% \changes{prot2}{2000/07/14}{New name and syntax for
+% \cs{ApplicableMainIndex}. (LH)}
+% The |\XDMainIndex| macro is an abbreviation to save a couple of
+% tokens in a very frequent call to |\IndexEntry|. It has the syntax
+% \begin{quote}
+% |\XDMainIndex|\marg{argument}
+% \end{quote}
+% and that expands to
+% \begin{quote}
+% |\IndexEntry|\marg{argument}|{main}{\TheXDIndexNumber}|
+% \end{quote}
+% \begin{macrocode}
+\newcommand\XDMainIndex[1]{\IndexEntry{#1}{main}{\TheXDIndexNumber}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{macro}
+% \changes{prot2.1}{2000/11/15}{Using \cs{MakeSortKey} to make index
+% entry. (LH)}
+% \begin{environment}{environment}
+% It is very easy to implement \texttt{macro} and \texttt{environment}
+% environments which behave pretty much as in \package{doc} using the
+% |\New|\-|Macro|\-|Environment| command. The important difference
+% is that in \package{doc} everything that distinguished the two
+% environments was to be found in various helper macros, but here all
+% that code is in the |\\macro| and |\\environment| macros. Thus to
+% define one new \texttt{macro}-like environment, one doesn't have to
+% define six or so new macros---everything can be handled in one
+% definition.
+%
+% The reason for the |\let| commands below is of course that
+% \texttt{macro} and \texttt{environment} are already defined, and
+% there is no |\Renew|\-|Macro|\-|Environment| command. It could
+% perhaps have been better if |\New|\-|Macro|\-|Environment| had
+% behaved like |\Declare|\-|Robust|\-|Command|, but I don't think that
+% is an important problem for the moment.
+% \begin{macrocode}
+\let\macro=\relax
+\let\endmacro=\relax
+\NewMacroEnvironment{macro}{\XD@grab@harmless@asmacro}{1}
+ {\MacroFont\Bslash#1}
+ {\MakeSortKey\@tempa{#1}{}%
+ \XDMainIndex{\LevelSorted{\@tempa}{\texttt{\Bslash#1}}}}
+ {{#1}{\texttt{\Bslash#1}}}
+ {\DoNotIndexHarmless{#1}}
+% \end{macrocode}
+% \begin{macrocode}
+\let\environment=\relax
+\let\endenvironment=\relax
+\NewMacroEnvironment{environment}{\XD@grab@harmless@asmacro}{1}
+ {\MacroFont#1}
+ {\XDMainIndex{\LevelSorted{#1}{\texttt{#1} (environment)}}%
+ \XDMainIndex{%
+ \LevelSame{environments:}\LevelSorted{#1}{\texttt{#1}}%
+ }}%
+ {{#1}{\texttt{#1}}}
+ {}%
+% \end{macrocode}
+% \end{environment}\end{environment}
+%
+%
+% \subsection{Further examples of \texttt{macro}-like environments}
+% \label{Ssec:More macros}
+%
+% \begin{environment}{option}
+% The \texttt{option} environment is for class\slash package options.
+% IMHO, something like this environment should have been added to
+% \package{doc} years ago!
+%
+% \begin{macrocode}
+\NewMacroEnvironment{option}{\XD@grab@harmless\relax}{1}
+ {\MacroFont#1 \normalfont option}
+ {\XDMainIndex{\LevelSorted{#1}{\texttt{#1} option}}%
+ \XDMainIndex{%
+ \LevelSame{options:}\LevelSorted{#1}{\texttt{#1}}%
+ }}%
+ {{#1 option}{\texttt{#1} option}}
+ {}%
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{switch}
+% \changes{prot2.1}{2000/11/18}{Using \cs{MakeSortKey}. (LH)}
+% The \texttt{switch} environment is for switches created by
+% |\newif| (\PlainTeX\ style).
+% \begin{macrocode}
+\NewMacroEnvironment{switch}{\XD@grab@harmless\relax}{1}
+ {\MacroFont#1 \normalfont switch}%
+% \end{macrocode}
+% What makes switches different from the other \texttt{macro}-like
+% environments defined here is the large number of index entries it
+% makes. For a switch \meta{sw} it first makes one under the `switches:'
+% heading:
+% \begin{macrocode}
+ {%
+ \MakeSortKey\XD@last@key{#1}{}%
+ \XDMainIndex{%
+ \LevelSame{switches:}\LevelSorted{\XD@last@key}{\texttt{#1}}%
+ }%
+% \end{macrocode}
+% Second it makes a `\meta{sw} switch' entry:
+% \begin{macrocode}
+ \XDMainIndex{\LevelSorted{\XD@last@key}{\texttt{#1} switch}}%
+% \end{macrocode}
+% Third it makes an entry for the macro |\if|\meta{sw}. The sort key
+% for this entry is \emph{not} subjected to |\MakeSortKey| because
+% no reasonable operator will act on the |if| prefix (an operator
+% which acts on |if| could do rather strange things to e.g. |\ifnum|).
+% \begin{macrocode}
+ \XDMainIndex{\LevelSorted{if#1}{\texttt{\Bslash if#1}}}%
+% \end{macrocode}
+% Fourth it makes an entry for the macro |\|\meta{sw}|false|:
+% \begin{macrocode}
+ \MakeSortKey\@tempa{#1false}{}%
+ \XDMainIndex{\LevelSorted{\@tempa}{\texttt{\Bslash#1false}}}%
+% \end{macrocode}
+% Finally it makes an entry for the macro |\|\meta{sw}|true|:
+% \begin{macrocode}
+ \MakeSortKey\@tempa{#1true}{}%
+ \XDMainIndex{\LevelSorted{\@tempa}{\texttt{\Bslash#1true}}}%
+ }%
+% \end{macrocode}
+% The |\changes| heading, on the other hand, is trivial.
+% \begin{macrocode}
+ {{#1}{\texttt{#1} switch}}
+% \end{macrocode}
+% Finally, \texttt{switch} should turn off indexing of the three macros
+% it makes \texttt{main} entries for, since \package{makeindex} will
+% otherwise complain.
+% \begin{macrocode}
+ {\DoNotIndexHarmless{if#1}%
+ \DoNotIndexHarmless{#1false}%
+ \DoNotIndexHarmless{#1true}}%
+%</pkg>
+% \end{macrocode}
+% \end{environment}
+%
+%
+% To end this section, there now follows two examples which are not
+% part of the package as they are very specific, but which have been
+% included here because they illustrate that \texttt{macro}-like
+% environments may have several arguments.
+%
+% \begin{environment}{enccommand}
+% \begin{environment}{enccomposite}
+% The \texttt{enccommand} and \texttt{enccomposite} environments can
+% be used for marking up sources for encoding definition files and the
+% like. \texttt{enccommand} is for encoding-specific commands and has
+% the syntax
+% \begin{quote}
+% |\begin{enccommand}|\marg{command}\oarg{encoding}
+% \end{quote}
+% where \meta{command} is the encoding-specific command and
+% \meta{encoding} is the encoding that this definition is for. If the
+% \meta{encoding} is omitted then the \texttt{enccommand} is assumed
+% to be for the default definition of the command.
+%
+% \texttt{enccomposite} is for composites of encoding-specific
+% commands (defined for example using |\Declare|\-|Text|\-|Composite|).
+% It has the syntax
+% \begin{quote}
+% |\begin{enccomposite}|\marg{command}\marg{encoding}\marg{argument}
+% \end{quote}
+% where \meta{command} and \meta{encoding} are as for
+% \texttt{enccommand} and \meta{argument} is the argument with which
+% the command is being composed.
+%
+% The marginal headings these commands print are the actual control
+% sequences in which the definitions are stored.
+% \begin{macrocode}
+%<*enccmds>
+\NewMacroEnvironment{enccommand}{%
+ \XD@grab@harmless@asmacro \XD@grab@oarg
+}{2}{\MacroFont\Bslash \ifx\NoValue#2?\else#2\fi \Bslash #1}{%
+ \XDMainIndex{%
+ \LevelSorted{#1}{\texttt{\Bslash#1}}%
+ \ifx \NoValue#2%
+ \LevelSame{default}%
+ \else
+ \LevelSorted{#2}{\texttt{#2} encoding}%
+ \fi
+ }%
+}{{#1}{\texttt{\Bslash#1}}}{\DoNotIndexHarmless{#1}}
+% \end{macrocode}
+% \begin{macrocode}
+\NewMacroEnvironment{enccomposite}{%
+ \XD@grab@harmless@asmacro \XD@grab@marg \XD@grab@harmless\relax
+}{3}{\MacroFont\Bslash#2\Bslash#1-#3}{%
+ \XDMainIndex{%
+ \LevelSorted{#1}{\texttt{\Bslash#1}}%
+ \LevelSorted{#2}{\texttt{#2} encoding}%
+ \LevelSorted{\XD@unbackslash#3\@empty}{\texttt{#3} composite}%
+ }%
+}{{#1}{\texttt{\Bslash#1}}}{\DoNotIndexHarmless{#1}}
+%</enccmds>
+% \end{macrocode}
+% In the file \texttt{cyoutenc.dtx} the definitions of many
+% encoding-specific commands are written so that the same line of
+% code can work is all four files \texttt{t2aenc.def},
+% \texttt{t2benc.def}, \texttt{t2cenc.def}, and \texttt{x2enc.def}.
+% Therefore the \meta{encoding} argument of the \texttt{enccommand}
+% and \texttt{enccomposite} environments should perhaps rather be a
+% comma-separated list of encodings than a single encoding, but that
+% would make this example unnecessarily complicated.
+% \end{environment}\end{environment}
+%
+%
+%
+% \section{Describing macros and the like}
+% \label{Sec:Describing}
+%
+% \begin{macro}{\if@mparswitch}
+% \begin{macro}{\if@reversemargin}
+% In two-sided mode, marginal notes should appear in the outer
+% margin. The following code takes care of that.
+% \begin{macrocode}
+%<*pkg>
+\if@twoside
+ \@mparswitchtrue
+ \normalmarginpar
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\GenericDescribePrint}
+% \changes{prot2}{2000/07/14}{\cs{leavevmode} and \cs{ignorespaces}
+% moved to \cs{NewDescribeCommand}. (LH)}
+% \changes{prot2}{2000/07/20}{Added \cs{strut}. Removed it from
+% arguments passed to \cs{GenericDescribePrint}. (LH)}
+% \changes{prot2.3}{2001/06/24}{Changed formatting to match that of
+% \cs{XDParToMargin}. (LH)}
+% The |\GenericDescribePrint| macro is a utility macro for use in
+% commands like |\Describe|\-|Macro|. Its syntax is
+% \begin{quote}
+% |\GenericDescribePrint|\marg{text}
+% \end{quote}
+% and it puts \meta{text} in a marginal paragraph, giving it the
+% appropriate justification for appearing in that margin.
+%
+% The first part simply tests whether the argument fits on a single
+% line.
+% \begin{macrocode}
+\newcommand\GenericDescribePrint[1]{%
+ \setbox\z@=\vbox{%
+ \parindent=\z@
+ \leftskip=\z@skip
+ \rightskip=\z@\@plus 1fil%
+ \parfillskip=\z@skip
+ \hsize=\marginparwidth
+ \linepenalty=\@m
+ \color@begingroup
+ \noindent\ignorespaces #1\@@par
+ \color@endgroup
+ \expandafter}%
+ \expandafter\ifnum \the\prevgraf<\tw@
+% \end{macrocode}
+% Then comes the actual typesetting. First the single-line format.
+% The braces in the optional argument are there to prevent trouble
+% in case |#1| contains a right brace; they will be stripped off when
+% the argument is grabbed.
+% \begin{macrocode}
+ \if@twoside
+ \marginpar[{\raggedleft\strut #1}]{\raggedright\strut #1}%
+ \else
+ \marginpar{\raggedleft\strut#1}%
+ \fi
+ \else
+ \if@twoside
+ \marginpar[{%
+ \leftskip=\z@ \@plus \marginparwidth
+ \rightskip=\leftskip
+ \parfillskip=\z@ \@plus -\marginparwidth
+ \noindent\nobreak\hskip\parfillskip
+ \ignorespaces #1%
+ }]{%
+ \leftskip=\z@ \@plus \marginparwidth
+ \rightskip=\leftskip
+ \parfillskip=\z@ \@plus 1fil%
+ \noindent\nobreak\hskip\parfillskip
+ \ignorespaces #1%
+ }%
+ \else
+ \marginpar{%
+ \leftskip=\z@ \@plus \marginparwidth
+ \rightskip=\leftskip
+ \parfillskip=\z@ \@plus -\marginparwidth
+ \noindent\nobreak\hskip\parfillskip
+ \ignorespaces #1%
+ }%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% The \texttt{describe}-commands are supposed to be invisible---only
+% leave a single space even when there are spaces both before and after
+% them---but there are problems with the mechanisms for this. I get the
+% impression that they have never worked perfectly, but that seems to
+% be mainly due to that certain macros in the \LaTeX\ kernel never did
+% either, and I suspect that the general problem has been thrashed over
+% many times before.
+%
+% \package{doc}'s |\DescribeMacro| and |\DescribeEnv| are wrapped up in
+% a |\@bsphack| \dots\ |\@esphack| ``group'' to become invisible, but
+% the |\marginpar| and various index commands they are built on are
+% themselves already invisible, so one would suspect that there is no
+% need for additional invisibility. There are however two factors which
+% create this need. One is that it doesn't do the right thing at
+% beginning of lines; here it seems like what the
+% \texttt{describe}-commands would need is the |\@vbsphack| macro
+% (whose definition appears in \texttt{ltspace.dtx}, but which has been
+% commented out) since they should start a new paragraph and leave no
+% following space if they are used in vertical mode. The other factor is
+% that the standard |\@bsphack|--|\@esphack| can only suppress every
+% second intermediate space if several invisible commands appear in
+% sequence, as is quite common for the
+% \texttt{describe}-commands.\footnote{It would seem that a simple fix
+% for this is to have \cs{@esphack} insert \cs{nobreak}
+% \cs{hskip}\texttt{-}\cs{@savsk} \cs{hskip}\cs{@savsk} before it
+% executes \cs{ignorespaces}, but since that fix hasn't been
+% incorporated into the kernel or the \package{fixltx2e} package there
+% probably is some problem with it.}
+%
+% Instead the \package{doc} implementations of |\DescribeMacro| and
+% |\DescribeEnv| begin with |\leavevmode| and end with |\ignorespaces|,
+% which means that they are only ``invisible'' if they appear on on the
+% left of visible material, but that's how it has been for over a decade
+% now.
+%
+% \begin{macro}{\NewDescribeCommand}
+% \changes{prot2}{2000/07/14}{Command added. (LH)}
+% The |\NewDescribeCommand| command is a relative to the
+% |\New|\-|Macro|\-|Environment| command which defines commands
+% analogous to |\Describe|\-|Macro| rather than \texttt{macro}-like
+% environments. Its syntax is
+% \begin{quote}
+% |\NewDescribeCommand|\marg{command}\marg{grabbers}\B
+% \marg{numargs}\B\marg{definition}
+% \end{quote}
+% \meta{command} is the control sequence to define. \meta{grabbers}
+% and \meta{numargs} are as for the |\NewMacroEnvironment| command.
+% \meta{definition} is the command definition.
+% In addition to the definition given in the \meta{definition}
+% argument and the code for grabbing the arguments, the command
+% actually defined by |\New|\-|Describe|\-|Command| will contain a
+% |\leavevmode| at the start and an |\ignorespaces| at the end.
+%
+% The |\NewDescribeCommand| command should really just be a call to
+% \package{xparse}'s |\Declare|\-|Document|\-|Command|, but that will
+% have to wait until \package{xdoc} becomes based on the
+% \package{xparse} package.
+% \begin{macrocode}
+\newcommand\NewDescribeCommand[4]{%
+ \@ifdefinable#1{%
+ \expandafter\def \expandafter#1\expandafter{%
+ \expandafter\XD@grab@arguments \csname\string#1\endcsname{#2}%
+ }%
+ \let\l@ngrel@x\relax
+ \expandafter\@yargdef \csname\string#1\endcsname \@ne {#3}%
+ {\leavevmode#4\ignorespaces}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DescribeMacro}
+% \changes{prot2.1}{2000/11/18}{Using \cs{MakeSortKey}. (LH)}
+% \begin{macro}{\DescribeEnv}
+% The |\DescribeMacro| and |\DescribeEnv| commands are as in
+% \package{doc}. The argument of |\DescribeMacro| is supposed to be
+% the actual control sequence to describe (not as with the
+% \texttt{macro} environment something which looks like the control
+% sequence after being |\string|ed).
+% \begin{macrocode}
+\let\DescribeMacro=\relax
+\NewDescribeCommand\DescribeMacro{\XD@grab@harmless@cs}{1}{%
+ \GenericDescribePrint{\MacroFont\Bslash#1}%
+ \MakeSortKey\@tempa{#1}{}%
+ \IndexEntry{%
+ \LevelSorted{\@tempa}{\texttt{\Bslash#1}}%
+ }{usage}{\thepage}%
+}
+% \end{macrocode}
+% The argument of |\DescribeEnv|, on the other hand, is treated like
+% that of the \texttt{environment} environment, but backslash isn't
+% given catcode 12---only the catcode assignments in
+% |\Make|\-|Private|\-|Letters| are made.
+% \begin{macrocode}
+\let\DescribeEnv=\relax
+\NewDescribeCommand\DescribeEnv{%
+ \XD@grab@harmless@withprivate\relax
+}{1}{%
+ \GenericDescribePrint{\MacroFont#1}%
+ \IndexEntry{%
+ \LevelSame{environments:}\LevelSorted{#1}{\texttt{#1}}%
+ }{usage}{\thepage}%
+ \IndexEntry{%
+ \LevelSorted{#1}{\texttt{#1} (environment)}%
+ }{usage}{\thepage}%
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\describeoption}
+% \changes{prot2}{2000/07/31}{Command added---I realised that the need
+% to describe options is probably as large as that to mark out
+% their definition. (LH)}
+% The |\describeoption| command is the \texttt{describe}-companion to
+% the \texttt{option} environment.
+% \begin{macrocode}
+\NewDescribeCommand\describeoption{\XD@grab@harmless\relax}{1}{%
+ \GenericDescribePrint{\MacroFont#1 \normalfont option}%
+ \IndexEntry{%
+ \LevelSame{options:}\LevelSorted{#1}{\texttt{#1}}%
+ }{usage}{\thepage}%
+ \IndexEntry{%
+ \LevelSorted{#1}{\texttt{#1} option}%
+ }{usage}{\thepage}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\describecsfamily}
+% \changes{prot2}{2000/07/14}{Renamed \cs{DescribeCSFamily} and
+% incorporated the code from \cs{XD@index@family}. (LH)}
+% \changes{prot2.1}{2000/11/18}{Using \cs{MakeSortKey}. (LH)}
+% The |\describecsfamily| command is for marking out sections in text
+% where a particular family of control sequences is described---just
+% like |\DescribeMacro| does for individual commands. To clarify what
+% I mean by a control sequence family, here are a couple of examples:
+% \begin{longtable}{l >{\raggedright}p{0.55\linewidth}}
+% |\c@|\meta{counter}\label{Tab:CS-families}&
+% countdef token for the |\count| register storing the
+% \LaTeX\ counter \meta{counter}\tabularnewline
+% |\ps@|\meta{pagestyle}&
+% macro storing settings for the pagestyle \meta{pagestyle}^^A
+% \tabularnewline
+% |\|\meta{enc}|/|\meta{fam}|/|\meta{ser}|/|\meta{sh}|/|\meta{sz}&
+% the fontdef token for the font which has encoding \meta{enc},
+% family \meta{fam}, series \meta{ser}, shape \meta{sh}, and
+% size \meta{sz} under NFSS\tabularnewline
+% |\|\meta{enc}|\|\meta{cmd}&
+% the macro containing the definition for encoding \meta{enc} of
+% the encoding-specific \LaTeX\ command |\|\meta{cmd}^^A
+% \tabularnewline
+% |\fps@|\meta{type}&
+% the default placement specifier for \LaTeX\ floats of type
+% \meta{type}\tabularnewline
+% |\l@|\meta{name}&
+% a macro which formats table of contents entries for items of
+% type \meta{name} (\texttt{chapter}, \texttt{section}, etc.)^^A
+% \tabularnewline
+% |\l@|\meta{language}&
+% the |\language| number \package{babel} has allocated for the
+% language \meta{language} (\texttt{english}, \texttt{french},
+% etc.)\tabularnewline
+% |\i-|\meta{int}&
+% the control sequence (either a mathchardef token or a macro)
+% which stores the value of the \package{fontinst} integer
+% \meta{int}
+% \end{longtable}
+%
+% The syntax for |\describecsfamily| is
+% \begin{quote}
+% |\describecsfamily|\marg{cs-fam specification}
+% \end{quote}
+% The \meta{cs-fam specification} includes only what would be put
+% between |\csname| and |\endcsname|; the |\describecsfamily| command
+% will add a backslash when printing the name. No special catcodes
+% will be in force in the argument, but the |#|, |$|, |&|, |_|, |^|,
+% and |~| characters present no problems even if they have their
+% ordinary catcodes. All spaces are seen as ASCII space and \TeX\ is
+% skipping spaces as usual. Characters with catcode 0, 1, 2, 5, 9, 14,
+% or 15 may however be problematic.
+% If you need to specify such a problematic character then you can do
+% so by writing |\PrintChar|\marg{code}, where \meta{code} is the
+% ASCII code for the character, as a valid \TeX\ number in the range
+% 0--255. In case you do not remember the ASCII code for some
+% character \meta{c}, there is no harm in specifying it as
+% |`\|\meta{c}, e.g. |\PrintChar{`\}}| for a right brace. It is even
+% possible to write |\PrintChar| commands for characters outside
+% visible ASCII (but those are typeset as |^^|-sequences).
+%
+% The variant parts in the control sequence names are specified as
+% \begin{quote}
+% |\meta|\marg{text}
+% \end{quote}
+% and these will be typeset exactly as in normal text. The arguments
+% of |\meta|s appearing in a \meta{cs-fam specification} are moving.
+% All control sequences other than |\PrintChar| and |\meta| in a
+% \meta{cs-fam specification} (and which do not appear in the argument
+% of a |\PrintChar| or |\meta|) are essentially treated as if they
+% had been |\string|ed.
+%
+% Apart from the above differences in treatment of the argument, the
+% |\describe|\-|cs|\-|family| command is similar to
+% |\DescribeMacro|---it prints the control sequence name in the margin
+% and makes a \texttt{usage} index entry.
+% \begin{macrocode}
+\NewDescribeCommand\describecsfamily{\XD@grab@harmless{}}{1}{%
+ \GenericDescribePrint{%
+ \MetaNormalfont\MacroFont\Bslash#1%
+ }%
+ \MakeSortKey\@tempa{#1}{\def\meta##1{(##1)}}%
+ \IndexEntry{%
+ \LevelSorted{\@tempa}{\texttt{\protect\MetaNormalfont\Bslash#1}}%
+ }{usage}{\thepage}%
+}
+%</pkg>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% As for |\NewMacroEnvironment|, I also give an example of an
+% application of |\NewDescribeCommand| which is much too special for
+% including in \package{xdoc} in general and therefore the code is
+% placed in a special module. I had originally written the code as part
+% of another package, but I removed it because I thought it was a bit
+% too special even for that context. The commentry below is kept
+% unchanged.\changes{prot2.1}{2000/09/16}{Additional
+% \cs{NewDescribeCommand} code example added. (LH)}
+%
+% \begin{quotation}
+%
+% I believe this feature is primarily of interest for MacOS programs,
+% but there might be sufficiently similar structures in other operating
+% systems to make it useful even in other contexts. Be as it may, what
+% the feature described here does is that it allows the user to put an
+% entry in the index for each resource in the code. This gives an easy
+% way of checking that no two resources are assigned the same id, even
+% though there is no mechanism for especially warning for such
+% collisions.
+%
+% \begin{macro}{\DescribeResource}
+% The main command available is
+% \begin{quote}
+% |\DescribeResource|\marg{type}\marg{id}\marg{text}
+% \end{quote}
+% \meta{type} is a four-character string. Most special characters are
+% treated as ordinary ones (very useful for |#|s), but the visible
+% ASCII characters |%|, |{|, |\|, and |}| retain their usual meaning.
+% To use such a troublesome character \meta{c} in a resource type,
+% write it as |\PrintChar{`\|\meta{c}|}|. \meta{id} is a \TeX\ number;
+% it will be used as the number of the resource. \meta{text} is normal
+% text that will be put in the index entry to describe the resource; it
+% seems a good idea to use the name of the resource for this. \meta{id}
+% and \meta{text} are read with normal \LaTeX\ catcodes. Note that
+% \meta{text} is a moving argument.
+%
+% |\DescribeResource| does two things---it prints the \meta{type} and
+% \meta{id} of the resource in the margin, and it writes an entry
+% \begin{quote}
+% \meta{type} resources:\\
+% \vadjust{}\qquad\meta{id}\\
+% \vadjust{}\qquad\qquad\meta{text}
+% \end{quote}
+% (plus a lot of formatting not shown here) to the \texttt{.idx} file.
+% The reference is for the page.
+%
+% The idea with advancing |\count@| like that when constructing the
+% index entry is to get a sort key for which lexicographic order equals
+% the wanted order. This would not be the case if the number was simply
+% written down. The current code maps numbers to six-digit positive
+% integers, but five-digits integers would be sufficient (a resource
+% \meta{id} is a signed 16-bits integer). The construction chosen
+% here furthermore puts the negative numbers after the positive ones.
+% \begin{macrocode}
+%<*rsrccmd>
+\NewDescribeCommand\DescribeResource{%
+ \XD@grab@harmless\relax \XD@grab@marg \XD@grab@marg
+}{3}{%
+ \GenericDescribePrint{#1%
+ \textnormal{:\ifnum#2<\z@ \textminus\number-\else\number\fi#2}%
+ }%
+ \count@=#2\relax
+ \advance \count@ 100000\ifnum \count@<\z@ 0\fi \relax
+ \protected@edef\@tempa{%
+ \noexpand\LevelSorted{\the\count@}{%
+ \ifnum #2<\z@ \string\textminus \number-\else\number\fi#2%
+ }%
+ }%
+ \IndexEntry{%
+ \LevelSorted{#1 resources:}{\texttt{#1} resources:}%
+ \@tempa
+ \LevelSame{#3}%
+ }{usage}{\thepage}%
+}
+%</rsrccmd>
+% \end{macrocode}
+% \end{macro}
+%
+% \end{quotation}
+%
+%
+% \section{The \cs{DocInclude} command}
+% \label{Sec:DocInclude}
+%
+% The code in this section is based on code from the \package{ltxdoc}
+% document class~\cite{ltxdoc} and it implements a command called
+% |\DocInclude|. Two implementations of this command are given: one
+% which is essentially that of \package{ltxdoc} (preserving all its
+% peculiarities), and one which is a reimplementation from scratch. The
+% default is to use the latter, but passing the \texttt{olddocinclude}
+% option to \package{xdoc} selects the former.
+%
+%
+% \subsection{Old implementation}
+%
+% It should be observed that this is not a complete implementation of the
+% |\Doc|\-|Include| command---it only redefines the \package{ltxdoc}
+% macros that need to be changed if the |\Doc|\-|Include| command is to
+% work with \package{xdoc} (it doesn't for example change the definition
+% of |\Doc|\-|Include| itself). Furthermore it doesn't define anything if
+% the \package{ltxdoc} document class hasn't been loaded, since then the
+% details of the definition of |\Doc|\-|Include| (even if it would be
+% defined) are unknown.
+%
+% \begin{macro}{\CodelineIndex}
+% \changes{prot2.1}{2000/10/08}{Using \cs{thecodelineno}. (LH)}
+% \begin{macro}{\filesep}
+% \changes{prot2.2}{2001/02/13}{Redefined to use
+% \cs{XD@page@compositor}. (LH)}
+% \begin{macro}{\@docinclude}
+% \package{ltxdoc} redefines |\codeline@wrindex| so that |\filesep| is
+% prepended to each codeline number that is written to the index file.
+% That redefinition has no effect unless the |\Codeline|\-|Index|
+% command is executed afterwards however, so there is no harm in having
+% |\Codeline|\-|Index| itself apply the corresponding change.
+% \begin{macrocode}
+%<*pkg>
+\@ifpackagewith{xdoc2}{olddocinclude}{%
+ \@ifclassloaded{ltxdoc}{%
+ \renewcommand\CodelineIndex{%
+ \makeindex
+ \let\XD@if@index=\@firstoftwo
+ \codeline@indextrue
+ \def\TheXDIndexNumber{\filesep\thecodelineno}%
+ }%
+% \end{macrocode}
+% The |\filesep| macro is redefined so that the \package{docindex}
+% package~\cite{docindex} can use a |page_compositor| string different
+% from the default |-| simply by redefining |\XD@page@compositor|.
+% This redefinition has to be put in |\docincludeaux| since that macro
+% redefines |\filesep| too.
+% \begin{macrocode}
+ \expandafter\def \expandafter\docincludeaux \expandafter{%
+ \docincludeaux
+ \gdef\filesep{\thepart\XD@page@compositor}%
+ }
+% \end{macrocode}
+% The change to |\@docinclude| merely consists of inserting code for
+% writing an |External|\-|XRef|\-|Wrap| to the \texttt{.aux} file to
+% record the new value of the \texttt{part} counter.
+% \begin{macrocode}
+ \def\@docinclude#1 {%
+ \clearpage
+ \if@filesw
+ \immediate\write\@mainaux{\string\@input{#1.aux}}%
+ \fi
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \edef\@tempb{#1}%
+ \@for\@tempa:=\@partlist\do{%
+ \ifx\@tempa\@tempb\@tempswatrue\fi
+ }%
+ \fi
+ \if@tempswa
+ \let\@auxout\@partaux
+ \if@filesw
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}%
+ \fi
+ \part{#1.dtx}%
+ \if@filesw
+ \immediate\write\@partaux{\@percentchar\@percentchar
+ ExternalXRefWrap {\filesep} {}%
+ }%
+ \fi
+ {%
+ \let\ttfamily\relax
+ \xdef\filekey{%
+ \filekey, \thepart={\ttfamily\currentfile}%
+ }%
+ }%
+ \DocInput{#1.dtx}%
+ \clearpage
+ \@writeckpt{#1}%
+ \if@filesw \immediate\closeout\@partaux \fi
+ \else
+ \@nameuse{cp@#1}%
+ \fi
+ \let\@auxout\@mainaux
+ }
+ }{}
+}{}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+%
+% \subsection{New implementation}
+% \label{Ssec:New DocInclude}
+%
+% The default action of the second implementation is to be precisely an
+% |\include| variant of |\DocInput|, but in addition to that it also
+% has a (one-argument) hook called |\docincludeaux| which is executed
+% before a file is actually |\DocInput|ted, but after it has been
+% determined that it should be included, and this hook is only executed
+% for the files which should be |\include|d. This hook is normally
+% |\@gobble|, but passing the \texttt{fileispart} option to
+% \package{xdoc} redefines it to start a new part and set the pagestyle.
+%
+% \begin{macro}{\DocInclude}
+% \begin{macro}{\@docinclude}
+% Most of the code for the |\DocInclude| command is put in the
+% |\@docinclude| macro; |\DocInclude| simply checks that it hasn't
+% been nested. The main difference to |\include| is that a nested
+% |\DocInclude| becomes an error plus the corresponding |\DocInput|,
+% whereas a nested |\include| simply becomes an error. The rationale
+% for this is that it is probably closer to what was intended.
+%
+% The argument of |\@docinclude| is, oddly enough, space-delimited.
+% This is inherited from the |\@include| macro in the \LaTeX\ kernel,
+% where it is a hack to make sure that the part \texttt{.aux} file
+% that is opened for writing really gets the suffix \texttt{.aux} (in
+% the worst case, \TeX\ could start overwriting a \texttt{.tex} file
+% instead).
+% \begin{macrocode}
+\@ifpackagewith{xdoc2}{olddocinclude}{}{%
+ \def\DocInclude#1{%
+ \ifnum\@auxout=\@partaux
+ \@latexerr{\string\include\space cannot be nested}{%
+ Your \protect\DocInclude\space will be reduced to a
+ \protect\DocInput.%
+ }%
+ \DocInput{#1.dtx}%
+ \else \@docinclude#1 \fi
+ }%
+% \end{macrocode}
+% The only things in this |\@docinclude| that are not precisely as in
+% |\@include| are the |\docincludeaux| and |\DocInput| commands.
+% \begin{macrocode}
+ \def\@docinclude#1 {%
+ \clearpage
+ \if@filesw
+ \immediate\write\@mainaux{\string\@input{#1.aux}}%
+ \fi
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \edef\@tempb{#1}%
+ \@for\@tempa:=\@partlist\do{%
+ \ifx\@tempa\@tempb \@tempswatrue \fi
+ }%
+ \fi
+ \if@tempswa
+ \let\@auxout\@partaux
+ \if@filesw
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}%
+ \fi
+ \docincludeaux{#1.dtx}%
+ \DocInput{#1.dtx}%
+ \clearpage
+ \@writeckpt{#1}%
+ \if@filesw \immediate\closeout\@partaux \fi
+ \else
+ \deadcycles\z@
+ \@nameuse{cp@#1}%
+ \fi
+ \let\@auxout\@mainaux
+ }%
+}{}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{option}{fileispart}
+% \begin{macro}{\docincludeaux}
+% The \texttt{fileispart} option works by (re)defining a couple of
+% macros, of which the |\doc|\-|include|\-|aux| macro is the most
+% important. Its syntax is
+% \begin{quote}
+% |\docincludeaux|\marg{filename}
+% \end{quote}
+% where \meta{filename} is the name of a file that will be inputted.
+% The \texttt{fileispart} definition of this is to set |\currentfile|
+% to the harmless character string of \meta{filename}, produce a
+% |\part| heading whose text is that \meta{filename}, add the
+% \meta{filename} to the |\filekey| macro, set the page style to
+% \texttt{docpart}, clear the |\filedate|, |\fileversion|, and
+% |\fileinfo| macros, and write an |External|\-|XRef|\-|Wrap|
+% XXR-command to the \texttt{.aux} file to record the new codeline
+% number prefix.
+% \begin{macrocode}
+\@ifpackagewith{xdoc2}{olddocinclude}{\iffalse}{
+ \@ifpackagewith{xdoc2}{fileispart}{\iftrue}{
+ \let\docincludeaux=\@gobble
+ \iffalse
+ }
+} % If fileispart and not olddocinclude then
+ \def\docincludeaux#1{%
+ \MakeHarmless\currentfile{#1}%
+ \part{\texttt{\currentfile}}%
+ \pagestyle{docpart}%
+ \let\filedate\@empty
+ \let\fileversion\@empty
+ \let\fileinfo\@empty
+ \protected@xdef\filekey{%
+ \filekey, \thepart=\texttt{\currentfile}%
+ }%
+ \if@filesw
+ \immediate\write\@partaux{\@percentchar\@percentchar
+ ExternalXRefWrap {\thepart\XD@page@compositor} {}%
+ }%
+ \fi
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\CodelineIndex}
+% \changes{prot2.1}{2000/10/08}{Using \cs{thecodelineno}. (LH)}
+% The \texttt{fileispart} option also adds the \texttt{codelineno}
+% counter to the reset list for \texttt{part} and changes the format
+% of codeline numbers written to the index.
+% \begin{macrocode}
+ \@ifclassloaded{ltxdoc}{}{\@addtoreset{codelineno}{part}}%
+ \renewcommand\CodelineIndex{%
+ \makeindex
+ \let\XD@if@index=\@firstoftwo
+ \codeline@indextrue
+ \def\TheXDIndexNumber{\thepart\XD@page@compositor\thecodelineno}%
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\partname}
+% \begin{macro}{\thepart}
+% \begin{macro}{\IndexParms}
+% Finally there are a couple of macros which are redefined for
+% aesthetic rather than technical reasons. Passing the
+% \texttt{fileispart} option sets |\partname| to \texttt{File}, sets
+% |\thepart| to |\aalph{part}|, and adds a setting of pagestyle to
+% |\IndexParms|. (The pagestyle setting is added to
+% |\index@|\B|prologue| by \package{ltxdoc}, but I think
+% |\Index|\-|Parms| is more appropriate.)
+% \begin{macrocode}
+ \def\partname{File}
+ \def\thepart{\aalph{part}}
+ \expandafter\def \expandafter\IndexParms
+ \expandafter{\IndexParms \pagestyle{docindex}}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% In case the index formatting is handled by the \package{docindex}
+% package~\cite{docindex} (or its \LaTeXe\ incarnation
+% \package{docidx2e}), the above addition to |\Index|\-|Parms| won't
+% have any effect. Therefore \package{xdoc} also passes the
+% \texttt{use}\-\texttt{doc}\-\texttt{index}\-\texttt{ps} option on
+% to these packages.
+% \begin{macrocode}
+ \PassOptionsToPackage{usedocindexps}{docindex}
+ \PassOptionsToPackage{usedocindexps}{docidx2e}
+\fi
+% \end{macrocode}
+% \end{option}
+%
+% \begin{macro}{\ps@docpart}
+% \begin{macro}{\setfileinfo}
+% \begin{macro}{\XD@set@file@info}
+% The \texttt{docpart} pagestyle is for pages made from the
+% |\DocInclude|d files. The page footers contain the page number, the
+% part (file) number, and the current file name. It also contains the
+% file date and version if that information is available.
+%
+% \package{ltxdoc} uses |\GetFileInfo| to get the date and version
+% information, but that's a very peculiar practice. The data one wants
+% to present are about the file being typeset---typically the version
+% of the package that is documented in this file---whereas the
+% |\GetFileInfo| command really extracts information about
+% \emph{unpacked} classes, packages, and similar files---files that
+% contribute to the typesetting by defining commands, not by containing
+% text. Such information may be of interest for documents which contain
+% alternative code for incompatible versions of for example a package,
+% but it is of no use for printing version information as above since
+% the version of a package used for typesetting a \texttt{.dtx} file
+% need not be the version actually contained in that \texttt{.dtx}
+% file. Thus the only way to make this work is by doing as the \LaTeX\
+% kernel source and include |\ProvidesFile| commands for the
+% \texttt{.dtx} file in each such file, which is a rather peculiar use
+% of the |\ProvidesFile| command.
+%
+% The |\setfileinfo| command provides an equivalent feature in a less
+% roundabout way. It has the syntax
+% \begin{quote}
+% |\setfileinfo[|\meta{date}\verb*+ +\meta{version}\verb*+ +^^A
+% \meta{info}|]|
+% \end{quote}
+% and it sets |\filedate| to \meta{date}, |\fileversion| to
+% \meta{version}, and |\fileinfo| to \meta{info} if the optional
+% argument is present; if the optional argument is missing or contains
+% fewer than three words then the missing fields are set to |?|.
+%
+% \begin{macrocode}
+\@ifpackagewith{xdoc2}{olddocinclude}{}{%
+ \def\ps@docpart{%
+ \def\@oddfoot{%
+ File: \texttt{\currentfile}%
+ \ifx \filedate\@empty \else \ Date: \filedate\fi
+ \ifx \fileversion\@empty \else \ Version: \fileversion\fi
+ \hfill\thepage
+ }%
+ \if@twoside
+ \def\@evenfoot{%
+ \thepage\hfill
+ File: \texttt{\currentfile}%
+ \ifx \filedate\@empty \else \ Date: \filedate\fi
+ \ifx \fileversion\@empty \else \ Version: \fileversion\fi
+ }%
+ \else \let\@evenfoot\@oddfoot \fi
+ }
+% \end{macrocode}
+% The corresponding definition in \package{ltxdoc} (there it appears in
+% |\docincludeaux|) is peculiar in that the odd page footer is set
+% globally but the even page footer only locally.
+%
+% The definition of |\setfileinfo| follows that of |\GetFileInfo|
+% except for the fact that the |\relax|es have been replaced by
+% |\@empty|s.
+% \begin{macrocode}
+ \newcommand\setfileinfo[1][]{%
+ \edef\@tempa{#1}%
+ \expandafter\XD@set@file@info \@tempa\@empty? ? \@empty\@empty
+ }
+ \def\XD@set@file@info#1 #2 #3\@empty#4\@empty{%
+ \def\filedate{#1}%
+ \def\fileversion{#2}%
+ \def\fileinfo{#3}%
+ }
+}{}
+% \end{macrocode}
+% The reason for making the argument of |\setfileinfo| optional is
+% that with the |\Provides|\-|File| practice one can (potentially) put
+% all date and version information in one place through tricks like
+% \iffalse
+%<*example>
+% \fi
+%\begin{verbatim}
+%% \begin{macrocode}
+%\ProvidesPackage{foobar}
+%% \end{macrocode}
+%% \ProvidesFile{foobar.dtx}
+% [2000/02/02 v1.0 Silly example package]
+%%
+%\end{verbatim}\iffalse
+%</example>
+% \fi
+% By making the argument of |\setfileinfo| optional, I make sure that
+% people who have used such tricks only have to replace the
+% |\ProvidesFile{foobar.dtx}| by |\setfileinfo|.
+% \end{macro}\end{macro}\end{macro}
+%
+%
+% \begin{macro}{\ps@docindex}
+% \begin{macro}{\filekey}
+% The \texttt{docindex} pagestyle is for the index in
+% \texttt{fileispart} documents. It prints a file key, which is a
+% list of all the included files and their corresponding part letters,
+% at the bottom of every page. The file key is stored in the macro
+% |\filekey|, which should have been constructed file by file as they
+% are included. To add a file to the file key, it is recommended that
+% you do
+% \begin{quote}
+% |\protected@xdef\filekey{\filekey, |\meta{entry for new file}|}|
+% \end{quote}
+% The \texttt{fileispart} version of |\docincludeaux| already does
+% this. The initial value of |\filekey| is |\@gobble| so that the
+% comma before the first entry is removed. The |\@empty| below is
+% there in case no entry has been inserted.
+% \begin{macrocode}
+% \@ifpackagewith{xdoc2}{olddocinclude}{}{%
+ \def\ps@docindex{%
+ \def\@oddfoot{%
+ \parbox{\textwidth}{%
+ \strut\footnotesize\raggedright
+ \textbf{File Key:} \filekey\@empty
+ }%
+ }%
+ \let\@evenfoot\@oddfoot
+ }%
+ \let\filekey\@gobble
+% }
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% It should be observed that since |\ps@docindex| only sets the page
+% style locally, the page style will revert to its previous setting at
+% the end of the \texttt{theindex} environment. As that previous
+% setting is probably that of the \texttt{docpart} page style, you
+% might have to set the page style manually.
+%
+% \begin{macro}{\aalph}
+% \begin{macro}{\@aalph}
+% |\aalph| is a variant of |\alph| which continues with the upper case
+% letters for 27--52. It is defined by \package{ltxdoc}, so it is
+% merely provided here.
+% \begin{macrocode}
+\providecommand*\aalph[1]{\@aalph{\csname c@#1\endcsname}}
+\providecommand*\@aalph[1]{%
+ \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or
+ j\or k\or l\or m\or n\or o\or p\or q\or r\or s\or
+ t\or u\or v\or w\or x\or y\or z\or A\or B\or C\or
+ D\or E\or F\or G\or H\or I\or J\or K\or L\or M\or
+ N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or
+ X\or Y\or Z\else\@ctrerr\fi
+}
+% \end{macrocode}
+% In \texttt{source2e.tex} one can see that \package{doc}'s standard
+% \texttt{gind.ist} index style file won't sort the 35th file (part
+% \texttt{I}) correctly since it causes \package{makeindex} to read an
+% \texttt{I} as ``upper case Roman numeral one'', but I doubt very
+% many people encounter that problem in their projects.
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\XD@page@compositor}
+% \changes{prot2.2}{2001/02/13}{Macro added, other macros changed to
+% use it. (LH)}
+% The |\XD@page@compositor| macro contains the string which is put
+% between the parts of a composite number in the index; it
+% corresponds to the |page_compositor| parameter of
+% \package{makeindex}.
+% \begin{macrocode}
+\providecommand*\XD@page@compositor{-}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Miscellanea}
+%
+% \subsection{Some \LaTeXplus\ stuff}
+%
+% \begin{macro}{\BooleanFalse}
+% \begin{macro}{\BooleanTrue}
+% \begin{macro}{\NoValue}
+% These three macros are borrowed from the \package{xparse}
+% package~\cite{xparse}, where they work as the three values
+% \emph{boolean false}, \emph{boolean true}, and \emph{absence of
+% value} respectively. The definitions are taken from
+% \package{xparse} v\,0.17 (1999/09/10).
+% \begin{macrocode}
+\@ifundefined{BooleanFalse}{\def\BooleanFalse{TF}}{}
+\@ifundefined{BooleanTrue}{\def\BooleanTrue{TT}}{}
+\@ifundefined{NoValue}{\def\NoValue{-NoValue-}}{}
+% \end{macrocode}
+% By using these macros (rather than some homegrown set of macros
+% or tokens) for denoting these values here I hopefully simplify a
+% transition to \LaTeXplus, but I don't want to rely on \LaTeXplus\
+% since it hasn't been released yet.
+% \end{macro}\end{macro}\end{macro}
+%
+%
+% \subsection{The \cs{meta} command}
+%
+% A reimplementation which has already (as of v\,2.0k) found its way into
+% the \package{doc} package is the one that the |\meta| command is made
+% robust, but since some people might still have older
+% versions of \package{doc} and since that feature is needed for
+% |\describe|\-|cs|\-|family|, I apply it here too. First I check
+% whether the definition of |\meta| is the old non-robust definition,
+% and only apply the fix if it is.
+% \begin{macrocode}
+\begingroup
+\obeyspaces%
+\catcode`\^^M\active%
+\gdef\@gtempa{\begingroup\obeyspaces\catcode`\^^M\active%
+\let^^M\do@space\let \do@space%
+\def\-{\egroup\discretionary{-}{}{}\hbox\bgroup\itshape}%
+\m@ta}%
+\endgroup
+\ifx \meta\@gtempa
+% \end{macrocode}
+%
+% \begin{macro}{\l@nohyphenation}
+% The new implementation needs a |\language| without any hyphenation
+% patterns. By switching to that language, one can inhibit
+% hyphenation in a piece of text regardless of what line-breaking
+% parameter settings are in force when the paragraph is actually
+% broken. This new language will be called \texttt{nohyphenation} and
+% it is only allocated if it isn't already known (since some
+% \package{babel} settings files already defines this |\language|).
+% \begin{macrocode}
+ \@ifundefined{l@nohyphenation}{\newlanguage\l@nohyphenation}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\meta}
+% \begin{macro}{\meta@font@select}
+% This is the definition of |\meta| from \package{doc} v\,2.0m. For
+% an explanation of the implementation, se a \texttt{doc.dtx} at least
+% that new or entry \texttt{latex/3170} in the \LaTeX\ bugs database.
+% \begin{macrocode}
+ \DeclareRobustCommand\meta[1]{%
+ \ensuremath\langle
+ \ifmmode \expandafter \nfss@text \fi
+ {%
+ \meta@font@select
+ \edef\meta@hyphen@restore
+ {\hyphenchar\the\font\the\hyphenchar\font}%
+ \hyphenchar\font\m@ne
+ \language\l@nohyphenation
+ #1\/%
+ \meta@hyphen@restore
+ }\ensuremath\rangle
+ }
+% \end{macrocode}
+% \begin{macrocode}
+ \let\meta@font@select=\itshape
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\MetaNormalfont}
+% \changes{prot2}{2000/07/24}{Removed robustness; protected it
+% explicitly wherever needed instead. (LH)}
+% The |\MetaNormalfont| command redefines |\meta@font@select| to do a
+% |\normal|\-|font| before the |\itshape|. It is useful if |\meta| is
+% going to be used to make |\rmfamily| interjections in |\ttfamily|
+% text.
+% \begin{macrocode}
+\newcommand\MetaNormalfont{\def\meta@font@select{\normalfont\itshape}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\XD@harmless\meta}
+% This macro is needed for making |\meta| behave as described in the
+% argument of |\describe|\-|cs|\-|family|, i.e., in text which is
+% going to be converted into a harmless character string.
+% \begin{macrocode}
+\@namedef{XD@harmless\string\meta}#1{%
+ \toks@=\expandafter{\the\toks@ \meta{#1}}%
+ \XD@harmless@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{The checksum feature}
+%
+% The checksum mechanism in \package{doc} is a remnant from the times
+% when file truncation was a common problem and a mechanism for
+% detecting this was a great help.\footnote{Even though I suspect that
+% the recommended use of it---to put the checking \cs{Finale} at the
+% end of the \texttt{.dtx} file---may have reduced its usefulness
+% dramatically, as that \cs{Finale} would have been the one thing that
+% surely disappears if the file is truncated.} Today its main usefulness
+% seems to lie in that it distinguishes versions of a file that are
+% ``being worked on'' (where the checksum probably doesn't match) from
+% versions of a file that are ``polished and ready for upload''
+% (someone has bothered to fix the checksum), and as it exists it might
+% as well stay. There is a problem however with files which do not
+% contain \TeX\ code, as simply counting backslashes quite probably
+% isn't a good (or even reasonable) way of forming a checksum for these
+% files (if the checksum turns out to be zero, \package{doc} will
+% complain no matter what you do).
+%
+% \begin{macro}{\check@checksum}
+% \changes{prot2.1}{2000/10/02}{Redefinition added. (LH)}
+% For that reason, the |\check@checksum| macro is redefined to only
+% write the ``no checksum'' warning to the log file if the checksum
+% hasn't been set.
+% \begin{macrocode}
+\renewcommand\check@checksum{%
+ \relax
+ \ifnum \check@sum=\z@
+ \PackageInfo{doc}{This macro file has no checksum!\MessageBreak
+ The checksum should be \the\bslash@cnt}%
+ \else\ifnum \check@sum=\bslash@cnt
+ \typeout{*******************}%
+ \typeout{* Checksum passed *}%
+ \typeout{*******************}%
+ \else
+ \PackageError{doc}{Checksum not passed (\the\check@sum
+ <>\the\bslash@cnt)}{The file currently documented seems
+ to be wrong.\MessageBreak Try to get a correct version.}%
+ \fi\fi
+ \global\check@sum\z@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{The \cs{theCodelineNo} situation}
+% \label{Ssec:CodelineNo}
+%
+% \changes{prot2.1}{2000/10/08}{\cs{theCodelineNo} situation cleared
+% up. (LH)}
+% \package{doc} incorporates formatting of the value of the
+% \texttt{CodelineNo} counter in the |\theCodelineNo| macro, which is a
+% bit awkward since it prevents using this macro in making e.g.\ index
+% entries. To get around this, \package{xdoc} introduces the alternative
+% name \texttt{codelineno} for this counter so that |\thecodelineno| can
+% produce the value representation without formatting.
+%
+% \begin{macro}{\c@codelineno}
+% \begin{macro}{\cl@codelineno}
+% \begin{macro}{\p@codelineno}
+% \begin{macro}{\thecodelineno}
+% The control sequences connected to the \texttt{codelineno} counter
+% are |\let| so that they refer to the same |\count| register as the
+% \texttt{CodelineNo} counter. Note that \texttt{CodelineNo} isn't a
+% proper \LaTeX\ counter, so the macros |\cl@CodelineNo| and
+% |\p@CodelineNo| are undefined. |\thecodelineno| is set to the default
+% value for a new counter.
+% \begin{macrocode}
+\@ifundefined{c@codelineno}{}{%
+ \PackageInfo{xdoc2}{Overwriting codelineno counter}%
+}
+\let\c@codelineno=\c@CodelineNo
+\let\cl@codelineno=\@empty
+\let\p@codelineno=\@empty
+\def\thecodelineno{\@arabic\c@codelineno}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\PrintCodelineNo}
+% The |\PrintCodelineNo| command is the new recommended command for
+% printing the formatted form of the codeline number counter. People
+% who write their own \texttt{macrocode}-like environments should use
+% |\PrintCodelineNo| instead of \package{doc}'s |\theCodelineNo|.
+% \begin{macrocode}
+\newcommand\PrintCodelineNo{\reset@font\scriptsize\thecodelineno}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\theCodelineNo}
+% Finally |\theCodelineNo| is redefined to reference
+% |\PrintCodelineNo|. This is done for the sake of backwards
+% compability; I didn't feel like redefining |\macro@code| just for
+% the sake of changing the |\theCodelineNo| into a |\PrintCodelineNo|).
+% \begin{macrocode}
+\def\theCodelineNo{\PrintCodelineNo}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</pkg>
+% \end{macrocode}
+%
+%
+% \section{Problems and things to do}
+%
+% This section lists some problems that exist with the current
+% implementations of commands in \package{xdoc}. The list is rather
+% unstable---items are added as I realize there is a problem and removed
+% when I find a solution---an in parts it is rather esoteric since most
+% of the problems have only been found theoretically.
+%
+% \medskip
+%
+% One of the less well-known features of the |\verb| command is that
+% it automatically inhibits the known syntactic ligatures. There is
+% no such mechanism implemented for the harmless character strings,
+% so some (in \TeX\ \texttt{macrocode} uncommon) character sequences
+% (such as |!`|) may produce unwanted results. The quick hack to
+% circumvent this is to use the |\SetHarmState| command to mark one
+% of the characters involved as problematic, as the |\PrintChar|
+% command is implemented so that the character it prints will not be
+% involved in ligaturing or kerning. On the other hand, \package{doc}
+% does nothing to suppress syntactic ligatures in macro or environment
+% names when they are printed in the margin, so for that material the
+% \package{xdoc} implementation might actually improve things, although
+% it could perform worse for verbatim material in the index and list of
+% changes.
+%
+% \medskip
+%
+% Things to do and\slash or think about:
+% \begin{itemize}
+% \item
+% Examine how complicated it would be to convert the
+% |\PrintChar| commands for visible characters in a harmless
+% character string back to explicit characters, for possible use in
+% sort keys. (This could be used to ensure that visible characters
+% are sorted in strict ASCII order.)
+% \item
+% Should those ``letters'' which are commonly used as word
+% separators---in \LaTeX\ code mainly |@|---be ignored when sort
+% keys are being formed (just like the backslash is)? (This would
+% require a change in the implementation of the \texttt{macro}
+% environment.)
+%
+% A mechanism for doing this is included as of prototype version~2.1.
+% \item
+% Examine how much more efficient it would be to put temporary
+% additions to the index exclude list in a separate list instead of
+% the main list. This could be advantageous for deeply nested
+% \texttt{macro} environments, as \TeX\ will otherwise store as many
+% (almost identical and often rather long) copies of the exclude list
+% as there are nested environments.
+%
+% When asked about it, Frank Mittelbach didn't think there was
+% any gains worth mentioning in this. On the other hand it might be
+% worth investigating reimplementations that avoid calling |\trivlist|
+% at the beginning of each \texttt{macro}-like environment when they
+% are nested, since |\trivlist| does quite a lot of assignments.
+%
+% \item
+% In an automatically generated index one often faces the problem
+% that the entries at the innermost level are best formatted in one
+% way when there is only one, but in a completely different way when
+% there are several of them. To get optimal formatting in both cases,
+% one would like to let the |\item|, |\subitem|, |\subsubitem| or
+% corresponding macros detect the situation in this respect and
+% choose the optimal formatting at each case.
+%
+% A mechanism for this is implemented by the \package{docindex}
+% package.
+% \end{itemize}
+%
+%
+% \begin{thebibliography}{9}
+% \bibitem{ltxdoc}
+% David Carlisle:
+% \textit{The file \texttt{ltxdoc.dtx} for use with \LaTeXe},
+% The \LaTeX3 Project; ^^A , 1993~ff.
+% \textsc{ctan}:\discretionary{}{}{\thinspace}\texttt{macros}\slash
+% \texttt{latex}\slash \texttt{base}\slash \texttt{ltxdoc.dtx}.
+% \bibitem{docindex}
+% Lars Hellstr\"om:
+% \textit{The \package{docindex} package}, 2001,
+% \textsc{ctan}:\discretionary{}{}{\thinspace}\texttt{macros}\slash
+% \texttt{latex}\slash \texttt{exptl}\slash \texttt{xdoc}\slash
+% \texttt{docindex.dtx}.
+% \bibitem{fontinst}
+% Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth (and as of v\,1.9 Lars
+% Hellstr\"om): \textit{The \package{fontinst} utility}, v\,1.8~ff.,
+% documented source code,
+% \textsc{ctan}:\discretionary{}{}{\thinspace}^^A
+% \texttt{fonts}\slash \texttt{utilities}\slash
+% \texttt{fontinst}\slash \texttt{source}/
+% \bibitem{clsguide}
+% The \LaTeX3 Project:
+% \textit{\LaTeXe~for class and package writers},
+% The \LaTeX3 Project; ^^A , 1995~ff.
+% \textsc{ctan}:\discretionary{}{}{\thinspace}\texttt{macros}\slash
+% \texttt{latex}\slash \texttt{base}\slash \texttt{clsguide.tex}.
+% \bibitem{doc}
+% Frank Mittelbach, B.~Hamilton Kelly, Andrew Mills, Dave Love, and
+% Joachim \mbox{Schrod}: \textit{The \package{doc} and
+% \package{shortvrb} Packages}, The \LaTeX3 Project; ^^A , 1993~ff.
+% \textsc{ctan}:\discretionary{}{}{\thinspace}\texttt{macros}\slash
+% \texttt{latex}\slash \texttt{base}\slash \texttt{doc.dtx}.
+% \bibitem{xparse}
+% Frank Mittelbach, Chris Rowley, and David Carlisle: \textit{The
+% \package{xparse} package}, The \LaTeX3 Project, 1999. Currently
+% not available by anonymous FTP, but available by HTTP from
+% \texttt{www.latex-project.org} (look for ``experimental code'').
+% \end{thebibliography}
+%
+% \Finale
+\endinput \ No newline at end of file