diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3doc.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3doc.dtx | 4799 |
1 files changed, 2923 insertions, 1876 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 34acef1916e..b781ba9d199 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -64,8 +64,8 @@ Do not distribute a modified version of this file. \fi %</driver> % -% Need to protect the file metadata for any modules that load l3doc. -% This is restored after "\ProvideExplClass" below. +% Need to protect the file metadata for any modules that load +% \cls{l3doc}. This is restored after \cs{ProvideExplClass} below. % \begin{macrocode} %<class>\let \filenameOld \ExplFileName %<class>\let \filedateOld \ExplFileDate @@ -75,10 +75,7 @@ Do not distribute a modified version of this file. % %<*driver|class> \RequirePackage{expl3,xparse,calc} -%</driver|class> -% -%<*driver|class> -\GetIdInfo$Id: l3doc.dtx 5204 2014-07-15 09:56:33Z mittelba $ +\GetIdInfo$Id: l3doc.dtx 5353 2014-08-23 01:23:51Z bruno $ {L3 Experimental documentation class} %</driver|class> % @@ -92,7 +89,8 @@ Do not distribute a modified version of this file. \end{document} %</driver> % -% This isn't included in the typeset documentation because it's a bit ugly: +% This isn't included in the typeset documentation because it's a bit +% ugly: %<*class> \ProvidesExplClass {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -103,7 +101,7 @@ Do not distribute a modified version of this file. %</class> % \fi % -% \title{The \pkg{l3doc} class\thanks{This file +% \title{The \cls{l3doc} class\thanks{This file % has version number v\ExplFileVersion, last % revised \ExplFileDate.}} % \author{\Team} @@ -116,106 +114,105 @@ Do not distribute a modified version of this file. % % \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. +% 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 \cls{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!} +% \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. +% It is written as a \enquote{self-contained} docstrip file: executing +% |latex l3doc.dtx| will generate the \file{l3doc.cls} file and typeset +% this documentation; execute |tex l3doc.dtx| to only generate +% \file{l3doc.cls}. % % \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 +% 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}. +% 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.) +% 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. (\emph{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. +% \item Provides \cs{DescribeRoutine} and the \env{routine} +% environment (\emph{etc.}) for MetaFont and MetaPost code. +% \item Provides \cs{DescribeVariable} and the \env{variable} +% environment (\emph{etc.}) for more general code. +% \item Provides \cs{Describe} and the \env{Code} environment +% (\emph{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. +% \item Two-sided printing. +% \item \cs{NewMacroEnvironment}, \cs{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. +% \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 +% (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! +% The \env{macro} should probably be renamed to \env{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). +% Furthermore, we need another \enquote{layer} of documentation commands +% to account for \enquote{user-macro} as opposed to +% \enquote{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}. +% \item Rename \env{function}/\env{macro} environments to better +% describe their use. +% \item Generalise \env{function}/\env{macro} for documenting +% \enquote{other things}, such as environment names, package +% options, even keyval options. +% \item New function like \tn{part} but for files (remove awkward +% \enquote{File} as \tn{partname}). +% \item Something better to replace \cs{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{Documentation} @@ -223,30 +220,32 @@ Do not distribute a modified version of this file. % \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. +% file \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 +% For example, to produce documentation on letter-sized paper instead of +% the default A4 size, create \file{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|. +% 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. +% \pkg{doc} uses the \cs{OnlyDocumentation}/\cs{AlsoImplementation} +% macros to guide the use of \cs{StopEventually}|{}|, which is intended +% to be placed to partition the documentation and implementation within +% a single \file{.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: -% +% to print the documentation. For the \pkg{expl3} sources, I wanted to +% be be able to input \file{.dtx} files in two modes: only displaying +% the documentation, and only displaying the implementation. For +% example: % \begin{verbatim} % \DisableImplementation % \DocInput{l3basics,l3prg,...} @@ -256,139 +255,237 @@ Do not distribute a modified version of this file. % \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. +% 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 +% \cs{EnableDocumentation}/\cs{EnableImplementation} will cause them to +% be typeset when the \file{.dtx} file is \cs{DocInput}; use +% \cs{DisableDocumentation}/\cs{DisableImplementation} to omit the +% contents of those environments. +% +% Note that \cs{DocInput} now takes comma-separated arguments, and +% \cs{DocInputAgain} can be used to re-input all \file{.dtx} files +% previously input in this way. +% +% \subsection{General text markup} +% +% Many of the commands in this section come from \pkg{ltxdoc} with some +% improvements. +% +% \begin{function}{\cmd, \cs} +% \begin{syntax} +% \cmd{\cmd} \oarg{options} \meta{control sequence}\\ +% \cs{cs} \oarg{options} \marg{csname} +% \end{syntax} +% These commands are provided to typeset control sequences. +% |\cmd\foo| produces \enquote{\cmd\foo} and |\cs{foo}| produces the +% same (\enquote{\cs{foo}}). In general, \cs{cs} is more robust since +% it doesn't rely on catcodes being \enquote{correct} and is therefore +% recommended. +% +% These commands are aware of the |@@| \pkg{l3docstrip} syntax and +% will replace such instances correctly in the typeset documentation. +% This only happens after a |%<@@=|\meta{module}|>| declaration. +% +% Additionally, commands can be used in the argument of \cs{cs}. For +% instance, |\cs{\meta{name}:\meta{signature}}| produces +% \cs{\meta{name}:\meta{signature}}. +% +% The \meta{options} are a key--value list which can contain the +% following keys: +% \begin{itemize} +% \item |index=|\meta{module}: the \meta{csname} will be indexed in +% the list of commands from the \meta{module}; the \meta{module} +% can in particular be |TeX| for \enquote{\TeX{} and \LaTeXe{}} +% commands, or empty for commands which should be placed in the +% main index. By default, the \meta{module} is deduced +% automatically from the command name. +% \item |replace| is a boolean key (\texttt{true} by default) which +% indicates whether to replace |@@| as \pkg{l3docstrip} does. +% \end{itemize} +% \end{function} +% +% \begin{function}{\tn} +% \begin{syntax} +% \cs{tn} \oarg{options} \marg{csname} +% \end{syntax} +% Analoguous to \cs{cs} but intended for \enquote{traditional} \TeX{} +% or \LaTeXe{} commands; they will be indexed accordingly. This is in +% fact equivalent to \cs{cs} |[index=TeX, replace=false,| +% \meta{options}|]| \Arg{csname}. +% \end{function} % -% 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. +% \begin{function}{\meta} +% \begin{syntax} +% \cs{meta} \Arg{name} +% \end{syntax} +% \cs{meta} typesets the \meta{name} italicised in \meta{angle +% brackets}. Within a \env{function} environment or similar, angle +% brackets |<...>| are set up to be a shorthand for |\meta{...}|. +% +% This function has additional functionality over its \pkg{ltxdoc} +% versions; underscores can be used to subscript material as in math +% mode. For example, |\meta{arg_{xy}}| produces +% \enquote{\meta{arg_{xy}}}. +% \end{function} % -% Note that "\DocInput" now takes comma-separated arguments, and "\DocInputAgain" -% can be used to re-input all DTX files previously input in this way. +% \begin{function}{\Arg, \marg, \oarg, \parg} +% \begin{syntax} +% |\Arg| \Arg{name} +% \end{syntax} +% Typesets the \meta{name} as for \cs{meta} and wraps it in braces. +% +% The \cs{marg}/\cs{oarg}/\cs{parg} versions follow from \pkg{ltxdoc} +% in being used for \enquote{mandatory} or \enquote{optional} or +% \enquote{picture} brackets as per \LaTeXe{} syntax. +% \end{function} +% +% \begin{function}{\file, \env, \pkg, \cls} +% \begin{syntax} +% \cs{pkg} \Arg{name} +% \end{syntax} +% These all take one argument and are intended to be used as semantic +% commands for representing files, environments, package names, and +% class names, respectively. +% \end{function} % % \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. +% Two heavily-used environments are defined to describe the syntax of +% \pkg{expl3} functions and variables. % \begin{framed} -% \vspace{-\baselineskip} +% \vspace{-\baselineskip} % \begin{verbatim} -% \begin{function}{ \function_one , \function_two: } +% \begin{function}{\function_one:, \function_two:} % \begin{syntax} -% "\foo_bar:" \Arg{meta} <test_1> +% |\foo_bar:| \Arg{meta} \meta{test_1} % \end{syntax} -% <description> +% \meta{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} +% \hrulefill +% \par +% \hspace*{0.25\textwidth} +% \begin{minipage}{0.5\textwidth} +% \begin{function}{\function_one:, \function_two:} +% \begin{syntax} +% |\foo_bar:| \Arg{meta} \meta{test_1} +% \end{syntax} +% \meta{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: +% 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} +% \vspace{-\baselineskip} % \begin{verbatim} -% \begin{function}[pTF]{ \cs_if_exist:N } +% \begin{function}[pTF]{\cs_if_exist:N} % \begin{syntax} -% "\cs_if_exist_p:N" <cs> +% \cs{cs_if_exist_p:N} \meta{cs} % \end{syntax} -% <description> +% \meta{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} +% \hrulefill +% \par +% \hspace*{0.25\textwidth} +% \begin{minipage}{0.5\textwidth} +% \begin{function}[pTF]{\cs_if_exist:N} +% \begin{syntax} +% \cs{cs_if_exist_p:N} \meta{cs} +% \end{syntax} +% \meta{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. +% If you are documenting a variable instead of a function, use the +% \env{variable} environment instead; it behaves identically to the +% \env{function} environment above. +% +% \DescribeEnv{texnote} +% This environment is used to call out sections within \env{function} +% and similar that are only of interest to seasoned \TeX{} developers. % % \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. +% 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{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. +% 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 \env{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]". +% but usually will not be documented for users to see; these can be +% marked as such with |\begin{macro}[int]|. % % 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. +% 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. +% \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. +% Within a \env{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 \env{macro} environment without a call to +% \file{Testfiles}. 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. +% 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. +% When documenting variable definitions, use the \env{variable} +% environment instead. It will, here, behave identically to the +% \env{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. +% 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{macro}{\foo:nn, \foo:VV} % % \begin{arguments} % % \item Name of froozle to be frazzled % % \item Name of muble to be jubled @@ -402,14 +499,14 @@ Do not distribute a modified version of this file. % % \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. +% 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. +% At the end of the document (\emph{i.e.}, after the \file{.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 @@ -417,40 +514,40 @@ Do not distribute a modified version of this file. % % \subsection{Documenting templates} % -% The following macros are provided for documenting templates; might -% end up being something completely different but who knows. +% 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}" +% |\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}" +% |\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}" +% |\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} @@ -467,113 +564,523 @@ Do not distribute a modified version of this file. %<@@=codedoc> % \end{macrocode} % +% \subsection{Variants and helpers} +% +% \begin{macro} +% { +% \tl_count:f, +% \tl_greplace_all:Nxn, +% \tl_if_head_eq_charcode:oNTF, +% \tl_if_head_eq_charcode:oNT, +% \tl_if_head_eq_charcode:oNF, +% \tl_if_in:NoTF, +% \tl_if_in:NoT, +% \tl_if_in:NoF, +% \tl_remove_all:Nx, +% \tl_replace_all:Nxn, +% \tl_replace_all:Nnx, +% \tl_replace_all:Non, +% \tl_replace_all:Nno, +% \tl_replace_once:Noo, +% \prop_get:NxNTF, +% \prop_put:Nxn, +% \prop_gput:NVx, +% } +% A few missing variants. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_count:n { f } +\cs_generate_variant:Nn \tl_greplace_all:Nnn { Nx } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { o } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { o } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { o } +\cs_generate_variant:Nn \tl_if_in:NnTF { No } +\cs_generate_variant:Nn \tl_if_in:NnT { No } +\cs_generate_variant:Nn \tl_if_in:NnF { No } +\cs_generate_variant:Nn \tl_remove_all:Nn { Nx } +\cs_generate_variant:Nn \tl_replace_all:Nnn { Nx , Nnx, No , Nno } +\cs_generate_variant:Nn \tl_replace_once:Nnn { Noo } +\cs_generate_variant:Nn \prop_get:NnNTF { Nx } +\cs_generate_variant:Nn \prop_put:Nnn { Nx } +\cs_generate_variant:Nn \prop_gput:Nnn { NVx } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_replace_at_at:N} +% \begin{macro}[aux]{\@@_replace_at_at_aux:Nn} +% If there is no \meta{module~name}, do nothing. Otherwise replace +% all other-|@| by letter-|@| and all other-|_| by letter-|_|, then +% replace |_@@| by |__|\meta{module~name} and |@@| by +% |__|\meta{module~name} too. The result contains |_| with category +% code letter because this is what the |macrocode| environment +% expects. Other use cases can apply \cs{tl_to_str:n} if needed. +% Note that we include spaces between the +% |@| in the code below, since it is also processed through the same +% replacement rules. +% \begin{macrocode} +\cs_new_protected:Npn \@@_replace_at_at:N #1 + { + \tl_if_empty:NF \g_@@_module_name_tl + { + \exp_args:NNo \@@_replace_at_at_aux:Nn + #1 \g_@@_module_name_tl + } + } +\cs_new_protected:Npn \@@_replace_at_at_aux:Nn #1#2 + { + \tl_replace_all:Non #1 { \token_to_str:N @ } { @ } + \tl_replace_all:Non #1 { \token_to_str:N _ } { _ } + \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 } + \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\@@_verb_get_seq:nN} +% The argument~|#1| is given with catcodes $10$ (space), $12$ (other) +% and $13$ (active). Turn active characters to other. Remove any +% \enquote{\%} character at the beginning of a line. Remove tabs and +% newlines. Finally, convert |_@@| and |@@| to |__|\meta{module name} +% (if it is non-empty). At this point, \cs{l_@@_tmpa_tl} contains a +% comma-delimited list of names, where |@| and~|_| have category code +% letter. Turn it to a string, parse it as a comma-delimited list, +% and turn the result into a sequence of function/macro names. +% \begin{macrocode} +\cs_new_protected:Npn \@@_verb_get_seq:nN #1#2 + { + \tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} } + \tl_remove_all:Nx \l_@@_tmpa_tl + { \iow_char:N \^^M \iow_char:N \% } + \tl_remove_all:Nx \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } } + \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^I } + \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^M } + \@@_replace_at_at:N \l_@@_tmpa_tl + \exp_args:NNx \seq_set_from_clist:Nn #2 + { \tl_to_str:N \l_@@_tmpa_tl } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux,rEXP] +% {\@@_signature_base_form:n, \@@_signature_base_form_aux:n} +% Expands to the \enquote{base form} of the signature. For instance, +% given |noxcfvV| it would obtain |nnnNnnn|, or given |ow| it would +% obtain |nw|. The loop stops at the first token that is not +% recognized. +% \begin{macrocode} +\cs_new:Npn \@@_signature_base_form:n #1 + { \@@_signature_base_form_aux:n #1 \c_empty_tl } +\cs_new:Npn \@@_signature_base_form_aux:n #1 + { + \str_case:nnTF {#1} + { + { N } { N } + { c } { N } + { n } { n } + { o } { n } + { f } { n } + { x } { n } + { V } { n } + { v } { n } + } + { \@@_signature_base_form_aux:n } + {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_predicate_from_base:N} +% Get predicate from a function's base name. This \enquote{works} for +% functions with no signature too. +% \begin{macrocode} +\cs_new:Npn \@@_predicate_from_base:N #1 + { + \__cs_get_function_name:N #1 _p: + \__cs_get_function_signature:N #1 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CodedocUseCs} +% To implement commands which can be used in bookmarks and moving +% arguments, it appears necessary to have an analogue of \cs{use:c} +% using only user-level category codes, or to make all auxiliaries +% user-level. +% \begin{macrocode} +\cs_new_protected:Npn \CodedocUseCs #1 { \use:c { \tl_to_str:n {#1} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\CodedocUnexpandedTokens} +% \begin{macro}[aux]{\CodedocUnexpandedTokens } +% \begin{macro}[aux]{\@@_exp_not:n} +% Function used as \cs{CodedocUnexpandedTokens} \meta{junk} +% \Arg{argument}. The braces are necessary, and \meta{junk}, ignored, +% must not contain braces. When used in a typesetting context, the +% function calls an auxiliary (whose name has a trailing space) which +% leaves the \meta{argument} in the input stream. When used in an +% \texttt{x}-expansion context instead, the auxiliary does not expand, +% and \cs{@@_exp_not:n} \Arg{argument} expands to itself. If this is +% written into a file and read back, the result has the original form +% \cs{CodedocUnexpandedTokens} \meta{junk} \Arg{argument}. +% \begin{macrocode} +\cs_new:Npn \CodedocUnexpandedTokens #1 # + { \use:c { CodedocUnexpandedTokens ~ } \@@_exp_not:n } +\cs_new_protected:cpn { CodedocUnexpandedTokens ~ } #1#2 {#2} +\cs_new:Npn \@@_exp_not:n #1 { \exp_not:n { \@@_exp_not:n {#1} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Variables} % +% \begin{variable}{\g_docinput_clist} +% The list of files which have been input through \cs{DocInput}. +% \begin{macrocode} +\clist_new:N \g_docinput_clist +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_doc_functions_seq, \g_doc_macros_seq} +% All functions documented through \env{function}, and all macros +% introduced through \env{macro}. They can be compared to see what +% documentation or code is missing. +% \begin{macrocode} +\seq_new:N \g_doc_functions_seq +\seq_new:N \g_doc_macros_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\l_@@_output_coffin} +% The \env{function} environment is typeset by combining coffins +% containing various pieces (function names, description, \emph{etc.}) +% into this coffin. +% \begin{macrocode} +\coffin_new:N \l_@@_output_coffin +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int] +% {\l_@@_names_coffin, \l_@@_descr_coffin, \l_@@_syntax_coffin} +% These coffins contain respectively the list of function names +% (argument of the \env{function} environment), the text between +% |\begin{function}| and |\end{function}|, and the syntax given in the +% \env{syntax} environment. % \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 +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\g_@@_syntax_box} +% The contents of the \env{syntax} environment are typeset in this box +% before being transferred to \cs{l_@@_syntax_coffin}. +% \begin{macrocode} \box_new:N \g_@@_syntax_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\l_@@_long_name_bool, \l_@@_trial_width_dim} +% The boolean \cs{l_@@_long_name_bool} is \texttt{true} if the width +% \cs{l_@@_trial_width_dim} of the coffin \cs{l_@@_names_coffin} +% (containing the current function names) is bigger than the space +% available in the margin. +% \begin{macrocode} \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} +% \end{variable} % +% \begin{variable}[int]{\l_@@_nested_macro_int} +% The nesting of \env{macro} environments (this is now~$0$ outside a +% \env{macro} environment). % \begin{macrocode} -\seq_new:N \g_@@_testfiles_seq -\seq_new:N \g_doc_functions_seq -\seq_new:N \g_doc_macros_seq +\int_new:N \l_@@_nested_macro_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int] +% { +% \l_@@_macro_tested_bool, +% \g_@@_missing_tests_prop, +% \g_@@_not_tested_seq, +% \g_@@_testfiles_seq, +% } +% A boolean describing whether the current macro has tests, and some +% global structures which contain information about test files and +% which tests are missing. +% \begin{macrocode} +\bool_new:N \l_@@_macro_tested_bool +\prop_new:N \g_@@_missing_tests_prop \seq_new:N \g_@@_not_tested_seq +\seq_new:N \g_@@_testfiles_seq % \end{macrocode} +% \end{variable} % -% For function/macro environments: +% \begin{variable}[aux] +% { +% \l_@@_macro_internal_bool, +% \l_@@_macro_aux_bool, +% \l_@@_macro_TF_bool, +% \l_@@_macro_pTF_bool, +% \l_@@_macro_EXP_bool, +% \l_@@_macro_rEXP_bool, +% \l_@@_macro_var_bool, +% } +% Contain information about some options of 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_EXP_bool +\bool_new:N \l_@@_macro_rEXP_bool \bool_new:N \l_@@_macro_var_bool % \end{macrocode} +% \end{variable} % -% For package options: +% \begin{variable}[aux] +% { +% \g_@@_lmodern_bool, +% \g_@@_checkfunc_bool, +% \g_@@_checktest_bool, +% } +% Information about 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} +% \end{variable} % -% Temporaries: +% \begin{variable}[int]{\l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpa_int} +% Some temporary variables. % \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} +% \end{variable} % -% Other: +% \begin{variable}[int]{\l_@@_functions_block_prop} +% Contains information about the functions to typeset and their +% variants. % \begin{macrocode} -\bool_new:N \l_@@_tested_bool +\prop_new:N \l_@@_functions_block_prop % \end{macrocode} +% \end{variable} % +% \begin{variable}[int]{\l_@@_function_input_seq, \l_@@_macro_input_seq} +% Both the \env{function} and the \env{macro} environments read their +% argument verbatim, then remove percent signs (at the beginning of +% lines), tabs and new lines, convert |_@@| and |@@| by +% |__|\meta{module name} if appropriate, and interpret the result as a +% comma list, which they store in these two sequences. +% \begin{macrocode} +\seq_new:N \l_@@_function_input_seq +\seq_new:N \l_@@_macro_input_seq +% \end{macrocode} +% \end{variable} % +% \begin{variable}[int]{\c_@@_backslash_tl, \c_@@_backslash_token} +% A single backslash, as a token list, or as an implicit character +% token. +% \begin{macrocode} +\tl_const:Nx \c_@@_backslash_tl { \iow_char:N \\ } +\exp_last_unbraced:NNo + \cs_new_eq:NN \c_@@_backslash_token { \c_@@_backslash_tl } +% \end{macrocode} +% \end{variable} % -% \subsection{Options and configuration} +% \begin{variable}[int]{\g_@@_function_name_prefix_tl} +% The \enquote{prefix} of the current function is a backslash if the +% function starts with it, and otherwise is empty. +% \begin{macrocode} +\tl_new:N \g_@@_function_name_prefix_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% {\l_@@_index_macro_tl, \l_@@_index_key_tl, \l_@@_index_module_tl} +% When analyzing a control sequence found within a \env{macrocode} +% environment, \cs{l_@@_index_macro_tl} holds the control sequence +% (partially a string), \cs{l_@@_index_key_tl} holds what will be used +% as a sort key in the index, and \cs{l_@@_index_module_tl} is the +% subindex in which the control sequence will be listed. +% \begin{macrocode} +\tl_new:N \l_@@_index_macro_tl +\tl_new:N \l_@@_index_key_tl +\tl_new:N \l_@@_index_module_tl +% \end{macrocode} +% \end{variable} % +% \begin{variable}{\g_@@_module_name_tl} +% The module name, set when reading a line |<@@=|\meta{module}|>|. % \begin{macrocode} -\DeclareOption{a5paper}{\@latexerr{Option not supported}{}} +\tl_new:N \g_@@_module_name_tl % \end{macrocode} +% \end{variable} % +% \begin{variable}{\c_@@_iow_rule_tl, \c_@@_iow_midrule_tl} +% $40$~equal signs. +% \begin{macrocode} +\tl_const:Nn \c_@@_iow_rule_tl + { ======================================== } +\tl_const:Nn \c_@@_iow_mid_rule_tl + { -------------------------------------- } +% \end{macrocode} +% \end{variable} % +% \begin{variable} +% {\l_@@_macro_box, \l_@@_macro_index_box, \l_@@_macro_int} +% A vertical box in which the names given to the macro environment are +% typeset, a horizontal box in which we store the targets created by +% indexing commands, and the number of macros so far (including those +% from surrounding \env{macro} environments). % \begin{macrocode} -\DeclareOption{full}{ \bool_set_true:N \g_@@_full_bool } -\DeclareOption{onlydoc}{ \bool_set_false:N \g_@@_full_bool } +\box_new:N \l_@@_macro_index_box +\box_new:N \l_@@_macro_box +\int_new:N \l_@@_macro_int % \end{macrocode} +% \end{variable} % +% \begin{variable}[int] +% { +% \l_@@_cmd_tl, +% \l_@@_cmd_index_tl, +% \l_@@_cmd_replace_bool, +% } +% Variables used to control the behaviour of \cs{cmd}, \cs{cs} and +% \cs{tn}. % \begin{macrocode} -\DeclareOption{check}{ \bool_set_true:N \g_@@_checkfunc_bool } -\DeclareOption{nocheck}{ \bool_set_false:N \g_@@_checkfunc_bool } +\tl_new:N \l_@@_cmd_tl +\tl_new:N \l_@@_cmd_index_tl +\bool_new:N \l_@@_cmd_replace_bool % \end{macrocode} +% \end{variable} % +% \begin{variable}{\l_@@_in_implementation_bool} +% This boolean is \texttt{true} within the \env{implementation} +% environment, and \texttt{false} anywhere else. % \begin{macrocode} -\DeclareOption{checktest}{ \bool_set_true:N \g_@@_checktest_bool } -\DeclareOption{nochecktest}{ \bool_set_false:N \g_@@_checktest_bool } +\bool_new:N \l_@@_in_implementation_bool % \end{macrocode} +% \end{variable} % +% \begin{variable} +% { +% \g_@@_typeset_documentation_bool, +% \g_@@_typeset_implementation_bool +% } +% These booleans control whether the documentation/implementation +% should be typeset. By default both should be. % \begin{macrocode} -\DeclareOption{cm-default}{ \bool_set_false:N \g_@@_lmodern_bool } -\DeclareOption{lm-default}{ \bool_set_true:N \g_@@_lmodern_bool } +\bool_new:N \g_@@_typeset_documentation_bool +\bool_new:N \g_@@_typeset_implementation_bool +\bool_set_true:N \g_@@_typeset_documentation_bool +\bool_set_true:N \g_@@_typeset_implementation_bool % \end{macrocode} +% \end{variable} % +% \begin{variable}{\g_@@_base_name_tl, \l_@@_variants_prop} +% The name of the macro which is being documented (without its +% signature), and a property list mapping base forms of variants to +% all variants which have the same base form. % \begin{macrocode} -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -\ExecuteOptions{full,a4paper,nocheck,nochecktest,lm-default} +\tl_new:N \g_@@_base_name_tl +\prop_new:N \l_@@_variants_prop % \end{macrocode} +% \end{variable} % -% 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{variable}[int]{\l_@@_no_label_bool} +% This boolean prevents the insertions of \tn{label}s in a +% \env{function} environment. This is only useful when a function's +% documentation appears multiple times, for instance in +% \file{source3body.tex} some examples repeat the documentation from +% actual functions. +% \begin{macrocode} +\bool_new:N \l_@@_no_label_bool +% \end{macrocode} +% \end{variable} % +% \begin{macro}[aux]{\@@_tmpa:w, \@@_tmpb:w} +% Auxiliary macros for temporary use. % \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} - } +\cs_new_eq:NN \@@_tmpa:w ? +\cs_new_eq:NN \@@_tmpb:w ? +% \end{macrocode} +% \end{macro} +% +% Bruno: can I delete this next line? +% \begin{macrocode} +% \int_new:N \c@CodelineNo +% \end{macrocode} +% +% \subsection{Options and configuration} +% +% \begin{macrocode} +\DeclareOption { a5paper } { \@latexerr { Option~not~supported } { } } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption { full } + { + \bool_gset_true:N \g_@@_typeset_documentation_bool + \bool_gset_true:N \g_@@_typeset_implementation_bool + } +\DeclareOption { onlydoc } + { + \bool_gset_true:N \g_@@_typeset_documentation_bool + \bool_gset_false:N \g_@@_typeset_implementation_bool + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption { check } + { \bool_gset_true:N \g_@@_checkfunc_bool } +\DeclareOption { nocheck } + { \bool_gset_false:N \g_@@_checkfunc_bool } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption { checktest } + { \bool_gset_true:N \g_@@_checktest_bool } +\DeclareOption { nochecktest } + { \bool_gset_false:N \g_@@_checktest_bool } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption { cm-default } + { \bool_gset_false:N \g_@@_lmodern_bool } +\DeclareOption { lm-default } + { \bool_gset_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 \file{.cfg} file +% with the class, this should usually always be true. Therefore, check +% for \cs{ExplMakeTitle} (defined in \enquote{our} \file{.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:nT { l3doc.cfg } + { + \cs_if_exist:cF { ExplMakeTitle } + { \msg_info:nn { l3doc } { input-cfg } } + } + } % \end{macrocode} % % \begin{macrocode} @@ -609,29 +1116,19 @@ Do not distribute a modified version of this file. \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} -% +% Depending on the option, load the package \pkg{lmodern} to set the +% font. Then replace the italic typewriter font with the oblique shape +% instead; the former makes my skin crawl. (Will, Aug 2011) % \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: - } + { + \RequirePackage[T1]{fontenc} + \RequirePackage{lmodern} + \group_begin: + \ttfamily + \DeclareFontShape{T1}{lmtt}{m}{it}{<->ec-lmtto10}{} + \group_end: + } % \end{macrocode} % % Must be last, as usual. @@ -639,91 +1136,128 @@ Do not distribute a modified version of this file. \RequirePackage{hypdoc} % \end{macrocode} % -% \subsection{Configuration} +% \subsection{Configuration and tweaks} % % \begin{macro}{\MakePrivateLetters} +% A few more letters are \enquote{private} in a \LaTeX3 programming +% environment. % \begin{macrocode} -\cs_set_nopar:Npn \MakePrivateLetters - { - \char_set_catcode_letter:N \@ - \char_set_catcode_letter:N \_ - \char_set_catcode_letter:N \: - } +\cs_gset_nopar:Npn \MakePrivateLetters + { + \char_set_catcode_letter:N \@ + \char_set_catcode_letter:N \_ + \char_set_catcode_letter:N \: + } % \end{macrocode} % \end{macro} % +% \begin{macro}{CodelineNo} +% Some configurations which have to do with line numbering. % \begin{macrocode} \setcounter{StandardModuleDepth}{1} \@addtoreset{CodelineNo}{part} \tl_replace_once:Nnn \theCodelineNo - { \HDorg@theCodelineNo } - { \textcolor[gray]{0.5} { \sffamily\tiny\arabic{CodelineNo} } } + { \HDorg@theCodelineNo } + { \textcolor[gray]{0.5} { \sffamily\tiny\arabic{CodelineNo} } } % \end{macrocode} +% \end{macro} % -% +% \begin{macro}{\verbatim, \endverbatim} +% In \file{.dtx} documents, the \env{verbatim} environment adds extra +% space because it only removes the first \enquote{\%} sign, and not +% the indentation (typically a space). Fix it with \pkg{fancyvrb}: +% \begin{macrocode} +\fvset{gobble=2} +\cs_gset_eq:NN \verbatim \Verbatim +\cs_gset_eq:NN \endverbatim \endVerbatim +% \end{macrocode} +% \end{macro} % % \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. +% 72~columns of code may appear in a \env{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.) +% (These were introduced when \cls{article} was the documentclass, but +% I've left them here for now to remind me to do something about them +% later.) % -% Customise lists: +% \begin{macro}{\list} +% \begin{macro}[aux]{\@@_oldlist:nn} +% Customise lists. % \begin{macrocode} -\cs_set_eq:NN \@@_oldlist:nn \list -\cs_set_nopar:Npn \list #1 #2 { \@@_oldlist:nn {#1} { #2 \listparindent\z@ } } +\cs_new_eq:NN \@@_oldlist:nn \list +\cs_gset_nopar:Npn \list #1 #2 + { \@@_oldlist:nn {#1} { #2 \dim_zero:N \listparindent } } \setlength \parindent { 2em } \setlength \itemindent { 0pt } \setlength \parskip { 0pt plus 3pt minus 0pt } % \end{macrocode} +% \end{macro} +% \end{macro} % -% Customise TOC (as we have so many sections). Different design and/or -% structure is called for ): +% \begin{macro}{\partname} +% Use \enquote{File} as a name in Part titles. % \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 +\tl_gset:Nn \partname {File} % \end{macrocode} +% \end{macro} % +% \begin{macro}{\l@section, \l@subsection} +% Customise the table of contents (as we have so many sections). +% Different design and/or structure is called for). +% \begin{macrocode} +\@addtoreset{section}{part} +\cs_gset_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_gset_nopar:Npn \l@subsection + { \@dottedtocline{2}{2.5em}{2.3em} } % #2 = 1.5em +% \end{macrocode} +% \end{macro} % % \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. +% Make "|" and |"| be \enquote{short verb} characters, but not in the +% document preamble, where an active character may interfere with +% packages that are loaded. Remove these short-hands at the end of the +% document before reading the \file{.aux} file, as they may appear in +% labels (for instance, \pkg{l3fp} documents an operation "||"). % \begin{macrocode} \AtBeginDocument - { - \MakeShortVerb \" - \MakeShortVerb \| - } + { + \MakeShortVerb \" + \MakeShortVerb \| + } +\AtEndDocument + { + \DeleteShortVerb \" + \DeleteShortVerb \| + } % \end{macrocode} % +% \begin{macro}{\eTeX, \IniTeX, \Lua, \LuaTeX, \pdfTeX, \XeTeX} +% Some commands for logos. % \begin{macrocode} \providecommand*\eTeX{\hologo{eTeX}} \providecommand*\IniTeX{\hologo{iniTeX}} @@ -732,1180 +1266,1379 @@ Do not distribute a modified version of this file. \providecommand*\pdfTeX{\hologo{pdfTeX}} \providecommand*\XeTeX{\hologo{XeTeX}} % \end{macrocode} +% \end{macro} % -% \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 } +% \begin{macro}{\cmd, \cs, \tn} +% To work within bookmarks, these commands must be expandable. They +% rely on a common auxiliary \cs{@@_cmd:nn} which receives as +% arguments the options and some tokens whose string representation +% starts with a backslash (to support cases such as |\cs{pkg_\ldots}|, +% we do not turn the whole argument into a string). +% \begin{macrocode} +\DeclareExpandableDocumentCommand \cmd { O{} m } + { \@@_cmd:no {#1} { \token_to_str:N #2 } } +\DeclareExpandableDocumentCommand \cs { O{} m } + { \@@_cmd:no {#1} { \c_@@_backslash_tl #2 } } +\DeclareExpandableDocumentCommand \tn { O{} m } + { + \@@_cmd:no + { index = TeX , replace = false , #1 } + { \c_@@_backslash_tl #2 } + } % \end{macrocode} +% \end{macro} % +% \begin{macro}{\meta} +% To work within a bookmark, this command must be expandable. % \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 } +\DeclareExpandableDocumentCommand { \meta } { m } + { \@@_meta:n {#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{macro}{\Arg, \marg, \oarg, \parg} +% |\marg{text}| prints \marg{text}, \enquote{mandatory argument}.\\ +% |\oarg{text}| prints \oarg{text}, \enquote{optional argument}.\\ +% |\parg{te,xt}| prints \parg{te,xt}, \enquote{picture mode argument}. +% Finally, \cs{Arg} is the same as \cs{marg}. % \begin{macrocode} -\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} } +\newcommand\Arg[1] + { \texttt{\char`\{} \meta{#1} \texttt{\char`\}} } +\providecommand\marg[1]{ \Arg{#1} } \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{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 \file {\nolinkurl} \DeclareRobustCommand \env {\texttt} \DeclareRobustCommand \pkg {\textsf} \DeclareRobustCommand \cls {\textsf} % \end{macrocode} % \end{macro} % -% \begin{environment}{texnote} +% \begin{macro}{\EnableDocumentation, \EnableImplementation} +% \begin{macro}{\DisableDocumentation, \DisableImplementation} +% Control whether to typeset the documentation/implementation or not. +% These simply set two switches. % \begin{macrocode} -\newenvironment{texnote} - { - \endgraf - \vspace{3mm} - \small\textbf{\TeX~hackers~note:} - } - { - \vspace{3mm} - } +\NewDocumentCommand \EnableDocumentation { } + { \bool_gset_true:N \g_@@_typeset_documentation_bool } +\NewDocumentCommand \EnableImplementation { } + { \bool_gset_true:N \g_@@_typeset_implementation_bool } +\NewDocumentCommand \DisableDocumentation { } + { \bool_gset_false:N \g_@@_typeset_documentation_bool } +\NewDocumentCommand \DisableImplementation { } + { \bool_gset_false:N \g_@@_typeset_implementation_bool } % \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{environment}{documentation} +% \begin{environment}{implementation} +% If the documentation/implementation should be typeset, then simply +% set the boolean \cs{l_@@_in_implementation_bool} which indicates +% whether we are within the implementation section. Otherwise use +% \cs{comment} (and a paired \cs{endcomment}). +% \begin{macrocode} +\NewDocumentEnvironment { documentation } { } + { + \bool_if:NTF \g_@@_typeset_documentation_bool + { \bool_set_false:N \l_@@_in_implementation_bool } + { \comment } + } + { \bool_if:NF \g_@@_typeset_documentation_bool { \endcomment } } +\NewDocumentEnvironment { implementation } { } + { + \bool_if:NTF \g_@@_typeset_implementation_bool + { \bool_set_true:N \l_@@_in_implementation_bool } + { \comment } + } + { \bool_if:NF \g_@@_typeset_implementation_bool { \endcomment } } +% \end{macrocode} +% \end{environment} % \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{environment}{variable} +% The \env{variable} environment behaves as a \env{function} or +% \env{macro} environment depending on the part of the document. % \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} - } - } +\DeclareDocumentEnvironment { variable } { O{} +v } + { + \bool_if:NTF \l_@@_in_implementation_bool + { \@@_macro:nnw { var , #1 } {#2} } + { \@@_function:nnw {#1} {#2} } + } + { + \bool_if:NTF \l_@@_in_implementation_bool + { \@@_macro_end: } + { \@@_function_end: } + } % \end{macrocode} -% \end{macro} +% \end{environment} % -% \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 - } +% \begin{environment}{function} +% \begin{environment}{macro} +% Environment for documenting function(s), and environment for +% documenting the implementation of a macro. +% \begin{macrocode} +\DeclareDocumentEnvironment { function } { O{} +v } + { \@@_function:nnw {#1} {#2} } + { \@@_function_end: } +\DeclareDocumentEnvironment { macro } { O{} +v } + { \@@_macro:nnw {#1} {#2} } + { \@@_macro_end: } % \end{macrocode} -% \end{macro} -% \end{macro} % \end{environment} % \end{environment} % +% \begin{environment}{syntax} +% Syntax block placed next to the list of functions to illustrate +% their use. TODO: test that the \env{syntax} environment is only +% used inside the \env{function} environment, and that it only appears +% once. +% \begin{macrocode} +\NewDocumentEnvironment { syntax } { } + { \@@_syntax:w } + { + \@@_syntax_end: + \ignorespacesafterend + } +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{texnote} +% Used to describe information destined to \TeX{} experts only. +% \begin{macrocode} +\NewDocumentEnvironment { texnote } { } + { + \endgraf + \vspace{3mm} + \small\textbf{\TeX~hackers~note:} + } + { + \vspace{3mm} + } +% \end{macrocode} +% \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 - } +% This environment is designed to be used within a \env{macro} +% environment to describe the arguments of the macro/function. +% \begin{macrocode} +\NewDocumentEnvironment { arguments } { } + { + \enumerate [ + nolistsep , + label = \texttt{\#\arabic*} ~ : , + labelsep = * , + ] + } + { + \endenumerate + } % \end{macrocode} % \end{environment} % +% \subsubsection{Implementing text markup} +% +% Keys for \cs{cmd}, \cs{cs} and \cs{tn}. % \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 = { } , - } +\keys_define:nn { l3doc/cmd } + { + index .tl_set:N = \l_@@_cmd_index_tl , + replace .bool_set:N = \l_@@_cmd_replace_bool , + } % \end{macrocode} % +% \begin{macro}[int]{\@@_cmd:nn, \@@_cmd:no} +% \begin{macro}[aux]{\@@_cmd_aux:nn} +% Within a |pdfstring|, use the second argument directly. Otherwise +% call \cs{@@_cmd_aux:nn}: the indirection through +% \cs{CodedocUnexpandedTokens} and \cs{CodedocUseCs} makes things +% work when they pass through a +% file. Apply the key--value \meta{options}~|#1| after setting some +% default values. Then (unless |replace=false|) replace |@@| in~|#2|, +% which is a bit tricky: the |_| must be given the catcode expected by +% \cs{@@_replace_at_at:N}, but should be reverted to their original +% catcode (normally active, needed for line-breaking) without +% rescanning the whole argument. Then typeset the command in +% \tn{verbatim@font}, after turning it to harmless characters if +% needed (and keeping the underscore breakable); in any case, spaces +% must be turned into \tn{@xobeysp}. Finally, produce an index entry. +% \begin{macrocode} +\cs_new:Npn \@@_cmd:nn #1#2 + { + \texorpdfstring + { + \CodedocUnexpandedTokens + { \CodedocUseCs { @@_cmd_aux:nn } {#1} {#2} } + } + {#2} + } +\cs_generate_variant:Nn \@@_cmd:nn { no } +\cs_new_protected:Npn \@@_cmd_aux:nn #1#2 + { + \bool_set_true:N \l_@@_cmd_replace_bool + \tl_set:Nn \l_@@_cmd_index_tl { \q_no_value } + \keys_set:nn { l3doc/cmd } {#1} + \tl_set:No \l_@@_cmd_tl { \token_to_str:N #2 } + \bool_if:NT \l_@@_cmd_replace_bool + { + \tl_set_rescan:Nnn \l_@@_tmpb_tl { } { _ } + \tl_replace_all:Non \l_@@_cmd_tl \l_@@_tmpb_tl { _ } + \@@_replace_at_at:N \l_@@_cmd_tl + \tl_replace_all:Nno \l_@@_cmd_tl { _ } \l_@@_tmpb_tl + } + \mode_if_math:T { \mbox } + { + \verbatim@font + \int_compare:nNnF + { \tl_count:N \l_@@_cmd_tl } + < { \tl_count:f { \tl_to_str:N \l_@@_cmd_tl } } + { + \tl_set:Nx \l_@@_cmd_tl { \tl_to_str:N \l_@@_cmd_tl } + \tl_replace_all:Non \l_@@_cmd_tl + { \token_to_str:N _ } { \_ } + } + \tl_replace_all:Nnn \l_@@_cmd_tl { ~ } { \@xobeysp } + \l_@@_cmd_tl + } + \exp_args:No \@@_key_get:n { \l_@@_cmd_tl } + \quark_if_no_value:NF \l_@@_cmd_index_tl + { \tl_set_eq:NN \l_@@_index_module_tl \l_@@_cmd_index_tl } + \@@_special_index_module:ooon + { \l_@@_index_key_tl } + { \l_@@_index_macro_tl } + { \l_@@_index_module_tl } + { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} % -% \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 } +% \begin{macro} +% { +% \@@_meta:n, +% \@@_meta_aux:n, +% \@@_ensuremath_sb:n, +% \@@_meta_original:n +% } +% Store |#1| in \cs{l_@@_tmpa_tl} and replaces every underscore, +% regardless of its category (\enquote{math toggle}, +% \enquote{alignment}, \enquote{superscript}, \enquote{subscript}, +% \enquote{letter}, \enquote{other}, or \enquote{active}) by +% \cs{@@_ensuremath_sb:n} (which creates math subscripts), then runs +% the code used for \tn{meta} in \pkg{doc.sty}. +% \begin{macrocode} +\cs_new:Npn \@@_meta:n #1 + { + \texorpdfstring + { + \CodedocUnexpandedTokens + { \CodedocUseCs { @@_meta_aux:n } {#1} } + } + { < #1 > } + } +\cs_new_protected:Npn \@@_meta_aux:n #1 + { + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_map_inline:nn + { { 3 } { 4 } { 7 } { 8 } { 11 } { 12 } { 13 } } + { + \tl_set_rescan:Nnn \l_@@_tmpb_tl + { \char_set_catcode:nn { `_ } {##1} } { _ } + \tl_replace_all:Non \l_@@_tmpa_tl \l_@@_tmpb_tl + { \@@_ensuremath_sb:n } + } + \exp_args:NV \@@_meta_original:n \l_@@_tmpa_tl + } +\cs_new_protected:Npn \@@_ensuremath_sb:n #1 + { \ensuremath { \sb {#1} } } +\cs_new_protected:Npn \@@_meta_original:n #1 + { + \ensuremath \langle + \mode_if_math:T { \nfss@text } { - \prop_put:Nxx \l_@@_functions_block_prop - { \cs_to_str:N \q_recursion_tail } - { { -1 } { } } + \meta@font@select + \edef \meta@hyphen@restore + { \hyphenchar \the \font \the \hyphenchar \font } + \hyphenchar \font \m@ne + \language \l@nohyphenation + #1 \/ + \meta@hyphen@restore } - { \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.) + \ensuremath \rangle + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{The \env{function} environment} +% % \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 } +\keys_define:nn { l3doc/function } + { + TF .code:n = + { + \bool_set_true:N \l_@@_macro_TF_bool + } , + EXP .code:n = + { + \bool_set_true:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + } , + rEXP .code:n = + { + \bool_set_false:N \l_@@_macro_EXP_bool + \bool_set_true:N \l_@@_macro_rEXP_bool + } , + pTF .code:n = + { + \bool_set_true:N \l_@@_macro_pTF_bool + \bool_set_true:N \l_@@_macro_TF_bool + \bool_set_true:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + } , + added .tl_set:N = \l_@@_date_added_tl , + updated .tl_set:N = \l_@@_date_updated_tl , + tested .code:n = { } , + no-label .bool_set:N = \l_@@_no_label_bool , + } +% \end{macrocode} +% +% +% \begin{macro}[int]{\@@_function:nnw} +% \begin{arguments} +% \item Key--value list. +% \item Comma-separated list of functions; input has already been +% sanitised by catcode changes before reading the argument. +% \end{arguments} +% \begin{macro}[int]{\@@_function_end:} +% Make sure any paragraph is finished, and similar safe practices at +% the beginning of an environment which will typeset material. +% Initialize some variables. Parse the key--value list. Clean up the +% list of functions, then go through them to extract some data. After +% this, typeset the function names in the coffin +% \cs{l_@@_names_coffin} and measure it to know if it fits in the +% margin. Finally, start a vertical coffin for the main part of the +% environment. This coffin stops when the environment ends, then all +% the pieces are assembled into a single coffin, which is typeset. +% \begin{macrocode} +\cs_new_protected:Npn \@@_function:nnw #1#2 + { + \@@_function_typeset_start: + \@@_function_init: + \keys_set:nn { l3doc/function } {#1} + \@@_verb_get_seq:nN {#2} \l_@@_function_input_seq + \@@_function_parse: + \@@_function_typeset: + \@@_function_descr_start:w + } +\cs_new_protected_nopar:Npn \@@_function_end: + { + \@@_function_descr_stop: + \@@_function_assemble: + \@@_function_typeset_stop: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux] +% {\@@_function_typeset_start:, \@@_function_typeset_stop:} +% At the start of the \env{function} environment, before performing +% any assignment, close the last paragraph, and set up the typesetting +% scene. Further code typesets a coffin, so we end the paragraph and +% allow a page break. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_function_typeset_start: + { + \par \bigskip \noindent + \phantomsection + } +\cs_new_protected_nopar:Npn \@@_function_typeset_stop: + { + \par + \allowbreak + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_function_init:} +% Allow |<...>| to be used as markup for |\meta{...}|. Clear various +% variables. +% \begin{macrocode} +\cs_new_protected:Npn \@@_function_init: + { + \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_@@_macro_TF_bool + \bool_set_false:N \l_@@_macro_pTF_bool + \bool_set_false:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + \bool_set_false:N \l_@@_no_label_bool + \char_set_active:Npn < ##1 > { \meta {##1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux] +% { +% \@@_function_parse:, +% \@@_function_parse_one:n, +% \@@_function_parse_cs_aux:nnN +% } +% The idea here is to populate \cs{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 \enquote{names} (stripped of signature) with values +% specified by a comma-separated list of (braced) signatures: +% \begin{center} +% |> {my_function} => {| \meta{sig_1} |,| \meta{sig_2} |, ... }| +% \end{center} +% In the case where the function has no signature (no colon), we use +% a \meta{sig} equal to \cs{scan_stop:}. +% This somewhat arcane syntax is chosen to distinguish between all +% variants of control sequence that may be being documented +% here. (With or without \pkg{expl3} function syntax.) +% +% If |#1| does not start with |\| then the \enquote{name prefix} is +% empty and we store \cs{scan_stop:} as the value for the key |#1|, not +% bothering with variants. If instead |#1| starts with |\| then the +% \enquote{name prefix} is |\| and we omit the first character of |#1| +% subsequently. If the next character is |:| then we have one of the +% weird functions named |\::N| and so on, and we ignore variants, +% putting \cs{scan_stop:} directly as the value for the key |::N|. +% Otherwise, we have a regular control sequence, which we decompose +% using \cs{@@_function_parse_cs_aux:nnN}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_function_parse: + { + \seq_map_function:NN + \l_@@_function_input_seq + \@@_function_parse_one:n + } +\cs_new_protected:Npn \@@_function_parse_one:n #1 + { + \tl_if_head_eq_charcode:nNTF {#1} \c_@@_backslash_token + { + \tl_gset_eq:NN \g_@@_function_name_prefix_tl \c_@@_backslash_tl + \exp_args:No \tl_if_head_eq_charcode:nNTF { \use_none:n #1 } : { - {\__cs_count_signature:N #1} - {\__cs_get_function_signature:N #1} + \prop_put:Nxn \l_@@_functions_block_prop + { \use_none:n #1 } { \scan_stop: } } - } - } - } + { + \exp_args:Nc \__cs_split_function:NN { \use_none:n #1 } + \@@_function_parse_cs_aux:nnN + } + } + { + \tl_gclear:N \g_@@_function_name_prefix_tl + \prop_put:Nnn \l_@@_functions_block_prop {#1} { \scan_stop: } + } + } +\cs_new_protected:Npn \@@_function_parse_cs_aux:nnN #1#2#3 + { + \prop_get:NnNF + \l_@@_functions_block_prop {#1} \l_@@_tmpb_tl + { \tl_clear:N \l_@@_tmpb_tl } + \prop_put:Nnx \l_@@_functions_block_prop {#1} + { + \l_@@_tmpb_tl , + \bool_if:NTF #3 { {#2} } { \scan_stop: } + } + } % \end{macrocode} -% False branch for keys and things that aren't actually csnames: +% \end{macro} +% +% \begin{macro}[aux]{\@@_function_typeset:} +% Typeset in the coffin \cs{l_@@_names_coffin} the functions listed in +% \cs{l_@@_functions_block_prop} and the relevant dates, then set +% \cs{l_@@_long_name_bool} to be \texttt{true} if this coffin is +% larger than the available width in the margin. The function +% \cs{@@_typeset_names:} is quite involved hence given later. % \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} {} } - } - } +\cs_new_protected_nopar:Npn \@@_function_typeset: + { + \dim_zero:N \l_@@_trial_width_dim + \hcoffin_set:Nn \l_@@_names_coffin { \@@_typeset_names: } + \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 } + } % \end{macrocode} % \end{macro} -% \end{environment} -% \end{environment} % +% \begin{macro}[aux] +% {\@@_function_descr_start:w, \@@_function_descr_stop:} +% The last step in \cs{@@_function:nnw} (the beginning of a +% \env{function} environment) is to open a coffin which will capture +% the description of the function, namely the body of the +% \env{function} environment. This is closed by \cs{@@_function_end:} +% (the end of a \env{function} environment). +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_function_descr_start:w + { + \vcoffin_set:Nnw \l_@@_descr_coffin { \textwidth } + \noindent \ignorespaces + } +\cs_new_protected_nopar:Npn \@@_function_descr_stop: + { \vcoffin_set_end: } +% \end{macrocode} +% \end{macro} % -% \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 } - } -} +% \begin{macro}[aux]{\@@_function_assemble:} +% The box \cs{g_@@_syntax_box} contains the contents of the syntax +% environment if it was used. Now that we have all the pieces, join +% together the syntax coffin, the names coffin, and the description +% coffin. The relative positions depend on whether the names coffin +% fits in the margin. Then typeset the combination. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_function_assemble: + { + \hcoffin_set:Nn \l_@@_syntax_coffin + { \box_use:N \g_@@_syntax_box } + \bool_if:NTF \l_@@_long_name_bool + { + \coffin_join:NnnNnnnn + \l_@@_output_coffin {hc} {vc} + \l_@@_syntax_coffin {l} {T} + {0pt} {0pt} + \coffin_join:NnnNnnnn + \l_@@_output_coffin {l} {t} + \l_@@_names_coffin {r} {t} + {-\marginparsep} {0pt} + \coffin_join:NnnNnnnn + \l_@@_output_coffin {l} {b} + \l_@@_descr_coffin {l} {t} + {0.75\marginparwidth + \marginparsep} {-\medskipamount} + \coffin_typeset:Nnnnn \l_@@_output_coffin + {\l_@@_descr_coffin-l} {\l_@@_descr_coffin-t} + {0pt} {0pt} + } + { + \coffin_join:NnnNnnnn + \l_@@_output_coffin {hc} {vc} + \l_@@_syntax_coffin {l} {t} + {0pt} {0pt} + \coffin_join:NnnNnnnn + \l_@@_output_coffin {l} {b} + \l_@@_descr_coffin {l} {t} + {0pt} {-\medskipamount} + \coffin_join:NnnNnnnn + \l_@@_output_coffin {l} {t} + \l_@@_names_coffin {r} {t} + {-\marginparsep} {0pt} + \coffin_typeset:Nnnnn \l_@@_output_coffin + {\l_@@_syntax_coffin-l} {\l_@@_syntax_coffin-T} + {0pt} {0pt} + } + } % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\@@_typeset_function_block:N} +% \begin{macro}[aux]{\@@_typeset_names:} +% This function builds the \cs{l_@@_names_coffin} by typesetting the +% function names (with variants) and the relevant dates in a +% \env{tabular} environment. The use of rules \tn{toprule}, +% \tn{midrule} and \tn{bottomrule} requires whatever lies between the +% last |\\| and the rule to be expandable, making our lives a bit +% complicated. % \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 } - } +\cs_new_protected_nopar:Npn \@@_typeset_names: + { + \small\ttfamily + \begin{tabular} { @{} l @{} r @{} } + \toprule + \@@_typeset_functions: + \@@_typeset_dates: + \bottomrule + \end{tabular} + \normalfont\normalsize + } % \end{macrocode} +% \end{macro} % +% \begin{macro}[aux]{\@@_typeset_functions:} +% \begin{macro}[aux] +% {\@@_typeset_functions_auxi:nn, \@@_typeset_functions_auxii: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} +% The mapping to \cs{l_@@_functions_block_prop} cannot use +% \cs{prop_map_inline:Nn} because the code following |\\| would not be +% expandable, thus breaking \tn{bottomrule}. The loop goes as +% follows: go through the list of variants |#2|, and collect them by +% \enquote{base form} in a \cs{l_@@_variants_prop} whose keys are the +% base form and whose values are the variants which can be obtained +% from that base form using \cs{cs_generate_variant:Nn}. Then start a +% nested loop through these base forms, calling +% \cs{@@_typeset_functions_auxii:nn}. This auxiliary does not care +% about the base form. It stores the variants it receives in +% \cs{g_@@_variants_clist}, remove the first, which will be displayed +% more prominently, and reconstructs its actual name, passing it to +% the \cs{@@_typeset_functions_auxiii:N} auxiliary. +% +% Braces around |##1| are crucial since this item can be empty. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_typeset_functions: + { + \prop_map_function:NN \l_@@_functions_block_prop + \@@_typeset_functions_auxi:nn + } +\cs_new_protected:Npn \@@_typeset_functions_auxi:nn #1#2 + { + \tl_gset:Nn \g_@@_base_name_tl {#1} + \prop_clear:N \l_@@_variants_prop + \clist_map_inline:nn {#2} + { + \tl_set:Nx \l_@@_tmpa_tl + { \@@_signature_base_form:n {##1} } + \prop_get:NoNTF \l_@@_variants_prop + \l_@@_tmpa_tl \l_@@_tmpb_tl + { \tl_put_right:Nn \l_@@_tmpb_tl { , {##1} } } + { \tl_set:Nn \l_@@_tmpb_tl { {##1} } } + \prop_put:Noo \l_@@_variants_prop + \l_@@_tmpa_tl \l_@@_tmpb_tl + } + \prop_map_function:NN \l_@@_variants_prop + \@@_typeset_functions_auxii:nn + } +\cs_new_protected:Npn \@@_typeset_functions_auxii:nn #1#2 + { + \clist_gset:Nn \g_@@_variants_clist {#2} + \clist_gpop:NN \g_@@_variants_clist \l_@@_tmpb_tl + \exp_args:Nc \@@_typeset_functions_auxiii:N + { + \g_@@_base_name_tl + \exp_last_unbraced:Nf \token_if_eq_meaning:NNF + { \tl_head:f { \l_@@_tmpb_tl ? } } + \scan_stop: + { : \l_@@_tmpb_tl } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\@@_typeset_functions_auxiii:N} % \begin{macrocode} -\cs_set:Nn \@@_typeset_function_basename:N - { \l_@@_function_name_prefix_tl \cs_to_str:N #1 } +\cs_new_protected:Npn \@@_typeset_functions_auxiii:N #1 + { + \bool_if:NT \l_@@_macro_pTF_bool + { + \tl_set:Nx \l_@@_pTF_name_tl + { \@@_predicate_from_base:N #1 } + \@@_function_index:x { \l_@@_pTF_name_tl } + } + \@@_function_index:x + { + \cs_to_str:N #1 + \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } + } + \bool_if:NT \l_@@_macro_pTF_bool + { + \exp_args:Nc \@@_typeset_function_block:NN + { \l_@@_pTF_name_tl } \c_false_bool + } + \@@_typeset_function_block:NN #1 \l_@@_macro_TF_bool + } +\cs_new_protected:Npn \@@_function_index:x #1 + { + \tl_set:Nx \l_@@_tmpa_tl + { \g_@@_function_name_prefix_tl #1 } + \seq_gput_right:No \g_doc_functions_seq { \l_@@_tmpa_tl } + \@@_special_index:on { \l_@@_tmpa_tl } { usage } + } % \end{macrocode} +% \end{macro} % +% \begin{macro}[internal]{\@@_typeset_function_block:NN} +% The first argument is a control sequence, the second a boolean which +% controls whether to typeset |TF| or not. % \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 } - } - } +\cs_new_protected:Npn \@@_typeset_function_block:NN #1#2 + { + \@@_function_label:x + { \g_@@_function_name_prefix_tl \cs_to_str:N #1 } + \g_@@_function_name_prefix_tl \cs_to_str:N #1 + \bool_if:NT #2 { \@@_typeset_TF: } + \@@_typeset_expandability: + \clist_if_empty:NF \g_@@_variants_clist + { \@@_typeset_variant_list:NN #1#2 } + \\ + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_typeset_expandability: + { + & + \bool_if:NT \l_@@_macro_EXP_bool + { + \hspace{\tabcolsep} + \hyperlink{expstar} {$\star$} + } + \bool_if:NT \l_@@_macro_rEXP_bool + { + \hspace{\tabcolsep} + \hyperlink{rexpstar} {\ding{73}} % hollow star + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_typeset_variant_list:NN #1#2 + { + \\ + \@@_typeset_aux:n + { + \g_@@_function_name_prefix_tl + \__cs_get_function_name:N #1 + } + : + \int_compare:nTF { \clist_count:N \g_@@_variants_clist == 1 } + { \clist_use:Nn \g_@@_variants_clist { } } + { + \textrm( + \clist_use:Nn \g_@@_variants_clist { \textrm| } + \textrm) + } + \bool_if:NT #2 { \@@_typeset_TF: } + \@@_typeset_expandability: + } +% \end{macrocode} +% +% TODO: understand whether we need one more boolean to only +% put labels if the whole document is typeset. +% \begin{macrocode} +\cs_new_protected:Npn \@@_function_label:n #1 + { + % \bool_if:NT \g_@@_typeset_implementation_bool + % { + \bool_if:NF \l_@@_no_label_bool + { + \@@_get_hyper_target:nN {#1} \l_@@_tmpa_tl + \exp_args:No \label { \l_@@_tmpa_tl } + } + % } + } +\cs_generate_variant:Nn \@@_function_label:n { x } % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\@@_typeset_dates:} -% To display metadata for when functions are added/modified. +% To display metadata for when functions are added/modified. +% This function must be expandable since it produces rules for use in +% alignments. % \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 } \\ - } +\cs_new_nopar:Npn \@@_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 } \\ - } - } + \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{macro}[aux]{\@@_syntax:w, \@@_syntax_end:} +% Implement the \env{syntax} environment. % \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`\} } - } +\dim_new:N \l_@@_syntax_dim +\cs_new_protected:Npn \@@_syntax:w + { + \dim_set:Nn \l_@@_syntax_dim + { + \textwidth + \bool_if:NT \l_@@_long_name_bool + { + 0.75 \marginparwidth - \l_@@_trial_width_dim } + } + \hbox_gset:Nw \g_@@_syntax_box + \small \ttfamily + \arrayrulecolor{white} + \begin{tabular} { @{} l @{} } + \toprule + \begin{minipage}{\l_@@_syntax_dim} + \raggedright + \obeyspaces + \obeylines + } +\cs_new_protected:Npn \@@_syntax_end: + { + \end{minipage} + \end{tabular} + \arrayrulecolor{black} + \hbox_gset_end: + } % \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. +% \subsubsection{The \env{macro} environment} % -% Keyval: +% Keyval for the \env{macro} environment. TODO: use +% |.value_forbidden:|. TODO: provide document command for talking about +% keys. % \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_set_false:N \l_@@_macro_aux_bool - \bool_set_false:N \l_@@_macro_internal_bool - \bool_set_false:N \l_@@_macro_TF_bool - \bool_set_false:N \l_@@_macro_pTF_bool - \bool_set_false:N \l_@@_macro_var_bool - \bool_set_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 } - } + { + 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_TF_bool + \bool_set_true:N \l_@@_macro_pTF_bool + \bool_set_true:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + } , + EXP .code:n = + { + \bool_set_true:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + } , + rEXP .code:n = + { + \bool_set_false:N \l_@@_macro_EXP_bool + \bool_set_true:N \l_@@_macro_rEXP_bool + } , + tested .code:n = + { + \bool_set_true:N \l_@@_macro_tested_bool + } , + added .code:n = {} , % TODO + updated .code:n = {} , % TODO + } % \end{macrocode} % -% \end{environment} +% \begin{macro}[int]{\@@_macro:nnw} +% The arguments are a key--value list of \meta{options} and a +% comma-list of \meta{names}, read verbatim by \pkg{xparse}. First +% initialize some variables before applying the \meta{options}, then +% parse the \meta{names} to get a sequence of macro names, then apply +% \cs{@@_macro_single:n} to each (this step is more subtle than +% \cs{seq_map_function:NN} because of |TF|/|pTF|). Finally typeset +% the macro names in the margin. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro:nnw #1#2 + { + \@@_macro_init: + \keys_set:nn { l3doc/macro } {#1} + \@@_verb_get_seq:nN {#2} \l_@@_macro_input_seq + \@@_macro_map:N \@@_macro_single:n + \@@_macro_typeset: + } +% \end{macrocode} +% \end{macro} % +% \begin{macro}[aux]{\@@_macro_init:} +% The booleans hold various key--value options, +% \cs{l_@@_nested_macro_int} counts the number of \env{macro} +% environments around the current point (is $0$ outside). % \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 - } +\cs_new_protected_nopar:Npn \@@_macro_init: + { + \int_incr:N \l_@@_nested_macro_int + \bool_set_false:N \l_@@_macro_aux_bool + \bool_set_false:N \l_@@_macro_internal_bool + \bool_set_false:N \l_@@_macro_TF_bool + \bool_set_false:N \l_@@_macro_pTF_bool + \bool_set_false:N \l_@@_macro_EXP_bool + \bool_set_false:N \l_@@_macro_rEXP_bool + \bool_set_false:N \l_@@_macro_var_bool + \bool_set_false:N \l_@@_macro_tested_bool + \cs_set_eq:NN \testfile \@@_print_testfile:n + \box_clear:N \l_@@_macro_index_box + \vbox_set:Nn \l_@@_macro_box + { + \hbox:n { \strut } + \vskip \int_eval:n { \l_@@_macro_int - 1 } \baselineskip + } + } % \end{macrocode} +% \end{macro} % -% \begin{macro}{\@@_print_macroname:n} +% \begin{macro}[aux]{\@@_macro_map:N} +% Applies |#1| to all macros. In the |pTF| case, this means going +% twice through the sequence \cs{l_@@_macro_input_seq}, once for the +% predicates and once for the |TF| variants. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_map:N #1 + { + \bool_if:NT \l_@@_macro_pTF_bool + { + \bool_set_false:N \l_@@_macro_TF_bool + \seq_map_inline:Nn \l_@@_macro_input_seq + { + \tl_set:Nn \l_@@_tmpa_tl {##1} + \tl_replace_once:Noo \l_@@_tmpa_tl + { \tl_to_str:n { : } } { \tl_to_str:n { _p: } } + \exp_args:No #1 \l_@@_tmpa_tl + } + \bool_set_true:N \l_@@_macro_TF_bool + } + \seq_map_function:NN \l_@@_macro_input_seq #1 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_macro_typeset:} +% This calls |\makelabel{}| % \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 } +\cs_new_protected_nopar:Npn \@@_macro_typeset: + { + \topsep\MacroTopsep + \trivlist + \cs_set:Npn \makelabel ##1 + { + \llap + { + \hbox_unpack_clear:N \l_@@_macro_index_box + \vtop to \baselineskip + { + \vbox_unpack_clear:N \l_@@_macro_box + \vss + } + } + } + \item [ ] + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_macro_single:n} +% Let's start to mess around with \cls{doc}'s \env{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} +% The assignment to \cs{saved@macroname} is used by \pkg{doc}'s +% \cs{changes} mechanism. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_single:n #1 + { + \tl_set:Nn \saved@macroname {#1} - % 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! - } - } + \@@_macro_typeset_one:n {#1} + \exp_args:Nx \@@_macro_index:n + { + #1 + \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n { TF } } + } + } +\cs_new_protected:Npn \@@_macro_index:n #1 + { + \bool_if:NF \l_@@_macro_aux_bool + { \seq_gput_right:Nn \g_doc_macros_seq {#1} } + \hbox_set:Nn \l_@@_macro_index_box + { + % This box only contains targets... it seems inefficient. + \hbox_unpack_clear:N \l_@@_macro_index_box + \int_gincr:N \c@CodelineNo + \@@_special_index:nn {#1} { main } + \DoNotIndex {#1} + \int_gdecr:N \c@CodelineNo + } + } % \end{macrocode} % \end{macro} -% \end{environment} % -% \begin{macro}{\MacroLongFont} +% \begin{macro}[aux]{\@@_macro_typeset_one:n} +% For a long time, \cls{l3doc} collected the macro names as labels in +% the first items of nested \tn{trivlist}, but these were not closed +% properly with \tn{endtrivlist}. Also, it interacted in surprising +% ways with \pkg{hyperref} targets. Now, we collect typeset macro +% names by hand in the box \cs{l_@@_macro_box}. Note the space |\ |. % \begin{macrocode} -\providecommand \MacroLongFont - { - \fontfamily{lmtt}\fontseries{lc}\small - } +\cs_new_protected:Npn \@@_macro_typeset_one:n #1 + { + \vbox_set:Nn \l_@@_macro_box + { + \vbox_unpack_clear:N \l_@@_macro_box + \hbox { \llap { \@@_print_macroname:n {#1} \ } } + } + \int_incr:N \l_@@_macro_int + } % \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{macro}{\@@_print_macroname:n} % \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 } - } +\cs_new_protected:Npn \@@_print_macroname:n #1 + { + \strut + \HD@target + + % TODO: 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} } } + { + \@@_get_hyper_target:nN {#1} \l_@@_tmpa_tl + \exp_last_unbraced:NNo \hyperref [ \l_@@_tmpa_tl ] + } + { \use:n } + { + \int_compare:nTF { \tl_count:n {#1} <= 28 } + { \MacroFont } { \MacroLongFont } + \@@_macroname_prefix:n {#1} \@@_macroname_suffix: + } + } +\cs_new_protected:Npn \@@_macroname_prefix:n #1 + { + \bool_if:NTF \l_@@_macro_aux_bool + { \@@_typeset_aux:n {#1} } {#1} + } +\cs_new_protected_nopar:Npn \@@_macroname_suffix: + { \bool_if:NTF \l_@@_macro_TF_bool { \@@_typeset_TF: } { } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_print_testfile:n} -% Used to show that a macro has a test, somewhere. +% \begin{macro}{\MacroLongFont} % \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} - } - } - } +\providecommand \MacroLongFont + { + \fontfamily{lmtt}\fontseries{lc}\small + } % \end{macrocode} -% Text for displaying: +% \end{macro} +% +% \begin{macro}{\@@_print_testfile:n, \@@_print_testfile_aux:n} +% Used to show that a macro has a test, somewhere. % \begin{macrocode} +\cs_new_protected:Npn \@@_print_testfile:n #1 + { + \bool_set_true:N \l_@@_macro_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} + } + } + } \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 - } + { + \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 + \textit + { + The~ following~ test~ files~ are~ + used~ for~ this~ code:~ \textsf{#1}. + } + \par \ignorespaces } - \par\ignorespaces - } % \end{macrocode} % \end{macro} % % \begin{macro}{\UnitTested} % \begin{macrocode} -\DeclareDocumentCommand \UnitTested {} { \testfile* } +\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} } - } +% \begin{macrocode} +\DeclareDocumentCommand \TestMissing { m } + { \@@_test_missing:n {#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{macro}[aux]{\@@_test_missing:n} +% Keys in \cs{g_@@_missing_tests_prop} are lists of macros given as +% arguments of one \env{macro} environment. Values are comma lists of +% filenames (Bruno thinks). % \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 } +\cs_new_protected:Npn \@@_test_missing:n #1 + { + \tl_set:Nx \l_@@_tmpb_tl + { \seq_use:Nn \l_@@_macro_input_seq { , } } + \prop_if_in:NVTF \g_@@_missing_tests_prop \l_@@_tmpb_tl + { + \prop_get:NVN \g_@@_missing_tests_prop \l_@@_tmpb_tl + \l_@@_tmpa_tl + } + { \tl_clear:N \l_@@_tmpa_tl } + \clist_set:Nx \l_@@_tmpa_clist { \l_@@_tmpa_tl , #1 } + \prop_gput:NVV \g_@@_missing_tests_prop \l_@@_tmpb_tl + \l_@@_tmpa_clist + } % \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 } +% \begin{macro}[aux]{\@@_macro_end:} +% It is too late for anyone to declare a test file for this macro, so +% we can check now whether the macro is tested. If the \env{macro} +% environment which is being ended is the outermost one, then wrap +% each macro in \tn{texttt} (with the addition of |TF| if relevant) +% and typeset two informations: that this ends the definition of some +% macros, and that they are documented on some page. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_end: + { + \endtrivlist + \@@_macro_end_check_tested: + \int_compare:nNnT \l_@@_nested_macro_int = 1 { - \seq_use:Nnnn \g_@@_tmpa_seq - { \,~and~ } { \,,~ } { \,,~and~ } - \@. + \@@_macro_end_style:n + { + \@@_print_end_definition: + \@@_print_documented: + } } - { \seq_item:Nn \g_@@_tmpa_seq {1}\,~and~others. } - + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_macro_end_check_tested:} +% If the |checktest| option was issued and the macro is not an +% auxiliary nor a variable (and it does not have a test), then add it +% to the sequence of non-tested macros. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_macro_end_check_tested: + { \bool_if:nT { - !\l_@@_macro_aux_bool && - !\l_@@_macro_internal_bool && - \int_compare_p:n {\g_@@_nested_macro_int<1} + \g_@@_checktest_bool && + ! \l_@@_macro_aux_bool && + ! \l_@@_macro_var_bool && + ! \l_@@_macro_tested_bool } { - \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)} + \seq_gput_right:Nx \g_@@_not_tested_seq + { + \seq_use:Nn \l_@@_macro_input_seq { , } + \bool_if:NTF \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{macro}[aux]{\@@_macro_end_style:n} +% Style for the extra information at the end of a top-level +% \env{macro} environment. % \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 - { +\cs_new_protected:Npn \@@_macro_end_style:n #1 + { + \nobreak \noindent + { \footnotesize ( \emph{#1} ) \par } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux] +% { +% \@@_print_end_definition:, +% \@@_macro_end_wrap_items:N, +% \@@_print_documented: +% } +% Surround each item by \tn{texttt} and |TF| if needed, replacing |_| +% by \tn{_} as well. Then list the +% macro names through \cs{seq_use:Nnnn}, unless there are too many. +% Finally, if the macro is neither auxiliary nor internal, add a link +% to where it is documented. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_end_wrap_items:N #1 + { + \bool_if:NT \l_@@_macro_TF_bool + { \seq_set_map:NNn #1 #1 { ##1 TF } } + \seq_set_map:NNn #1 #1 + { + \exp_not:n + { + \tl_set:Nn \l_@@_tmpa_tl {##1} + \tl_replace_all:Non \l_@@_tmpa_tl + { \token_to_str:N _ } { \_ } + \texttt { \l_@@_tmpa_tl } + } + } + } +\cs_new_protected_nopar:Npn \@@_print_end_definition: + { + \group_begin: + \@@_macro_end_wrap_items:N \l_@@_macro_input_seq + End~ definition~ for~ + \int_compare:nTF { \seq_count:N \l_@@_macro_input_seq <= 3 } + { + \seq_use:Nnnn \l_@@_macro_input_seq + { \,~and~ } { \,,~ } { \,,~and~ } + \@. + } + { \seq_item:Nn \l_@@_macro_input_seq {1}\,~and~others. } \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: + } +\cs_new_protected_nopar:Npn \@@_print_documented: + { + \bool_if:nT + { + ! \l_@@_macro_aux_bool && + ! \l_@@_macro_internal_bool + } + { + \int_set:Nn \l_@@_tmpa_int + { \seq_count:N \l_@@_macro_input_seq } + \int_compare:nNnTF \l_@@_tmpa_int = 1 {~This~} {~These~} + \bool_if:NTF \l_@@_macro_var_bool {variable} {function} + \int_compare:nNnTF \l_@@_tmpa_int = 1 {~is~} {s~are~} + documented~on~page~ + \exp_args:Nx \@@_get_hyper_target:nN + { \seq_item:Nn \l_@@_macro_input_seq { 1 } } + \l_@@_tmpa_tl + \exp_args:Nx \pageref { \l_@@_tmpa_tl } . + } + } % \end{macrocode} % \end{macro} -% \end{environment} +% +% \subsubsection{Common between \env{macro} and \env{function}} +% +% \begin{macro}{\@@_typeset_TF:, \@@_typeset_aux:n} +% Used by \cs{@@_macro_single:n} and in the \env{function} environment +% to typeset conditionals and auxiliary functions. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_typeset_TF: + { + \hyperlink{explTF} + { + \color{black} + \itshape TF + \makebox[0pt][r] + { + \color{red} + \underline { \phantom{\itshape TF} \kern-0.1em } + } + } + } +\cs_new_protected:Npn \@@_typeset_aux:n #1 + { + { \color[gray]{0.7} #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_get_hyper_target:nN} +% Create a \pkg{hyperref} anchor from a macro name~|#1| and stores it +% in the token list variable~|#2|. For instance, |\prg_replicate:nn| +% gives |doc/function//prg/replicate:nn|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_hyper_target:nN #1#2 + { + \tl_set:Nx #2 + { + \tl_to_str:n {#1} + \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } + } + \tl_replace_all:Nxn #2 { \iow_char:N \_ } { / } + \tl_remove_all:Nx #2 { \iow_char:N \\ } + \tl_put_left:Nn #2 { doc/function// } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Misc} % % \begin{macro}{\DescribeOption} -% For describing package options. Due to Joseph Wright. -% Name/usage might change soon. +% For describing package options. Due to Joseph Wright. Name/usage +% might change soon. % \begin{macrocode} \newcommand*{\DescribeOption} - { - \leavevmode - \@bsphack - \begingroup - \MakePrivateLetters - \Describe@Option - } + { + \leavevmode + \@bsphack + \begingroup + \MakePrivateLetters + \Describe@Option + } % \end{macrocode} % % \begin{macrocode} \newcommand*{\Describe@Option}[1] - { - \endgroup - \marginpar{ - \raggedleft - \PrintDescribeEnv{#1} + { + \endgroup + \marginpar{ + \raggedleft + \PrintDescribeEnv{#1} + } + \SpecialOptionIndex{#1} + \@esphack + \ignorespaces } - \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 - } + { + \@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} % @@ -1914,52 +2647,51 @@ Do not distribute a modified version of this file. % % \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{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} } +\font \manual = manfnt \scan_stop: +\cs_gset_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. +% 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} - } + { + \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. +% 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} - } + { + \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} @@ -1968,65 +2700,65 @@ Do not distribute a modified version of this file. % % \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 - } + { + \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 + \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:} - } + \hfill\penalty500\hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par + } + \def\TemplateSemantics + { + \enddescription\endgroup + \subsubsection*{Semantics~\&~Comments:} + } } - {\par\bigskip} + { \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 + \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} + { \par \bigskip } % \end{macrocode} % % \subsection{Inheriting doc} @@ -2034,186 +2766,251 @@ Do not distribute a modified version of this file. % 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 +% \begin{macro} +% {\StopEventually, \Finale, \AlsoImplementation, \OnlyDescription} +% \begin{variable}[aux]{\g_@@_finale_tl} +% TODO: remove these four commands altogether, document that it is +% better to use the \env{documentation} and \env{implementation} +% environments. +% \begin{macrocode} +\DeclareDocumentCommand \OnlyDescription { } + { \bool_gset_false:N \g_@@_typeset_implementation_bool } +\DeclareDocumentCommand \AlsoImplementation { } + { \bool_gset_true:N \g_@@_typeset_implementation_bool } +\DeclareDocumentCommand \StopEventually { m } + { + \bool_if:NTF \g_@@_typeset_implementation_bool + { + \@bsphack + \tl_gset:Nn \g_@@_finale_tl { #1 \check@checksum } + \init@checksum + \@esphack + } + { #1 \endinput } + } +\DeclareDocumentCommand \Finale { } + { \tl_use:N \g_@@_finale_tl } +\tl_new:N \g_@@_finale_tl % \end{macrocode} +% \end{variable} % \end{macro} % +% \begin{macro}[aux]{\@@_input:n} +% Inputting a file, with some setup: the module name should be empty +% before the first |<@@=|\meta{module}|>| line in the file. % \begin{macrocode} -\cs_set_nopar:Npn \partname{File} +\cs_new_protected:Npn \@@_input:n #1 + { + \tl_gclear:N \g_@@_module_name_tl + \MakePercentIgnore + \input{#1} + \MakePercentComment + } % \end{macrocode} +% \end{macro} % % \begin{macro}{\DocInput} -% From \pkg{doc}. Now accepts comma-list input (who has commas in filenames?). +% Modified from \pkg{doc} to accept 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 - } - } +\DeclareDocumentCommand \DocInput { m } + { + \clist_map_inline:nn {#1} + { + \clist_put_right:Nn \g_docinput_clist {##1} + \@@_input:n {##1} + } + } % \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. +% Uses \cs{g_docinput_clist} to re-input whatever's already been +% \tn{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 - } - } +\DeclareDocumentCommand \DocInputAgain { } + { \clist_map_function:NN \g_docinput_clist \@@_input:n } % \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 +% More or less exactly the same as \tn{include}, but uses +% \tn{DocInput} on a \file{.dtx} file, not \tn{input} on a \file{.tex} +% file. +% +% \begin{macrocode} +\NewDocumentCommand \DocInclude { m } + { + \relax\clearpage + \docincludeaux + \IfFileExists{#1.fdd} + { \cs_set_nopar:Npn \currentfile{#1.fdd} } + { \cs_set_nopar:Npn \currentfile{#1.dtx} } + \int_compare:nNnTF \@auxout = \@partaux + { \@latexerr{\string\include\space cannot~be~nested}\@eha } + { \@docinclude #1 } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_gset:Npn \@docinclude #1 + { \clearpage - \@writeckpt{#1} - \immediate\closeout\@partaux - \else - \@nameuse{cp@#1} - \fi - \cs_set_eq:NN \@auxout\@mainaux - } + \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 } - } - } +\cs_gset:Npn \codeline@wrindex #1 + { + \immediate\write\@indexfile + { + \string\indexentry{#1} + { \filesep \int_use:N \c@CodelineNo } + } + } +\tl_gclear:N \filesep % \end{macrocode} % \end{macro} % +% \begin{macro}{\docincludeaux} % \begin{macrocode} -\cs_set_eq:NN \filesep \@empty +\cs_gset_nopar:Npn \docincludeaux + { + \tl_set:Nn \thepart { \alphalph { part } } + \tl_set:Nn \filesep { \thepart - } + \cs_set_eq:NN \filekey \use_none:n + \tl_gput_right:Nn \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 + { + \cs_if_exist:cTF { ver @ \currentfile } + { File~\thepart :~{\ttfamily\currentfile}~ } + { + \GetFileInfo{\currentfile} + File~\thepart :~{\ttfamily\filename}~ + Date:~\ExplFileDate\ % space + Version~\ExplFileVersion + } + \hfill \thepage + } + \cs_set_eq:NN \@evenfoot \@oddfoot + } % \end{macrocode} +% \end{macro} % -% \begin{macro}{\docincludeaux} +% \subsubsection{The \env{macrocode} environment} +% +% \begin{macro}[aux]{\xmacro@code, \@@_xmacro_code:n, \@@_xmacro_code:w} +% Hook into the \texttt{macrocode} environment in a dirty way: +% \tn{xmacro@code} is responsible for grabbing (and tokenizing) the +% body of the environment. Redefine it to pass what it grabs to +% \cs{@@_xmacro_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. +% TODO: right now, in a line containing |<@@=|\meta{module}|>|, the +% |@@| are replaced (using different values of the \meta{module} +% before and after the assignment). Is this a waste? % \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 - } +\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} % @@ -2226,195 +3023,433 @@ Do not distribute a modified version of this file. % \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: } +\tl_new:N \l_@@_doc_def_tl +\tl_new:N \l_@@_doc_undef_tl +\tl_new:N \l_@@_undoc_def_tl +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_show_functions_defined: + { + \bool_if:nT + { \g_@@_typeset_implementation_bool && \g_@@_checkfunc_bool } + { + \iow_term:x { \c_@@_iow_separator_tl \iow_newline: } + \iow_open:Nn \g_@@_func_iow { \c_job_name_tl .cmds } - \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: } + \tl_clear:N \l_@@_doc_def_tl + \tl_clear:N \l_@@_doc_undef_tl + \tl_clear:N \l_@@_undoc_def_tl + \seq_map_inline:Nn \g_doc_functions_seq + { + \seq_if_in:NnTF \g_doc_macros_seq {##1} + { + \tl_put_right:Nx \l_@@_doc_def_tl + { ##1 \iow_newline: } + \iow_now:Nn \g_@@_func_iow { > ~ ##1 } + } + { + \tl_put_right:Nx \l_@@_doc_undef_tl + { ##1 \iow_newline: } + \iow_now:Nn \g_@@_func_iow { ! ~ ##1 } + } + } + \seq_map_inline:Nn \g_doc_macros_seq + { + \seq_if_in:NnF \g_doc_functions_seq {##1} + { + \tl_put_right:Nx \l_@@_undoc_def_tl + { ##1 \iow_newline: } + \iow_now:Nn \g_@@_func_iow { ? ~ ##1 } + } + } + \@@_functions_typeout:nN + { + Functions~both~documented~and~defined: \iow_newline: + (In~order~of~being~documented) + } + \l_@@_doc_def_tl + \@@_functions_typeout:nN + { Functions~documented~but~not~defined: } + \l_@@_doc_undef_tl + \@@_functions_typeout:nN + { Functions~defined~but~not~documented: } + \l_@@_undoc_def_tl - \iow_close:N \g_@@_func_iow - \typeout{ ======================================== } + \iow_close:N \g_@@_func_iow + \iow_term:x { \c_@@_iow_separator_tl } + } } -} -\AtEndDocument{ \@@_show_functions_defined: } +\AtEndDocument { \@@_show_functions_defined: } % \end{macrocode} % +% TODO: use \cs{iow_term:x}. % \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 - } - } +\cs_new_protected:Npn \@@_functions_typeout:nN #1#2 + { + \tl_if_empty:NF #2 + { + \typeout + { + \c_@@_iow_midrule_tl \iow_newline: + #1 \iow_newline: + \c_@@_iow_midrule_tl \iow_newline: + #2 + } + \tl_clear:N #2 + } + } % \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: } +\cs_new_protected_nopar:Npn \@@_show_not_tested: + { + \bool_if:NT \g_@@_checktest_bool + { + \tl_clear:N \l_@@_tmpa_tl + \prop_if_empty:NF \g_@@_missing_tests_prop + { + \cs_set:Npn \@@_tmpa:w ##1##2 + { + \iow_newline: + \space\space\space\space \exp_not:n {##1} + \clist_map_function:nN {##2} \@@_tmpb:w + } + \cs_set:Npn \@@_tmpb:w ##1 + { + \iow_newline: + \space\space\space\space\space\space * ~ ##1 + } + \tl_put_right:Nx \l_@@_tmpa_tl + { + \iow_newline: \iow_newline: + The~ following~ macro(s)~ have~ incomplete~ tests: + \iow_newline: + \prop_map_function:NN + \g_@@_missing_tests_prop \@@_tmpa:w + } + } + \seq_if_empty:NF \g_@@_not_tested_seq + { + \cs_set:Npn \@@_tmpa:w ##1 + { \clist_map_function:nN {##1} \@@_tmpb:w } + \cs_set:Npn \@@_tmpb:w ##1 + { + \iow_newline: + \space\space\space\space ##1 + } + \tl_put_right:Nx \l_@@_tmpa_tl + { + \iow_newline: + \iow_newline: + The~ following~ macro(s)~ do~ not~ have~ any~ tests: + \iow_newline: + \seq_map_function:NN + \g_@@_not_tested_seq \@@_tmpa:w + } + } + \tl_if_empty:NF \l_@@_tmpa_tl + { + \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} % +% \subsubsection{Userspace commands} +% % Fix index (for now): % \begin{macrocode} -\g@addto@macro\theindex{\MakePrivateLetters} -\cs_set:Npn \verbatimchar {&} +\g@addto@macro \theindex { \MakePrivateLetters } +\cs_gset:Npn \verbatimchar {&} % \end{macrocode} % % \begin{macrocode} -\setcounter{IndexColumns}{2} +\setcounter { IndexColumns } { 2 } % \end{macrocode} % -% Set up the Index to use "\part" +% Set up the Index to use \tn{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. - } + { + \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}{\SpecialIndex} +% An attempt at affecting how commands which appear within the +% \env{macrocode} environment are treated in the index. +% \begin{macrocode} +\cs_gset_protected:Npn \SpecialIndex #1 + { + \@bsphack + \@@_special_index:nn {#1} { } + \@esphack + } +% \end{macrocode} +% \end{macro} % -% \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 } +\msg_new:nnn { l3doc } { print-index-howto } + { + Generate~the~index~by~executing\\ + \iow_indent:n + { makeindex~-s~gind.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} +% +% \subsubsection{Internal index commands} +% +% \begin{macro}[int]{\it@is@a} +% The index of one-character commands within the \env{macrocode} +% environment is produced using \tn{it@is@a} \meta{char}. Alter that +% command. +% \begin{macrocode} +\cs_gset_protected:Npn \it@is@a #1 + { + \use:x + { + \@@_special_index_module:nnnn + { \quotechar #1 } + { \quotechar \bslash \quotechar #1 } + { } + { } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_special_index:nn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_special_index:nn #1#2 + { + \@@_key_get:n {#1} + \@@_special_index_module:ooon + { \l_@@_index_key_tl } + { \l_@@_index_macro_tl } + { \l_@@_index_module_tl } + {#2} + } +\cs_generate_variant:Nn \@@_special_index:nn { o } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_special_index_module:nnnn, +% \@@_special_index_module:ooon, +% \@@_special_index_aux:nnnnn, +% \@@_special_index_aux:onnnn, +% \@@_special_index_set:Nn, +% } +% Remotely based on Heiko's replacement to play nicely with +% \pkg{hypdoc}. We use \tn{verb} or a \tn{verbatim@font} construction +% depending on whether the number of tokens in |#2| is equal to its +% number of characters. +% \begin{macrocode} +\tl_new:N \l_@@_index_escaped_macro_tl +\cs_new_protected:Npn \@@_special_index_module:nnnn #1#2#3#4 + { + \use:x + { + \exp_not:n { \@@_special_index_aux:nnnnn {#1} {#2} } + \str_case_x:nnF {#3} + { + { } { { } { } } + { TeX } + { + { TeX~and~LaTeX2e~commands } + { \string\TeX{}~and~\string\LaTeXe{}~commands: } + } + } + { { #3~commands } { \string\pkg{#3}~commands: } } + } + {#4} + } +\cs_generate_variant:Nn \@@_special_index_module:nnnn { ooo } +\cs_new_protected:Npn \@@_special_index_aux:nnnnn #1#2#3#4#5 + { + \HD@target + \@@_special_index_set:Nn \l_@@_index_escaped_macro_tl {#2} + \index + { + \tl_if_empty:nF { #3 #4 } + { #3 \actualchar #4 \levelchar } + #1 + \actualchar + { + \token_to_str:N \verbatim@font \c_space_tl + \l_@@_index_escaped_macro_tl + } + \encapchar + hdclindex{\the\c@HD@hypercount}{#5} + } + } +\cs_generate_variant:Nn \@@_special_index_aux:nnnnn { o } +\cs_new_protected:Npn \@@_special_index_set:Nn #1#2 + { + \tl_set:Nx #1 { \tl_to_str:n {#2} } + \int_compare:nNnTF { \tl_count:n {#2} } < { \tl_count:N #1 } + { + \tl_set:Nn #1 {#2} + \tl_replace_all:Non #1 + { \c_@@_backslash_tl } + { \token_to_str:N \bslash \c_space_tl } + } + { + \exp_args:Nx \tl_map_inline:nn + { \tl_to_str:N \verbatimchar \token_to_str:N _ } + { + \tl_replace_all:Nnn #1 {##1} + { + \verbatimchar \c_@@_backslash_tl ##1 + \token_to_str:N \verb \quotechar * \verbatimchar + } + } + \tl_map_inline:nn { \actualchar \encapchar \levelchar } + { + \tl_replace_all:Nxn #1 + { \tl_to_str:N ##1 } { \quotechar \tl_to_str:N ##1 } + } + \tl_set:Nx #1 + { + \token_to_str:N \verb \quotechar * \verbatimchar + #1 \verbatimchar + } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Finding sort-key and module} +% +% \begin{macro}[aux]{\@@_key_get:n} +% Sets \cs{l_@@_index_macro_tl}, \cs{l_@@_index_key_tl}, and +% \cs{l_@@_index_module_tl} from |#1|. The \cs{l_@@_index_macro_tl} +% contains~|#1| directly. The starting point for the \meta{key} is +% |#1| as a string. If it the first character is a backslash, remove +% it. Then recognize |expl| functions and variables by the presence +% of |:| or~|_| and \TeX{}/\LaTeXe{} commands by the presence of~|@|. +% For |expl| names, we call \cs{@@_key_expl:}, which is responsible +% for removing some characters and finding the module name, while for +% \TeX{}/\LaTeXe{} commands the module name is |TeX|, and others have +% an empty module name. The function \cs{@@_key_expl:} detects a +% leading~|.| and removes it (key property), and otherwise does the +% following: if the second character is~|_| and the first is as well, +% then remove both (internal |expl| function); if the second character +% is~|_| but the first is not (the case of an |expl| variable), then +% remove both and remove a subsequent~|_| character (for internal +% variables). In all cases, call \cs{@@_key_get_module:}, which sets +% \cs{l_@@_index_module_tl} by removing anything after |_| or~|:| in +% \cs{l_@@_index_key_tl}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_key_get:n #1 + { + \tl_set:Nn \l_@@_index_macro_tl {#1} + \tl_set:Nx \l_@@_index_key_tl { \tl_to_str:n {#1} } + \tl_clear:N \l_@@_index_module_tl + \tl_if_head_eq_charcode:oNT + { \l_@@_index_key_tl } \c_@@_backslash_token + { \@@_key_pop: } + \tl_if_in:NoTF \l_@@_index_key_tl { \token_to_str:N : } + { \@@_key_expl: } + { + \tl_if_in:NoTF \l_@@_index_key_tl { \token_to_str:N _ } + { \@@_key_expl: } + { + \tl_if_in:NoT \l_@@_index_key_tl { \token_to_str:N @ } + { \tl_set:Nn \l_@@_index_module_tl { TeX } } + } + } + } +\cs_new_protected_nopar:Npn \@@_key_pop: + { + \tl_set:Nx \l_@@_index_key_tl + { \tl_tail:N \l_@@_index_key_tl } + } +\cs_new_protected_nopar:Npn \@@_key_expl: + { + \tl_if_head_eq_charcode:oNTF { \l_@@_index_key_tl } . + { \@@_key_pop: } + { + \exp_args:Nx \tl_if_head_eq_charcode:nNT + { \exp_args:No \str_tail:n \l_@@_index_key_tl } _ + { + \tl_if_head_eq_charcode:oNTF { \l_@@_index_key_tl } _ + { + \@@_key_pop: + \@@_key_pop: + } + { + \@@_key_pop: + \@@_key_pop: + \tl_if_head_eq_charcode:oNT { \l_@@_index_key_tl } _ + { \@@_key_pop: } + } + } + } + \@@_key_get_module: + } % \end{macrocode} % \end{macro} % +% \begin{macro}[aux]{\@@_key_get_module:, \@@_key_get_module_aux:n} +% Sets \cs{l_@@_index_module_tl} from \cs{l_@@_index_key_tl}, by +% removing anything after |:| or |_|, taking care of not expanding the +% rest for cases such as |\cs{\meta{name}:\meta{signature}}|. % \begin{macrocode} -\msg_new:nnn {l3doc} {print-index-howto} - { - Generate~the~index~by~executing\\ - \iow_indent:n { makeindex~-s~gind.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} } } +\cs_new_protected_nopar:Npn \@@_key_get_module: + { + \tl_set_eq:NN \l_@@_index_module_tl \l_@@_index_key_tl + \exp_args:No \@@_key_get_module_aux:n { \token_to_str:N : } + \exp_args:No \@@_key_get_module_aux:n { \token_to_str:N _ } + } +\cs_new_protected:Npn \@@_key_get_module_aux:n #1 + { + \cs_set:Npn \@@_tmpa:w ##1 #1 ##2 \q_stop { \exp_not:n {##1} } + \tl_set:Nx \l_@@_index_module_tl + { \exp_after:wN \@@_tmpa:w \l_@@_index_module_tl #1 \q_stop } + } % \end{macrocode} +% \end{macro} % % \subsection{Change history} % -% Set the change history to use "\part". -% Allow control names to be hyphenated in here... +% Set the change history to use \tn{part}. +% Allow control names to be hyphenated in here\dots % \begin{macrocode} \GlossaryPrologue - { - \part*{Change~History} - {\GlossaryParms\ttfamily\hyphenchar\font=`\-} - \markboth{Change~History}{Change~History} - \addcontentsline{toc}{part}{Change~History} - } + { + \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} } } +\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 @@ -2440,18 +3475,18 @@ Do not distribute a modified version of this file. % \subsection{Default configuration} % % \begin{macrocode} -\bool_if:NTF \g_@@_full_bool - { - \RecordChanges - \CodelineIndex - \EnableCrossrefs - \AlsoImplementation - } - { - \CodelineNumbered - \DisableCrossrefs - \OnlyDescription - } +\bool_if:NTF \g_@@_typeset_implementation_bool + { + \RecordChanges + \CodelineIndex + \EnableCrossrefs + \AlsoImplementation + } + { + \CodelineNumbered + \DisableCrossrefs + \OnlyDescription + } % \end{macrocode} % % @@ -2461,10 +3496,10 @@ Do not distribute a modified version of this file. % % \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. +% These definitions are only used by the \LaTeX3 documentation; they are +% not necessary for third-party users of \cls{l3doc}. In time this will +% be broken into a separate package that is specifically loaded in the +% various \pkg{expl3} modules, \emph{etc.} % % \begin{macrocode} %<*cfg> @@ -2472,49 +3507,48 @@ Do not distribute a modified version of this file. % % 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 - } - } +\tl_const: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 - } + { + \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.}} +\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} @@ -2523,14 +3557,14 @@ Do not distribute a modified version of this file. % % \begin{macrocode} \AtBeginDocument - { - \clist_map_inline:nn - { - asin, acos, atan, acot, - asinh, acosh, atanh, acoth, round, floor, ceil - } - { \exp_args:Nc \DeclareMathOperator{#1}{#1} } - } + { + \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} @@ -2546,14 +3580,14 @@ Do not distribute a modified version of this file. % % \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. +% The makeindex style \file{l3doc.ist} is used in place of the usual +% \file{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? % % Frank: at the moment we do not distribute or generate this file. -% gind.ist is used instead. +% \file{gind.ist} is used instead. % % \begin{macrocode} %<*docist> @@ -2588,179 +3622,192 @@ page_precedence "rnaA" % \section{Testing} % % \begin{function}{foo} -% \begin{syntax} -% "\foo" <something_n> \Arg{something_1} -% \end{syntax} -% Does <something_1> with <something_n> +% \begin{syntax} +% |\foo| \meta{something_n} \Arg{something_1} +% \end{syntax} +% Does \meta{something_1} with \meta{something_n} % \end{function} % % \begin{function}{.bool_set:N} -% blah +% blah % \end{function} % -% \ExplSyntaxOn \cs_set_eq:NN \c_alignment_token @ \ExplSyntaxOff -% \begin{variabledoc} +% \begin{variable} % { % \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{variable} +% +% \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> +% \begin{function}[added=2011-09-06] +% {\foo, \fooo:, \foooo:n, \foooo:x, \fooooo:n, \fooooo:c, \fooooo:x} +% \begin{syntax} +% |\example_foo:N| \meta{arg_1} +% \end{syntax} +% \meta{0123456789} % \end{function} % -% \begin{function}[TF]{\foo:N , \foo_if:c } -% Test. +% \begin{function}[TF]{\foo:N, \foo_if:c} +% Test. % \end{function} -% \begin{function}[TF,EXP]{\foo:N , \foo_if:c } -% Test. +% \begin{function}[TF,EXP]{\foo:N, \foo_if:c} +% Test. % \end{function} % % \begin{function}[added=2011-09-06,EXP]{\fffoo:N} -% Test. +% Test. % \end{function} % \begin{function}[added=2011-09-06,updated=2011-09-07,EXP]{\fffoo:N} -% Test. +% Test. % \end{function} % \begin{function}[updated=2011-09-06,EXP]{\fffoo:N} -% Test. +% Test. % \end{function} % \begin{function}[TF]{\ffffoo:N} -% Test. +% Test. % \end{function} % \begin{function}[pTF]{\ffoo:N} -% \lipsum[6] +% \lipsum[6] % \end{function} -% \begin{function}[pTF]{\ffoo:N,\ffoo:c,\ffoo:V} -% \lipsum[6] +% \begin{function}[pTF]{\ffoo:N, \ffoo:c, \ffoo:V} +% \lipsum[6] % \end{function} -% \begin{function}[pTF]{\ffoo:N,\ffoo:c} -% \lipsum[6] +% \begin{function}[pTF]{\ffoo:N, \ffoo:c} +% \lipsum[6] % \end{function} % % % \begin{function}[TF]{\ffffoo_with_very_very_very_long_name:N} -% \lipsum[1] +% \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] +% \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] +% \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] +% \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. +% \begin{macro}[aux]{\foo_aux:} +% Testing the \enquote{aux} option. % \end{macro} % -% \begin{macro}[TF]{ \foo_if:c } -% Testing `TF' option. +% \begin{macro}[TF]{\foo_if:c} +% Testing the \enquote{TF} option. % \end{macro} -% \begin{macro}[TF]{ \foo_if:c, \fooo_if:n } -% Testing `TF' option. +% \begin{macro}[TF]{\foo_if:c, \fooo_if:n} +% Testing the \enquote{TF} option. % \end{macro} % % \begin{macro}[pTF]{ \foo_if:d } -% Testing `pTF' option. +% Testing the \enquote{pTF} option. % \end{macro} % -% \begin{macro}[internal]{ \test_internal: } -% Testing `internal' option. +% \begin{macro}[internal]{\test_internal:} +% Testing the \enquote{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. +% 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 +% This is (no longer) weird. % \end{function} % % \begin{macro}{\::N} -% this is (no longer) weird +% This is (no longer) weird. % \end{macro} % -% -% % \begin{function}[EXP]{\foo}\end{function} % \begin{function}[rEXP]{\foo}\end{function} % -% here is some verbatim text: +% 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} -% +% without overriding this with \pkg{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 } +% \seq_map_inline:Nn \g_doc_macros_seq { \texttt{\enquote{#1}} \quad } % \ExplSyntaxOff % % \subsection{Functions} % \ExplSyntaxOn -% \seq_map_inline:Nn \g_doc_functions_seq { `\texttt{#1}' \quad } +% \seq_map_inline:Nn \g_doc_functions_seq { \texttt{\enquote{#1}} \quad } % \ExplSyntaxOff % % \end{implementation} |