summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3doc.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3doc.dtx2064
1 files changed, 2064 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
new file mode 100644
index 00000000000..5039b8c0f62
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
@@ -0,0 +1,2064 @@
+% \iffalse meta-comment
+%
+%% File: l3doc.dtx Copyright (C) 1990-2011 The LaTeX3 project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This file is part of the "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver>
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input docstrip.tex
+\askforoverwritefalse
+\preamble
+
+
+EXPERIMENTAL CODE
+
+Do not distribute this file without also distributing the
+source files specified above.
+
+Do not distribute a modified version of this file.
+
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+\generate{\file{l3doc.cls}{\from{l3doc.dtx}{class}}}
+\generate{\file{l3doc.ist}{\from{l3doc.dtx}{docist}}}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</driver>
+%
+%<*driver|class>
+\RequirePackage{l3names}
+%</driver|class>
+%
+% Need to protect the file metadata for any modules that load l3doc.
+% This is restored after "\ProvideExplClass" below.
+% \begin{macrocode}
+%<class>\let \filenameOld \ExplFileName
+%<class>\let \filedateOld \ExplFileDate
+%<class>\let \fileversionOld \ExplFileVersion
+%<class>\let \filedescriptionOld \ExplFileDescription
+% \end{macrocode}
+%
+%<*driver|class>
+\GetIdInfo$Id: l3doc.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental documentation class}
+%</driver|class>
+%
+%<*driver>
+\ProvidesFile{\ExplFileName.dtx}
+ [\ExplFileDate\space v\ExplFileVersion\space\ExplFileDescription]
+\documentclass{l3doc}
+\usepackage{framed}
+\begin{document}
+ \DocInput{l3doc.dtx}
+\end{document}
+%</driver>
+%
+% This isn't included in the typeset documentation because it's a bit ugly:
+%<*class>
+\ProvidesExplClass
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\RequirePackage{expl3,xparse}
+\let \ExplFileName \filenameOld
+\let \ExplFileDate \filedateOld
+\let \ExplFileVersion \fileversionOld
+\let \ExplFileDescription \filedescriptionOld
+%</class>
+% \fi
+%
+% \title{The \pkg{l3doc} class\thanks{This file
+% has version number v\ExplFileVersion, last
+% revised \ExplFileDate.}}
+% \author{\Team}
+% \date{\ExplFileDate}
+% \maketitle
+% \tableofcontents
+%
+% \begin{documentation}
+%
+% \section{Introduction}
+%
+% This is an ad-hoc class for documenting the \pkg{expl3} bundle,
+% a collection of modules or packages that make up \LaTeX3's programming
+% environment. Eventually it will replace the "ltxdoc" class for \LaTeX3,
+% but not before the good ideas in \pkg{hypdoc}, \cls{xdoc2}, \pkg{docmfp}, and
+% \cls{gmdoc} are incorporated.
+%
+% \textbf{It is even less stable than the main \pkg{expl3} packages. Use at own risk!}
+%
+% It is written as a `self-contained' docstrip file: executing
+% "latex l3doc.dtx"
+% will generate the "l3doc.cls" file and typeset this
+% documentation; execute "tex l3doc.dtx" to only generate the ".cls" file.
+%
+% \section{Features of other packages}
+%
+% This class builds on the \pkg{ltxdoc} class and the \pkg{doc} package, but
+% in the time since they were originally written some
+% improvements and replacements have appeared that we would like to use as
+% inspiration.
+%
+% These packages or classes are \pkg{hypdoc}, \pkg{docmfp}, \pkg{gmdoc},
+% and \pkg{xdoc}. I have summarised them below in order to work out what
+% sort of features we should aim at a minimum for \pkg{l3doc}.
+%
+% \subsection{The \pkg{hypdoc} package}
+%
+% This package provides hyperlink support for the \pkg{doc} package. I have
+% included it in this list to remind me that cross-referencing between
+% documentation and implementation of methods is not very good. (E.g., it
+% would be nice to be able to automatically hyperlink the documentation for
+% a function from its implementation and vice-versa.)
+%
+% \subsection{The \pkg{docmfp} package}
+%
+% \begin{itemize}
+% \item Provides "\DescribeRoutine" and the "routine" environment (etc.)
+% for MetaFont and MetaPost code.
+% \item Provides "\DescribeVariable" and the "variable" environment (etc.)
+% for more general code.
+% \item Provides "\Describe" and the "Code" environment (etc.) as a
+% generalisation of the above two instantiations.
+% \item Small tweaks to the DocStrip system to aid non-\LaTeX\ use.
+% \end{itemize}
+%
+% \subsection{The \pkg{xdoc2} package}
+%
+% \begin{itemize}
+% \item Two-sided printing.
+% \item "\NewMacroEnvironment", "\NewDescribeEnvironment"; similar idea
+% to \pkg{docmfp} but more comprehensive.
+% \item Tons of small improvements.
+% \end{itemize}
+%
+% \subsection{The \pkg{gmdoc} package}
+%
+% Radical re-implementation of \pkg{doc} as a package or class.
+% \begin{itemize}
+% \item Requires no "\begin{macrocode}" blocks!
+% \item Automatically inserts "\begin{macro}" blocks!
+% \item And a whole bunch of other little things.
+% \end{itemize}
+%
+% \section{Problems \& Todo}
+%
+% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (e.g., the odd `"/ (...)"' tags; (3)~no obvious link between the "\begin{function}" environment for documenting things to the "\begin{macro}" function that's used analogously in the implementation.
+%
+% The "macro" should probably be renamed to "function" when it is used within
+% an implementation section. But they should have the same syntax before that happens!
+%
+% Furthermore, we need another `layer' of documentation commands to
+% account for `user-macro' as opposed to `code-functions'; the \pkg{expl3}
+% functions should be documented differently, probably, to the \pkg{xparse}
+% user macros (at least in terms of indexing).
+%
+% In no particular order, a list of things to do:
+% \begin{itemize}
+% \item Rename \env{function}/\env{macro} environments to better describe
+% their use.
+% \item Generalise \env{function}/\env{macro} for documenting `other things',
+% such as environment names, package options, even keyval options.
+% \item Use \pkg{xparse}.
+% \item New function like "\part" but for files (remove awkward `File' as "\partname").
+% \item Something better to replace "\StopEventually"; I'm thinking two
+% environments \env{documentation} and \env{implementation} that can
+% conditionally typeset/ignore their material.
+% (This has been implemented but needs further consideration.)
+% \item Hyperlink documentation and implementation of macros (see
+% the \textsc{dtx} file of \pkg{svn-multi} v2 as an example).
+% \end{itemize}
+%
+% \section{Bugs}
+%
+% \begin{itemize}
+% \item Spaces are ignored entirely within \env{function} and \env{macro}
+% arguments. This is just waiting for a convenient space-trimming
+% macro in \pkg{expl3}.
+% \end{itemize}
+%
+% \section{Documentation}
+%
+% \subsection{Configuration}
+%
+% Before class options are processed, \pkg{l3doc} loads a configuration
+% file "l3doc.cfg" if it exists, allowing you to customise the behaviour of
+% the class without having to change the documentation source files.
+%
+% For example, to produce documentation on letter-sized paper instead of the
+% default A4 size, create |l3doc.cfg| and include the line
+% \begin{verbatim}
+% \PassOptionsToClass{letterpaper}{l3doc}
+% \end{verbatim}
+%
+% By default, \pkg{l3doc} selects the |T1| font encoding and loads the
+% Latin Modern fonts.
+% To prevent this, use the class option |cm-default|.
+%
+% \subsection{Partitioning documentation and implementation}
+%
+% \pkg{doc} uses the "\OnlyDocumentation"/"\AlsoImplementation" macros
+% to guide the use of "\StopEventually{}", which is intended to be placed
+% to partition the documentation and implementation within a single DTX file.
+%
+% This isn't very flexible, since it assumes that we \emph{always} want
+% to print the documentation. For the \pkg{expl3} sources, I wanted to be
+% be able to input DTX files in two modes: only displaying the documentation,
+% and only displaying the implementation. For example:
+%
+% \begin{verbatim}
+% \DisableImplementation
+% \DocInput{l3basics,l3prg,...}
+% \EnableImplementation
+% \DisableDocumentation
+% \DocInputAgain
+% \end{verbatim}
+%
+% The idea being that the entire \pkg{expl3} bundle can be documented,
+% with the implementation included at the back. Now, this isn't perfect,
+% but it's a start.
+%
+% Use "\begin{documentation}...\end{documentation}" around the documentation,
+% and "\begin{implementation}...\end{implementation}" around the implementation.
+% The "\EnableDocumentation"/"\EnableImplementation" will cause them to be typeset
+% when the DTX file is "\DocInput"; use "\DisableDocumentation"/"\DisableImplementation"
+% to omit the contents of those environments.
+%
+% Note that \cmd\DocInput\ now takes comma-separated arguments, and \cmd\DocInputAgain\
+% can be used to re-input all DTX files previously input in this way.
+%
+% \subsection{Describing functions in the documentation}
+%
+% \DescribeEnv{function}
+% \DescribeEnv{syntax}
+% Two heavily-used environments are defined to describe the syntax
+% of \textsf{expl3} functions and variables.
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}{ list_of , functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{verbatim}
+% \vspace{-2\baselineskip}
+% \hrulefill
+% \begin{function}{ list_of , functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{framed}
+%
+% Function environments take an optional argument to indicate whether the function(s) it
+% describes are expandable or defined in conditional forms. Use "EXP", "TF", or "pTF"
+% for this; note that "pTF" implies "EXP" since predicates must always be expandable.
+% As an example:
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}[pTF]{ \cs_if_exist:N }
+% \begin{syntax}
+% "\cs_if_exist_p:N" <cs>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{verbatim}
+% \vspace{-2\baselineskip}
+% \hrulefill
+% \begin{function}[pTF]{ \cs_if_exist:N }
+% \begin{syntax}
+% "\cs_if_exist_p:N" <cs>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{framed}
+%
+% Note that the list of functions used to use "|" as a separator instead,
+% and this syntax is still supported.
+%
+% In the old syntax, individual functions could be suffixed by an optional flag or
+% two to indicate the same information given in the optional argument.
+% This is still supported; use "/" to separate the function name
+% from the flag(s) and then add any of "(EXP)", "(TF)", or "(pTF)".
+%
+% \DescribeEnv{variable}
+% If you are documenting a variable instead of a function, use the "variable" environment instead; it behaves identically to the "function" environment above.
+%
+% \subsection{Describing functions in the implementation}
+%
+% \DescribeEnv{macro}
+% The well-used environment from \LaTeXe\ for marking up the implementation
+% of macros/functions remains the \env{macro} environment.
+% Some changes in \pkg{l3doc}: it now accepts comma-separated lists
+% of functions, to avoid a very large number of consecutive "\end{macro}"
+% statements.
+% \begin{verbatim}
+% % \begin{macro}{\foo:N,\foo:c}
+% % \begin{macrocode}
+% ... code for \foo:N and \foo:c ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+% If you are documenting an auxiliary macro, it's generally not necessary
+% to highlight it as much and you also don't need to check it for, say,
+% having a test function and having a documentation chunk earlier in a "function"
+% environment. In this case, write "\begin[aux]{macro}" and it will be
+% marked as such; its margin call-out will be printed in grey.
+%
+% Similarly, an internal package function still requires documentation
+% but usually will not be documented for users to see; these can be marked
+% as such with "\begin[internal]{macro}".
+%
+% For documenting \pkg{expl3}-type conditionals, you may also pass this
+% environment a "TF" option (and omit it from the function name) to denote that
+% the function is provided with "T", "F", and "TF" suffixes.
+% A similar "pTF" option will print both "TF" and "_p" predicate forms.
+%
+%
+% \DescribeMacro{\TestFiles}
+% \cs{TestFiles}\marg{list of files} is used to indicate which test files
+% are used for the current code; they will be printed in the documentation.
+%
+% \DescribeMacro{\UnitTested}
+% Within a "macro" environment, it is a good idea to mark whether a unit test has
+% been created for the commands it defines. This is indicated by writing \cs{UnitTested}
+% anywhere within "\begin{macro}" \dots "\end{macro}".
+%
+% If the class option "checktest" is enabled, then it is an \emph{error} to have a
+% "macro" environment without a \cs{testfile} file. This is intended for large packages such
+% as \pkg{expl3} that should have absolutely comprehensive tests suites and whose authors
+% may not always be as sharp at adding new tests with new code as they should be.
+%
+% \DescribeMacro{\TestMissing}
+% If a function is missing a test, this may be flagged by writing (as many times as needed)
+% \cs{TestMissing}\marg{explanation of test required}.
+% These missing tests will be summarised in the listing printed at the end of the
+% compilation run.
+%
+% \DescribeEnv{variable}
+% When documenting variable definitions, use the "variable" environment instead.
+% It will, here, behave identically to the "macro" environment, except that if the class
+% option "checktest" is enabled, variables will not be required to have a test file.
+%
+% \DescribeEnv{arguments}
+% Within a \env{macro} environment, you may use the \env{arguments} environment
+% to describe the arguments taken by the function(s). It behaves
+% like a modified enumerate environment.
+% \begin{verbatim}
+% % \begin{macro}{\foo:nn,\foo:VV}
+% % \begin{arguments}
+% % \item Name of froozle to be frazzled
+% % \item Name of muble to be jubled
+% % \end{arguments}
+% % \begin{macrocode}
+% ... code for \foo:nn and \foo:VV ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+%
+% \bigskip
+% \textbf{OPTIONS FOR THE FUTURE}\qquad Any improvements to the markup
+% for the \env{function} environment would be good to mirror in \env{macro}.
+%
+% Perhaps this would be a better syntax for describing arguments?
+% \begin{verbatim}
+% \begin{macro}{\foo:nn,foo:VV}
+% \dArg{Name of froozle to be frazzled}
+% \dArg{Name of mumble to be jumbled}
+% ...
+% \end{verbatim}
+% I.e., get rid of the environment and do things like in, say, \pkg{fontspec}.
+%
+% \subsection{Keeping things consistent}
+%
+% Whenever a function is either documented or defined with \env{function}
+% and \env{macro} respectively, its name is stored in a sequence for later
+% processing.
+%
+% At the end of the document (i.e., after the \textsc{dtx} file has finished
+% processing), the list of names is analysed to check whether all defined
+% functions have been documented and vice versa. The results are printed
+% in the console output.
+%
+% If you need to do more serious work with these lists of names, take a
+% look at the implementation for the data structures and methods used to
+% store and access them directly.
+%
+% \subsection{Documenting templates}
+%
+% The following macros are provided for documenting templates; might
+% end up being something completely different but who knows.
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{TemplateInterfaceDescription}" \Arg{template type name}
+% " \TemplateArgument{none}{---}"
+% \textsc{or one or more of these:}
+% " \TemplateArgument" \Arg{arg no} \Arg{meaning}
+% \textsc{and}
+% "\TemplateSemantics"
+% " " \meta{text describing the template type semantics}
+% "\end{TemplateInterfaceDescription}"
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{TemplateDescription}" \Arg{template type name} \Arg{name}
+% \textsc{one or more of these:}
+% " \TemplateKey" \marg{key name} \marg{type of key}
+% " "\marg{textual description of meaning}
+% " "\marg{default value if any}
+% \textsc{and}
+% "\TemplateSemantics"
+% " " \meta{text describing special additional semantics of the template}
+% "\end{TemplateDescription}"
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{InstanceDescription}" \oarg{text to specify key column width (optional)}
+% \hfill\marg{template type name}\marg{instance name}\marg{template name}
+% \textsc{one or more of these:}
+% " \InstanceKey" \marg{key name} \marg{value}
+% \textsc{and}
+% "\InstanceSemantics"
+% " " \meta{text describing the result of this instance}
+% "\end{InstanceDescription}"
+% \end{quote}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3doc} implementation}
+%
+% \begin{macrocode}
+%<*class>
+% \end{macrocode}
+%
+% The Guilty Parties.
+% \begin{macrocode}
+\cs_new_nopar:Npn\Team{%
+ The~\LaTeX3~Project\thanks{%
+ Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~
+ Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~
+ David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~
+ Javier~Bezos,~Will~Robertson,~Joseph~Wright}}
+% \end{macrocode}
+%
+% \subsection{Options and configuration}
+%
+% \begin{macrocode}
+\DeclareOption{a5paper}{\@latexerr{Option not supported}{}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \g_doc_full_bool
+\bool_new:N \g_doc_lmodern_bool
+\bool_new:N \g_doc_checkfunc_bool
+\bool_new:N \g_doc_checktest_bool
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool }
+\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{check}{ \bool_set_true:N \g_doc_checkfunc_bool }
+\DeclareOption{nocheck}{ \bool_set_false:N \g_doc_checkfunc_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{checktest}{ \bool_set_true:N \g_doc_checktest_bool }
+\DeclareOption{nochecktest}{ \bool_set_false:N \g_doc_checktest_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{cm-default}{ \bool_set_false:N \g_doc_lmodern_bool }
+\DeclareOption{lm-default}{ \bool_set_true:N \g_doc_lmodern_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
+\ExecuteOptions{full,a4paper,nocheck,nochecktest,lm-default}
+% \end{macrocode}
+%
+% Input a local configuration file, if it exists.
+%
+% \begin{macrocode}
+\InputIfFileExists{l3doc.cfg}
+ {
+ \typeout{*************************************^^J
+ *~Local~config~file~l3doc.cfg~used ^^J
+ *************************************}
+ }
+ { \@input{l3doc.ltx} }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessOptions
+% \end{macrocode}
+%
+%
+% \subsection{Class and package loading}
+%
+% \begin{macrocode}
+\LoadClass{article}
+\RequirePackage{doc}
+\RequirePackage{array,alphalph,booktabs,color,fixltx2e,enumitem,textcomp,trace,underscore,csquotes}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_if:NT \g_doc_lmodern_bool {
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{lmodern}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage{hypdoc}
+% \end{macrocode}
+% Just want the "comment" environment from \pkg{verbatim}:
+% \begin{macrocode}
+\let\doc@verbatim\verbatim
+\let\enddoc@verbatim\endverbatim
+\let\doc@@verbatim\@verbatim
+\expandafter\let\csname doc@verbatim*\expandafter\endcsname
+ \csname verbatim*\endcsname
+\expandafter\let\csname enddoc@verbatim*\expandafter\endcsname
+ \csname endverbatim*\endcsname
+\expandafter\let\csname doc@@verbatim*\expandafter\endcsname
+ \csname @verbatim*\endcsname
+\RequirePackage{verbatim}
+\AtBeginDocument{%
+ \let\verbatim\doc@verbatim
+ \let\endverbatim\enddoc@verbatim
+ \let\@verbatim\doc@@verbatim
+ \expandafter\let\csname verbatim*\expandafter\endcsname
+ \csname doc@verbatim*\endcsname
+ \expandafter\let\csname endverbatim*\expandafter\endcsname
+ \csname enddoc@verbatim*\endcsname
+ \expandafter\let\csname @verbatim*\expandafter\endcsname
+ \csname doc@@verbatim*\endcsname
+}
+% \end{macrocode}
+%
+% \subsection{Configuration}
+%
+% \begin{macro}{\MakePrivateLetters}
+% \begin{macrocode}
+\cs_set_nopar:Npn \MakePrivateLetters {
+ \char_set_catcode_letter:N \@
+ \char_set_catcode_letter:N \_
+ \char_set_catcode_letter:N \:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\setcounter{StandardModuleDepth}{1}
+\@addtoreset{CodelineNo}{part}
+\cs_set_nopar:Npn \theCodelineNo {
+ \textcolor[gray]{0.5}{ \sffamily\tiny\arabic{CodelineNo} }
+}
+% \end{macrocode}
+%
+%
+%
+% \subsection{Design}
+%
+% Increase the text width slightly so that width the standard fonts
+% 72 columns of code may appear in a |macrocode| environment.
+% Increase the marginpar width slightly, for long command names.
+% And increase the left margin by a similar amount.
+% \begin{macrocode}
+\setlength \textwidth { 385pt }
+\addtolength \marginparwidth { 30pt }
+\addtolength \oddsidemargin { 20pt }
+\addtolength \evensidemargin { 20pt }
+% \end{macrocode}
+% (These were introduced when "article" was the documentclass, but
+% I've left them here for now to remind me to do something about them
+% later; we still have the problem of \emph{very long} command names.)
+%
+% Customise lists:
+% \begin{macrocode}
+\cs_set_eq:NN \@@oldlist\list
+\cs_set_nopar:Npn \list#1#2{\@@oldlist{#1}{#2\listparindent\z@}}
+\setlength \parindent { 0pt }
+\setlength \itemindent { 0pt }
+\setlength \parskip { \medskipamount }
+% \end{macrocode}
+%
+% \subsection{Text markup}
+%
+% Make "|" and |"| be `short verb' characters, but not in
+% the document preamble, where an active character may interfere
+% with packages that are loaded.
+% \begin{macrocode}
+\AtBeginDocument {
+ \MakeShortVerb \"
+ \MakeShortVerb \|
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\providecommand*\eTeX{
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi
+ $\m@th\varepsilon$-\TeX
+}
+\providecommand*\IniTeX{Ini\TeX}
+\providecommand*\Lua{Lua}
+\providecommand*\LuaTeX{\Lua\TeX}
+\providecommand*\pdfTeX{pdf\TeX}
+\RequirePackage{graphicx}
+\cs_if_free:NT \XeTeX {
+ \cs_new_protected_nopar:Npn \XeTeX
+ {X\kern-.125em\lower.5ex\hbox{\reflectbox{E}}\kern-.1667em\TeX}
+}
+% \end{macrocode}
+%
+% \begin{macro}{\cmd,\cs}
+% |\cmd{\foo}| Prints |\foo| verbatim. It may be used inside moving
+% arguments. |\cs{foo}| also prints |\foo|, for those who prefer that
+% syntax.
+% \begin{macrocode}
+\cs_set_nopar:Npn \cmd #1 { \cs{\expandafter\cmd@to@cs\string#1} }
+\cs_set_nopar:Npn \cmd@to@cs #1#2 { \char\number`#2\relax }
+\DeclareRobustCommand \cs [1] { \texttt { \char`\\ #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\marg,\oarg,\parg}
+% |\marg{text}| prints \marg{text}, `mandatory argument'.\\
+% |\oarg{text}| prints \oarg{text}, `optional argument'.\\
+% |\parg{te,xt}| prints \parg{te,xt}, `picture mode argument'.
+% \begin{macrocode}
+\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} }
+\providecommand\oarg[1]{ \texttt[ \meta{#1} \texttt] }
+\providecommand\parg[1]{ \texttt( \meta{#1} \texttt) }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\m,\file,\env,\pkg,\cls}
+% This list may change\dots this is just my preference for markup.
+% \begin{macrocode}
+\cs_set_eq:NN \m \meta
+\cs_set_eq:NN \file \nolinkurl
+\DeclareRobustCommand \env {\texttt}
+\DeclareRobustCommand \pkg {\textsf}
+\DeclareRobustCommand \cls {\textsf}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{texnote}
+% \begin{macrocode}
+\newenvironment{texnote}{
+ \endgraf
+ \vspace{3mm}
+ \small\textbf{\TeX~hackers~note:}
+}{
+ \vspace{3mm}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\tn}
+% As \cs{cs}. Use this to mark up all \TeX\ and \LaTeXe\ commands; they
+% then end up together in the index. TODO: hyperlinks in the index entries.
+% \begin{macrocode}
+\newcommand\tn[1]{
+ \texttt{\bslash #1}
+ \index{TeX~and~LaTeX2e~commands\actualchar
+ \string\TeX{}~and~\string\LaTeXe{}~commands:\levelchar
+ #1\actualchar{\string\ttfamily\string\bslash{}#1}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{documentation}
+% \begin{environment}{implementation}
+% \begin{macro}{\EnableDocumentation,\EnableImplementation}
+% \begin{macro}{\DisableDocumentation,\DisableImplementation}
+% \begin{macrocode}
+\cs_new:Npn \doc_implementation: {
+ \cs_set:Npn \variable {\macro[var]}
+}
+\cs_new:Npn \doc_docu: {
+ \cs_set_eq:NN \variable \variabledoc
+}
+\AtEndOfPackage{\doc_docu:}
+\newenvironment{documentation}{\doc_docu:}{}
+\newenvironment{implementation}{\doc_implementation:}{}
+\newcommand\EnableDocumentation{%
+ \renewenvironment{documentation}{\doc_docu:}{}%
+}
+\newcommand\EnableImplementation{%
+ \renewenvironment{implementation}{\doc_implementation:}{}%
+}
+\newcommand\DisableDocumentation{%
+ \cs_set_eq:NN \documentation \comment
+ \cs_set_eq:NN \enddocumentation \endcomment
+}
+\newcommand\DisableImplementation{%
+ \cs_set_eq:NN \implementation \comment
+ \cs_set_eq:NN \endimplementation \endcomment
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{environment}
+% \end{environment}
+%
+% \begin{environment}{arguments}
+% This environment is designed to be used within a \env{macro} environment
+% to describe the arguments of the macro/function.
+% \begin{macrocode}
+\newenvironment{arguments}{
+ \enumerate[
+ nolistsep,
+ label=\texttt{\#\arabic*}~:,
+ labelsep=*,
+ ]
+}{
+ \endenumerate
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{function}
+% \begin{environment}{variabledoc}
+% Environment for documenting function(s).
+% Stick the function names in a box. Use a "|" as delimiter and
+% allow |<...>| to be used as markup for |\meta{...}|.
+% Ignore spaces and sanitize with catcodes before reading argument.
+% \begin{macrocode}
+\char_set_catcode_active:N \<
+\DeclareDocumentCommand \function { O{} } {
+
+ \phantomsection
+
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \bool_gset_false:N \l_doc_meta_pTF_bool
+ \bool_gset_false:N \l_doc_meta_EXP_bool
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_meta_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \char_set_catcode_active:N \<
+ \cs_set_eq:NN < \doc_open_meta:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_other:N \|
+ \char_set_catcode_other:N \\
+ \char_set_catcode_space:N \~
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \function_aux:n
+}
+\char_set_catcode_other:N \<
+\cs_set_eq:NN \variabledoc \function
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set:Nn \doc_meta_opt_TF: {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+}
+\cs_set:Nn \doc_meta_opt_EXP: {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+\cs_set:Nn \doc_meta_opt_pTF: {
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+% \end{macrocode}
+%
+% \begin{macro}{\function_aux:n}
+% \begin{arguments}
+% \item Vertical bar--separated list of functions with optional metadata;
+% input has already been sanitised by catcode changes before reading
+% the argument.
+% \end{arguments}
+% Because vertical bars are odd delimiters to choose, we also now iterate over commas!
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \function_aux:n #1 {
+ \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}}
+ \tl_gset_eq:NN \g_doc_macro_tl \c_empty_tl
+ \bigskip\endgraf\noindent\ttfamily
+ \tabular[b]{ | l @{} c | }
+ \hline
+ \clist_map_inline:nn {#1} {\doc_showmacro:w ##1 | \q_stop} \\
+ \hline
+ \endtabular
+ \group_end:
+}
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \end{environment}
+%
+% \begin{macro}{\doc_showmacro:w}
+% This function reads in a "|"-separated list, passing each item to
+% the auxiliary function "\doc_showmacro_aux:w".
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \doc_showmacro:w #1 | {
+ \tl_if_blank:nTF {#1} {
+ \use_none:n
+ }{
+ \doc_showmacro_aux:w #1 / \q_stop
+ \peek_meaning:NTF \q_stop { \use_none:n } { \doc_showmacro:w }
+ }
+}
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_meta_TF_bool
+\bool_new:N \l_doc_meta_pTF_bool
+\bool_new:N \l_doc_meta_EXP_bool
+% \end{macrocode}
+%
+% \begin{macro}{\doc_showmacro_aux:w}
+% This macro is passed one of:
+% \begin{quote}
+% "\abc:cnx / (EXP) / \q_stop" \\
+% "\abc:cnx / \q_stop" \\
+% \end{quote}
+% We also have some code here to print out every documented macro at the end
+% of the document.
+% \begin{arguments}
+% \item Function/macro/variable name \item Metadata tags (if any)
+% \end{arguments}
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_showmacro_aux:w #1 / #2 \q_stop {
+
+ \tl_if_in:nnT {#2} { (TF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ }
+
+ \tl_if_in:nnT {#2} { (EXP) } {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \tl_if_in:nnT {#2} { (pTF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \bool_if:NT \l_doc_meta_pTF_bool {
+ \tl_set:Nx \l_doc_pTF_name_tl { \doc_predicate_from_base:w #1 \q_nil }
+ \doc_special_main_index:o { \l_doc_pTF_name_tl }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:N \l_doc_pTF_name_tl }
+ }
+
+ \bool_if:NTF \l_doc_meta_TF_bool {
+ \doc_special_main_index:o { #1 TF }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } }
+ }{
+ \doc_special_main_index:o { #1 }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } }
+ }
+
+ \bool_if:NTF \l_doc_meta_pTF_bool {
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \exp_after:wN \doc_showmacro_aux_ii:w \l_doc_pTF_name_tl ::\q_stop
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }{
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_showmacro_aux_ii:w}
+% This macro is passed arguments in the following ways:
+% \begin{quote}
+% "\doc_showmacro_aux_ii:w "^^A
+% \makebox[\widthof{\texttt{123456}}]{\meta{name}}^^A
+% " ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo: ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo:Z ::\q_stop" \\
+% \end{quote}
+% Notice that for "\foo", "#2" and "#3" are empty,\\
+% for "\foo:", "#2" is empty, and "#3" is `":"'\\
+% for "\foo:Z", "#2" is `"Z"' and "#3" is `":"' .
+% \begin{arguments}
+% \item Function name \item Possible arg.\ spec. \item Possible colon
+% \end{arguments}
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_showmacro_aux_ii:w #1:#2:#3 \q_stop {
+ \nextnewline
+ \str_if_eq:xxTF {#1} {\g_doc_macro_tl} {
+ \doc_typeset_aux:n
+ }{
+ \tl_gset:Nn \g_doc_macro_tl {#1}
+ \use:n
+ }
+ { \g_doc_macro_tl }
+ #3
+ #2
+ \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: }
+ &
+ \bool_if:NT \l_doc_meta_EXP_bool {
+ \hspace{\tabcolsep}
+ $\star$
+ }
+ \tl_set:Nx \g_doc_macro_tl { \tl_to_str:N \g_doc_macro_tl }
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\@backslashchar} {}
+ \bool_if:NT \g_doc_full_bool {
+ \exp_args:Nf\label{doc/function/\g_doc_macro_tl#3#2}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{syntax}
+% Syntax block placed next to the list of functions to illustrate their use.
+% \begin{macrocode}
+\dim_new:N \g_doc_syntax_dim
+\dim_set:Nn \g_doc_syntax_dim {0.7\textwidth}
+\newenvironment{syntax}{
+ \minipage[b]{\g_doc_syntax_dim}
+ \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!)
+ \small\ttfamily\raggedright
+ \obeyspaces\obeylines
+}{
+ \endminipage
+ \hfil\break
+ \global\@ignoretrue
+}
+% \end{macrocode}
+% \end{environment}
+%
+% Perhaps these belong in \file{l3token}?
+% \begin{macrocode}
+\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 }
+% \end{macrocode}
+%
+% \begin{macro}{\doc_open_meta:n,\doc_close_meta:n}
+% This code turns all numbers within "<...>" markup to be set as subscripts.
+% You can use escaped numbers to get the real thing (e.g., "\1" = `1').
+% \begin{macrocode}
+\group_begin:
+ \tl_map_inline:nn {0123456789} { \char_set_catcode_active:N #1 }
+ \cs_new:Npn \doc_open_meta:n {
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_meta:w
+ }
+ \cs_new:Npn \Arg {
+ \texttt{ \char`\{ }
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_Arg:n
+ }
+\group_end:
+\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: }
+\cs_new_nopar:Npn \doc_close_Arg:n #1 {
+ \meta {#1}
+ \group_end:
+ \texttt{ \char`\} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_assign_num:n}
+% This function takes a numeral (`0'), defines its escaped self to be equal
+% to itself ("\0" $\to$ `0'), makes it active, and turns itself into a subscript
+% instead (`0' $\to$ `${}_0$').
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_assign_num:n #1 {
+ \cs_set_eq:cc { \string #1 } { char_other_\string #1 }
+ \char_set_catcode_active:N #1
+ \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{macro}
+% We want to extend the old definition to allow comma-separated lists of
+% macros, rather than one at a time. keyval processing is very rudimentary;
+% awaiting a more robust solution.
+% \begin{macrocode}
+\renewcommand \macro [1][] {
+
+ \int_compare:nNnTF \currentgrouplevel=2
+ { \int_gzero:N \g_doc_nested_macro_int }
+ { \int_incr:N \g_doc_nested_macro_int }
+
+ \bool_set_false:N \l_doc_macro_aux_bool
+ \bool_set_false:N \l_doc_macro_internal_bool
+ \bool_set_false:N \l_doc_macro_TF_bool
+ \bool_set_false:N \l_doc_macro_pTF_bool
+ \bool_set_false:N \l_doc_macro_var_bool
+ \bool_set_false:N \l_doc_tested_bool
+
+ \cs_set_eq:NN \doc_macroname_prefix:n \use:n
+ \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_macro_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \cs_set_eq:NN \testfile \doc_print_testfile:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_letter:N \\
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \doc_macro_aux:n
+}
+% \end{macrocode}
+% After changing the catcodes, parse the arguments:
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_macro_aux:n #1 {
+ \group_end:
+ \cs_set:Npn \l_doc_macro_input_clist {#1}
+ \bool_if:NTF \l_doc_macro_pTF_bool
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \tl_if_blank:nF {##1}
+ {
+ \exp_args:Nf \doc_macro_single
+ { \doc_predicate_from_base:w ##1 \q_nil }
+ }
+ }
+ \bool_set_true:N \l_doc_macro_TF_bool
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ \bool_set_false:N \l_doc_macro_TF_bool
+ }
+ {
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_macro_internal_bool
+\bool_new:N \l_doc_macro_aux_bool
+\bool_new:N \l_doc_macro_TF_bool
+\bool_new:N \l_doc_macro_pTF_bool
+\bool_new:N \l_doc_macro_var_bool
+\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool }
+\cs_set_nopar:Npn \doc_macro_opt_internal: { \bool_set_true:N \l_doc_macro_internal_bool }
+\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_pTF: { \bool_set_true:N \l_doc_macro_pTF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_var: { \bool_set_true:N \l_doc_macro_var_bool }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macrocode}
+\cs_set:Npn \doc_predicate_from_base:w #1:#2 \q_nil {#1_p:#2}
+% \end{macrocode}
+%
+% \begin{environment}{doc_macro_single}
+% Let's start to mess around with "doc"'s "macro" environment. See \file{doc.dtx}
+% for a full explanation of the original environment. It's
+% rather \emph{enthusiastically} commented.
+% \begin{arguments}
+% \item Macro/function/whatever name; input has already been sanitised.
+% \end{arguments}
+% \begin{macrocode}
+\int_new:N \l_doc_macro_int
+\cs_set_nopar:Npn \doc_macro_single #1 {
+ \int_incr:N \l_doc_macro_int
+ \tl_set:Nx \saved@macroname { \token_to_str:N #1 }
+ \topsep\MacroTopsep
+ \trivlist
+ \cs_set_nopar:Npn \makelabel ##1 { \llap{##1} }
+ \if@inlabel
+ \cs_set_eq:NN \@tempa \@empty
+ \count@ \macro@cnt
+ \loop \ifnum\count@>\z@
+ \cs_set_nopar:Npx \@tempa{\@tempa\hbox{\strut}}
+ \advance\count@\m@ne
+ \repeat
+ \cs_set_nopar:Npx \makelabel ##1 {
+ \llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}}
+ }
+ \advance \macro@cnt \@ne
+ \else
+ \macro@cnt \@ne
+ \fi
+
+ \bool_if:NT \l_doc_macro_aux_bool {
+ \cs_set_eq:NN \doc_macroname_prefix:n \doc_typeset_aux:n
+ }
+ \bool_if:NT \l_doc_macro_TF_bool {
+ \cs_set_eq:NN \doc_macroname_suffix: \doc_typeset_TF:
+ }
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \tl_gset:Nx \l_doc_macro_tl { \tl_to_str:n {#1} }
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\@backslashchar} {}
+ }
+
+ \use:x {
+ \exp_not:N \item [ \exp_not:N \doc_print_macroname:n {
+ \tl_to_str:n {#1}
+ }]
+ }
+ \global\advance \c@CodelineNo \@ne
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 F } }
+ }{
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n {#1} }
+ }
+ }
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \SpecialMainIndex{#1 TF}\nobreak
+ \DoNotIndex{#1 TF}
+ }{
+ \SpecialMainIndex{#1}\nobreak
+ \DoNotIndex{#1}
+ }
+
+ \global\advance \c@CodelineNo \m@ne
+ \ignorespaces
+}
+% \end{macrocode}
+%
+% \begin{macro}{\doc_print_macroname:n}
+% \begin{macrocode}
+\tl_clear:N \l_doc_macro_tl
+\cs_set_nopar:Npn \doc_print_macroname:n #1 {
+ \strut
+ \int_compare:nTF { \tl_elt_count:n {#1} <= 28 }
+ { \MacroFont } { \MacroLongFont }
+
+ % INEFFICIENT: (!)
+ \exp_args:NNx \seq_if_in:NnTF \g_doc_functions_seq
+ { #1 \bool_if:NT \l_doc_macro_TF_bool { \tl_to_str:n {TF} } }
+ {
+ \hyperref [doc/function/\l_doc_macro_tl]
+ }
+ { \use:n }
+ {
+ \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space!
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\MacroLongFont}
+% \begin{macrocode}
+\providecommand \MacroLongFont {
+ \fontfamily{lmtt}\fontseries{lc}\small
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_typeset_TF:,\doc_typeset_aux:n}
+% Used by \cs{doc_macro_single} and \cs{doc_showmacro_aux_ii:w} to typeset
+% conditionals and auxiliary functions.
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_typeset_TF: {
+ \itshape TF%
+ \makebox[0pt][r]{%
+ \color[gray]{0.5}
+ \underline { \phantom{\itshape TF} \kern-0.1em }
+ }
+}
+\cs_set_nopar:Npn \doc_typeset_aux:n #1 {
+ {\color[gray]{0.5} #1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_print_testfile:n}
+% Used to show that a macro has a test, somewhere.
+% \begin{macrocode}
+\DeclareDocumentCommand \doc_print_testfile:n {m} {
+ \bool_set_true:N \l_doc_tested_bool
+ \tl_if_eq:nnF {#1} {*} {
+ \seq_if_in:NnF \g_doc_testfiles_seq {#1}
+ {
+ \par{\footnotesize(\textit{
+ The~ test~ suite~ for~ this~ command,~ and~ others~ in~ this~ file,~ is~ \textsf{#1}}.
+ )\par}
+ \seq_gput_right:Nn \g_doc_testfiles_seq {#1}
+ }
+ }
+}
+\seq_new:N \g_doc_testfiles_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestFiles}
+% \begin{macrocode}
+\DeclareDocumentCommand \TestFiles {m} {
+ \par
+ {\itshape
+ The~ following~ test~ files~ are~ used~ for~ this~ code:~ \textsf{#1}.
+ }
+ \par\ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\UnitTested}
+% \begin{macrocode}
+\DeclareDocumentCommand \UnitTested {} {
+ \testfile*
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestMissing}
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_gput:Nnn {NVx}
+\prop_new:N \g_doc_missing_tests_prop
+\DeclareDocumentCommand \TestMissing {m} {
+ \prop_if_in:NVTF \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ \prop_get:NVN \g_doc_missing_tests_prop \l_doc_macro_input_clist \l_tmpa_tl
+ \prop_gput:NVx \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ *~ \l_tmpa_tl
+ ^^J \exp_not:n {\space\space\space\space\space\space}
+ *~ #1
+ }
+ }
+ { \prop_gput:NVn \g_doc_missing_tests_prop \l_doc_macro_input_clist {#1} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\endmacro}
+% \begin{macrocode}
+\int_new:N \g_doc_nested_macro_int
+\cs_set:Nn \doc_texttt_comma:n {\,,~\texttt{#1}}
+\cs_set:Npn \endmacro {
+ \int_compare:nT {\g_doc_nested_macro_int<1}
+ {
+ \par\nobreak{\footnotesize(\emph{
+ End~ definition~ for~
+ \prg_case_int:nnn { \clist_length:N \l_doc_macro_input_clist }
+ {
+ {1} { \texttt{ \clist_use:N \l_doc_macro_input_clist }. }
+ {2}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \texttt{\l_clist_first_tl}\,~ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ {3}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_mid_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {2} }
+ \texttt{\l_clist_first_tl}\,,~
+ \texttt{\l_clist_mid_tl}\,,~
+ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ }
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \texttt{\l_clist_first_tl}\,~and~others.
+ }
+ \bool_if:nT {
+ !\l_doc_macro_aux_bool &&
+ !\l_doc_macro_internal_bool &&
+ \int_compare_p:n {\g_doc_nested_macro_int<1}
+ }
+ {
+ \int_compare:nNnTF \l_doc_macro_int=1 {~This~} {~These~}
+ \bool_if:NTF \l_doc_macro_var_bool{variable}{function}
+ \int_compare:nNnTF \l_doc_macro_int=1 {~is~}{s~are~}
+ documented~on~page~
+ \exp_args:Nx\pageref{doc/function/\l_doc_macro_tl}.
+ }
+ })\par}
+ }
+ \bool_if:nT
+ { \g_doc_checktest_bool &&
+ !( \l_doc_macro_aux_bool || \l_doc_macro_var_bool ) &&
+ !\l_doc_tested_bool
+ }
+ {
+ \seq_gput_right:Nx \g_doc_not_tested_seq
+ {
+ \l_doc_macro_input_clist
+ \bool_if:NT \l_doc_macro_pTF_bool {~(pTF)}
+ \bool_if:NT \l_doc_macro_TF_bool {~(TF)}
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DescribeOption}
+% For describing package options. Due to Joseph Wright.
+% Name/usage might change soon.
+% \begin{macrocode}
+\newcommand*{\DescribeOption}{
+ \leavevmode
+ \@bsphack
+ \begingroup
+ \MakePrivateLetters
+ \Describe@Option
+}
+\newcommand*{\Describe@Option}[1]{
+ \endgroup
+ \marginpar{
+ \raggedleft
+ \PrintDescribeEnv{#1}
+ }
+ \SpecialOptionIndex{#1}
+ \@esphack
+ \ignorespaces
+}
+\newcommand*{\SpecialOptionIndex}[1]{
+ \@bsphack
+ \begingroup
+ \HD@target
+ \let\HDorg@encapchar\encapchar
+ \edef\encapchar usage{
+ \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage}
+ }
+ \index{
+ #1\actualchar{\protect\ttfamily#1}~(option)
+ \encapchar usage
+ }
+ \index{
+ options:\levelchar#1\actualchar{\protect\ttfamily#1}
+ \encapchar usage
+ }
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Here are some definitions for additional markup that will help to
+% structure your documentation.
+%
+% \begin{environment}{danger}
+% \begin{environment}{ddanger}
+% \begin{syntax}
+% |\begin{[d]danger}|\\
+% dangerous code\\
+% |\end{[d]danger}|
+% \end{syntax}
+%
+% \begin{danger}
+% Provides a danger bend, as known from the \TeX{}book.
+% \end{danger}
+% The actual character from the font |manfnt|:
+% \begin{macrocode}
+\font\manual=manfnt
+\cs_set_nopar:Npn \dbend { {\manual\char127} }
+% \end{macrocode}
+%
+% Defines the single danger bend. Use it whenever there is a feature in your
+% package that might be tricky to use.
+% FIXME: Has to be fixed when in combination with a macro-definition.
+% \begin{macrocode}
+\newenvironment {danger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=2pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+% \end{macrocode}
+%
+% \begin{ddanger}
+% Use the double danger bend if there is something which could cause serious
+% problems when used in a wrong way. Better the normal user does not know
+% about such things.
+% \end{ddanger}
+% \begin{macrocode}
+\newenvironment {ddanger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=3.5pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsection{Documenting templates}
+%
+% \begin{macrocode}
+\newenvironment{TemplateInterfaceDescription}[1]
+ {\subsection{The~object~type~`#1'}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics:}}%
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{TemplateDescription}[2]
+ {\subsection{The~template~`#2'~(object~type~#1)}%
+ \subsubsection*{Attributes:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateKey##1##2##3##4{\item[##1~(##2)]##3%
+ \ifx\TemplateKey##4\TemplateKey\else
+% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4%
+ \hfill\penalty500\hbox{}\hfill Default:~##4%
+ \nobreak\hskip-\parfillskip\hskip0pt\relax
+ \fi
+ \par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics~\&~Comments:}}%
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx]
+ {\subsubsection{The~instance~`#3'~(template~#2/#4)}%
+ \subsubsection*{Attribute~values:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}%
+ \def\InstanceSemantics{\endtabbing\endgroup
+ \vskip-30pt\vskip0pt
+ \subsubsection*{Layout~description~\&~Comments:}}%
+ \tabbing
+ xxxx\=#1\=\kill
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \subsection{Inheriting doc}
+%
+% Code here is taken from \pkg{doc}, stripped of comments and translated
+% into \pkg{expl3} syntax. New features are added in various places.
+%
+% \begin{macro}{\StopEventually,\Finale,\AlsoImplementation,\OnlyDescription}
+% \begin{macrocode}
+\bool_new:N \g_doc_implementation_bool
+\cs_set_nopar:Npn \AlsoImplementation {
+ \bool_set_true:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 {
+ \@bsphack
+ \cs_gset_nopar:Npn \Finale { ##1 \check@checksum }
+ \init@checksum
+ \@esphack
+ }
+}
+\AlsoImplementation
+\cs_set_nopar:Npn \OnlyDescription {
+ \@bsphack
+ \bool_set_false:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 { ##1 \endinput }
+ \@esphack
+}
+\cs_set_eq:NN \Finale \relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \partname{File}
+% \end{macrocode}
+%
+% \begin{macro}{\DocInput}
+% From \pkg{doc}. Now accepts comma-list input (who has commas in filenames?).
+% \begin{macrocode}
+\clist_new:N \g_docinput_clist
+\cs_set:Npn \DocInput #1 {
+ \clist_map_inline:nn {#1} {
+ \clist_put_right:Nn \g_docinput_clist {##1}
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInputAgain}
+% Uses "\g_docinput_clist" to re-input whatever's already been "\DocInput"-ed until now.
+% May be used multiple times.
+% \begin{macrocode}
+\cs_set:Npn \DocInputAgain {
+ \clist_map_inline:Nn \g_docinput_clist {
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInclude}
+% More or less exactly the same as |\include|, but uses |\DocInput|
+% on a |dtx| file, not |\input| on a |tex| file.
+% \begin{macrocode}
+\cs_set_nopar:Npn \partname{File}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand*{\DocInclude}[1]{%
+ \relax\clearpage
+ \docincludeaux
+ \IfFileExists{#1.fdd}{
+ \cs_set_nopar:Npn \currentfile{#1.fdd}
+ }{
+ \cs_set_nopar:Npn \currentfile{#1.dtx}
+ }
+ \ifnum\@auxout=\@partaux
+ \@latexerr{\string\include\space cannot~be~nested}\@eha
+ \else
+ \@docinclude #1
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \@docinclude #1 {
+ \clearpage
+ \immediate\write\@mainaux{\string\@input{#1.aux}}
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \cs_set_nopar:Npx \@tempb{#1}
+ \@for\@tempa:=\@partlist\do{
+ \ifx\@tempa\@tempb\@tempswatrue\fi
+ }
+ \fi
+ \if@tempswa
+ \cs_set_eq:NN \@auxout\@partaux
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}
+ \cs_set_eq:NN \@ltxdoc@PrintIndex\PrintIndex
+ \cs_set_eq:NN \PrintIndex\relax
+ \cs_set_eq:NN \@ltxdoc@PrintChanges\PrintChanges
+ \cs_set_eq:NN \PrintChanges\relax
+ \cs_set_eq:NN \@ltxdoc@theglossary\theglossary
+ \cs_set_eq:NN \@ltxdoc@endtheglossary\endtheglossary
+ \part{\currentfile}
+ {
+ \cs_set_eq:NN \ttfamily\relax
+ \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}
+ }
+ \DocInput{\currentfile}
+ \cs_set_eq:NN \PrintIndex\@ltxdoc@PrintIndex
+ \cs_set_eq:NN \PrintChanges\@ltxdoc@PrintChanges
+ \cs_set_eq:NN \theglossary\@ltxdoc@theglossary
+ \cs_set_eq:NN \endtheglossary\@ltxdoc@endtheglossary
+ \clearpage
+ \@writeckpt{#1}
+ \immediate\closeout\@partaux
+ \else
+ \@nameuse{cp@#1}
+ \fi
+ \cs_set_eq:NN \@auxout\@mainaux
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_gset_nopar:Npn \codeline@wrindex #1 {
+ \immediate\write\@indexfile {
+ \string\indexentry{#1}
+ {\filesep\number\c@CodelineNo}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_set_eq:NN \filesep \@empty
+% \end{macrocode}
+%
+% \begin{macro}{\docincludeaux}
+% \begin{macrocode}
+\cs_set_nopar:Npn \docincludeaux {
+ \cs_set_nopar:Npn \thepart {\alphalph{part}}
+ \cs_set_nopar:Npn \filesep {\thepart-}
+ \cs_set_eq:NN \filekey\@gobble
+ \g@addto@macro\index@prologue{
+ \cs_gset_nopar:Npn\@oddfoot{
+ \parbox{\textwidth}{
+ \strut\footnotesize
+ \raggedright{\bfseries File~Key:}~\filekey
+ }
+ }
+ \cs_set_eq:NN \@evenfoot\@oddfoot
+ }
+ \cs_gset_eq:NN \docincludeaux\relax
+ \cs_gset_nopar:Npn\@oddfoot{
+ \expandafter\ifx\csname ver@\currentfile\endcsname\relax
+ File~\thepart :~{\ttfamily\currentfile}~
+ \else
+ \GetFileInfo{\currentfile}
+ File~\thepart :~{\ttfamily\filename}~
+ Date:~\ExplFileDate\ % space
+ Version~\ExplFileVersion
+ \fi
+ \hfill\thepage
+ }
+ \cs_set_eq:NN \@evenfoot \@oddfoot
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{At end document}
+%
+% Print all defined and documented macros/functions.
+%
+% \begin{macrocode}
+\seq_new:N \g_doc_functions_seq
+\seq_new:N \g_doc_macros_seq
+\seq_new:N \g_doc_not_tested_seq
+% \end{macrocode}
+%
+% \begin{macrocode}
+\iow_open:Nn \g_write_func_stream { \jobname.cmds }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_show_functions_defined: {
+ \bool_if:nT { \g_doc_implementation_bool && \g_doc_checkfunc_bool } {
+ \typeout{ ======================================== ^^J }
+
+ \tl_clear:N \l_tmpa_tl
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnT \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ \iow_now:Nn \g_write_func_stream { ##1 }
+ }
+ }
+ \iow_close:N \g_write_func_stream
+ \doc_functions_typeout:n {
+ Functions~both~documented~and~defined:^^J (In~order~of~being~documented)
+ }
+
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnF \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~documented~but~not~defined: }
+
+ \seq_map_inline:Nn \g_doc_macros_seq {
+ \seq_if_in:NnF \g_doc_functions_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~defined~but~not~documented: }
+
+ \typeout{ ======================================== }
+ }
+}
+\AtEndDocument{ \doc_show_functions_defined: }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_functions_typeout:n #1 {
+ \tl_if_empty:NF \l_tmpa_tl {
+ \typeout{
+ -------------------------------------- ^^J #1 ^^J
+ -------------------------------------- ^^J \l_tmpa_tl
+ }
+ \tl_clear:N \l_tmpa_tl
+ }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \doc_show_not_tested: {
+ \bool_if:NT \g_doc_checktest_bool
+ {
+ \bool_if:nT { !(\seq_if_empty_p:N \g_doc_not_tested_seq) ||
+ !(\prop_if_empty_p:N \g_doc_missing_tests_prop) }
+ {
+ \tl_clear:N \l_tmpa_tl
+ \prop_if_empty:NF \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^JThe~ following~ macro(s)~ have~ incomplete~ tests:^^J
+ }
+ \prop_map_inline:Nn \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {^^J\space\space\space\space ##1
+ ^^J\space\space\space\space\space\space ##2}
+ }
+ }
+ \seq_if_empty:NF \g_doc_not_tested_seq
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^J
+ The~ following~ macro(s)~ do~ not~ have~ any~ tests:^^J
+ }
+ \seq_map_inline:Nn \g_doc_not_tested_seq
+ {
+ \clist_map_inline:nn {##1}
+ {
+ \tl_put_right:Nn \l_tmpa_tl {^^J\space\space\space\space ####1}
+ }
+ }
+ \int_set:Nn \l_tmpa_int {\etex_interactionmode:D}
+ \errorstopmode
+ \ClassError{l3doc}{\l_tmpa_tl}{}
+ \int_set:Nn \etex_interactionmode:D {\l_tmpa_int}
+ }
+ }
+ }
+}
+\AtEndDocument{ \doc_show_not_tested: }
+% \end{macrocode}
+%
+% \subsection{Indexing}
+%
+% Fix index (for now):
+% \begin{macrocode}
+\g@addto@macro\theindex{\MakePrivateLetters}
+\cs_set:Npn \verbatimchar {&}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\setcounter{IndexColumns}{2}
+% \end{macrocode}
+%
+% Set up the Index to use "\part"
+% \begin{macrocode}
+\IndexPrologue{
+ \part*{Index}
+ \markboth{Index}{Index}
+ \addcontentsline{toc}{part}{Index}
+ The~italic~numbers~denote~the~pages~where~the~
+ corresponding~entry~is~described,~
+ numbers~underlined~point~to~the~definition,~
+ all~others~indicate~the~places~where~it~is~used.
+}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\doc_special_main_index:n,\doc_special_main_index:o,\hdpgindex}
+% Heiko's replacement to play nicely with |hypdoc|:
+% \begin{macrocode}
+
+\cs_set_nopar:Npn \doc_special_main_index:n #1 {
+ \index{
+ \@gobble#1
+ \actualchar
+ \string\verb\quotechar*\verbatimchar#1\verbatimchar
+ \encapchar
+ hdpgindex{\thepage}{usage}
+ }
+}
+\cs_set_nopar:Npn \doc_special_main_index:o { \exp_args:No \doc_special_main_index:n }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_set_nopar:Npn \hdpgindex #1#2#3 {
+ \csname\ifx\\#2\\relax\else#2\fi\endcsname{
+ \hyperlink{page.#1}{#3}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\g@addto@macro \PrintIndex { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~index~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~l3doc.ist~-o~\jobname.ind~\jobname.idx^^J
+ ========================================^^J
+ }}
+}
+% \end{macrocode}
+%
+% \subsection{Change history}
+%
+% Set the change history to use "\part".
+% Allow control names to be hyphenated in here...
+% \begin{macrocode}
+\GlossaryPrologue{
+ \part*{Change~History}
+ {\GlossaryParms\ttfamily\hyphenchar\font=`\-}
+ \markboth{Change~History}{Change~History}
+ \addcontentsline{toc}{part}{Change~History}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\g@addto@macro \PrintChanges { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~change~list~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~gglo.ist~~-o~\jobname.gls~\jobname.glo^^J
+ ========================================^^J
+ }}
+}
+% \end{macrocode}
+%
+%^^A The standard \changes command modified slightly to better cope with
+%^^A this multiple file document.
+%^^A\def\changes@#1#2#3{%
+%^^A \let\protect\@unexpandable@protect
+%^^A \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar
+%^^A \ifx\saved@macroname\@empty
+%^^A \space
+%^^A \actualchar
+%^^A \generalname
+%^^A \else
+%^^A \expandafter\@gobble
+%^^A \saved@macroname
+%^^A \actualchar
+%^^A \string\verb\quotechar*%
+%^^A \verbatimchar\saved@macroname
+%^^A \verbatimchar
+%^^A \fi
+%^^A :\levelchar #3}}%
+%^^A \@tempa\endgroup\@esphack}
+%
+% \subsection{cfg}
+%
+% \begin{macrocode}
+\bool_if:NTF \g_doc_full_bool {
+ \RecordChanges
+ \CodelineIndex
+ \EnableCrossrefs
+ \AlsoImplementation
+}{
+ \CodelineNumbered
+ \DisableCrossrefs
+ \OnlyDescription
+}
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</class>
+% \end{macrocode}
+%
+%
+% \subsection{Makeindex configuration}
+%
+% The makeindex style "l3doc.ist" is used in place of the usual
+% "gind.ist" to ensure that I is used in the sequence I J K
+% not I II II, which would be the default makeindex behaviour.
+%
+% Will: Do we need this?
+%
+% \begin{macrocode}
+%<*docist>
+actual '='
+quote '!'
+level '#'
+preamble
+"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n"
+postamble
+"\n\n \\end{theindex}\n"
+item_x1 "\\efill \n \\subitem "
+item_x2 "\\efill \n \\subsubitem "
+delim_0 "\\pfill "
+delim_1 "\\pfill "
+delim_2 "\\pfill "
+% The next lines will produce some warnings when
+% running Makeindex as they try to cover two different
+% versions of the program:
+lethead_prefix "{\\bfseries\\hfil "
+lethead_suffix "\\hfil}\\nopagebreak\n"
+lethead_flag 1
+heading_prefix "{\\bfseries\\hfil "
+heading_suffix "\\hfil}\\nopagebreak\n"
+headings_flag 1
+
+% and just for source3:
+% Remove R so I is treated in sequence I J K not I II III
+page_precedence "rnaA"
+%</docist>
+% \end{macrocode}
+%
+% \section{Testing}
+%\ExplSyntaxOn
+%\cs_set_eq:NN\g_saved_doc_functions_seq\g_doc_functions_seq
+%\cs_set_eq:NN\g_saved_doc_macros_seq\g_doc_macros_seq
+%\ExplSyntaxOff
+%
+% \begin{function}{\example_foo:N|\example_foo:c}
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9> \Arg{arg1} ":("
+% \end{function}
+%
+% \begin{function}{ \foo | \foo: | \foo:x | \barrz: }
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9>
+% \end{function}
+%
+% \begin{function}{\foo:N / (TF) | \foo_if:c / (TF) (EXP)}
+% Test.
+% \end{function}
+%
+% \begin{function}[EXP]{\fffoo:N}
+% Test.
+% \end{function}
+% \begin{function}[TF]{\ffffoo:N}
+% Test.
+% \end{function}
+% \begin{function}[pTF]{\ffoo:N}
+% Test.
+% \end{function}
+%
+% \begin{function}{ \bar / (EXP) | \bar: / (EXP) | \bar:x / (EXP) | }
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9>
+% \end{function}
+%
+% \begin{macro}{ \foo , \foo: , \foo:x }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}[aux]{ \foo_aux: }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}[TF]{ \foo_if:c }
+% Testing.
+% \end{macro}
+%
+% \begin{macro}[internal]{ \foo_if:d }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}{\aaaa_bbbb_cccc_dddd_eeee_ffff_gggg_hhhh}
+% Long macro names need to be printed in a shorter font.
+% \begin{macrocode}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\c_minus_one,
+% \c_zero,
+% \c_one,
+% \c_two,
+% \c_three,
+% \c_four,
+% \c_five,
+% \c_six,
+% \c_seven,
+% \c_eight,
+% \c_nine,
+% \c_ten,
+% \c_eleven,
+% \c_sixteen,
+% \c_thirty_two,
+% \c_hundred_one,
+% \c_twohundred_fifty_five,
+% \c_twohundred_fifty_six,
+% \c_thousand,
+% \c_ten_thousand,
+% \c_ten_thousand_one}
+% \begin{arguments}
+% \item name
+% \item parameters
+% \end{arguments}
+% Another test.
+% \end{macro}
+%
+%
+%\ExplSyntaxOn
+%\cs_set_eq:NN\g_doc_functions_seq\g_saved_doc_functions_seq
+%\cs_set_eq:NN\g_doc_macros_seq\g_saved_doc_macros_seq
+%\ExplSyntaxOff
+%
+%
+% \subsection{Macros}
+% \raggedright
+% \ExplSyntaxOn
+% \seq_map_inline:Nn \g_doc_macros_seq { `\texttt{#1}' \quad }
+% \ExplSyntaxOff
+%
+% \subsection{Functions}
+% \ExplSyntaxOn
+% \seq_map_inline:Nn \g_doc_functions_seq { `\texttt{#1}' \quad }
+% \ExplSyntaxOff
+%
+% \end{implementation}
+%
+% \PrintIndex
+%
+% \endinput