% \iffalse meta-comment
%
%% File: l3doc.dtx Copyright (C) 1990-2012 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 "l3kernel 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 l3docstrip.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,cfg}}}
\generate{\file{l3doc.ist}{\from{l3doc.dtx}{docist}}}
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile
\else
  \expandafter\endgroup
\fi
%</driver>
%
% 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>
\RequirePackage{expl3,xparse,calc}
%</driver|class>
%
%<*driver|class>
\GetIdInfo$Id: l3doc.dtx 4267 2012-11-04 19:42:13Z joseph $
          {L3 Experimental documentation class}
%</driver|class>
%
%<*driver>
\ProvidesFile{\ExplFileName.dtx}
  [\ExplFileDate\space v\ExplFileVersion\space\ExplFileDescription]
\documentclass{l3doc}
\usepackage{framed,lipsum}
\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}
\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 much 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)~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 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).
%       This is partially done, now, but should be improved.
% \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 "\DocInput" now takes comma-separated arguments, and "\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}{ \function_one , \function_two: }
%   \begin{syntax}
%     "\foo_bar:" \Arg{meta} <test_1>
%   \end{syntax}
% <description>
% \end{function}
% \end{verbatim}
% \hrulefill
% \par
% \hspace*{0.25\textwidth}
% \begin{minipage}{0.5\textwidth}
% \begin{function}{ \function_one: , \function_two: }
%   \begin{syntax}
%     "\foo_bar:" \Arg{meta} <test_1>
%   \end{syntax}
% <description>
% \end{function}
% \end{minipage}
% \end{framed}
%
% Function environments take an optional argument to indicate whether the function(s) it
% describes are expandable or restricted-expandable or defined in conditional forms. Use "EXP", "rEXP", "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}
% \hrulefill
% \par
% \hspace*{0.25\textwidth}
% \begin{minipage}{0.5\textwidth}
% \begin{function}[pTF]{ \cs_if_exist:N }
%   \begin{syntax}
%     "\cs_if_exist_p:N" <cs>
%   \end{syntax}
% <description>
% \end{function}
% \end{minipage}
% \end{framed}
%
% \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{macro}[aux]" 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{macro}[internal]".
%
% 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}
%
%
% \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}
%
%    \begin{macrocode}
%<@@=codedoc>
%    \end{macrocode}
%
% \subsection{Variables}
%
%    \begin{macrocode}
\coffin_new:N \l_@@_output_box
\coffin_new:N \l_@@_names_coffin
\coffin_new:N \l_@@_descr_coffin
\coffin_new:N \l_@@_syntax_coffin
\box_new:N \g_@@_syntax_box
\bool_new:N \l_@@_long_name_bool
\bool_new:N \g_@@_implementation_bool
\dim_new:N \l_@@_trial_width_dim
\tl_new:N \l_@@_macro_tl
\int_new:N \l_@@_macro_int
\int_new:N \g_@@_nested_macro_int
%\int_new:N \c@CodelineNo
\prop_new:N \g_@@_missing_tests_prop
\clist_new:N \g_docinput_clist
\tl_new:N \l_@@_at_replaced_macro_tl
%    \end{macrocode}
%
%    \begin{macrocode}
\seq_new:N \g_@@_testfiles_seq
\seq_new:N \g_doc_functions_seq
\seq_new:N \g_doc_macros_seq
\seq_new:N \g_@@_not_tested_seq
%    \end{macrocode}
%
% For function/macro environments:
%    \begin{macrocode}
\bool_new:N \l_@@_meta_TF_bool
\bool_new:N \l_@@_meta_pTF_bool
\bool_new:N \l_@@_meta_EXP_bool
\bool_new:N \l_@@_meta_rEXP_bool
\bool_new:N \l_@@_macro_internal_bool
\bool_new:N \l_@@_macro_aux_bool
\bool_new:N \l_@@_macro_TF_bool
\bool_new:N \l_@@_macro_pTF_bool
\bool_new:N \l_@@_macro_var_bool
%    \end{macrocode}
%
% For package options:
%    \begin{macrocode}
\bool_new:N \g_@@_full_bool
\bool_new:N \g_@@_lmodern_bool
\bool_new:N \g_@@_checkfunc_bool
\bool_new:N \g_@@_checktest_bool
%    \end{macrocode}
%
% Temporaries:
%    \begin{macrocode}
\seq_new:N \g_@@_tmpa_seq
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
\int_new:N \l_@@_tmpa_int
%    \end{macrocode}
%
% Other:
%    \begin{macrocode}
\bool_new:N \l_@@_tested_bool
%    \end{macrocode}
%
% 
%
% \subsection{Options and configuration}
%
%    \begin{macrocode}
\DeclareOption{a5paper}{\@latexerr{Option not supported}{}}
%    \end{macrocode}
%
%
%    \begin{macrocode}
\DeclareOption{full}{ \bool_set_true:N \g_@@_full_bool }
\DeclareOption{onlydoc}{ \bool_set_false:N \g_@@_full_bool }
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareOption{check}{ \bool_set_true:N \g_@@_checkfunc_bool }
\DeclareOption{nocheck}{ \bool_set_false:N \g_@@_checkfunc_bool }
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareOption{checktest}{ \bool_set_true:N \g_@@_checktest_bool }
\DeclareOption{nochecktest}{ \bool_set_false:N \g_@@_checktest_bool }
%    \end{macrocode}
%
%    \begin{macrocode}
\DeclareOption{cm-default}{ \bool_set_false:N \g_@@_lmodern_bool }
\DeclareOption{lm-default}{ \bool_set_true:N \g_@@_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, with a message to the console that this has happened. Since we distribute a cfg file with the class, this should usually always be true. Therefore, check for \cs{ExplMakeTitle} (defined in `our' cfg file) and only output the informational message if it's not found.
%
%    \begin{macrocode}
\msg_new:nnn {l3doc} {input-cfg}
 {
  Local~config~file~l3doc.cfg~loaded.
 }
\file_if_exist:nT {l3doc.cfg}
 {
  \file_input:n {l3doc.cfg}
  \msg_info:nn {l3doc} {input-cfg}
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
%
%
% \subsection{Class and package loading}
%
%    \begin{macrocode}
\LoadClass{article}
\RequirePackage{doc}
\RequirePackage
  {
    array,
    alphalph,
    amsmath,
    booktabs,
    color,
    colortbl,
    fixltx2e,
    hologo,
    enumitem,
    pifont,
    textcomp,
    trace,
    underscore,
    csquotes,
    fancyvrb,
    verbatim
  }
\raggedbottom
%    \end{macrocode}
%
%
% I've never worked out why the verbatim environment adds extra space in dtx documents.
% Fix it with fancyvrb:
%    \begin{macrocode}
\fvset{gobble=2}
\cs_set_eq:NN \verbatim \Verbatim
\cs_set_eq:NN \endverbatim \endVerbatim
%    \end{macrocode}
%
%    \begin{macrocode}
\bool_if:NT \g_@@_lmodern_bool
 {
  \RequirePackage[T1]{fontenc}
  \RequirePackage{lmodern}
%    \end{macrocode}
% Now replace the italic typewriter font with the oblique shape instead;
% the former makes my skin crawl. (Will, Aug 2011)
%    \begin{macrocode}
  \group_begin:
    \ttfamily
    \DeclareFontShape{T1}{lmtt}{m}{it}{<->ec-lmtto10}{}
  \group_end:
 }
%    \end{macrocode}
%
% Must be last, as usual.
%    \begin{macrocode}
\RequirePackage{hypdoc}
%    \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}
\tl_replace_once:Nnn \theCodelineNo
 { \HDorg@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.)
%
% Customise lists:
%    \begin{macrocode}
\cs_set_eq:NN \@@_oldlist:nn \list
\cs_set_nopar:Npn \list #1 #2 { \@@_oldlist:nn {#1} { #2 \listparindent\z@ } }
\setlength \parindent  { 2em }
\setlength \itemindent { 0pt }
\setlength \parskip    { 0pt plus 3pt minus 0pt }
%    \end{macrocode}
%
% Customise TOC (as we have so many sections). Different design and/or
% structure is called for ):
%    \begin{macrocode}
\@addtoreset{section}{part}
\cs_set_nopar:Npn \l@section #1#2
 {
  \ifnum \c@tocdepth >\z@
    \addpenalty\@secpenalty
    \addvspace{1.0em \@plus\p@}
    \setlength\@tempdima{2.5em}  % was 1.5em
    \begingroup
      \parindent \z@ \rightskip \@pnumwidth
      \parfillskip -\@pnumwidth
      \leavevmode \bfseries
      \advance\leftskip\@tempdima
      \hskip -\leftskip
      #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
    \endgroup
  \fi
 }
\cs_set_nopar:Npn\l@subsection{\@dottedtocline{2}{2.5em}{2.3em}}  % #2 = 1.5em
%    \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{\hologo{eTeX}}
\providecommand*\IniTeX{\hologo{iniTeX}}
\providecommand*\Lua{Lua}
\providecommand*\LuaTeX{\hologo{LuaTeX}}
\providecommand*\pdfTeX{\hologo{pdfTeX}}
\providecommand*\XeTeX{\hologo{XeTeX}}
%    \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.  There is a bit of shuffling around to make sure that |_|
%   has the catcode that \cs{doc_replace_at_at:N} expects, without
%   rescanning the whole argument.  For that we store in
%   \cs{l_@@_tmpb_tl} a single underscore with the current catcode,
%   then replace all such underscores by letter underscores in |#1|
%   (stored in the |tmpa| token list).  After calling
%   \cs{doc_replace_at_at:N}, we replace the underscores back to their
%   old meaning before using the token list.
%    \begin{macrocode}
\DeclareDocumentCommand \cmd {m} { \@@_cmd:n { #1 } }
\DeclareDocumentCommand \cs  {m} { \@@_cs:n  { #1 } }
%    \end{macrocode}
%
% This is |\cmd{\foo}| and |\cs{foo}|: \cmd\foo\ and \cs{foo}.
%    \begin{macrocode}
\cs_new:Npn \@@_cmd:n #1 { \cs{ \expandafter \@@_cmd_to_cs:w \string#1 } }
\cs_set_nopar:Npn \@@_cmd_to_cs:w #1#2 { \char\number`#2\relax }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \@@_cs:n #1
 {
  \tl_set_rescan:Nnn \l_@@_tmpb_tl { } { _ }
  \tl_set:Nn \l_@@_tmpa_tl {#1}
  \tl_replace_all:NVn \l_@@_tmpa_tl \l_@@_tmpb_tl { _ }
  \@@_replace_at_at:N \l_@@_tmpa_tl
  \tl_replace_all:NnV \l_@@_tmpa_tl { _ } \l_@@_tmpb_tl
  \texttt { \char`\\ \tl_use:N \l_@@_tmpa_tl}
 }
\cs_generate_variant:Nn \tl_replace_all:Nnn { NV , NnV }
%    \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}{\file,\env,\pkg,\cls}
% This list may change\dots this is just my preference for markup.
%    \begin{macrocode}
\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}
\DeclareDocumentCommand \tn {m}
 {
  \texttt { \char`\\ #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 \@@_implementation:
 {
  \DeclareDocumentCommand {\variable} { O{} } { \@@_macro:n { var , ##1 } }
  \cs_set_eq:NN \endvariable \endmacro
 }
\cs_new:Npn \@@_docu:
 {
  \cs_set_eq:NN \variable \variabledoc
  \cs_set_eq:NN \endvariable \endvariabledoc
 }
\AtEndOfPackage{\@@_docu:}
\newenvironment{documentation}{\@@_docu:}{}
\newenvironment{implementation}{\@@_implementation:}{}
%    \end{macrocode}
%
%    \begin{macrocode}
\NewDocumentCommand \EnableDocumentation {}
 {
  \renewenvironment{documentation}{\@@_docu:}{}
 }
\NewDocumentCommand \EnableImplementation {}
 {
  \renewenvironment{implementation}{\@@_implementation:}{}
 }
\NewDocumentCommand \DisableDocumentation {}
 {
  \cs_set_eq:NN \documentation \comment
  \cs_set_eq:NN \enddocumentation \endcomment
 }
\NewDocumentCommand \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{macrocode}
\keys_define:nn { l3doc/function }
 {
  TF .code:n =
   {
    \bool_gset_true:N \l_@@_meta_TF_bool
   } ,
  EXP .code:n =
   {
    \bool_gset_true:N \l_@@_meta_EXP_bool
    \bool_gset_false:N \l_@@_meta_rEXP_bool
   } ,
  rEXP .code:n =
   {
    \bool_gset_false:N \l_@@_meta_EXP_bool
    \bool_gset_true:N \l_@@_meta_rEXP_bool
   } ,
  pTF .code:n =
   {
    \bool_gset_true:N \l_@@_meta_pTF_bool
    \bool_gset_true:N \l_@@_meta_TF_bool
    \bool_gset_true:N \l_@@_meta_EXP_bool
   } ,
   added .tl_set:N = \l_@@_date_added_tl ,
   updated .tl_set:N = \l_@@_date_updated_tl ,
   tested .code:n = { } ,
 }
%    \end{macrocode}
%
%
% \begin{environment}{function}
% \begin{environment}{variabledoc}
% Environment for documenting function(s).
% Stick the function names in a box.
% Allow |<...>| to be used as markup for |\meta{...}|.
% Ignore spaces and sanitize with catcodes before reading argument.
%    \begin{macrocode}
\char_set_catcode_active:N \<
\DeclareDocumentEnvironment {function} { O{} }
 {

  \par\bigskip\noindent
  \phantomsection

  \coffin_clear:N \l_@@_descr_coffin
  \box_gclear:N \g_@@_syntax_box
  \coffin_clear:N \l_@@_syntax_coffin
  \coffin_clear:N \l_@@_names_coffin

  \bool_set_false:N \l_@@_meta_TF_bool
  \bool_set_false:N \l_@@_meta_pTF_bool
  \bool_set_false:N \l_@@_meta_EXP_bool
  \bool_set_false:N \l_@@_meta_rEXP_bool

  \keys_set:nn { l3doc/function } {#1}

  \char_set_active_eq:NN < \@@_open_meta:w

  \group_begin:
    \MakePrivateLetters
    \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
    \exp_after:wN
  \group_end:
  \@@_function:n
 }
 {
  \vcoffin_set_end:
  \hcoffin_set:Nn  \l_@@_syntax_coffin { \box_use:N \g_@@_syntax_box }
%    \end{macrocode}
% \cs{g_@@_syntax_box} is defined in the syntax environment.
%    \begin{macrocode}
  \bool_if:NTF \l_@@_long_name_bool
   {
    \coffin_join:NnnNnnnn
      \l_@@_output_box {hc} {vc}
      \l_@@_syntax_coffin {l} {T}
      {0pt} {0pt}
    \coffin_join:NnnNnnnn
      \l_@@_output_box {l} {t}
      \l_@@_names_coffin  {r} {t}
      {-\marginparsep} {0pt}
    \coffin_join:NnnNnnnn
      \l_@@_output_box {l} {b}
      \l_@@_descr_coffin  {l} {t}
      {0.75\marginparwidth + \marginparsep} {-\medskipamount}

    \coffin_typeset:Nnnnn \l_@@_output_box {\l_@@_descr_coffin-l} {\l_@@_descr_coffin-t} {0pt} {0pt}
   }
   {
    \coffin_join:NnnNnnnn
      \l_@@_output_box {hc} {vc}
      \l_@@_syntax_coffin {l} {t}
      {0pt} {0pt}
    \coffin_join:NnnNnnnn
      \l_@@_output_box {l} {b}
      \l_@@_descr_coffin  {l} {t}
      {0pt} {-\medskipamount}
    \coffin_join:NnnNnnnn
      \l_@@_output_box {l} {t}
      \l_@@_names_coffin  {r} {t}
      {-\marginparsep} {0pt}

    \coffin_typeset:Nnnnn
      \l_@@_output_box {\l_@@_syntax_coffin-l} {\l_@@_syntax_coffin-T}
      {0pt} {0pt}
   }
  \par
  \allowbreak
 }
\char_set_catcode_other:N \<
\cs_set_eq:NN \variabledoc \function
\cs_set_eq:NN \endvariabledoc \endfunction
%    \end{macrocode}
%
%
% \begin{macro}{\@@_function:n}
% \begin{arguments}
% \item Comma-separated list of functions;
%       input has already been sanitised by catcode changes before reading
%       the argument.
% \end{arguments}
%    \begin{macrocode}
\cs_set_nopar:Npn \@@_function:n #1
 {

  \tl_set:Nn \l_@@_function_input_tl {#1}

  \dim_zero:N \l_@@_trial_width_dim
  \hcoffin_set:Nn \l_@@_names_coffin { \function_typeset:n {#1} }
  \dim_set:Nn \l_@@_trial_width_dim { \box_wd:N \l_@@_names_coffin }

  \bool_set:Nn \l_@@_long_name_bool
    { \dim_compare_p:nNn \l_@@_trial_width_dim > \marginparwidth }

  \vcoffin_set:Nnw \l_@@_descr_coffin {\textwidth}
    \noindent\ignorespaces
 }
\cs_gset_nopar:Npn \function_typeset:n #1 %^^A todo: use "\cs_new:Npn" here
 {
  \tl_gclear:N \g_@@_macro_tl

  % populate "\l_@@_functions_block_prop" with info on the functions present:
  % with a hack as we don't currently read verbatim and that means that
  % \q_recursion_tail is an issue!
  \str_if_eq:nnTF {#1} { \q_recursion_tail }
    {
      \prop_put:Nxx \l_@@_functions_block_prop
        { \cs_to_str:N \q_recursion_tail }
        { { -1 } { } }
    }
    { \clist_map_function:nN {#1} \@@_parse_functions:n }

  \small\ttfamily
  \begin{tabular}{ @{} l @{} r @{} }
    \toprule
    \prop_map_function:NN \l_@@_functions_block_prop \@@_typeset_functions:nn
    \@@_typeset_dates:
    \bottomrule
  \end{tabular}
  \normalfont\normalsize
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_parse_functions:n}
% The idea here is to populate "\l_@@_functions_block_prop" with information
% about the functions being typeset and their variants.
% The property list uses a specific format: the keys contained are the function `names' (stripped of signature) with values specified by a comma-separated list containing two brace groups per item:
% \begin{center}
% |>  {my_function}  =>  {| \Arg{Nargs_1} \Arg{sig_1} |,| \Arg{Nargs_2} \Arg{sig_2} |, ... }|
% \end{center}
% This somewhat arcane syntax is chosen to distinguish between all variants of control sequence that may be being documented here. (With or without \textsf{expl3} function syntax.)
%    \begin{macrocode}
\prop_new:N \l_@@_functions_block_prop
\cs_generate_variant:Nn \prop_put:Nnn {Nxx}
\cs_new:Nn \@@_parse_functions:n
 {
  \exp_args:Nxx \tl_if_head_eq_charcode:nNTF { \token_to_str:N #1 } {\cs_to_str:N \\}
   {
    \tl_gset_eq:NN \l_@@_function_name_prefix_tl \@backslashchar
    % for the weird functions named "\::N" and so on:
    \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \cs_to_str:N #1 } { : }
     {
      % again, no variants:
      \prop_put:Nxx \l_@@_functions_block_prop  { \cs_to_str:N #1 } { {-1} {} }
     }
     {
      % finally, for regular old csnames:
      \exp_args:NNf \prop_get:NnNTF
        \l_@@_functions_block_prop
        { \__cs_get_function_name:N #1 } \l_@@_tmpb_tl
       {
        \prop_put:Nxx \l_@@_functions_block_prop
         { \__cs_get_function_name:N #1 }
         {
           \l_@@_tmpb_tl ,
           {\__cs_count_signature:N #1}
           {\__cs_get_function_signature:N #1}
         }
       }
       {
        \prop_put:Nxx \l_@@_functions_block_prop
          { \__cs_get_function_name:N #1 }
          {
            {\__cs_count_signature:N #1}
            {\__cs_get_function_signature:N #1}
          }
       }
     }
   }
%    \end{macrocode}
% False branch for keys and things that aren't actually csnames: 
%    \begin{macrocode}
   {
    % for now don't bother splitting into variants:
    \tl_gclear:N \l_@@_function_name_prefix_tl
    \prop_put:Nxx \l_@@_functions_block_prop  { \tl_to_str:n {#1} } { {-1} {} }
   }
 }
%    \end{macrocode}
% \end{macro}
% \end{environment}
% \end{environment}
%
%
% \begin{macro}{\@@_typeset_functions:nn}
% \begin{arguments}
% \item Function/macro/variable name (stripped of signature in the first case, if any)
% \item Comma-list containing information about the signature variants being documented (if any)
% \end{arguments}
%    \begin{macrocode}
\cs_new:Nn \@@_typeset_functions:nn
 {
  \clist_gset:Nn \l_@@_variants_clist {#2}
  \clist_gpop:NN \l_@@_variants_clist \l_@@_tmpb_tl
  \exp_args:Nc \@@_typeset_functions_aux:N
   {
    #1
    \int_compare:nT { \exp_after:wN \use_i:nn \l_@@_tmpb_tl > -1 } {:}
    \int_compare:nT { \exp_after:wN \use_i:nn \l_@@_tmpb_tl >  0 }
      { \exp_after:wN \use_ii:nn \l_@@_tmpb_tl }
   }
  \\
 }

\cs_new_nopar:Nn \@@_typeset_functions_aux:N
 {
  \bool_if:NT \l_@@_meta_pTF_bool
   {
    \tl_set:Nx \l_@@_pTF_name_tl
      { \l_@@_function_name_prefix_tl \@@_predicate_from_base:N #1 }
    \@@_special_main_index:o { \l_@@_pTF_name_tl }
    \seq_gput_right:Nx \g_doc_functions_seq
      { \tl_to_str:N \l_@@_pTF_name_tl }
    \tl_set:Nx \l_@@_pTF_name_tl { \@@_predicate_from_base:N #1 }
   }

  \tl_set:Nx \l_@@_tmpa_tl
   {
    \l_@@_function_name_prefix_tl
    \cs_to_str:N #1
    \bool_if:NT \l_@@_meta_TF_bool { \tl_to_str:n {TF} }
   }
  \@@_special_main_index:o { \l_@@_tmpa_tl }
  \seq_gput_right:No \g_doc_functions_seq { \l_@@_tmpa_tl }

  \bool_if:NTF \l_@@_meta_pTF_bool
   {
    \bool_gset_false:N \l_@@_meta_TF_bool
    \exp_args:Nc \@@_typeset_function_block:N { \l_@@_pTF_name_tl }
    \bool_gset_true:N \l_@@_meta_TF_bool

    \\
    \@@_typeset_function_block:N #1
   }
   {
    \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \exp_after:wN \use_none:n \token_to_str:N #1 } {:}
      { \@@_show_macro_unusual:N #1 }
      { \@@_typeset_function_block:N #1 }
   }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_typeset_function_block:N}
%    \begin{macrocode}
\cs_set_nopar:Nn \@@_typeset_function_block:N
 {
  \tl_gset:Nx \l_@@_function_name_tl { \__cs_get_function_name:N #1 }
  \tl_gset:Nx \l_@@_function_sig_tl { \__cs_get_function_signature:N #1 }
  \tl_gset:Nx \g_@@_macro_tl { \l_@@_function_name_prefix_tl \l_@@_function_name_tl }

  \@@_typeset_function_basename:N #1
  \bool_if:NT \l_@@_meta_TF_bool { \@@_typeset_TF: }
  \@@_typeset_expandability:
  \clist_if_empty:NF \l_@@_variants_clist { \@@_typeset_variants: }
  \bool_if:NT \g_@@_full_bool { \@@_label_function:N #1 }
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set:Nn \@@_typeset_function_basename:N
 { \l_@@_function_name_prefix_tl \cs_to_str:N #1 }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set:Nn \@@_typeset_expandability:
 {
  &
  \bool_if:NT \l_@@_meta_EXP_bool
   {
    \hspace{\tabcolsep}
    \hyperlink{expstar} {$\star$}
   }
   \bool_if:NT \l_@@_meta_rEXP_bool
    {
     \hspace{\tabcolsep}
     \hyperlink{rexpstar} {\ding{73}} % hollow star
    }
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set:Nn \@@_typeset_variants:
 {
  \\
  \@@_typeset_aux:n \g_@@_macro_tl :
  \int_compare:nTF { \clist_count:N \l_@@_variants_clist == 1 }
   { \exp_after:wN \use_ii:nn \l_@@_variants_clist }
   {
     \textrm(
       \clist_pop:NN \l_@@_variants_clist \l_@@_tmpb_tl
       \exp_after:wN \use_ii:nn \l_@@_tmpb_tl
       \clist_map_inline:Nn \l_@@_variants_clist {\textrm| \use_ii:nn ##1}
     \textrm)
   }
  \bool_if:NT \l_@@_meta_TF_bool { \@@_typeset_TF: }
  &
  \bool_if:NT \l_@@_meta_EXP_bool
   {
    \hspace{\tabcolsep}
    \hyperlink{expstar} {$\star$}
   }
  \bool_if:NT \l_@@_meta_rEXP_bool
   {
    \hspace{\tabcolsep}
    \hyperlink{rexpstar} {\ding{73}} % hollow star
   }
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set:Nn \@@_label_function:N
 {
  \tl_set:Nx \l_@@_tmpa_tl { \l_@@_function_name_prefix_tl \cs_to_str:N #1 }
  \exp_args:NNf \tl_replace_all:Nnn \l_@@_tmpa_tl {\token_to_str:N _} {/}
  \exp_args:NNf \tl_remove_all:Nn \l_@@_tmpa_tl {\@backslashchar}
  \exp_args:Nx \label {doc/function//\l_@@_tmpa_tl}
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[aux]{\@@_show_macro_unusual:N}
% This is for the case when the function is one of the weird ones like \cs{::N}.
%    \begin{macrocode}
\cs_set_nopar:Nn \@@_show_macro_unusual:N
 {
  \tl_gset:Nx \g_@@_macro_tl { \token_to_str:N #1}
  \token_to_str:N #1 &

  \exp_args:NNf \tl_replace_all:Nnn \g_@@_macro_tl {\token_to_str:N _} {/}
  \exp_args:NNf \tl_replace_all:Nnn \g_@@_macro_tl {\@backslashchar} {}
  \bool_if:NT \g_@@_full_bool
   {
    \exp_args:Nx \label { doc/function//\g_@@_macro_tl }
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_typeset_dates:}
% To display metadata for when functions are added/modified.
%    \begin{macrocode}
\cs_set:Nn \@@_typeset_dates:
 {
  \bool_if:nF { \tl_if_empty_p:N \l_@@_date_added_tl &&
                \tl_if_empty_p:N \l_@@_date_updated_tl }
   { \midrule }

  \tl_if_empty:NF \l_@@_date_added_tl
   {
    \multicolumn{2}{@{}r@{}}
      { \scriptsize New:\,\l_@@_date_added_tl } \\
   }

  \tl_if_empty:NF \l_@@_date_updated_tl
   {
    \multicolumn{2}{@{}r@{}}
      { \scriptsize Updated:\,\l_@@_date_updated_tl } \\
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{syntax}
% Syntax block placed next to the list of functions to illustrate their use.
%    \begin{macrocode}
\newenvironment{syntax}
 {
  \small\ttfamily
  \bool_if:NTF \l_@@_long_name_bool
    {
     \hbox_gset:Nw \g_@@_syntax_box
     \arrayrulecolor{white}
     \begin{tabular}{@{}l@{}}
     \toprule
     \begin{minipage}
       { \textwidth+0.75\marginparwidth-\l_@@_trial_width_dim }
    }
    {
     \hbox_gset:Nw \g_@@_syntax_box
     \arrayrulecolor{white}
     \begin{tabular}{@{}l@{}}
     \toprule
     \begin{minipage}{ \textwidth }
    }
  \raggedright
  \obeyspaces\obeylines
 }
 {
  \end{minipage}
  \end{tabular}
  \arrayrulecolor{black}
  \hbox_set_end:
  \ignorespacesafterend
 }
%    \end{macrocode}
% \end{environment}
%
% \begin{macro}{\@@_ensuremath_sb:n}
%    \begin{macrocode}
\cs_new:Npn \@@_ensuremath_sb:n #1
 {
  \ensuremath{\sb{#1}}
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_open_meta:w,\@@_close_meta:n}
%    \begin{macrocode}
\cs_set_eq:NN \@@_meta:n \meta
\cs_set:Npn \meta
 {
  \group_begin:
    \char_set_active_eq:NN _ \@@_ensuremath_sb:n
    \@@_close_meta:n
 }
\cs_new:Npn \@@_open_meta:w
 {
  \group_begin:
    \char_set_active_eq:NN _ \@@_ensuremath_sb:n
    \@@_close_meta:w
 }
\cs_new:Npn \Arg
 {
  \texttt{ \char`\{ }
  \group_begin:
    \char_set_active_eq:NN _ \@@_ensuremath_sb:n
    \@@_close_Arg:n
 }
\cs_new_nopar:Npn \@@_close_meta:n #1  { \@@_meta:n {#1} \group_end: }
\cs_new_nopar:Npn \@@_close_meta:w #1> { \@@_meta:n {#1} \group_end: }
\cs_new_nopar:Npn \@@_close_Arg:n #1
 {
  \@@_meta:n {#1}
  \group_end:
  \texttt{ \char`\} }
 }
%    \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:
%    \begin{macrocode}
\keys_define:nn { l3doc/macro }
 {
  aux .code:n =
    { \bool_set_true:N \l_@@_macro_aux_bool } ,
  internal .code:n =
    { \bool_set_true:N \l_@@_macro_internal_bool } ,
  int .code:n =
    { \bool_set_true:N \l_@@_macro_internal_bool } ,
  var .code:n =
    { \bool_set_true:N \l_@@_macro_var_bool } ,
  TF .code:n =
    { \bool_set_true:N \l_@@_macro_TF_bool } ,
  pTF .code:n =
    { \bool_set_true:N \l_@@_macro_pTF_bool } ,
  tested .code:n =
    { } ,
  EXP .code:n = {} , % TODO
  rEXP .code:n = {} , % TODO
  added .code:n = {} , % TODO
  updated .code:n = {} , % TODO
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\RenewDocumentCommand { \macro } { O{} } { \@@_macro:n {#1} }
\cs_new_protected:Npn \@@_macro:n #1
 {

  \int_compare:nNnTF \currentgrouplevel=2
   { \int_gzero:N \g_@@_nested_macro_int }
   { \int_incr:N  \g_@@_nested_macro_int }

  \bool_gset_false:N \l_@@_macro_aux_bool
  \bool_gset_false:N \l_@@_macro_internal_bool
  \bool_gset_false:N \l_@@_macro_TF_bool
  \bool_gset_false:N \l_@@_macro_pTF_bool
  \bool_gset_false:N \l_@@_macro_var_bool
  \bool_gset_false:N \l_@@_tested_bool

  \cs_set_eq:NN \@@_macroname_prefix:n \use:n
  \cs_set_eq:NN \@@_macroname_suffix: \c_empty_tl

  \keys_set:nn { l3doc/macro } {#1}

  \cs_set_eq:NN \testfile \@@_print_testfile:n

  \peek_meaning_ignore_spaces:NTF \c_group_begin_token
   {
    \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
      \@@_macro_aux:n
   }
   {
    \@@_macro_verbatim:w
   }
 }
\NewDocumentCommand {\@@_macro_verbatim:w} {v}
 {
  \group_begin: % pretty useless
  \@@_macro_aux:n {#1}
 }
%    \end{macrocode}
% After changing the catcodes, parse the arguments:
%    \begin{macrocode}
\clist_new:N \l_@@_macro_input_clist
\cs_new_nopar:Npn \@@_macro_aux:n #1
 {
  \group_end:
  \clist_set:Nn \l_@@_macro_input_clist {#1}
  \bool_if:NTF \l_@@_macro_pTF_bool
   {
    \clist_map_inline:Nn \l_@@_macro_input_clist
      {
        \exp_args:Nx \@@_macro_single:n { \@@_predicate_from_base:w ##1 \q_nil }
      }
    \bool_set_true:N \l_@@_macro_TF_bool
    \clist_map_function:NN \l_@@_macro_input_clist \@@_macro_single:n
    \bool_set_false:N \l_@@_macro_TF_bool
   }
   { \clist_map_function:NN \l_@@_macro_input_clist \@@_macro_single:n }
 }
%    \end{macrocode}
%
% \end{environment}
%
%    \begin{macrocode}
\cs_set:Nn \@@_predicate_from_base:N
 {
  \__cs_get_function_name:N #1 _p: \__cs_get_function_signature:N #1
 }
\cs_set:Npn \@@_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}
% \cs{l_@@_at_replaced_macro_tl} stores the macro name after
% replacement of |@@|.
%    \begin{macrocode}
\cs_set_nopar:Npn \@@_macro_single:n #1
 {
  \int_incr:N \l_@@_macro_int
  
  \tl_set:Nx \l_@@_at_replaced_macro_tl { \token_to_str:N #1 }
  \@@_replace_at_at:N \l_@@_at_replaced_macro_tl
  \tl_set_eq:NN \saved@macroname \l_@@_at_replaced_macro_tl
  
  \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_@@_macro_aux_bool
   {
    \cs_set_eq:NN \@@_macroname_prefix:n \@@_typeset_aux:n
   }
  \bool_if:NT \l_@@_macro_TF_bool
   {
    \cs_set_eq:NN \@@_macroname_suffix: \@@_typeset_TF:
   }

  \bool_if:NF \l_@@_macro_aux_bool
   {
    \tl_gset:Nx \l_@@_macro_tl { \tl_to_str:N \l_@@_at_replaced_macro_tl }
    \exp_args:NNf \tl_greplace_all:Nnn \l_@@_macro_tl {\token_to_str:N _} {/}
    \exp_args:NNf \tl_greplace_all:Nnn \l_@@_macro_tl {\@backslashchar} {}
   }

  \use:x
   {
    \exp_not:N \item [ \exp_not:N \@@_print_macroname:n {
      \tl_to_str:N \l_@@_at_replaced_macro_tl
    }]
   }
  \int_gincr:N \c@CodelineNo

  \bool_if:NF \l_@@_macro_aux_bool
   {
    \bool_if:NTF \l_@@_macro_TF_bool
     {
      \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:N \l_@@_at_replaced_macro_tl \tl_to_str:n {TF} }
      \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:N \l_@@_at_replaced_macro_tl \tl_to_str:n {T } }
      \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:N \l_@@_at_replaced_macro_tl \tl_to_str:n { F} }
     }
     {
      \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:N \l_@@_at_replaced_macro_tl }
     }
   }
  \bool_if:NTF \l_@@_macro_TF_bool
   {
    \exp_args:Nx \SpecialMainIndex{ \tl_to_str:N \l_@@_at_replaced_macro_tl TF}\nobreak
    \exp_args:Nx \DoNotIndex{ \tl_to_str:N \l_@@_at_replaced_macro_tl TF}
   }
   {
    \exp_args:Nx \SpecialMainIndex{ \tl_to_str:N \l_@@_at_replaced_macro_tl }\nobreak
    \exp_args:Nx \DoNotIndex{ \tl_to_str:N \l_@@_at_replaced_macro_tl }
   }

  \int_gdecr:N \c@CodelineNo
  \ignorespaces
 }
%    \end{macrocode}
%
% \begin{macro}{\@@_print_macroname:n}
%    \begin{macrocode}
\tl_clear:N \l_@@_macro_tl
\cs_set_nopar:Npn \@@_print_macroname:n #1
 {
  \strut
  \HD@target
  \int_compare:nTF { \tl_count:n {#1} <= 28 }
    { \MacroFont } { \MacroLongFont }

  % INEFFICIENT: (!)
  \exp_args:NNx \seq_if_in:NnTF \g_doc_functions_seq
   { #1 \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } }
   {
    \hyperref [doc/function//\l_@@_macro_tl]
   }
   { \use:n }
   {
    \@@_macroname_prefix:n {#1} \@@_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}{\@@_typeset_TF:,\@@_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 \@@_typeset_TF:
 {
  \hyperlink{explTF}
   {
    \color{black}
    \itshape TF
    \makebox[0pt][r]
     {
      \color{red}
      \underline { \phantom{\itshape TF} \kern-0.1em }
     }
   }
 }
\cs_set_nopar:Npn \@@_typeset_aux:n #1
 {
  { \color[gray]{0.7} #1 }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_print_testfile:n}
% Used to show that a macro has a test, somewhere.
%    \begin{macrocode}
\DeclareDocumentCommand \@@_print_testfile:n {m}
 {
  \bool_set_true:N \l_@@_tested_bool
  \tl_if_eq:nnF {#1} {*}
   {
    \seq_if_in:NnF \g_@@_testfiles_seq {#1}
     {
      \seq_gput_right:Nn \g_@@_testfiles_seq {#1}
      \par
      \@@_print_testfile_aux:n {#1}
     }
   }
 }
%    \end{macrocode}
% Text for displaying:
%    \begin{macrocode}
\cs_new_protected:Npn \@@_print_testfile_aux:n #1
 {
  \footnotesize
  (
   \textit{
     The~ test~ suite~ for~ this~ command,~
     and~ others~ in~ this~ file,~ is~ \textsf{#1}
   }.
  )\par
 }
%    \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}
%   Note: There \cs{l_@@_macro_input_clist} may contain unconverted |@@|.
%    \begin{macrocode}
\cs_generate_variant:Nn \prop_gput:Nnn {NVx}
\DeclareDocumentCommand \TestMissing {m}
 {
  \prop_if_in:NVTF \g_@@_missing_tests_prop \l_@@_macro_input_clist
   {
    \prop_get:NVN \g_@@_missing_tests_prop \l_@@_macro_input_clist \l_@@_tmpa_tl
    \prop_gput:NVx \g_@@_missing_tests_prop \l_@@_macro_input_clist
     {
      *~ \l_@@_tmpa_tl
      ^^J \exp_not:n {\space\space\space\space\space\space}
      *~ #1
     }
   }
   { \prop_gput:NVn \g_@@_missing_tests_prop \l_@@_macro_input_clist {#1} }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\g_@@_module_name_tl}
% \begin{macro}[internal]{\@@_replace_at_at:N}
%    \begin{macrocode}
\tl_new:N \g_@@_module_name_tl
\cs_new_protected:Npn \@@_replace_at_at:N #1
 {
  \tl_if_empty:NF \g_@@_module_name_tl
   {
    \tl_replace_all:Non #1 { \token_to_str:N @ } { @ }
    \tl_replace_all:Non #1 { \token_to_str:N _ } { _ }
%    \end{macrocode}
%    To make the search-and-replace work, in the source of l3doc 
%    itself the \verb|@@| search string needs to be protected from 
%    replacement by l3docstrip! This is easy to do by adding a space.
%    \begin{macrocode}
    \tl_replace_all:Nox #1 { _@ @ } { __ \g_@@_module_name_tl }
    \tl_replace_all:Nox #1 { @ @ } { __ \g_@@_module_name_tl }
   }
 }
\cs_generate_variant:Nn \tl_replace_all:Nnn { Non, Nox }
%    \end{macrocode}
% \end{macro}
% \end{variable}
%
% \begin{macro}{\endmacro}
%   The \cs{doc_endmacro_wrap_each:N} puts each item of the sequence |#1|
%   in \cs{texttt} font and with a trailing TF if needed.  This should
%   go inline in the definition of \cs{endmacro}, but somehow the |#|
%   doesn't go through some \LaTeXe{} internals.
%    \begin{macrocode}
\cs_new_protected:Nn \@@_endmacro_build_seq:N
 {
  \seq_gclear:N #1
  \clist_map_inline:Nn \l_@@_macro_input_clist
   {
    \tl_set:Nn \l_@@_tmpa_tl {##1}
    \@@_replace_at_at:N \l_@@_tmpa_tl
    \seq_gput_right:No #1 { \l_@@_tmpa_tl }
   }
 }
\cs_set_protected:Nn \@@_endmacro_wrap_each:N
 {
  \bool_if:NTF \l_@@_macro_TF_bool
   { \seq_gset_map:NNn #1 #1 { \exp_not:N \texttt { ##1 TF } } }
   { \seq_gset_map:NNn #1 #1 { \exp_not:N \texttt { ##1 } } }
 }
\cs_set:Nn \@@_texttt_comma:n {\,,~\texttt{#1}}
\cs_set:Npn \endmacro
 {
  \int_compare:nT { \g_@@_nested_macro_int < 1 }
   {
    \par\nobreak\noindent{\footnotesize(\emph{
    End~ definition~ for~
    \@@_endmacro_build_seq:N \g_@@_tmpa_seq
    \@@_endmacro_wrap_each:N \g_@@_tmpa_seq
    \int_compare:nTF { \seq_count:N \g_@@_tmpa_seq <= 3 }
      {
        \seq_use:Nnnn \g_@@_tmpa_seq
          { \,~and~ } { \,,~ } { \,,~and~ }
      }
      { \seq_item:Nn \g_@@_tmpa_seq {1}\,~and~others. }
      
    \bool_if:nT
     {
      !\l_@@_macro_aux_bool &&
      !\l_@@_macro_internal_bool &&
      \int_compare_p:n {\g_@@_nested_macro_int<1}
     }
     {
      \int_compare:nNnTF \l_@@_macro_int=1 {~This~} {~These~}
      \bool_if:NTF \l_@@_macro_var_bool{variable}{function}
      \int_compare:nNnTF \l_@@_macro_int=1 {~is~}{s~are~}
      documented~on~page~
      \exp_args:Nx\pageref{doc/function//\l_@@_macro_tl}.
     }
    })\par}
   }

  \bool_if:nT
   {
    \g_@@_checktest_bool &&
    !( \l_@@_macro_aux_bool || \l_@@_macro_var_bool ) &&
    !\l_@@_tested_bool
   }
   {
    \seq_gput_right:Nx \g_@@_not_tested_seq
     {
      \seq_use:Nnnn \g_@@_tmpa_seq { , } { , } { , }
      \bool_if:NT \l_@@_macro_pTF_bool {~(pTF)}
      \bool_if:NT \l_@@_macro_TF_bool {~(TF)}
     }
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{macrocode}
% \begin{macro}[aux]{\@@_xmacro_code:n}
%   Hook into the \texttt{macrocode} environment in a dirty way:
%   \cs{xmacro@code} is responsible for grabbing (and tokenizing) the
%   body of the environment.  Redefine it to pass what it grabs to
%   \cs{doc_xparse_code:n}.  This new macro replaces all |@@| by the
%   appropriate module name.  One exceptional case is the
%   |<@@=|\meta{module}|>| lines themselves, where |@@| should not be
%   modified.  Actually, we search for such lines, to set the module
%   name automatically.  We need to be careful: no |<@@=| should appear
%   as such in the code below since \pkg{l3doc} is also typeset using
%   this code.
%    \begin{macrocode}
\group_begin:
  \char_set_catcode_escape:N \/
  \char_set_catcode_other:N \^^A
  \char_set_catcode_active:N \^^S
  \char_set_catcode_active:N \^^B
  \char_set_catcode_other:N \^^L
  \char_set_catcode_other:N \^^R
  \char_set_lccode:nn { `\^^A } { `\% }
  \char_set_lccode:nn { `\^^S } { `\  }
  \char_set_lccode:nn { `\^^B } { `\\ }
  \char_set_lccode:nn { `\^^L } { `\{ }
  \char_set_lccode:nn { `\^^R } { `\} }
  \tl_to_lowercase:n
   {
    \group_end:
    \cs_set_protected:Npn \xmacro@code
        #1 ^^A ^^S^^S^^S^^S ^^Bend ^^Lmacrocode^^R
      { \@@_xmacro_code:n {#1} /end{macrocode} }
   }
\group_begin:
  \char_set_catcode_active:N \<
  \char_set_catcode_active:N \>
  \cs_new_protected:Npn \@@_xmacro_code:n #1
   {
    \tl_if_in:nnTF {#1} { < @ @ = }
     { \@@_xmacro_code:w #1 \q_stop }
     {
      \tl_set:Nn \l_@@_tmpa_tl {#1}
      \@@_replace_at_at:N \l_@@_tmpa_tl
      \tl_use:N \l_@@_tmpa_tl
     }
   }
  \cs_new_protected:Npn \@@_xmacro_code:w #1 < @ @ = #2 > #3 \q_stop
   {
    \tl_set:Nn \l_@@_tmpa_tl {#1}
    \@@_replace_at_at:N \l_@@_tmpa_tl

    \tl_gset:Nn \g_@@_module_name_tl {#2}
    \tl_put_right:Nn \l_@@_tmpa_tl { < @ @ = #2 > }

    \tl_set:Nn \l_@@_tmpb_tl {#3}
    \@@_replace_at_at:N \l_@@_tmpb_tl
    \tl_put_right:No \l_@@_tmpa_tl { \l_@@_tmpb_tl }

    \tl_use:N \l_@@_tmpa_tl
   }
\group_end:
%    \end{macrocode}
% \end{macro}
% \end{environment}
%
% \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
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\newcommand*{\Describe@Option}[1]
 {
  \endgroup
  \marginpar{
    \raggedleft
    \PrintDescribeEnv{#1}
  }
  \SpecialOptionIndex{#1}
  \@esphack
  \ignorespaces
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\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}
\cs_set_nopar:Npn \AlsoImplementation
 {
  \bool_set_true:N \g_@@_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_@@_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}
\cs_set:Npn \DocInput #1
 {
  \clist_map_inline:nn {#1}
   {
    \clist_put_right:Nn \g_docinput_clist {##1}
    \tl_gclear:N \g_@@_module_name_tl
    \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
    \tl_gclear:N \g_@@_module_name_tl
    \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 \int_use:N \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}
\iow_new:N \g_@@_func_iow
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_show_functions_defined:
 {
  \bool_if:nT { \g_@@_implementation_bool && \g_@@_checkfunc_bool }
   {
    \typeout{ ======================================== ^^J }
    \iow_open:Nn \g_@@_func_iow { \c_job_name_tl .cmds }

    \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_@@_func_iow { > ~ ##1 }
       }
     }

    \@@_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 }
        \iow_now:Nn \g_@@_func_iow { ! ~ ##1}
       }
     }
    \@@_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 }
        \iow_now:Nn \g_@@_func_iow { ? ~ ##1}
       }
     }
    \@@_functions_typeout:n { Functions~defined~but~not~documented: }

    \iow_close:N \g_@@_func_iow
    \typeout{ ======================================== }
  }
}
\AtEndDocument{ \@@_show_functions_defined: }
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_set_nopar:Npn \@@_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 \@@_show_not_tested:
 {
  \bool_if:NT \g_@@_checktest_bool
   {
    \bool_if:nT { !(\seq_if_empty_p:N  \g_@@_not_tested_seq) ||
                  !(\prop_if_empty_p:N \g_@@_missing_tests_prop) }
     {
      \tl_clear:N \l_@@_tmpa_tl
      \prop_if_empty:NF \g_@@_missing_tests_prop
       {
        \tl_put_right:Nn \l_@@_tmpa_tl
         {
          ^^J^^JThe~ following~ macro(s)~ have~ incomplete~ tests:^^J
         }
        \prop_map_inline:Nn \g_@@_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_@@_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_@@_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{ \@@_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}{\@@_special_main_index:n,\@@_special_main_index:o, \@@_special_main_index:x}
% Heiko's replacement to play nicely with |hypdoc|:
%    \begin{macrocode}

\cs_set_nopar:Npn \@@_special_main_index:n #1
 {
  \HD@target
  \index
   {
    \@gobble#1
    \actualchar
    \string\verb\quotechar*\verbatimchar#1\verbatimchar
    \encapchar
    hdclindex{\the\c@HD@hypercount}{usage}
   }
 }
\cs_generate_variant:Nn \@@_special_main_index:n { o , x }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\msg_new:nnn {l3doc} {print-index-howto}
 {
  Generate~the~index~by~executing\\
  \iow_indent:n { makeindex~-s~l3doc.ist~-o~\c_job_name_tl .ind~\c_job_name_tl .idx }
 }
\tl_gput_right:Nn \PrintIndex { \AtEndDocument{ \msg_info:nn {l3doc} {print-index-howto} } }
%    \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}
\msg_new:nnn {l3doc} {print-changes-howto}
 {
  Generate~the~change~list~by~executing\\
  \iow_indent:n { makeindex~-s~gglo.ist~-o~\c_job_name_tl .gls~\c_job_name_tl .glo }
 }
\tl_gput_right:Nn \PrintChanges { \AtEndDocument{ \msg_info:nn {l3doc} {print-changes-howto} } }
%    \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{Default configuration}
%
%    \begin{macrocode}
\bool_if:NTF \g_@@_full_bool
 {
  \RecordChanges
  \CodelineIndex
  \EnableCrossrefs
  \AlsoImplementation
 }
 {
  \CodelineNumbered
  \DisableCrossrefs
  \OnlyDescription
 }
%    \end{macrocode}
%
%
%    \begin{macrocode}
%</class>
%    \end{macrocode}
%
% \subsection{Internal macros for \LaTeX3 sources}
%
% These definitions are only used by the \LaTeX3 documentation;
% they are not necessary for third-party users of l3doc.
% In time this will be broken into a separate package that is specifically
% loaded in the various expl3 modules, etc.
%
%    \begin{macrocode}
%<*cfg>
%    \end{macrocode}
%
% The Guilty Parties.
%    \begin{macrocode}
\tl_new:N \Team
\tl_set:Nn \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,~Bruno~Le~Floch
   }
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\NewDocumentCommand{\ExplMakeTitle}{mm}
 {
  \title
   {
    The~\pkg{#1}~package \\ #2
    \thanks
     {
      This~file~describes~v\ExplFileVersion,~
      last~revised~\ExplFileDate.
     }
   }
   \author
    {
     The~\LaTeX3~Project\thanks{E-mail:~
     \href{mailto:latex-l@listserv.uni-heidelberg.de}
          {latex-l@listserv.uni-heidelberg.de}}
    }
   \date{Released~\ExplFileDate}
   \maketitle
 }
%    \end{macrocode}
%
% \subsection{Text extras}
%
%    \begin{macrocode}
\DeclareDocumentCommand\ie{}{\emph{i.e.}}
\DeclareDocumentCommand\eg{}{\emph{e.g.}}
\DeclareDocumentCommand\Ie{}{\emph{I.e.}}
\DeclareDocumentCommand\Eg{}{\emph{E.g.}}
%    \end{macrocode}
%
% \subsection{Math extras}
%
% For \pkg{l3fp}.
% 
%    \begin{macrocode}
\AtBeginDocument
 {
  \clist_map_inline:nn
   {
    asin, acos, atan, acot,
    asinh, acosh, atanh, acoth, round, floor, ceil
   }
   { \exp_args:Nc \DeclareMathOperator{#1}{#1} }
 }
%    \end{macrocode}
%    
% \begin{macro}{\nan}
%    \begin{macrocode}
\NewDocumentCommand { \nan } { } { \text { \texttt { nan } } }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</cfg>
%    \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}
%
% \begin{function}{foo}
% \begin{syntax}
% "\foo" <something_n> \Arg{something_1}
% \end{syntax}
% Does <something_1> with <something_n>
% \end{function}
%
% \begin{function}{.bool_set:N}
% blah
% \end{function}
%
% \ExplSyntaxOn \cs_set_eq:NN \c_alignment_token @ \ExplSyntaxOff
% \begin{variabledoc}
%   {
%     \c_alignment_token,
%   }
% \end{variabledoc}
% \ExplSyntaxOn \cs_set_eq:NN \c_alignment_token & \ExplSyntaxOff
%
% \begin{function}[added=2011-09-06]{\example_foo:N,\example_foo:c}
% \begin{syntax}
%   "\example_foo:N" <arg_1>
%   "\example_foo:c" \Arg{arg_1}
% \end{syntax}
% <0123456789>
% \end{function}
%
% \begin{function}[added=2011-09-06]{ \foo , \fooo: , \foooo:n , \foooo:x , \fooooo:n , \fooooo:c , \fooooo:x }
% \begin{syntax}
%   "\example_foo:N" <arg_1>
% \end{syntax}
% <0123456789>
% \end{function}
%
% \begin{function}[TF]{\foo:N , \foo_if:c }
% Test.
% \end{function}
% \begin{function}[TF,EXP]{\foo:N  , \foo_if:c }
% Test.
% \end{function}
%
% \begin{function}[added=2011-09-06,EXP]{\fffoo:N}
% Test.
% \end{function}
% \begin{function}[added=2011-09-06,updated=2011-09-07,EXP]{\fffoo:N}
% Test.
% \end{function}
% \begin{function}[updated=2011-09-06,EXP]{\fffoo:N}
% Test.
% \end{function}
% \begin{function}[TF]{\ffffoo:N}
% Test.
% \end{function}
% \begin{function}[pTF]{\ffoo:N}
% \lipsum[6]
% \end{function}
% \begin{function}[pTF]{\ffoo:N,\ffoo:c,\ffoo:V}
% \lipsum[6]
% \end{function}
% \begin{function}[pTF]{\ffoo:N,\ffoo:c}
% \lipsum[6]
% \end{function}
%
%
% \begin{function}[TF]{\ffffoo_with_very_very_very_long_name:N}
% \lipsum[1]
% \end{function}
%
% \begin{function}[TF]{\ffffoo_with_very_very_very_long_name:N,\ffffoo_with_very_very_very_long_name:c,\ffffoo_with_very_very_very_long_name:V}
% \lipsum[1]
% \end{function}
%
% \begin{function}[TF]{\ffffoo_with_very_very_very_long_name:N,\ffffoo_with_very_very_very_long_name:c,\ffffoo_with_very_very_very_long_name:V}
% \begin{syntax}
% this is how you use it
% \end{syntax}
% \lipsum[1]
% \end{function}
%
% \begin{function}[TF]{\ffffoo_with_very_very_very_long_name:N,\ffffoo_with_very_very_very_long_name:V}
% \begin{syntax}
% this is how you use it
% \end{syntax}
% \lipsum[1]
% \end{function}
%
% \bigskip\bigskip
%
% \begin{macro}[aux]{ \foo_aux: }
% Testing `aux' option.
% \end{macro}
%
% \begin{macro}[TF]{ \foo_if:c }
% Testing `TF' option.
% \end{macro}
% \begin{macro}[TF]{ \foo_if:c, \fooo_if:n }
% Testing `TF' option.
% \end{macro}
%
% \begin{macro}[pTF]{ \foo_if:d }
% Testing `pTF' option.
% \end{macro}
%
% \begin{macro}[internal]{ \test_internal: }
% Testing `internal' option.
% \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{function}{\::N}
% this is (no longer) weird
% \end{function}
%
% \begin{macro}{\::N}
% this is (no longer) weird
% \end{macro}
%
%
%
% \begin{function}[EXP]{\foo}\end{function}
% \begin{function}[rEXP]{\foo}\end{function}
%
% here is some verbatim text:
% \begin{verbatim}
% a & B # c
% \end{verbatim}
% without overriding this with fancyvrb there would be extraneous whitespace.
%
% \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}
%
%
%
%
% \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
