% \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} % % \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|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> }{% \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 % %\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 % % \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 % \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@ \csname XD@harmless@\number`#1\endcsname}% % \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 % \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@ \csname XD@harmless@\number#1\endcsname}% % \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} % % \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 % \csname XD@harmless@\number`#1\endcsname % \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 % \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@ \csname XD@harmless@\number`#1\endcsname}% % \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 % %\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}}% % % \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}} % % \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}% } % % \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}% } % % \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 % % \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} % % \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