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