% \iffalse
% collargs.edtx (this is not a .dtx file; to produce a .dtx, process it with edtx2dtx)
%% 
%% This file is a part of CollArgs, a TeX package providing a command which can
%% determine the argument scope of any command whose argument structure
%% conforms to xparse's argument specification, available at
%% https://ctan.org/pkg/advice and https://github.com/sasozivanovic/advice.
%%
%% Copyright (c) 2023- Saso Zivanovic <saso.zivanovic@guest.arnes.si>
%%                     (Sa\v{s}o \v{Z}ivanovi\'{c})
%%
%% This work may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License, either version 1.3c of this license or (at
%% your option) any later version.  The latest version of this license is in
%% https://www.latex-project.org/lppl.txt and version 1.3c or later is part of
%% all distributions of LaTeX version 2008 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%% The Current Maintainer of this work is Saso Zivanovic.
%%
%% The files belonging to this work and covered by LPPL are listed in
%% (<texmf>/doc/generic/collargs/)FILES.
%
% \fi
% 
%    \begin{macrocode}
% 
% Package CollArgs provides commands |\CollectArguments| and
% |\CollectArgumentsRaw|, which (what a surprise!) collect the arguments
% conforming to the given (slightly extended) |xparse| argument specification.
% The package was developed to help out with automemoization (see
% section~\ref{sec:code:automemoization}).  It started out as a few lines of
% code, but had grown once I realized I want automemoization to work for
% verbatim environments as well --- the environment-collecting code is based on
% Bruno Le Floch's package |cprotect| --- and had then grown some more once I
% decided to support the |xparse| argument specification in full detail, and to
% make the verbatim mode flexible enough to deal with a variety of situations.
% 
% The implementation of this package does not depend on |xparse|. Perhaps this
% is a mistake, especially as the |xparse| code is now included in the base
% \hologo{LaTeX}, but the idea was to have a light-weight package (not sure
% this is the case anymore, given all the bells and whistles), to have its
% functionality available in plain \hologo{TeX} and \hologo{ConTeXt} as well
% (same as Memoize), and, perhaps most importantly, to have the ability to
% collect the arguments verbatim.
% 
% 
% \paragraph{Identification}
%<latex>\ProvidesPackage{collargs}[2024/03/15 v1.2.0 Collect arguments of any command]
%<context>%D \module[
%<context>%D         file=t-collargs.tex,
%<context>%D      version=1.2.0,
%<context>%D        title=CollArgs,
%<context>%D     subtitle=Collect arguments of any command,
%<context>%D       author=Saso Zivanovic,
%<context>%D         date=2024-03-15,
%<context>%D    copyright=Saso Zivanovic,
%<context>%D      license=LPPL,
%<context>%D ]
%<context>\writestatus{loading}{ConTeXt User Module / collargs}
%<context>\unprotect
%<context>\startmodule[collargs]
% \paragraph{Required packages}
%<latex>\RequirePackage{pgfkeys}
%<plain>\input pgfkeys
%<context>\input t-pgfkey
%<latex>\RequirePackage{etoolbox}
%<plain,context>\input etoolbox-generic
%<plain>\edef\resetatcatcode{\catcode`\noexpand\@\the\catcode`\@\relax}
%<plain>\catcode`\@11\relax
% 
% \begin{macro}{\toksapp,\gtoksapp,\etoksapp,\xtoksapp}
%   Macros for appending to a token register.  We don't have to define them in
%   \hologo{LuaTeX}, where they exist as primitives.  Same as these primitives,
%   out macros accept either a register number or a |\toksdef|fed control
%   sequence as the (unbraced) |#1|; |#2| is the text to append.
\ifdefined\luatexversion
\else
  \def\toksapp{\toks@cs@or@num\@toksapp}
  \def\gtoksapp{\toks@cs@or@num\@gtoksapp}
  \def\etoksapp{\toks@cs@or@num\@etoksapp}
  \def\xtoksapp{\toks@cs@or@num\@xtoksapp}
  \def\toks@cs@or@num#1#2#{%
    % Test whether |#2| (the original |#1|) is a number or a control sequence.
    \ifnum-2>-1#2
      % It is a number. |\toks@cs@or@num@num| will gobble |\toks@cs@or@num@cs|
      % below.
      \expandafter\toks@cs@or@num@num
      % The register control sequence in |#2| is skipped over in the false
      % branch.
    \fi
    \toks@cs@or@num@cs{#1}{#2}%
  }
  % |#1| is one of |\@toksapp| and friends.  The second macro prefixes the
  % register number by |\toks|.
  \def\toks@cs@or@num@cs#1#2{#1{#2}}
  \def\toks@cs@or@num@num\toks@cs@or@num@cs#1#2{#1{\toks#2 }}
  % Having either |\tokscs| or |\toks<number>| in |#1|, we can finally do the
  % real job.
  \long\def\@toksapp#1#2{#1\expandafter{\the#1#2}}%
  \long\def\@etoksapp#1#2{#1\expandafter{\expanded{\the#1#2}}}%
  \long\def\@gtoksapp#1#2{\global#1\expandafter{\the#1#2}}%
  \long\def\@xtoksapp#1#2{\global#1\expandafter{\expanded{\the#1#2}}}%
\fi
% \end{macro}
% 
% \begin{macro}{\CollectArguments,\CollectArgumentsRaw}
%   |\CollectArguments| takes three arguments: the optional |#1| is the option
%   list, processed by |pgfkeys| (given the grouping structure, these options
%   will apply to all arguments); the mandatory |#2| is the |xparse|-style
%   argument specification; the mandatory |#3| is the ``next'' command (or a
%   sequence of commands).  The argument list is expected to start immediately
%   after the final argument; |\CollectArguments| parses it, effectively
%   figuring out its extent, and then passes the entire argument list to the
%   ``next'' command (as a single argument).
% 
%   |\CollectArgumentsRaw| differs only in how it takes and processes the
%   options.  For one, these should be given as a mandatory argument.
%   Furthermore, they do not take the form of a keylist, but should deploy the
%   ``programmer's interface.''  |#1| should thus be a sequence of invocations
%   of the macro counterparts of the keys defined in
%   section~\ref{sec:code:collargs:keys}, which can be recognized as starting
%   with |\collargs| followed by a capital letter, e.g.\ |\collargsCaller|.
%   Note that |\collargsSet| may also be used in |#1|.  (The ``optional,''
%   i.e.\ bracketed, argument of |\CollectArgumentsRaw| is in fact mandatory.)
\protected\def\CollectArguments{%
  \pgf@keys@utilifnextchar[\CollectArguments@i{\CollectArgumentsRaw{}}%]
}
\def\CollectArguments@i[#1]{\CollectArgumentsRaw{\collargsSet{#1}}}
\protected\def\CollectArgumentsRaw#1#2#3{%
  % This group will be closed by |\collargs@.| once we grinded through the
  % argument specification.
  \begingroup
  % Initialize category code fixing; see section~\ref{sec:code:collargs:fix}
  % for details. We have to do this before applying the settings, so that
  % |\collargsFixFromNoVerbatim| et al can take effect.
  \global\let\ifcollargs@last@verbatim\ifcollargs@verbatim
  \global\let\ifcollargs@last@verbatimbraces\ifcollargs@verbatimbraces
  \global\collargs@double@fixfalse
  % Apply the settings.
  \collargs@verbatim@wrap{#1}%
  % Initialize the space-grabber.
  \collargs@init@grabspaces
  % Remember the code to execute after collection.
  \def\collargs@next{#3}%
  % Initialize the token register holding the collected arguments.
  \ifcollargsClearArgs
    \global\collargsArgs{}%
  \fi
  % Execute the central loop macro, which expects the argument specification
  % |#2| to be delimited from the following argument tokens by a dot.
  \collargs@#2.%
}
% \end{macro}
% 
% \begin{macro}{\collargsSet}
%   This macro processes the given keys in the |/collargs| keypath.  When it is
%   used to process options given by the end user (the optional argument to
%   |\CollectArguments|, and the options given within the argument
%   specification, using the new modifier |&|), its invocation should be
%   wrapped in |\collargs@verbatim@wrap| to correctly deal with the changes of
%   the verbatim mode.
\def\collargsSet#1{\pgfqkeys{/collargs}{#1}}
% \end{macro}
%
% \subsubsection{The keys}
% \label{sec:code:collargs:keys}
% 
% \begin{macro}{\collargs@cs@cases}
%   If the first argument of this auxiliary macro is a single control sequence,
%   then the second argument is executed.  If the first argument starts with a
%   control sequence but this control sequence does not form the entire
%   argument, the third argument is executed.  Otherwise, the fourth argument
%   is executed. 
% 
%   This macro is defined in package CollArgs because we use it in key |caller|
%   below, but it is really useful in package Auto, where having it we don't
%   have to bother the end-user with a separate keys for commands and
%   environments, but automatically detect whether the argument of |auto| and
%   (|de|)|activate| is a command or an environment.
\def\collargs@cs@cases#1{\collargs@cs@cases@i#1\collargs@cs@cases@end}
\let\collargs@cs@cases@end\relax
\def\collargs@cs@cases@i{\futurelet\collargs@temp\collargs@cs@cases@ii}
\def\collargs@cs@cases@ii#1#2\collargs@cs@cases@end{%
  \ifcat\noexpand\collargs@temp\relax
    \ifx\relax#2\relax
      \expandafter\expandafter\expandafter\@firstofthree
    \else
      \expandafter\expandafter\expandafter\@secondofthree
    \fi
  \else
    \expandafter\@thirdofthree
  \fi
}
\def\@firstofthree#1#2#3{#1}
\def\@secondofthree#1#2#3{#2}
\def\@thirdofthree#1#2#3{#3}
% \end{macro}
% 
% \begin{collargskey}{caller}
%   \begin{macro}{\collargsCaller}
%     Every macro which grabs a part of the argument list will be accessed
%     through the ``caller'' control sequence, so that \hologo{TeX}'s reports
%     of any errors in the argument structure can contain a command name
%     familiar to the author.\footnote{The idea is borrowed from package
%     |environ|, which is in turn based on code from |amsmath|.}  For example,
%     if the argument list ``originally'' belonged to command |\foo| with
%     argument structure |r()|, but no parentheses follow in the input, we want
%     \hologo{TeX} to complain that |Use of \foo doesn't match its definition|.
%     This can be achieved by setting |caller=\foo|; the default is
%     |caller=\CollectArguments|, which is still better than seeing an error
%     involving some random internal control sequence.  It is also ok to set an
%     environment name as the caller, see below.
% 
%     The key and macro defined below store the caller control sequence into
%     |\collargs@caller|, e.g.\ when we say |caller=\foo|, we effectively
%     execute |\def\collargs@caller{\foo}|.
\collargsSet{
  caller/.code={\collargsCaller{#1}},
}
\def\collargsCaller#1{%
  \collargs@cs@cases{#1}{%
    \let\collargs@temp\collargs@caller@cs
  }{%
    \let\collargs@temp\collargs@caller@csandmore
  }{%
    \let\collargs@temp\collargs@caller@env
  }%
  \collargs@temp{#1}%
}
\def\collargs@caller@cs#1{%
  % If |#1| is a single control sequence, just use that as the caller.
  \def\collargs@caller{#1}%
}
\def\collargs@caller@csandmore#1{%
  % If |#1| starts with a control sequence, we don't complain, but convert the
  % entire |#1| into a control sequence.
  \begingroup
  \escapechar -1
  \expandafter\endgroup
  \expandafter\def\expandafter\collargs@caller\expandafter{%
    \csname\string#1\endcsname
  }%
}
\def\collargs@caller@env#1{%
  % If |#1| does not start with a control sequence, we assume that is an
  % environment name, so we prepend |start| in \hologo{ConTeXt}, and dress it
  % up into |\begin{#1}| in \hologo{LaTeX}.
  \expandafter\def\expandafter\collargs@caller\expandafter{%
    \csname
    %<context>start%
    %<latex>begin{%
    #1%
    %<latex>}%
    \endcsname
  }%
}
\collargsCaller\CollectArguments
%   \end{macro}
% \end{collargskey}
% 
% \begin{macro}{\ifcollargs@verbatim,\ifcollargs@verbatimbraces}
%       The first of these conditional
%         signals that we're collecting the arguments in one of the verbatim
%         modes; the second one signals the |verb| mode in particular.
\newif\ifcollargs@verbatim
\newif\ifcollargs@verbatimbraces
% \end{macro}
% 
% \begin{collargskey}{verbatim, verb, no verbatim}
% \begin{macro}{\collargs@verbatim@wrap}
%   These keys set the verbatim mode macro which will be executed by
%   |\collargsSet| after processing all keys.  
%   The verbatim mode macros |\collargsVerbatim|, |\collargsVerb| and
%   |\collargsNoVerbatim| are somewhat complex; we postpone their definition
%   until section~\ref{sec:code:collargs:verbatim}.  Their main effect is to
%   set conditionals |\ifcollargs@verbatim| and |\ifcollargs@verbatimbraces|,
%   which are be inspected by the argument type handlers --- and to make
%   the requested category code changes, of course.
% 
%   Here, note that the verbatim-selection code is not executed while the
%   keylist is being processed.  Rather, the verbatim keys simply set the macro
%   which will be executed \emph{after} the keylist is processed, and this is
%   why processing of a keylist given by the user must be always wrapped in
%   |\collargs@verbatim@wrap|.
\collargsSet{
  verbatim/.code={\let\collargs@apply@verbatim\collargsVerbatim},
  verb/.code={\let\collargs@apply@verbatim\collargsVerb},
  no verbatim/.code={\let\collargs@apply@verbatim\collargsNoVerbatim},
}
\def\collargs@verbatim@wrap#1{%
  \let\collargs@apply@verbatim\relax
  #1%
  \collargs@apply@verbatim
}
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{fix from verbatim, fix from verb, fix from no verbatim}
%   \begin{macro}{\collargsFixFromVerbatim,\collargsFixFromVerb,\collargsFixFromNoVerbatim}
%     These keys and macros should be used to request a category code fix, when
%     the offending tokenization took place prior to invoking
%     |\CollectArguments|; see section~\ref{sec:code:collargs:fix} for details.
%     While I assume that only |\collargsFixFromNoVerbatim| will ever be used
%     (and it is used by |\mmz|), we provide macros for all three transitions,
%     for completeness.\indentmacrocode
\collargsSet{
  fix from verbatim/.code={\collargsFixFromVerbatim},
  fix from verb/.code={\collargsFixFromVerb},
  fix from no verbatim/.code={\collargsFixFromNoVerbatim},
}
% \noindentmacrocode
\def\collargsFixFromNoVerbatim{%
  \global\collargs@fix@requestedtrue
  \global\let\ifcollargs@last@verbatim\iffalse
}
\def\collargsFixFromVerbatim{%
  \global\collargs@fix@requestedtrue
  \global\let\ifcollargs@last@verbatim\iftrue
  \global\let\ifcollargs@last@verbatimbraces\iftrue
}
\def\collargsFixFromVerb{%
  \global\collargs@fix@requestedtrue
  \global\let\ifcollargs@last@verbatim\iftrue
  \global\let\ifcollargs@last@verbatimbraces\iffalse
}
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{braces}
%   Set the characters which are used as the grouping characters in the full
%   verbatim mode.  The user is only required to do this when multiple
%   character pairs serve as the grouping characters.  The underlying macro,
%   |\collargsBraces|, will be defined in
%   section~\ref{sec:code:collargs:verbatim}.
\collargsSet{
  braces/.code={\collargsBraces{#1}}%
}
% \end{collargskey}
% 
% \begin{collargskey}{environment}
%   \begin{macro}{\collargsEnvironment}
%     Set the environment name. 
%     \indentmacrocode
\collargsSet{
  environment/.estore in=\collargs@b@envname
}
\def\collargsEnvironment#1{\edef\collargs@b@envname{#1}}
\collargsEnvironment{}
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{begin tag, end tag, tags}
%   \begin{macro}{\ifcollargsBeginTag,\ifcollargsEndTag,\ifcollargsAddTags}
%           When |begin tag|\slash|end tag| is in effect, the begin\slash end-tag will
%           be will be prepended/appended to the environment body. |tags| is a
%           shortcut for setting |begin tag| and |end tag| simultaneously.
%           \indentmacrocode
\collargsSet{
  begin tag/.is if=collargsBeginTag,
  end tag/.is if=collargsEndTag,
  tags/.style={begin tag=#1, end tag=#1},
  tags/.default=true,
}
\newif\ifcollargsBeginTag
\newif\ifcollargsEndTag
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{ignore nesting}
%   \begin{macro}{\ifcollargsIgnoreNesting}
%       When this key is in effect, we will
%         ignore any \cs{begin}\marg{name}s and simply grab everything up to
%         the first \cs{end}\marg{name} (again, the markers are automatically
%         adapted to the format).
\collargsSet{
  ignore nesting/.is if=collargsIgnoreNesting,
}
\newif\ifcollargsIgnoreNesting
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{ignore other tags}
%   \begin{macro}{\ifcollargsIgnoreOtherTags}
%       This key is only relevant in the
%         non-verbatim and partial verbatim modes in \hologo{LaTeX}.  When it
%         is in effect, CollArgs checks the environment name following each
%         |\begin| and |\end|, ignoring the tags with an environment name other
%         than |\collargs@b@envname|.
\collargsSet{
  ignore other tags/.is if=collargsIgnoreOtherTags,
}
\newif\ifcollargsIgnoreOtherTags
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}[noindex]{(append/prepend) (pre/post)processor}
%   \begin{macro}[noindex]{\collargs(Append/Prepend)(Pre/Post)processor}
%     \begin{collargskey}[noprint]{append preprocessor, prepend preprocessor,
%       append postprocessor, prepend postprocessor}
%       \begin{macro}[noprint]{\collargsAppendPreprocessor,\collargsPrependPreprocessor,\collargsAppendPostprocessor,\collargsPrependPostprocessor}
%         These keys and
%         macros populate the list of preprocessors,
%         |\collargs@preprocess@arg|, and the list of post-processors,
%         |\collargs@postprocess@arg|, executed in |\collargs@appendarg|.
\collargsSet{
  append preprocessor/.code={\collargsAppendPreprocessor{#1}},
  prepend preprocessor/.code={\collargsPrependPreprocessor{#1}},
  append postprocessor/.code={\collargsAppendPostprocessor{#1}},
  prepend postprocessor/.code={\collargsPrependPostprocessor{#1}},
}
\def\collargsAppendPreprocessor#1{\appto\collargs@preprocess@arg{#1}}
\def\collargsPrependPreprocessor#1{\preto\collargs@preprocess@arg{#1}}
\def\collargsAppendPostprocessor#1{\appto\collargs@postprocess@arg{#1}}
\def\collargsPrependPostprocessor#1{\preto\collargs@postprocess@arg{#1}}
% \end{macro}
% \end{collargskey}
% \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}[noindex]{clear (pre/post)processors}
%   \begin{macro}[noindex]{\collargsClear(Pre/Post)processors}
%     \begin{collargskey}[noprint]{clear preprocessors, clear postprocessors}
%       \begin{macro}[noprint]{\collargsClearPreprocessors,\collargsClearPostprocessors}
%         These keys and macros
%         clear the pre- and post-processor lists, which are initially empty as
%         well.
\def\collargs@preprocess@arg{}
\def\collargs@postprocess@arg{}
\collargsSet{
  clear preprocessors/.code={\collargsClearPreprocessors},
  clear postprocessors/.code={\collargsClearPostprocessors},
}
\def\collargsClearPreprocessors{\def\collargs@preprocess@arg{}}%
\def\collargsClearPostprocessors{\def\collargs@postprocess@arg{}}%
% \end{macro}
% \end{collargskey}
% \end{macro}
% \end{collargskey}
%
% \begin{collargskey}[noindex]{(append/prepend) expandable (pre/post)processor}
%   \begin{macro}[noindex]{\collargs(Append/Prepend)Expandable(Pre/Post)processor}
%     \begin{collargskey}[noprint]{append expandable preprocessor, prepend expandable preprocessor, append expandable postprocessor, prepend expandable postprocessor}
%       \begin{macro}[noprint]{\collargsAppendExpandablePreprocessor,\collargsPrependExpandablePreprocessor,\collargsAppendExpandablePostprocessor,\collargsPrependExpandablePostprocessor}
%         These keys and macros simplify the definition of expandable
%         processors.  Note that expandable processors are added to the same
%         list as non-expandable processors.
\collargsSet{
  append expandable preprocessor/.code={\collargsAppendExpandablePreprocessor{#1}},
  prepend expandable preprocessor/.code={\collargsPrependExpandablePreprocessor{#1}},
  append expandable postprocessor/.code={\collargsAppendExpandablePostprocessor{#1}},
  prepend expandable postprocessor/.code={\collargsPrependExpandablePostprocessor{#1}},
}
\def\collargsAppendExpandablePreprocessor#1{%
  \appto\collargs@preprocess@arg{%
    \collargsArg\expandafter{\expanded{#1}}%
  }%
}
\def\collargsPrependExpandablePreprocessor#1{%
  \preto\collargs@preprocess@arg{%
    \collargsArg\expandafter{\expanded{#1}}%
  }%
}
\def\collargsAppendExpandablePostprocessor#1{%
  \appto\collargs@postprocess@arg{%
    \collargsArg\expandafter{\expanded{#1}}%
  }%
}
\def\collargsPrependExpandablePostprocessor#1{%
  \preto\collargs@postprocess@arg{%
    \collargsArg\expandafter{\expanded{#1}}%
  }%
}
% \end{macro}
% \end{collargskey}
% \end{macro}
% \end{collargskey}
% 
% 
% \begin{collargskey}{no delimiters}
%   \begin{macro}{\ifcollargsNoDelimiters}
%       When this conditional is in effect, the
%         delimiter wrappers set by |\collargs@wrap| are ignored by
%         |\collargs@appendarg|.
\collargsSet{%
  no delimiters/.is if=collargsNoDelimiters,
}
\newif\ifcollargsNoDelimiters
%   \end{macro}
% \end{collargskey}
%
% \begin{collargskey}{clear args}
%   \begin{macro}{\ifcollargsClearArgs}
%       When this conditional is set to |false|, the global token register
%       |\collargsArgs| receiving the collected arguments is not cleared prior
%       to argument collection.
\collargsSet{%
  clear args/.is if=collargsClearArgs,
}
\newif\ifcollargsClearArgs
\collargsClearArgstrue
%     \end{macro}
%   \end{collargskey}
%
% \begin{collargskey}{return}
%   \begin{macro}{\collargsReturn}
%     Exiting |\CollectArguments|, should the next-command be followed by the
%     braced collected arguments, collected arguments as they are, or nothing?
\collargsSet{%
  return/.is choice,
  return/braced/.code=\collargsReturnBraced,
  return/plain/.code=\collargsReturnPlain,
  return/no/.code=\collargsReturnNo,
}
\def\collargsReturnBraced{\def\collargsReturn{0}}
\def\collargsReturnPlain{\def\collargsReturn{1}}
\def\collargsReturnNo{\def\collargsReturn{2}}
\collargsReturnBraced
%   \end{macro}
% \end{collargskey}
% 
% \begin{collargskey}{alias}
%   \begin{macro}{\collargsAlias}
%
\collargsSet{%
  alias/.code 2 args=\collargsAlias{#1}{#2}%
}
\def\collargsAlias#1#2{%
  \csdef{collargs@#1}{\collargs@@@#2}%
}
% \end{macro}
% \end{collargskey}
% 
% 
% 
% \subsubsection{The central loop}
% \label{sec:code:collargs:central-loop}
%
% The central loop is where we grab the next \meta{token} from the argument
% specification and execute the corresponding argument type or modifier
% handler, |\collargs@|\meta{token}.  The central loop consumes the argument
% type \meta{token}; the handler will see the remainder of the argument
% specification (which starts with the arguments to the argument type, if any,
% e.g.\ by |()| of |d()|), followed by a dot, and then the tokens list from
% which the arguments are to be collected.  It is the responsibility of handler
% to preserve the rest of the argument specification and reexecute the central
% loop once it is finished.
% 
% \begin{macro}{\collargs@}
%   Each argument is processed in a group to allow for local settings.  This
%   group is closed by |\collargs@appendarg|.
\def\collargs@{%
  \begingroup
  \collargs@@@
}
% \end{macro}
% 
% \begin{macro}{\collargs@@@}
%   This macro is where modifier handlers reenter the central loop --- we don't
%   want modifers to open a group, because their settings should remain in
%   effect until the next argument.  Furthermore, modifiers do not trigger
%   category code fixes.
\def\collargs@@@#1{%
  \collargs@in@{#1}{&+!>.}%
  \ifcollargs@in@
    \expandafter\collargs@@@iii
  \else
    \expandafter\collargs@@@i
  \fi
  #1%
}
\def\collargs@@@i#1.{%
  % Fix the category code of the next argument token, if necessary, and then
  % proceed with the main loop.
  \collargs@fix{\collargs@@@ii#1.}%
}
% Reset the fix request and set the last verbatim conditionals to the current
% state.
\def\collargs@@@ii{%
  \global\collargs@fix@requestedfalse
  \global\let\ifcollargs@last@verbatim\ifcollargs@verbatim
  \global\let\ifcollargs@last@verbatimbraces\ifcollargs@verbatimbraces
  \collargs@@@iii
}
% Call the modifier or argument type handler denoted by the first token of the
% remainder of the argument specification.
\def\collargs@@@iii#1{%
  \ifcsname collargs@#1\endcsname
    \csname collargs@#1\expandafter\endcsname
  \else
    % We throw an error if the token refers to no argument type or modifier.
    \collargs@error@badtype{#1}%
  \fi
}
% Throwing an error stops the processing of the argument specification, and
% closes the group opened in |\collargs@i|.
\def\collargs@error@badtype#1#2.{%
  \PackageError{collargs}{Unknown xparse argument type or modifier "#1"
    for "\expandafter\string\collargs@caller\space"}{}%
  \endgroup
}
% \end{macro}
% 
% {\catcode`\&=11
% \begin{macro}{\collargs@&}
%   We extend the |xparse| syntax with modifier |&|, which applies the given
%   options to the following (and only the following) argument.  If |&| is
%   followed by another |&|, the options are expected to occur in the raw
%   format, like the options given to |\CollectArgumentsRaw|.  Otherwise, the
%   options should take the form of a keylist, which will be processed by
%   |\collargsSet|.  In any case, the options should be given within the
%   argument specification, immediately following the (single or double) |&|.
\csdef{collargs@&}{%
  \futurelet\collargs@temp\collargs@amp@i
}
\def\collargs@amp@i{%
  % In \hologo{ConTeXt}, |&| has character code ``other'' in the text.
  %<!context>\ifx\collargs@temp&%
  %<context>\expandafter\ifx\detokenize{&}\collargs@temp
    \expandafter\collargs@amp@raw
  \else
    \expandafter\collargs@amp@set
  \fi
}
\def\collargs@amp@raw#1#2{%
  \collargs@verbatim@wrap{#2}%
  \collargs@@@
}
\def\collargs@amp@set#1{%
  \collargs@verbatim@wrap{\collargsSet{#1}}%
  \collargs@@@
}
% \end{macro}}
% 
% \begin{macro}[noindex]{\collargs@+}
%   \MyIndex{collargs@&plus;}{\texttt{\textbackslash collargs@+}}{main}
%   This modifier makes the next argument long, i.e.\ accept paragraph tokens.
\csdef{collargs@+}{%
  \collargs@longtrue
  \collargs@@@
}
\newif\ifcollargs@long
% \end{macro}
% 
% \begin{macro}{\collargs@>}
%   We can simply ignore the processor modifier. (This, |xparse|'s processor,
%   should not be confused with CollArgs's processors, which are set using
%   keys |append preprocessor| etc.)
\csdef{collargs@>}#1{\collargs@@@}
% \end{macro}
%
% \begin{macro}[noindex]{\collargs@!}
%   \MyIndex{collargs@&excl;}{\texttt{\textbackslash collargs@\exclamationmark}}{main}
%   Should we accept spaces before an optional argument following a mandatory
%   argument (\pkg{xparse} manual, \S1.1)?  By default, yes.  This modifier is
%   only applicable to types |d| and |t|, and derived types, but, unlike
%   |xparse|, we don't bother to enforce this; when used with other types, |!|
%   simply has no effect.
\csdef{collargs@!}{%
  \collargs@grabspacesfalse
  \collargs@@@
}
% \end{macro}
% 
% \begin{macro}{\collargsArgs}
%   This token register is where we store the collected argument tokens.  All
%   assignments to this register are global, because it needs to survive the
%   groups opened for individual arguments.
\newtoks\collargsArgs
% \end{macro}
%
% \begin{macro}{\collargsArg}
%   An auxiliary, but publicly available token register, used for processing
%   the argument, and by some argument type handlers.
\newtoks\collargsArg
% \end{macro}
% 
% \begin{macro}{\collargs@.}
%   This fake argument type is used to signal the end of the argument list.
%   Note that this really counts as an extension of the |xparse| argument
%   specification.
\csdef{collargs@.}{%
  % Close the group opened in |\collargs@|.
  \endgroup
  % Close the main |\CollectArguments| group, fix the category code of the next
  % token if necessary, and execute the next-code, followed by the collected
  % arguments in braces.  Any over-grabbed spaces are reinserted into the input
  % stream, non-verbatim.
  \expanded{%
    \endgroup
    \noexpand\collargs@fix{%
      \expandonce\collargs@next
        \ifcase\collargsReturn\space
          {\the\collargsArgs}%
        \or
          \the\collargsArgs
        \fi
      \collargs@spaces
    }%
  }%
}
% \end{macro}
% 
% \subsubsection{Auxiliary macros}
% \label{sec:code:collargs:aux}
%
% \begin{macro}{\collargs@appendarg}
%   This macro is used by the argument type
%   handlers to append the collected argument to the storage
%   (|\collargsArgs|).
\long\def\collargs@appendarg#1{%
  % Temporarily store the collected argument into a token register.  The
  % processors will manipulate the contents of this register.
  \collargsArg={#1}%
  % This will clear the double-fix conditional, and potentially request a
  % normal, single fix.  We can do this here because this macro is only called
  % when something is actually collected.  For details, see
  % section~\ref{sec:code:collargs:fix}.
  \ifcollargs@double@fix
    \collargs@cancel@double@fix
  \fi
  % Process the argument with user-definable preprocessors, the wrapper defined
  % by the argument type, and user-definable postprocessors.
  \collargs@preprocess@arg
  \ifcollargsNoDelimiters
  \else
    \collargs@process@arg
  \fi
  \collargs@postprocess@arg
  % Append the processed argument, preceded by any grabbed spaces (in the
  % correct mode), to the storage.
  \xtoksapp\collargsArgs{\collargs@grabbed@spaces\the\collargsArg}%
  % Initialize the space-grabber.
  \collargs@init@grabspaces
  % Once the argument was appended to the list, we can close its group, opened
  % by |\collargs@|.
  \endgroup
}
% \end{macro}
% 
% \begin{macro}{\collargs@wrap}
%   This macro is used by argument type handlers to declare their delimiter
%   wrap, like square brackets around the optional argument of type |o|.  It
%   uses |\collargs@addwrap|, defined in section~\ref{sec:code:collargs:keys},
%   but adds to |\collargs@process@arg|, which holds the delimiter wrapper
%   defined by the argument type handler.  Note that this macro \emph{appends}
%   a wrapper, so multiple wrappers are allowed --- this is used by type |e|
%   handler.
\def\collargs@wrap#1{%
  \appto\collargs@process@arg{%
    \long\def\collargs@temp##1{#1}%
    \expandafter\expandafter\expandafter\collargsArg
    \expandafter\expandafter\expandafter{%
      \expandafter\collargs@temp\expandafter{\the\collargsArg}%
    }%
  }%
}
\def\collargs@process@arg{}
% \end{macro}
%
% \begin{macro}{\collargs@defcollector,\collargs@defusecollector,\collargs@letusecollector}
%     These macros streamline the usage of
%     the ``caller'' control sequence.  They are like a |\def|, but should not
%     be given the control sequence to define, as they will automatically
%     define the control sequence residing in |\collargs@caller|; the usage is
%     thus |\collargs@defcollector<parameters>{<definition>}|.  For example, if
%     |\collargs@caller| holds |\foo|, |\collargs@defcollector#1{(#1)}| is
%     equivalent to |\def\foo#1{(#1)}|.  Macro |\collargs@defcollector| will
%     only define the caller control sequence to be the collector, while
%     |\collargs@defusecollector| will also immediately execute it.
\def\collargs@defcollector#1#{%
  \ifcollargs@long\long\fi
  \expandafter\def\collargs@caller#1%
}
\def\collargs@defusecollector#1#{%
  \afterassignment\collargs@caller
  \ifcollargs@long\long\fi
  \expandafter\def\collargs@caller#1%
}
\def\collargs@letusecollector#1{%
  \expandafter\let\collargs@caller#1%
  \collargs@caller
}
\newif\ifcollargs@grabspaces
\collargs@grabspacestrue
% \end{macro}
% 
% \begin{macro}{\collargs@init@grabspaces}
%   The space-grabber macro
%   |\collargs@grabspaces| should be initialized by executing this macro.  If
%   |\collargs@grabspaces| is called twice without an intermediate
%   initialization, it will assume it is in the same position in the input
%   stream and simply bail out.
\def\collargs@init@grabspaces{%
  \gdef\collargs@gs@state{0}%
  \gdef\collargs@spaces{}%
  \gdef\collargs@otherspaces{}%
}
% \end{macro}
% 
% \begin{macro}{\collargs@grabspaces}
%   This auxiliary macro grabs any following
%   spaces, and then executes the next-code given as the sole argument.  The
%   spaces will be stored into two macros, |\collargs@spaces| and
%   |\collargs@otherspaces|, which store the spaces in the non-verbatim and the
%   verbatim form.  With the double storage, we can grab the spaces in the
%   verbatim mode and use them non-verbatim, or vice versa.  The macro takes a
%   single argument, the code to execute after maybe grabbing the spaces.
% 
\def\collargs@grabspaces#1{%
  \edef\collargs@gs@next{\unexpanded{#1}}%
  \ifnum\collargs@gs@state=0
    \gdef\collargs@gs@state{1}%
    \expandafter\collargs@gs@i
  \else
    \expandafter\collargs@gs@next
  \fi
}
\def\collargs@gs@i{%
  \futurelet\collargs@temp\collargs@gs@g
}
% We check for grouping characters even in the verbatim mode, because we might
% be in the partial verbatim.
\def\collargs@gs@g{%
  \ifcat\noexpand\collargs@temp\bgroup
    \expandafter\collargs@gs@next
  \else
    \ifcat\noexpand\collargs@temp\egroup
      \expandafter\expandafter\expandafter\collargs@gs@next
    \else
      \expandafter\expandafter\expandafter\collargs@gs@ii
    \fi
  \fi
}
\def\collargs@gs@ii{%
  \ifcollargs@verbatim
    \expandafter\collargs@gos@iii
  \else
    \expandafter\collargs@gs@iii
  \fi
}
% This works because the character code of a space token is always 32.
\def\collargs@gs@iii{%
  \expandafter\ifx\space\collargs@temp
    \expandafter\collargs@gs@iv
  \else
    \expandafter\collargs@gs@next
  \fi
}
\expandafter\def\expandafter\collargs@gs@iv\space{%
  \gappto\collargs@spaces{ }%
  \xappto\collargs@otherspaces{\collargs@otherspace}%
  \collargs@gs@i
}
% We need the space of category 12 above.
\begingroup\catcode`\ =12\relax\gdef\collargs@otherspace{ }\endgroup
\def\collargs@gos@iii#1{%
  % Macro |\collargs@cc| recalls the ``outside'' category code of character
  % |#1|; see section~\ref{sec:code:collargs:verbatim}.
  \ifnum\collargs@cc{#1}=10
    % We have a space.
    \expandafter\collargs@gos@iv
  \else
    \ifnum\collargs@cc{#1}=5
      % We have a newline.
      \expandafter\expandafter\expandafter\collargs@gos@v
    \else
      \expandafter\expandafter\expandafter\collargs@gs@next
    \fi
  \fi
  #1%
}
\def\collargs@gos@iv#1{%
  \gappto\collargs@otherspaces{#1}%
  % No matter how many verbatim spaces we collect, they equal a single
  % non-verbatim space.
  \gdef\collargs@spaces{ }%
  \collargs@gs@i
}
\def\collargs@gos@v{%
  % Only add the first newline.
  \ifnum\collargs@gs@state=2
    \expandafter\collargs@gs@next
  \else
    \expandafter\collargs@gs@vi
  \fi
}
\def\collargs@gs@vi#1{%
  \gdef\collargs@gs@state{2}%
  \gappto\collargs@otherspaces{#1}%
  \gdef\collargs@spaces{ }%
  \collargs@gs@i
}
% \end{macro}
% 
% \begin{macro}{\collargs@maybegrabspaces}
%   This macro grabs any following spaces, but it will do so only when
%   conditional |\ifcollargs@grabspaces|, which can be \emph{un}set by modifier
%     |!|, is in effect.  The macro is used by handlers for types |d| and |t|.
\def\collargs@maybegrabspaces{%
  \ifcollargs@grabspaces
    \expandafter\collargs@grabspaces
  \else
    \expandafter\@firstofone
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@grabbed@spaces}
%   This macro expands to either the verbatim
%   or the non-verbatim variant of the grabbed spaces, depending on the
%   verbatim mode in effect at the time of expansion.
\def\collargs@grabbed@spaces{%
  \ifcollargs@verbatim
    \collargs@otherspaces
  \else
    \collargs@spaces
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@reinsert@spaces}
%   Inserts the grabbed spaces back into the
%   input stream, but with the category code appropriate for the verbatim mode
%   then in effect.  After the insertion, the space-grabber is initialized and
%   the given next-code is executed in front of the inserted spaces.
\def\collargs@reinsert@spaces#1{%
  \expanded{%
    \unexpanded{%
      \collargs@init@grabspaces
      #1%
    }%
    \collargs@grabbed@spaces
  }%
}
% \end{macro}
% 
% \begin{macro}{\collargs@ifnextcat}
%   An adaptation of |\pgf@keys@utilifnextchar|
%   which checks whether the \emph{category} code of the next non-space
%   character matches the category code of |#1|.
\long\def\collargs@ifnextcat#1#2#3{%
  \let\pgf@keys@utilreserved@d=#1%
  \def\pgf@keys@utilreserved@a{#2}%
  \def\pgf@keys@utilreserved@b{#3}%
  \futurelet\pgf@keys@utillet@token\collargs@ifncat}
\def\collargs@ifncat{%
  \ifx\pgf@keys@utillet@token\pgf@keys@utilsptoken
    \let\pgf@keys@utilreserved@c\collargsxifnch
  \else
    \ifcat\noexpand\pgf@keys@utillet@token\pgf@keys@utilreserved@d
      \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@a
    \else
      \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@b
    \fi
  \fi
  \pgf@keys@utilreserved@c}
{%
  \def\:{\collargs@xifncat}
  \expandafter\gdef\: {\futurelet\pgf@keys@utillet@token\collargs@ifncat}
}
% \end{macro} 
% 
% \begin{macro}{\collargs@forrange}
%   This macro executes macro |\collargs@do| for every integer from |#1| and
%   |#2|, both inclusive.  |\collargs@do| should take a single parameter, the
%   current number.
\def\collargs@forrange#1#2{%
  \expanded{%
     \noexpand\collargs@forrange@i{\number#1}{\number#2}%
   }%
 }
\def\collargs@forrange@i#1#2{%
  \ifnum#1>#2 %
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {%
    \collargs@do{#1}%
    \expandafter\collargs@forrange@i\expandafter{\number\numexpr#1+1\relax}{#2}%
  }%
}
% \end{macro}
% 
% \begin{macro}{\collargs@forranges}
%   This macro executes macro |\collargs@do| for every integer falling into the
%   ranges specified in |#1|.  The ranges should be given as a comma-separated
%   list of |from-to| items, e.g.\ |1-5,10-11|.
\def\collargs@forranges{\forcsvlist\collarg@forrange@i}
\def\collarg@forrange@i#1{\collarg@forrange@ii#1-}
\def\collarg@forrange@ii#1-#2-{\collargs@forrange{#1}{#2}}
% \end{macro}
% 
% \begin{macro}{\collargs@percentchar}
%   This macro holds the percent character of category 12.
\begingroup
\catcode`\%=12
\gdef\collargs@percentchar{%}
\endgroup
% \end{macro}
% 
% 
% \subsubsection{The handlers}
% \label{sec:code:collargs:handlers}
%
% \begin{macro}{\collargs@l}
%   We will first define the handler for the very funky argument type |l|,
%   which corresponds to \hologo{TeX}'s |\def\foo#1#{...}|, which grabs (into
%   |#1|) everything up to the first opening brace --- not because this type is
%   important or even recommended to use, but because the definition of the
%   handler is very simple, at least for the non-verbatim case.
%   
\def\collargs@l#1.{%
  % Any pre-grabbed spaces in fact belong into the argument.
  \collargs@reinsert@spaces{\collargs@l@i#1.}%
}
\def\collargs@l@i{%
  % We request a correction of the category code of the delimiting brace if the
  % verbatim mode changes for the next argument; for details, see
  % section~\ref{sec:code:collargs:fix}.
  \global\collargs@fix@requestedtrue
  % Most handlers will branch into the verbatim and the non-verbatim part using
  % conditional |\ifcollargs@verbatim|.  This handler is a bit special, because
  %   it needs to distinguish verbatim and non-verbatim \emph{braces}, and
  %   braces are verbatim only in the full verbatim mode, i.e.\ when
  %   |\ifcollargs@verbatimbraces| is true.
  \ifcollargs@verbatimbraces
    \expandafter\collargs@l@verb
  \else
    \expandafter\collargs@l@ii
  \fi
}
% We grab the rest of the argument specification (|#1|), to be reinserted into
% the token stream when we reexecute the central loop.
\def\collargs@l@ii#1.{%
  % In the non-verbatim mode, we merely have to define and execute the
  % collector macro.  The parameter text |##1##| (note the doubled hashes),
  % which will put everything up to the first opening brace into the first
  % argument, looks funky, but that's all.
  \collargs@defusecollector##1##{%
    % We append the collected argument, |##1|, to |\collargsArgs|, the token
    % register holding the collected argument tokens.
    \collargs@appendarg{##1}%
    % Back to the central loop, with the rest of the argument specification
    % reinserted.
    \collargs@#1.%
  }%
}
\def\collargs@l@verb#1.{%
  % In the verbatim branch, we need to grab everything up to the first opening
  % brace of category code 12, so we want to define the collector with
  % parameter text |##1{|, with the opening brace of category 12.  We have
  % stored this token in macro |\collargs@other@bgroup|, which we now need to
  % expand.
  \expandafter\collargs@defusecollector
  \expandafter##\expandafter1\collargs@other@bgroup{%
    % Appending the argument works the same as in the non-verbatim case.
    \collargs@appendarg{##1}%
    % Reexecuting the central loop macro is a bit more involved, as we need to
    % reinsert the verbatim opening brace (contrary to the regular brace above,
    % the verbatim brace is consumed by the collector macro) back into the
    % token stream, behind the reinserted argument specification.
    \expanded{%
      \noexpand\collargs@\unexpanded{#1.}%
      \collargs@other@bgroup
    }%
  }%
}
% \end{macro}
% 
% \begin{macro}{\collargs@u}
%   Another weird type --- |u|\meta{tokens} reads everything up to the given
%   \meta{tokens}, i.e.\ this is \hologo{TeX}'s
%   |\def\foo#1|\meta{tokens}|{...}| --- but again, simple enough to allow us
%   to showcase solutions to two recurring problems.  
% 
%   We start by branching into the verbatim mode (full or partial) or the
%   non-verbatim mode.
\def\collargs@u{%
  \ifcollargs@verbatim
    \expandafter\collargs@u@verb
  \else
    \expandafter\collargs@u@i
  \fi
}
% To deal with the verbatim mode, we only need to convert the above
% \meta{tokens} (i.e.\ the argument of |u| in the argument specification) to
% category 12, i.e.\ we have to |\detokenize| them.  Then, we may proceed as in
% the non-verbatim branch, |\collargs@u@ii|.
\def\collargs@u@verb#1{%
  % The |\string| here is a temporary solution to a problem with spaces.  Our
  % verbatim mode has them of category ``other'', but |\detokenize| produces a
  % space of category ``space'' behind control words. ^^A todo
  \expandafter\collargs@u@i\expandafter{\detokenize\expandafter{\string#1}}%
}
% We then reinsert any pre-grabbed spaces into the stream, but we take care not
% to destroy the braces around our delimiter in the argument specification.
\def\collargs@u@i#1#2.{%
  \collargs@reinsert@spaces{\collargs@u@ii{#1}#2.}%
}
\def\collargs@u@ii#1#2.{%
  % |#1| contains the delimiter tokens, so |##1| below will receive everything
  % in the token stream up to these.  But we have a problem: if we defined the
  % collector as for the non-verbatim |l|, and the delimiter happened to be
  % preceded by a single brace group, we would lose the braces.  For example,
  % if the delimiter was |-| and we received |{foo}-|, we would collect |foo-|.
  % We solve this problem by inserting |\collargs@empty| (with an empty
  % definition) into the input stream (at the end of this macro) --- this way,
  % the delimiter can never be preceded by a single brace group --- and then
  % expanding it away before appending to storage (within the argument of
  % |\collargs@defusecollector|).
  \collargs@defusecollector##1#1{%
    % Define the wrapper which will add the delimiter tokens (|#1|) after the
    % collected argument.  The wrapper will be applied during argument
    % processing in |\collargs@appendarg| (sandwiched between used-definable
    % pre- and post-processors).
    \collargs@wrap{####1#1}%
    % Expand the first token in |##1|, which we know to be |\collargs@empty|,
    % with empty expansion.
    \expandafter\collargs@appendarg\expandafter{##1}%
    \collargs@#2.%
  }%
  % Insert |\collargs@empty| into the input stream, in front of the ``real''
  % argument tokens.
  \collargs@empty
}
\def\collargs@empty{}
% \end{macro}
% 
% \begin{macro}{\collargs@r}
%   Finally, a real argument type: required delimited argument.
\def\collargs@r{%
  \ifcollargs@verbatim
    \expandafter\collargs@r@verb
  \else
    \expandafter\collargs@r@i
  \fi
}
\def\collargs@r@verb#1#2{%
  \expandafter\collargs@r@i\detokenize{#1#2}%
}
\def\collargs@r@i#1#2#3.{%
  % We will need to use the |\collargs@empty| trick from type |u|, but with an
  % additional twist: we need to insert it \emph{after} the opening delimiter
  % |#1|.  To do this, we consume the opening delimiter by the ``outer''
  % collector below --- we need to use the collector so that we get a nice
  % error message when the opening delimiter is not present --- and have this
  % collector define the ``inner'' collector in the spirit of type |u|.
  % 
  % The outer collector has no parameters, it just requires the presence of the
  % opening delimiter.
  \collargs@defcollector#1{%
    % The inner collector will grab everything up to the closing delimiter.
    \collargs@defusecollector####1#2{%
      % Append the collected argument |####1| to the list, wrapping it into the
      % delimiters (|#1| and |#2|), but not before expanding its first token,
      % which we know to be |\collargs@empty|.
      \collargs@wrap{#1########1#2}%
      \expandafter\collargs@appendarg\expandafter{####1}%
      \collargs@#3.%
    }%
    \collargs@empty
  }%
  % Another complication: our delimited argument may be preceded by spaces.  To
  % replicate the argument tokens faithfully, we need to collect them before
  % trying to grab the argument itself.
  \collargs@grabspaces\collargs@caller
}
% \end{macro}
% 
% \begin{macro}{\collargs@R}
%   Discard the default and execute |r|.
\def\collargs@R#1#2#3{\collargs@r#1#2}
% \end{macro}
% 
% \begin{macro}{\collargs@d}
%   Optional delimited argument.  Very similar to |r|.
\def\collargs@d{%
  \ifcollargs@verbatim
    \expandafter\collargs@d@verb
  \else
    \expandafter\collargs@d@i
  \fi
}
\def\collargs@d@verb#1#2{%
  \expandafter\collargs@d@i\detokenize{#1#2}%
}
\def\collargs@d@i#1#2#3.{%
  % This macro will be executed when the optional argument is not present.  It
  % simply closes the argument's group and reexecutes the central loop.
  \def\collargs@d@noopt{%
    \global\collargs@fix@requestedtrue
    \endgroup
    \collargs@#3.%
  }%
  % The collector(s) are exactly as for |r|.
  \collargs@defcollector#1{%
    \collargs@defusecollector####1#2{%
      \collargs@wrap{#1########1#2}%
      \expandafter\collargs@appendarg\expandafter{####1}%
      \collargs@#3.%
    }%
    \collargs@empty
  }%
  % This macro will check, in conjunction with |\futurelet| below, whether the
  % optional argument is present or not.
  \def\collargs@d@ii{%
    \ifx#1\collargs@temp
      \expandafter\collargs@caller
    \else
      \expandafter\collargs@d@noopt
    \fi
  }%
  % Whether spaces are allowed in front of this type of argument depends on the
  % presence of modifier |!|.
  \collargs@maybegrabspaces{\futurelet\collargs@temp\collargs@d@ii}%
}
% \end{macro}
% 
% \begin{macro}{\collargs@D}
% Discard the default and execute |d|.
\def\collargs@D#1#2#3{\collargs@d#1#2}
% \end{macro}
% 
% \begin{macro}{\collargs@o}
%   |o| is just |d| with delimiters |[| and |]|.
\def\collargs@o{\collargs@d[]}
% \end{macro}
% 
% \begin{macro}{\collargs@O}
%   |O| is just |d| with delimiters |[| and |]| and the discarded default.
\def\collargs@O#1{\collargs@d[]}
% \end{macro}
% 
% \begin{macro}{\collargs@t}
%   An optional token.  Similar to |d|.
\def\collargs@t{%
  \ifcollargs@verbatim
    \expandafter\collargs@t@verb
  \else
    \expandafter\collargs@t@i
  \fi
}
\def\collargs@t@space{ }
\def\collargs@t@verb#1{%
  \let\collargs@t@space\collargs@otherspace
  \expandafter\collargs@t@i\expandafter{\detokenize{#1}}%
}
\def\collargs@t@i#1{%
  \expandafter\ifx\space#1%
    \expandafter\collargs@t@s
  \else
    \expandafter\collargs@t@I\expandafter#1%
  \fi
}
\def\collargs@t@s#1.{%
  \collargs@grabspaces{%
    \ifcollargs@grabspaces
      \collargs@appendarg{}%
    \else
      \expanded{%
        \noexpand\collargs@init@grabspaces
        \noexpand\collargs@appendarg{\collargs@grabbed@spaces}%
      }%
    \fi
    \collargs@#1.%
  }%
}
\def\collargs@t@I#1#2.{%
  \def\collargs@t@noopt{%
    \global\collargs@fix@requestedtrue
    \endgroup
    \collargs@#2.%
  }%
  \def\collargs@t@opt##1{%
    \collargs@appendarg{#1}%
    \collargs@#2.%
  }%
  \def\collargs@t@ii{%
    \ifx#1\collargs@temp
      \expandafter\collargs@t@opt
    \else
      \expandafter\collargs@t@noopt
    \fi
  }%
  \collargs@maybegrabspaces{\futurelet\collargs@temp\collargs@t@ii}%
}
\def\collargs@t@opt@space{%
  \expanded{\noexpand\collargs@t@opt{\space}\expandafter}\romannumeral-0%
}%
% \end{macro}
% 
% \begin{macro}{\collargs@s}
%   The optional star is just a special case of |t|.
\def\collargs@s{\collargs@t*}
% \end{macro}
%
%  \begin{macro}{\collargs@m}
%    Mandatory argument.  Interestingly, here's where things get complicated,
%    because we have to take care of several \hologo{TeX} quirks.
\def\collargs@m{%
  \ifcollargs@verbatim
    \expandafter\collargs@m@verb
  \else
    \expandafter\collargs@m@i
  \fi
}
% The non-verbatim mode. First, collect any spaces in front of the argument.
\def\collargs@m@i#1.{%
  \collargs@grabspaces{\collargs@m@checkforgroup#1.}%
}
% Is the argument in braces or not?
\def\collargs@m@checkforgroup#1.{%
  \edef\collargs@action{\unexpanded{\collargs@m@checkforgroup@i#1.}}%
  \futurelet\collargs@token\collargs@action
}
\def\collargs@m@checkforgroup@i{%
  \ifcat\noexpand\collargs@token\bgroup
    \expandafter\collargs@m@group
  \else
    \expandafter\collargs@m@token
  \fi
}
% The argument is given in braces, so we put them back around it
% (|\collargs@wrap|) when appending to the storage.
\def\collargs@m@group#1.{%
  \collargs@defusecollector##1{%
    \collargs@wrap{{####1}}%
    \collargs@appendarg{##1}%
    \collargs@#1.%
  }%
}
% The argument is a single token, we append it to the storage as is.
\def\collargs@m@token#1.{%
  \collargs@defusecollector##1{%
    \collargs@appendarg{##1}%
    \collargs@#1.%
  }%
}
% The verbatim mode.  Again, we first collect any spaces in front of the
% argument.
\def\collargs@m@verb#1.{%
  \collargs@grabspaces{\collargs@m@verb@checkforgroup#1.}%
}
% We want to check whether we're dealing with a braced argument.  We're in the
% verbatim mode, but are braces verbatim as well?  In other words, are we in
% |verbatim| or |verb| mode?  In the latter case, braces are regular, so we
% redirect to the regular mode.
\def\collargs@m@verb@checkforgroup{%
  \ifcollargs@verbatimbraces
    \expandafter\collargs@m@verb@checkforgroup@i
  \else
    \expandafter\collargs@m@checkforgroup
  \fi
}
% Is the argument in verbatim braces?
\def\collargs@m@verb@checkforgroup@i#1.{%
  \def\collargs@m@verb@checkforgroup@ii{\collargs@m@verb@checkforgroup@iii#1.}%
  \futurelet\collargs@temp\collargs@m@verb@checkforgroup@ii
}
\def\collargs@m@verb@checkforgroup@iii#1.{%
  \expandafter\ifx\collargs@other@bgroup\collargs@temp
    % Yes, the argument is in (verbatim) braces.
    \expandafter\collargs@m@verb@group
  \else
    % We need to manually check whether the following token is a (verbatim)
    % closing brace, and throw an error if it is.
    \expandafter\ifx\collargs@other@egroup\collargs@temp
      \expandafter\expandafter\expandafter\collargs@m@verb@egrouperror
    \else
      % The argument is a single token.
      \expandafter\expandafter\expandafter\collargs@m@v@token
    \fi
  \fi
  #1.%
}
\def\collargs@m@verb@egrouperror#1.{%
  \PackageError{collargs}{%
    Argument of \expandafter\string\collargs@caller\space has an extra
    \iffalse{\else\string}}{}%
}
% A single-token verbatim argument.
\def\collargs@m@v@token#1.#2{%
  % Is it a control sequence?  (Macro |\collargs@cc| recalls the ``outside''
  % category code of character |#1|; see
  % section~\ref{sec:code:collargs:verbatim}.)
  \ifnum\collargs@cc{#2}=0
    \expandafter\collargs@m@v@token@cs
  \else
    \expandafter\collargs@m@token
  \fi
  #1.#2%
}
% Is it a one-character control sequence?
\def\collargs@m@v@token@cs#1.#2#3{%
  \ifnum\collargs@cc{#3}=11
    \expandafter\collargs@m@v@token@cs@letter
  \else
    \expandafter\collargs@m@v@token@cs@nonletter
  \fi
  #1.#2#3%
}
% Store |\<token>|.
\def\collargs@m@v@token@cs@nonletter#1.#2#3{%
  \collargs@appendarg{#2#3}%
  \collargs@#1.%
}
% Store |\| to a temporary register, we'll parse the control sequence name now.
\def\collargs@m@v@token@cs@letter#1.#2{%
  \collargsArg{#2}%
  \def\collargs@tempa{#1}%
  \collargs@m@v@token@cs@letter@i
}
% Append a letter to the control sequence.
\def\collargs@m@v@token@cs@letter@i#1{%
  \ifnum\collargs@cc{#1}=11
    \toksapp\collargsArg{#1}%
    \expandafter\collargs@m@v@token@cs@letter@i
  \else
    % Finish, returning the non-letter to the input stream.
    \expandafter\collargs@m@v@token@cs@letter@ii\expandafter#1%
  \fi
}
% Store the verbatim control sequence.
\def\collargs@m@v@token@cs@letter@ii{%
  \expanded{%
    \unexpanded{%
      \expandafter\collargs@appendarg\expandafter{\the\collargsArg}%
    }%
    \noexpand\collargs@\expandonce\collargs@tempa.%
  }%
}
% The verbatim mandatory argument is delimited by verbatim braces.  We have to
% use the heavy machinery adapted from |cprotect|.
\def\collargs@m@verb@group#1.#2{%
  \let\collargs@begintag\collargs@other@bgroup
  \let\collargs@endtag\collargs@other@egroup
  \def\collargs@tagarg{}%
  \def\collargs@commandatend{\collargs@m@verb@group@i#1.}%
  \collargs@readContent
}
% This macro appends the result given by the heavy machinery, waiting for us in
% macro |\collargsArg|, to |\collargsArgs|, but not before dressing
% it up (via |\collargs@wrap|) in a pair of verbatim braces.
\def\collargs@m@verb@group@i{%
  \edef\collargs@temp{%
    \collargs@other@bgroup\unexpanded{##1}\collargs@other@egroup}%
  \expandafter\collargs@wrap\expandafter{\collargs@temp}%
  \expandafter\collargs@appendarg\expandafter{\the\collargsArg}%
  \collargs@
}
% \end{macro}
% 
% \begin{macro}{\collargs@g}
%   An optional group: same as |m|, but we simply bail out if we don't find the
%   group character.
\def\collargs@g{%
  \def\collargs@m@token{%
    \global\collargs@fix@requestedtrue
    \endgroup
    \collargs@
  }%
  \let\collargs@m@v@token\collargs@m@token
  \collargs@m
}
% \end{macro}
% 
% \begin{macro}{\collargs@G}
%   Discard the default and execute |g|.
\def\collargs@G#1{\collargs@g}
% \end{macro}
%
% \begin{macro}{\collargs@v}
%   Verbatim argument.  The code is executed in the group, deploying
%   |\collargsVerbatim|.  The grouping characters are always set to braces, to
%   mimick |xparse| perfectly.
\def\collargs@v#1.{%
  \begingroup
  \collargsBraces{{}}%
  \collargsVerbatim
  \collargs@grabspaces{\collargs@v@i#1.}%
}
\def\collargs@v@i#1.#2{%
  \expandafter\ifx\collargs@other@bgroup#2%
    % If the first token we see is an opening brace, use the |cprotect|
    % adaptation to grab the group.
    \let\collargs@begintag\collargs@other@bgroup
    \let\collargs@endtag\collargs@other@egroup
    \def\collargs@tagarg{}%
    \def\collargs@commandatend{%
      \edef\collargs@temp{%
        \collargs@other@bgroup\unexpanded{####1}\collargs@other@egroup}%
      \expandafter\collargs@wrap\expandafter{\collargs@temp}%
      \expandafter\collargs@appendarg\expandafter{\the\collargsArg}%
      \endgroup
      \collargs@#1.%
    }%
    \expandafter\collargs@readContent
  \else
    % Otherwise, the verbatim argument is delimited by two identical characters
    % (|#2|).
    \collargs@defcollector##1#2{%
      \collargs@wrap{#2####1#2}%
      \collargs@appendarg{##1}%
      \endgroup
      \collargs@#1.%
    }%
    \expandafter\collargs@caller
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@b}
%   Environments.  Here's where all hell breaks loose.  We survive by adapting
%   some code from Bruno Le Floch's |cprotect|.  We first define the
%   environment-related keys, then provide the handler code, and finish with
%   the adaptation of |cprotect|'s environment-grabbing code.
% 
%   The argument type |b| token may be followed by a braced environment name
%   (in the argument specification).
\def\collargs@b{%
  \collargs@ifnextcat\bgroup\collargs@bg\collargs@bi
}
\def\collargs@bg#1{%
  \edef\collargs@b@envname{#1}%
  \collargs@bi
}
\def\collargs@bi#1.{%
  % Convert the environment name to verbatim if necessary.
  \ifcollargs@verbatim
    \edef\collargs@b@envname{\detokenize\expandafter{\collargs@b@envname}}%
  \fi
  % This is a format-specific macro which sets up |\collargs@begintag| and
  % |\collargs@endtag|.
  \collargs@bi@defCPTbeginend
  \edef\collargs@tagarg{%
    \ifcollargs@verbatimbraces
    \else
      \ifcollargsIgnoreOtherTags
        \collargs@b@envname
      \fi
    \fi
  }%
  % Run this after collecting the body.
  \def\collargs@commandatend{%
    % In \hologo{LaTeX}, we might, depending on the verbatim mode, need to
    % check whether the environment name is correct.
    %<latex>\collargs@bii
    % In \hologo{plainTeX} and \hologo{ConTeXt}, we can skip directly to
    % |\collargs@biii|.
    %<plain,context>\collargs@biii
    #1.%
  }%
  % Collect the environment body, but first, put any grabbed spaces back into
  % the input stream.
  \collargs@reinsert@spaces\collargs@readContent
}
%<*latex>
% In \hologo{LaTeX} in the regular and the partial verbatim mode, we search for
% |\begin|\slash|\end| --- as we cannot search for braces --- either as control
% sequences in the regular mode, or as strings in the partial verbatim
% mode. (After search, we will have to check whether the argument of
% |\begin|\slash|\end| matches our environment name.)  In the full verbatim
% mode, we can search for the entire string |\begin|\slash|\end|\marg{name}.
\def\collargs@bi@defCPTbeginend{%
  \edef\collargs@begintag{%
    \ifcollargs@verbatim
      \expandafter\string
    \else
      \expandafter\noexpand
    \fi
    \begin
    \ifcollargs@verbatimbraces
      \collargs@other@bgroup\collargs@b@envname\collargs@other@egroup
    \fi
  }%
  \edef\collargs@endtag{%
    \ifcollargs@verbatim
      \expandafter\string
    \else
      \expandafter\noexpand
    \fi
    \end
    \ifcollargs@verbatimbraces
      \collargs@other@bgroup\collargs@b@envname\collargs@other@egroup
    \fi
  }%
}
%</latex>
%<*plain,context>
% We can search for the entire |\|\meta{name}\slash|\end|\meta{name} (in
% \hologo{TeX}) or |\start|\meta{name}\slash|\stop|\meta{name} (in
% \hologo{ConTeXt}), either as a control sequence (in the regular mode), or as
% a string (in the verbatim modes).
\def\collargs@bi@defCPTbeginend{%
  \edef\collargs@begintag{%
    \ifcollargs@verbatim
      \expandafter\expandafter\expandafter\string
    \else
      \expandafter\expandafter\expandafter\noexpand
    \fi
    \csname
      %<context>start%
      \collargs@b@envname
    \endcsname
  }%
  \edef\collargs@endtag{%
    \ifcollargs@verbatim
      \expandafter\expandafter\expandafter\string
    \else
      \expandafter\expandafter\expandafter\noexpand
    \fi
    \csname
      %<plain>end%
      %<context>stop%
      \collargs@b@envname
    \endcsname
  }%
}
%</plain,context>
%<*latex>
% Check whether we're in front of the (braced) environment name (in
% \hologo{LaTeX}), and consume it.
\def\collargs@bii{%
  \ifcollargs@verbatimbraces
    \expandafter\collargs@biii
  \else
    \ifcollargsIgnoreOtherTags
      % We shouldn't check the name in this case, because it was already
      % checked, and consumed.
      \expandafter\expandafter\expandafter\collargs@biii
    \else
      \expandafter\expandafter\expandafter\collargs@b@checkend
    \fi
  \fi
}
\def\collargs@b@checkend#1.{%
  \collargs@grabspaces{\collargs@b@checkend@i#1.}%
}
\def\collargs@b@checkend@i#1.#2{%
  \def\collargs@temp{#2}%
  \ifx\collargs@temp\collargs@b@envname
  \else
    \collargs@b@checkend@error
  \fi
  \collargs@biii#1.%
}
\def\collargs@b@checkend@error{%
  \PackageError{collargs}{Environment "\collargs@b@envname" ended as
    "\collargs@temp"}{}%
}
%</latex>
% This macro stores the collected body.
\def\collargs@biii{%
  % Define the wrapper macro (|\collargs@temp|).
  \collargs@b@def@wrapper
  % Execute |\collargs@appendarg| to append the body to the list.  Expand the
  % wrapper in |\collargs@temp| first and the body in |\collargsArg| next.
  \expandafter\collargs@appendarg\expandafter{\the\collargsArg}%
  % Reexecute the central loop.
  \collargs@
}
\def\collargs@b@def@wrapper{%
  %<latex>\edef\collargs@temp{{\collargs@b@envname}}%
  \edef\collargs@temp{%
    % Was the begin-tag requested?
    \ifcollargsBeginTag
      % |\collargs@begintag| is already adapted to the format and the verbatim mode.
      \expandonce\collargs@begintag
      % Add the braced environment name in \hologo{LaTeX} in the regular and
      % partial verbatim mode.
      % 
      %<*latex>
      \ifcollargs@verbatimbraces\else\collargs@temp\fi
      %</latex>
    \fi
    % This is the body.
    ####1%
    % Rinse and repeat for the end-tag.
    \ifcollargsEndTag
      \expandonce\collargs@endtag
      %<*latex>
      \ifcollargs@verbatimbraces\else\collargs@temp\fi
      %</latex>
    \fi
  }%
  \expandafter\collargs@wrap\expandafter{\collargs@temp}%
}
% \end{macro}
% 
% \begin{macro}{\collargs@readContent}
%   This macro, which is an adaptation of
%   \texttt{cprotect}'s environment-grabbing code, collects some delimited
%   text, leaving the result in |\collargsArg|.  Before calling it, one must
%   define the following macros: |\collargs@begintag| and |\collargs@endtag|
%   are the content delimiters; |\collargs@tagarg|, if non-empty, is the token
%   or grouped text which must follow a delimiter to be taken into account;
%   |\collargs@commandatend| is the command that will be executed once the
%   content is collected.
\def\collargs@readContent{%
  % Define macro which will search for the first begin-tag.
  \ifcollargs@long\long\fi
  \collargs@CPT@def\collargs@gobbleOneB\collargs@begintag{%
    % Assign the collected tokens into a register.  The first token in |##1|
    % will be |\collargs@empty|, so we expand to get rid of it.
    \toks0\expandafter{##1}%
    % |cprotect| simply grabs the token following the |\collargs@begintag| with
    % a parameter. We can't do this, because we need the code to work in the
    % non-verbatim mode, as well, and we might stumble upon a brace there.  So
    % we take a peek.
    \futurelet\collargs@temp\collargs@gobbleOneB@i
  }%
  % Define macro which will search for the first end-tag.  We make it long if
  % so required (by |+|).
  \ifcollargs@long\long\fi
  \collargs@CPT@def\collargs@gobbleUntilE\collargs@endtag{%
    % Expand |\collargs@empty| at the start of |##1|.
    \expandafter\toksapp\expandafter0\expandafter{##1}%
    \collargs@gobbleUntilE@i
  }%
  % Initialize.
  \collargs@begins=0\relax
  \collargsArg{}%
  \toks0{}%
  % We will call |\collargs@gobbleUntilE| via the caller control sequence.
  \collargs@letusecollector\collargs@gobbleUntilE
  % We insert |\collargs@empty| to avoid the potential debracing problem.
  \collargs@empty
}
% How many begin-tags do we have opened?
\newcount\collargs@begins
% An auxiliary macro which |\def|s |#1| so that it will grab everything up
% until |#2|.  Additional parameters may be present before the definition.
\def\collargs@CPT@def#1#2{%
  \expandafter\def\expandafter#1%
  \expandafter##\expandafter1#2%
}
% A quark quard.
\def\collargs@qend{\collargs@qend}
% This macro will collect the ``environment'', leaving the result in
% |\collargsArg|.  It expects |\collargs@begintag|, |\collargs@endtag| and
% |\collargs@commandatend| to be set.
\def\collargs@gobbleOneB@i{%
  \def\collargs@begins@increment{1}%
  \ifx\collargs@qend\collargs@temp
    % We have reached the fake begin-tag. Note that we found the end-tag.
    \def\collargs@begins@increment{-1}%
    % Gobble the quark guard.
    \expandafter\collargs@gobbleOneB@v
  \else
    % Append the real begin-tag to the temporary tokens.
    \etoksapp0{\expandonce\collargs@begintag}%
    \expandafter\collargs@gobbleOneB@ii
  \fi
}%
% Do we have to check the tag argument (i.e.\ the environment name after |\begin|)?
\def\collargs@gobbleOneB@ii{%
  \expandafter\ifx\expandafter\relax\collargs@tagarg\relax
    \expandafter\collargs@gobbleOneB@vi
  \else
    % Yup, so let's (carefully) collect the tag argument.
    \expandafter\collargs@gobbleOneB@iii
  \fi
}
\def\collargs@gobbleOneB@iii{%
  \collargs@grabspaces{%
    \collargs@letusecollector\collargs@gobbleOneB@iv
  }%
}
\def\collargs@gobbleOneB@iv#1{%
  \def\collargs@temp{#1}%
  \ifx\collargs@temp\collargs@tagarg
    % This is the tag argument we've been waiting for! 
  \else
    % Nope, this |\begin| belongs to someone else.
    \def\collargs@begins@increment{0}%
  \fi
  % Whatever the result was, we have to append the gobbled group to the
  % temporary toks.
  \etoksapp0{\collargs@grabbed@spaces\unexpanded{{#1}}}%
  \collargs@init@grabspaces
  \collargs@gobbleOneB@vi
}
\def\collargs@gobbleOneB@v#1{\collargs@gobbleOneB@vi}
\def\collargs@gobbleOneB@vi{%
  % Store.
  \etoksapp\collargsArg{\the\toks0}%
  % Advance the begin-tag counter.
  \advance\collargs@begins\collargs@begins@increment\relax
  % Find more begin-tags, unless this was the final one.
  \ifnum\collargs@begins@increment=-1
  \else
    \expandafter\collargs@gobbleOneB\expandafter\collargs@empty
  \fi
}
\def\collargs@gobbleUntilE@i{%
  % Do we have to check the tag argument (i.e.\ the environment name after |\end|)?
  \expandafter\ifx\expandafter\relax\collargs@tagarg\relax
    \expandafter\collargs@gobbleUntilE@iv
  \else
    % Yup, so let's (carefully) collect the tag argument.
    \expandafter\collargs@gobbleUntilE@ii
  \fi
}
\def\collargs@gobbleUntilE@ii{%
  \collargs@grabspaces{%
    \collargs@letusecollector\collargs@gobbleUntilE@iii
  }%
}
\def\collargs@gobbleUntilE@iii#1{%
  \etoksapp0{\collargs@grabbed@spaces}%
  \collargs@init@grabspaces
  \def\collargs@tempa{#1}%
  \ifx\collargs@tempa\collargs@tagarg
    % This is the tag argument we've been waiting for!
    \expandafter\collargs@gobbleUntilE@iv
  \else
    % Nope, this |\end| belongs to someone else.  Insert the end tag plus the
    % tag argument, and collect until the next |\end|.
    \expandafter\toksapp\expandafter0\expandafter{\collargs@endtag{#1}}%
    \expandafter\collargs@letusecollector\expandafter\collargs@gobbleUntilE
  \fi
}
\def\collargs@gobbleUntilE@iv{%
  % Invoke |\collargs@gobbleOneB| with the collected material, plus a fake
  % begin-tag and a quark guard.
  \ifcollargsIgnoreNesting
    \expandafter\collargsArg\expandafter{\the\toks0}%
    \expandafter\collargs@commandatend
  \else
    \expandafter\collargs@gobbleUntilE@v
  \fi
}
\def\collargs@gobbleUntilE@v{%
  \expanded{%
    \noexpand\collargs@letusecollector\noexpand\collargs@gobbleOneB
    \noexpand\collargs@empty
    \the\toks0
    % Add a fake begin-tag and a quark guard.
    \expandonce\collargs@begintag
    \noexpand\collargs@qend
  }%
  \ifnum\collargs@begins<0
    \expandafter\collargs@commandatend
  \else
    \etoksapp\collargsArg{%
      \expandonce\collargs@endtag
      \expandafter\ifx\expandafter\relax\collargs@tagarg\relax\else{%
          \expandonce\collargs@tagarg}\fi
    }%
    \toks0={}%
    \expandafter\collargs@letusecollector\expandafter\collargs@gobbleUntilE
    \expandafter\collargs@empty
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@e}
%   Embellishments.  Each embellishment counts as an argument, in the sense
%   that we will execute |\collargs@appendarg|, with all the processors, for
%   each embellishment separately.
\def\collargs@e{%
  % We open an extra group, because |\collargs@appendarg| will close a group
  % for each embellishment.
  \global\collargs@fix@requestedtrue
  \begingroup
  \ifcollargs@verbatim
    \expandafter\collargs@e@verbatim
  \else
    \expandafter\collargs@e@i
  \fi
}
% Detokenize the embellishment tokens in the verbatim mode.
\def\collargs@e@verbatim#1{%
  \expandafter\collargs@e@i\expandafter{\detokenize{#1}}%
}
% Ungroup the embellishment tokens, separating them from the rest of the
% argument specification by a dot.
\def\collargs@e@i#1{\collargs@e@ii#1.}
% We now have embellishment tokens in |#1| and the rest of the argument
% specification in |#2|.  Let's grab spaces first.
\def\collargs@e@ii#1.#2.{%
  \collargs@grabspaces{\collargs@e@iii#1.#2.}%
}
% What's the argument token?
\def\collargs@e@iii#1.#2.{%
  \def\collargs@e@iv{\collargs@e@v#1.#2.}%
  \futurelet\collargs@temp\collargs@e@iv
}
% If it is a open or close group character, we surely don't have an
% embellishment.
\def\collargs@e@v{%
  \ifcat\noexpand\collargs@temp\bgroup\relax
    \let\collargs@marshal\collargs@e@z
  \else
    \ifcat\noexpand\collargs@temp\egroup\relax
      \let\collargs@marshal\collargs@e@z
    \else
      \let\collargs@marshal\collargs@e@vi
    \fi
  \fi
  \collargs@marshal
}
% We borrow the ``Does |#1| occur within |#2|?'' macro from |pgfutil-common|,
% but we fix it by executing |\collargs@in@@| in a braced group.  This will
% prevent an |&| in an argument to function as an alignment character; the
% minor price to pay is that we assign the conditional globally.
\newif\ifcollargs@in@
\def\collargs@in@#1#2{%
 \def\collargs@in@@##1#1##2##3\collargs@in@@{%
   \ifx\collargs@in@##2\global\collargs@in@false\else\global\collargs@in@true\fi
 }%
 {\collargs@in@@#2#1\collargs@in@\collargs@in@@}%
}
% Let' see whether the following token, now |#3|, is an embellishment token.
\def\collargs@e@vi#1.#2.#3{%
  \collargs@in@{#3}{#1}%
  \ifcollargs@in@
    \expandafter\collargs@e@vii
  \else
    \expandafter\collargs@e@z
  \fi
  #1.#2.#3%
}
% |#3| is the current embellishment token.  We'll collect its argument using
% |\collargs@m|, but to do that, we have to (locally) redefine
% |\collargs@appendarg| and |\collargs@|, which get called by |\collargs@m|.
\def\collargs@e@vii#1.#2.#3{%
  % We'll have to execute the original |\collargs@appendarg| later, so let's
  % remember it.  The temporary |\collargs@appendarg| simply stores the
  % collected argument into |\collargsArg| --- we'll do the processing etc.\
  % later.
  \let\collargs@real@appendarg\collargs@appendarg
  \def\collargs@appendarg##1{\collargsArg{##1}}%
  % Once |\collargs@m| is done, it will call the redefined |\collargs@| and
  % thereby get us back into this handler.
  \def\collargs@{\collargs@e@viii#1.#3}%
  \collargs@m#2.%
}
% The parameters here are as follows.  |#1| are the embellishment tokens, and
% |#2| is the current embellishment token; these get here via our local
% redefinition of |\collargs@| in |\collargs@e@vii|.  |#3| are the rest of the
% argument specification, which is put behind control sequence |\collargs@| by
% the |m| handler.
\def\collargs@e@viii#1.#2#3.{%
  % Our wrapper puts the current embellishment token in front of the collected
  % embellishment argument.  Note that if the embellishment argument was in
  % braces, |\collargs@m| has already set one wrapper (which will apply first).
  \collargs@wrap{#2##1}%
  % We need to get rid of the current embellishment from embellishments, not to
  % catch the same embellishment twice.
  \def\collargs@e@ix##1#2{\collargs@e@x##1}%
  \collargs@e@ix#1.#3.%
}
% When this is executed, the input stream starts with the (remaining)
% embellishment tokens, followed by a dot, then the rest of the argument
% specification, also followed by a dot.
\def\collargs@e@x{%
  % Process the argument and append it to the storage.
  \expandafter\collargs@real@appendarg\expandafter{\the\collargsArg}%
  % |\collargs@real@appendarg| has closed a group, so we open it again, and
  % start looking for another embellishment token in the input stream.
  \begingroup
  \collargs@e@ii
}
% The first argument token in not an embellishment token. We finish by
% consuming the list of embellishment tokens, closing the two groups opened by
% this handler, and reexecuting the central loop.
\def\collargs@e@z#1.{\endgroup\endgroup\collargs@}
% \end{macro}
% 
% \begin{macro}{\collargs@E}
%   Discard the defaults and execute |e|.
\def\collargs@E#1#2{\collargs@e{#1}}
% \end{macro}
% 
%
% \subsubsection{The verbatim modes}
% \label{sec:code:collargs:verbatim}
% 
%   \begin{macro}{\collargsVerbatim,\collargsVerb,\collargsNoVerbatim}
%     These macros set the two verbatim-related
%     conditionals, |\ifcollargs@verbatim| and |\ifcollargs@verbatimbraces|,
%         and then call |\collargs@make@verbatim| to effect the requested
%         category code changes (among other things).  A group should be opened
%         prior to executing either of them.  After execution, they are
%         redefined to minimize the effort needed to enter into another mode in
%         an embedded group.  Below, we first define all the possible transitions.
\let\collargs@NoVerbatimAfterNoVerbatim\relax
\def\collargs@VerbAfterNoVerbatim{%
  \collargs@verbatimtrue
  \collargs@verbatimbracesfalse
  \collargs@make@verbatim
  \collargs@after{Verb}%
}
\def\collargs@VerbatimAfterNoVerbatim{%
  \collargs@verbatimtrue
  \collargs@verbatimbracestrue
  \collargs@make@verbatim
  \collargs@after{Verbatim}%
}
\def\collargs@NoVerbatimAfterVerb{%
  \collargs@verbatimfalse
  \collargs@verbatimbracesfalse
  \collargs@make@other@groups
  \collargs@make@no@verbatim
  \collargs@after{NoVerbatim}%
}
\def\collargs@VerbAfterVerb{%
  \collargs@make@other@groups
}
\def\collargs@VerbatimAfterVerb{%
  \collargs@verbatimbracestrue
  \collargs@make@other@groups
  % Process the lists of grouping characters, created by
  % |\collargs@make@verbatim|, making these characters of category ``other''.
  \def\collargs@do##1{\catcode##1=12 }%
  \collargs@bgroups
  \collargs@egroups
  \collargs@after{Verbatim}%
}%
\let\collargs@NoVerbatimAfterVerbatim\collargs@NoVerbatimAfterVerb
\def\collargs@VerbAfterVerbatim{%
  \collargs@verbatimbracesfalse
  \collargs@make@other@groups
  % Process the lists of grouping characters, created by
  % |\collargs@make@verbatim|, making these characters be of their normal
  % category.
  \def\collargs@do##1{\catcode##1=1 }%
  \collargs@bgroups
  \def\collargs@do##1{\catcode##1=2 }%
  \collargs@egroups
  \collargs@after{Verb}%
}%
\let\collargs@VerbatimAfterVerbatim\collargs@VerbAfterVerb
% This macro expects |#1| to be the mode just entered (|Verbatim|, |Verb| or
% |NoVerbatim|), and points macros |\collargsVerbatim|, |\collargsVerb| and
% |\collargsNoVerbatim| to the appropriate transition macro.
\def\collargs@after#1{%
  \letcs\collargsVerbatim{collargs@VerbatimAfter#1}%
  \letcs\collargsVerb{collargs@VerbAfter#1}%
  \letcs\collargsNoVerbatim{collargs@NoVerbatimAfter#1}%
}
% The first transition is always from the non-verbatim mode.
\collargs@after{NoVerbatim}
% \end{macro}
% 
% \begin{macro}{\collargs@bgroups,\collargs@egroups}
%   Initialize the lists of the current grouping characters used in the
%   redefinitions of macros |\collargsVerbatim| and |\collargsVerb| above.
%   Each entry is of form |\collargs@do|\marg{character code}.  These lists
%   will be populated by |\collargs@make@verbatim|.  They may be local, as they
%   only used within the group opened for a verbatim environment.
\def\collargs@bgroups{}%
\def\collargs@egroups{}%
% \end{macro}
% 
% \begin{macro}{\collargs@cc}
%   This macro recalls the category code of character |#1|.  In
%   \hologo{LuaTeX}, we simply look up the category code in the original
%   category code table; in other engines, we have stored the original category
%   code into |\collargs@cc@|\meta{character code} by
%   |\collargs@make@verbatim|.  (Note that |#1| is a character, not a number.)
\ifdefined\luatexversion
  \def\collargs@cc#1{%
    \directlua{tex.sprint(tex.getcatcode(\collargs@catcodetable@original,
      \the\numexpr\expandafter`\csname#1\endcsname\relax))}%
  }
\else
  \def\collargs@cc#1{%
    \ifcsname collargs@cc@\the\numexpr\expandafter`\csname#1\endcsname\endcsname
      \csname collargs@cc@\the\numexpr\expandafter`\csname#1\endcsname\endcsname
    \else
      12%
    \fi
  }
\fi
% \end{macro}
%
%
% \begin{macro}{\collargs@other@bgroup,\collargs@other@egroup,\collargsBraces}
%   Macros |\collargs@other@bgroup| and
%   |\collargs@other@egroup| hold the characters of category code ``other''
%   which will play the role of grouping characters in the full verbatim mode.
%   They are usually defined when entering a verbatim mode in
%   |\collargs@make@verbatim|, but may be also set by the user via
%   |\collargsBraces| (it is not even necessary to select characters which
%   indeed have the grouping function in the outside category code regime).
%   The setting process is indirect: executing |\collargsBraces| merely sets
%   |\collargs@make@other@groups|, which gets executed by the subsequent
%   |\collargsVerbatim|, |\collargsVerb| or |\collargsNoVerbatim| (either
%   directly or via |\collargs@make@verbatim|).
\def\collargsBraces#1{%
  \expandafter\collargs@braces@i\detokenize{#1}\relax
}
\def\collargs@braces@i#1#2#3\relax{%
  \def\collargs@make@other@groups{%
    \def\collargs@other@bgroup{#1}%
    \def\collargs@other@egroup{#2}%
  }%
}
\def\collargs@make@other@groups{}
% \end{macro}
% 
% \begin{macro}{\collargs@catcodetable@verbatim,\catcodetable@atletter,\collargs@catcodetable@initex}
%   We declare several new catcode tables in \hologo{LuaTeX}, the most
%   important one being |\collargs@catcodetable@verbatim|, where all characters
%   have category code 12.  We only need the other two tables in some formats:
%   |\collargs@catcodetable@atletter| holds the catcode in effect at the time
%   of loading the package, and |\collargs@catcodetable@initex| is the
%   \hologo{iniTeX} table.
\ifdefined\luatexversion
  %<*latex,context>
  \newcatcodetable\collargs@catcodetable@verbatim
  %<latex>\let\collargs@catcodetable@atletter\catcodetable@atletter
  %<context>\newcatcodetable\collargs@catcodetable@atletter
  %</latex,context>
  %<*plain>
  \ifdefined\collargs@catcodetable@verbatim\else
    \chardef\collargs@catcodetable@verbatim=4242
  \fi
  \chardef\collargs@catcodetable@atletter=%
    \number\numexpr\collargs@catcodetable@verbatim+1\relax
  \chardef\collargs@catcodetable@initex=%
    \number\numexpr\collargs@catcodetable@verbatim+2\relax
    \initcatcodetable\collargs@catcodetable@initex
  %</plain>
  %<plain,context>\savecatcodetable\collargs@catcodetable@atletter
  \begingroup
  \@firstofone{%
    %<latex>\catcodetable\catcodetable@initex
    %<plain>\catcodetable\collargs@catcodetable@initex
    %<context>\catcodetable\inicatcodes
    \catcode`\\=12
    \catcode13=12
    \catcode0=12
    \catcode32=12
    \catcode`\%=12
    \catcode127=12
    \def\collargs@do#1{\catcode#1=12 }%
    \collargs@forrange{`\a}{`\z}%
    \collargs@forrange{`\A}{`\Z}%
    \savecatcodetable\collargs@catcodetable@verbatim
    \endgroup
  }%
\fi
% \end{macro}
% 
% \begin{collargskey}{verbatim ranges}
%   \begin{macro}{\collargsVerbatimRanges,\collargs@verbatim@ranges}
%     This key and macro set the character ranges to which the verbatim mode
%     will apply (in \hologo{pdfTeX} and \hologo{XeTeX}), or which will be
%     inspected for grouping and comment characters (in \hologo{LuaTeX}).  In
%     \hologo{pdfTeX}, the default value |0-255| should really remain
%     unchanged.
\collargsSet{
  verbatim ranges/.store in=\collargs@verbatim@ranges,
}
\def\collargsVerbatimRanges#1{\def\collargs@verbatim@ranges{#1}}
\def\collargs@verbatim@ranges{0-255}
%   \end{macro}
% \end{collargskey}
% 
% \begin{macro}{\collargs@make@verbatim}
%   This macro changes the category code of all characters to ``other'' ---
%   except the grouping characters in the partial verbatim mode.  While doing
%   that, it also stores (unless we're in \hologo{LuaTeX}) the current category
%   codes into |\collargs@cc@|\meta{character code} (easily recallable by
%   |\collargs@cc|), redefines the ``primary'' grouping characters
%   |\collargs@make@other@bgroup| and |\collargs@make@other@egroup| if
%   necessary, and ``remembers'' the grouping characters (storing them into
%   |\collargs@bgroups| and |\collargs@egroups|) and the comment characters
%   (storing them into |\collargs@comments|).
% 
%   In \hologo{LuaTeX}, we can use catcode tables, so we change the category
%   codes by switching to category code table
%   |\collargs@catcodetable@verbatim|.  In other engines, we have to change the
%   codes manually.  In order to offer some flexibility in \hologo{XeTeX}, we
%   perform the change for characters in |verbatim ranges|.
\ifdefined\luatexversion
  \def\collargs@make@verbatim{%
    \directlua{%
      for from, to in string.gmatch(
        "\luaescapestring{\collargs@verbatim@ranges}",
        "(\collargs@percentchar d+)-(\collargs@percentchar d+)"
      ) do
        for char = tex.round(from), tex.round(to) do
          catcode = tex.catcode[char]
          % For category codes 1, 2 and 14, we have to call macros
          % |\collargs@make@verbatim@bgroup|, |\collargs@make@verbatim@egroup|
          % and |\collargs@make@verbatim@comment|, same as for engines other
          % than \hologo{LuaTeX}.
          if catcode == 1 then
            tex.sprint(
              \number\collargs@catcodetable@atletter,
              "\noexpand\\collargs@make@verbatim@bgroup{" .. char .. "}")
          elseif catcode == 2 then
            tex.sprint(
              \number\collargs@catcodetable@atletter,
              "\noexpand\\collargs@make@verbatim@egroup{" .. char .. "}")
          elseif catcode == 14 then
            tex.sprint(
              \number\collargs@catcodetable@atletter,
              "\noexpand\\collargs@make@verbatim@comment{" .. char .. "}")
          end
        end
      end
    }%
    \edef\collargs@catcodetable@original{\the\catcodetable}%
    \catcodetable\collargs@catcodetable@verbatim
    % Even in \hologo{LuaTeX}, we switch between the verbatim braces regimes by
    % hand.
    \ifcollargs@verbatimbraces
    \else
      \def\collargs@do##1{\catcode##1=1\relax}%
      \collargs@bgroups
      \def\collargs@do##1{\catcode##1=2\relax}%
      \collargs@egroups
    \fi
  }
\else
  % The non-\hologo{LuaTeX} version:
  \def\collargs@make@verbatim{%
    \ifdefempty\collargs@make@other@groups{}{%
        % The user has executed |\collargsBraces|.  We first apply that setting
        % by executing macro |\collargs@make@other@groups|, and then disable our
        % automatic setting of the primary grouping characters.
      \collargs@make@other@groups
      \def\collargs@make@other@groups{}%
      \let\collargs@make@other@bgroup\@gobble
      \let\collargs@make@other@egroup\@gobble
    }%
    % Initialize the list of current comment characters.  Each entry is of
    % form |\collargs@do|\marg{character code}.  The definition must be global,
    % because the macro will be used only once we exit the current group (by
    % |\collargs@fix@cc@from@other@comment|, if at all).
    \gdef\collargs@comments{}%
    \let\collargs@do\collargs@make@verbatim@char
    \expandafter\collargs@forranges\expandafter{\collargs@verbatim@ranges}%
  }
  \def\collargs@make@verbatim@char#1{%
    % Store the current category code of the current character.
    \ifnum\catcode#1=12
    \else
      \csedef{collargs@cc@#1}{\the\catcode#1}%
    \fi
    \ifnum\catcode#1=1
      \collargs@make@verbatim@bgroup{#1}%
    \else
      \ifnum\catcode#1=2
        \collargs@make@verbatim@egroup{#1}%
      \else
        \ifnum\catcode#1=14
          \collargs@make@verbatim@comment{#1}%
        \fi
        % Change the category code of the current character (including the
        % comment characters).
        \ifnum\catcode#1=12
        \else
          \catcode#1=12\relax
        \fi
      \fi
    \fi
  }
\fi
% \end{macro}
% 
% \begin{macro}{\collargs@make@verbatim@bgroup}
%   This macro changes the category of
%   the opening group character to ``other'', but only in the full verbatim
%   mode.  Next, it populates |\collargs@bgroups|, to facilitate the potential
%   transition into the other verbatim mode.  Finally, it executes
%   |\collargs@make@other@bgroup|, which stores the ``other'' variant of the
%   current character into |\collargs@other@bgroup|, and automatically disables
%   itself, so that it is only executed for the first encountered opening group
%   character --- unless it was already |\relax|ed at the top of
%   |\collargs@make@verbatim| as a consequence of the user executing
%   |\collargsBraces|.
\def\collargs@make@verbatim@bgroup#1{%
  \ifcollargs@verbatimbraces
    \catcode#1=12\relax
  \fi
  \appto\collargs@bgroups{\collargs@do{#1}}%
  \collargs@make@other@bgroup{#1}%
}
\def\collargs@make@other@bgroup#1{%
  \collargs@make@char\collargs@other@bgroup{#1}{12}%
  \let\collargs@make@other@bgroup\@gobble
}
% \end{macro}
%
% \begin{macro}{\collargs@make@verbatim@egroup}
%   Ditto for the closing group character.
\def\collargs@make@verbatim@egroup#1{%
  \ifcollargs@verbatimbraces
    \catcode#1=12\relax
  \fi
  \appto\collargs@egroups{\collargs@do{#1}}%
  \collargs@make@other@egroup{#1}%
}
\def\collargs@make@other@egroup#1{%
  \collargs@make@char\collargs@other@egroup{#1}{12}%
  \let\collargs@make@other@egroup\@gobble
}
% \end{macro}
% 
% \begin{macro}{\collargs@make@verbatim@comment}
%   This macro populates
%   |\collargs@make@comments@other|.
\def\collargs@make@verbatim@comment#1{%
  \gappto\collargs@comments{\collargs@do{#1}}%
}
% \end{macro}
% 
% \begin{macro}{\collargs@make@no@verbatim}
%   This macro switches back to the non-verbatim mode: in \hologo{LuaTeX}, by
%   switching to the original catcode table; in other engines, by recalling the
%   stored category codes.
\ifdefined\luatexversion
  \def\collargs@make@no@verbatim{%
    \catcodetable\collargs@catcodetable@original\relax
  }%
\else
\def\collargs@make@no@verbatim{%
  \let\collargs@do\collargs@make@no@verbatim@char
  \expandafter\collargs@forranges\expandafter{\collargs@verbatim@ranges}%
}
\fi
\def\collargs@make@no@verbatim@char#1{%
  % The original category code of a characted was stored into
  % |\collargs@cc@|\meta{character code} by |\collargs@make@verbatim|. (We don't
  % use |\collargs@cc|, because we have a number.)
  \ifcsname collargs@cc@#1\endcsname
    \catcode#1=\csname collargs@cc@#1\endcsname\relax
    % We don't have to restore category code 12.
  \fi
}
% \end{macro}
% 
% 
% \subsubsection{Transition between the verbatim and the non-verbatim mode}
% \label{sec:code:collargs:fix}
% 
% At the transition from verbatim to non-verbatim mode, and vice versa, we
% sometimes have to fix the category code of the next argument token.  This
% happens when we have an optional argument type in one mode followed by an
% argument type in another mode, but the optional argument is absent, or when
% an optional, but absent, verbatim argument is the last argument in the
% specification.  The problem arises because the presence of optional arguments
% is determined by looking ahead in the input stream; when the argument is
% absent, this means that we have fixed the category code of the next token.
% CollArgs addresses this issue by noting the situations where a token receives
% the wrong category code, and then does its best to replace that token with
% the same character of the appropriate category code.
% 
% \begin{macro}{\ifcollargs@fix@requested}
%     This conditional is set, globally,
%       by the optional argument handlers when the argument is in fact absent,
%       and reset in the central loop after applying the fix if necessary.
\newif\ifcollargs@fix@requested
% \end{macro}
% 
% \begin{macro}{\collargs@fix}
%   This macro selects the fixer appropriate to the transition between the
%   previous verbatim mode (determined by |\ifcollargs@last@verbatim| and
%     |\ifcollargs@last@verbatimbraces|) and the current verbatim mode (which
%       is determined by macros |\ifcollargs@verbatim| and
%         |\ifcollargs@verbatimbraces|); if the category code fix was not
%           requested (for this, we check |\ifcollargs@fix@requested|), the
%             macro simply executes the next-code given as the sole argument.
%             The name of the fixer macro has the form
%             |\collargs@fix@|\meta{last mode}|to|\meta{current mode}, where
%             the modes are given by mnemonic codes: |V| = full verbatim, |v| =
%             partial verbatim, and |N| = non-verbatim.
\long\def\collargs@fix#1{%
  % Going through |\edef| + |\unexpanded| avoids doubling the hashes.
  \edef\collargs@fix@next{\unexpanded{#1}}%
  \ifcollargs@fix@requested
    \letcs\collargs@action{collargs@fix@%
      \ifcollargs@last@verbatim
        \ifcollargs@last@verbatimbraces V\else v\fi
      \else
        N%
      \fi
      to%
      \ifcollargs@verbatim
        \ifcollargs@verbatimbraces V\else v\fi
      \else
        N%
      \fi
    }%
  \else
    \let\collargs@action\collargs@fix@next
  \fi
  \collargs@action
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@NtoN,\collargs@fix@vtov,\collargs@fix@VtoV}
%   \indentmacrocode
%   Nothing to do, continue with the next-code.
\def\collargs@fix@NtoN{\collargs@fix@next}
\let\collargs@fix@vtov\collargs@fix@NtoN
\let\collargs@fix@VtoV\collargs@fix@NtoN
% \end{macro}
% 
% \begin{macro}{\collargs@fix@Ntov}
%   We do nothing for the group tokens; for other tokens, we redirect to
%   |\collargs@fix@NtoV|.
\def\collargs@fix@Ntov{%
  \futurelet\collargs@temp\collargs@fix@cc@to@other@ii
}
\def\collargs@fix@cc@to@other@ii{%
  \ifcat\noexpand\collargs@temp\bgroup
    \let\collargs@action\collargs@fix@next
  \else
    \ifcat\noexpand\collargs@temp\egroup
      \let\collargs@action\collargs@fix@next
    \else
      \let\collargs@action\collargs@fix@NtoV
    \fi
  \fi
  \collargs@action
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@NtoV}
%   The only complication here is that we might be in front of a control
%   sequence that was a result of a previous fix in the other direction.
\def\collargs@fix@NtoV{%
  \ifcollargs@double@fix
    \ifcollargs@in@second@fix
      \expandafter\expandafter\expandafter\collargs@fix@NtoV@secondfix
    \else
      \expandafter\expandafter\expandafter\collargs@fix@NtoV@onemore
    \fi
  \else
    \expandafter\collargs@fix@NtoV@singlefix
  \fi
}
% This is the usual situation of a single fix.  We just use |\string| on
% the next token here (but note that some situations can't be saved: noone
% can bring a comment back to life, or distinguish a newline and a space)
\def\collargs@fix@NtoV@singlefix{%
  \expandafter\collargs@fix@next\string
}
% If this is the first fix of two, we know |#1| is a control sequence, so it is
% safe to grab it.
\def\collargs@fix@NtoV@onemore#1{%
  \collargs@do@one@more@fix{%
    \expandafter\collargs@fix@next\string#1%  
  }%
}
% If this is the second fix of the two, we have to check whether the next token
% is a control sequence, and if it is, we need to remember it.  Afterwards, we
% redirect to the single-fix.
\def\collargs@fix@NtoV@secondfix{%
  \if\noexpand\collargs@temp\relax
    \expandafter\collargs@fix@NtoV@secondfix@i
  \else
    \expandafter\collargs@fix@NtoV@singlefix
  \fi
}
\def\collargs@fix@NtoV@secondfix@i#1{%
  \gdef\collargs@double@fix@cs@ii{#1}%
  \collargs@fix@NtoV@singlefix#1%
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@vtoN}
%   Do nothing for the grouping tokens, redirect to |\collargs@fix@VtoN| for
%   other tokens.
\def\collargs@fix@vtoN{%
  \futurelet\collargs@token\collargs@fix@vtoN@i
}
\def\collargs@fix@vtoN@i{%
  \ifcat\noexpand\collargs@token\bgroup
    \expandafter\collargs@fix@next
  \else
    \ifcat\noexpand\collargs@token\egroup
      \expandafter\expandafter\expandafter\collargs@fix@next
    \else
      \expandafter\expandafter\expandafter\collargs@fix@VtoN
    \fi
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@vtoV}
%   Redirect group tokens to |\collargs@fix@NtoV|, and do nothing for other
%   tokens.
\def\collargs@fix@vtoV{%
  \futurelet\collargs@token\collargs@fix@vtoV@i
}
\def\collargs@fix@vtoV@i{%
  \ifcat\noexpand\collargs@token\bgroup
    \expandafter\collargs@fix@NtoV
  \else
    \ifcat\noexpand\collargs@token\egroup
      \expandafter\expandafter\expandafter\collargs@fix@NtoV
    \else
      \expandafter\expandafter\expandafter\collargs@fix@next
    \fi
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@Vtov}
%   Redirect group tokens to |\collargs@fix@VtoN|, and do nothing for other
%   tokens.  |#1| is surely of category 12, so we can safely grab it.
\def\collargs@fix@catcode@of@braces@fromverbatim#1{%
  \ifnum\catcode`#1=1
    \expandafter\collargs@fix@VtoN
    \expandafter#1%
  \else
    \ifnum\catcode`#1=2
      \expandafter\expandafter\expandafter\collargs@fix@cc@VtoN
      \expandafter\expandafter\expandafter#1%
    \else
      \expandafter\expandafter\expandafter\collargs@fix@next
    \fi
  \fi
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@VtoN}
%   This is the only complicated part.  Control sequences and comments (but not
%   grouping characters!) require special attention.  We're fine to grab the
%   token right away, as we know it is of category 12.
\def\collargs@fix@VtoN#1{%
  \ifnum\catcode`#1=0
    \expandafter\collargs@fix@VtoN@escape
  \else
    \ifnum\catcode`#1=14
      \expandafter\expandafter\expandafter\collargs@fix@VtoN@comment
    \else
      \expandafter\expandafter\expandafter\collargs@fix@VtoN@token
    \fi
  \fi
  #1%
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@VtoN@token}
%   We create a new character with the current
%   category code behing the next-code.  This works even for grouping
%   characters.
\def\collargs@fix@VtoN@token#1{%
  \collargs@insert@char\collargs@fix@next{`#1}{\the\catcode`#1}%
}
% \end{macro}
% 
% \begin{macro}{\collargs@fix@VtoN@comment}
%   This macro defines a macro which will,
%   when placed at a comment character, remove the tokens until the end of the
%   line.  The code is adapted from the TeX.SE answer at
%   \url(https://){tex.stackexchange.com/a/10454/16819} by Bruno Le Floch.
\def\collargs@defcommentstripper#1#2{%
  % We chuck a parameter into the following definition, to grab the (verbatim)
  % comment character.  This is why this macro must be executed precisely
  % before the (verbatim) comment character.
  \def#1##1{%
    \begingroup%
    \escapechar=`\\%
    \catcode\endlinechar=\active%
    % We assign the ``other'' category code to comment characters.  Without
    % this, comment characters behind the first one make trouble: there would
    % be no |^||^M| at the end of the line, so the comment stripper would
    % gobble the following line as well; in fact, it would gobble all
    % subsequent lines containing a comment character.  We also make sure to
    % change the category code of \emph{all} comment characters, even if there
    % is usually just one.
    \def\collargs@do####1{\catcode####1=12 }%
    \collargs@comments
    \csname\string#1\endcsname%
  }%
  \begingroup%
  \escapechar=`\\%
  \lccode`\~=\endlinechar%
  \lowercase{%
    \expandafter\endgroup
    \expandafter\def\csname\string#1\endcsname##1~%
  }{%
    % I have removed |\space| from the end of the following line.  We don't
    % want it for our application.
    \endgroup#2%
  }%
}
\collargs@defcommentstripper\collargs@fix@VtoN@comment{%
  \collargs@fix@next
}
% We don't need the generator any more.
\let\collargs@defcommentstripper\relax
% \end{macro}
% 
% \begin{macro}{\collargs@fix@VtoN@escape}
%   An escape character of category code 12
%   is the most challenging --- and we won't get things completely right --- as
%   we have swim further down the input stream to create a control sequence.
%   This macro will throw away the verbatim escape character |#1|.
\def\collargs@fix@VtoN@escape#1{%
  \ifcollargs@double@fix
    % We need to do things in a special way if we're in the double-fix
    % situation triggered by the previous fixing of a control sequence
    % (probably this very one).  In that case, we can't collect it in the usual
    % way because the entire control sequence is spelled out in verbatim.
    \expandafter\collargs@fix@VtoN@escape@d
  \else
    % This here is the usual situation where the escape character was tokenized
    % verbatim, but the control sequence name itself will be collected (right
    % away) in the non-verbatim regime.
    \expandafter\collargs@fix@VtoN@escape@i
  \fi
}
\def\collargs@fix@VtoN@escape@i{%
  % The sole character forming a control symbol name may be of any category.
  % Temporarily redefining the category codes of the craziest characters allows
  % |\collargs@fix@VtoN@escape@ii| to simply grab the following
  % character.
  \begingroup
  \catcode`\\=12
  \catcode`\{=12
  \catcode`\}=12
  \catcode`\ =12
  \collargs@fix@VtoN@escape@ii
}
% The argument is the first character of the control sequence name.
\def\collargs@fix@VtoN@escape@ii#1{%
  \endgroup
  \def\collargs@csname{#1}%
  % Only if |#1| is a letter may the control sequence name continue.
  \ifnum\catcode`#1=11
    \expandafter\collargs@fix@VtoN@escape@iii
  \else
    % In the case of a control space, we have to throw away the following
    % spaces.
    \ifnum\catcode`#1=10
      \expandafter\expandafter\expandafter\collargs@fix@VtoN@escape@s
    \else
      % We have a control symbol.  That means that we haven't peeked ahead and
      % can thus skip |\collargs@fix@VtoN@escape@z|.
      \expandafter\expandafter\expandafter\collargs@fix@VtoN@escape@z@i
    \fi
  \fi
}
% We still have to collect the rest of the control sequence name.  Braces have
% their usual meaning again, so we have to check for them explicitly (and bail
% out if we stumble upon them).
\def\collargs@fix@VtoN@escape@iii{%
  \futurelet\collargs@temp\collargs@fix@VtoN@escape@iv
}
\def\collargs@fix@VtoN@escape@iv{%
  \ifcat\noexpand\collargs@temp\bgroup
    \let\collargs@action\collargs@fix@VtoN@escape@z
  \else
    \ifcat\noexpand\collargs@temp\egroup
      \let\collargs@action\collargs@fix@VtoN@escape@z
    \else
      \expandafter\ifx\space\collargs@temp
        \let\collargs@action\collargs@fix@VtoN@escape@s
      \else
        \let\collargs@action\collargs@fix@VtoN@escape@v
      \fi
    \fi
  \fi
  \collargs@action
}
% If we have a letter, store it and loop back, otherwise finish.  
\def\collargs@fix@VtoN@escape@v#1{%
  \ifcat\noexpand#1a%
    \appto\collargs@csname{#1}%
    \expandafter\collargs@fix@VtoN@escape@iii
  \else
    \expandafter\collargs@fix@VtoN@escape@z\expandafter#1%
  \fi
}
% Throw away the following spaces.
\def\collargs@fix@VtoN@escape@s{%
  \futurelet\collargs@temp\collargs@fix@VtoN@escape@s@i
}
\def\collargs@fix@VtoN@escape@s@i{%
  \expandafter\ifx\space\collargs@temp
    \expandafter\collargs@fix@VtoN@escape@s@ii
  \else
    \expandafter\collargs@fix@VtoN@escape@z
  \fi
}
\def\collargs@fix@VtoN@escape@s@ii{%
  \expandafter\collargs@fix@VtoN@escape@z\romannumeral-0%
}
% Once we have collected the control sequence name into |\collargs@csname|, we
% will create the control sequence behind the next-code.  However, we have two
% complications.  The minor one is that |\csname| defines an unexisting control
% sequence to mean |\relax|, so we have to check whether the control sequence
% we will create is defined, and if not, ``undefine'' it in advance.
% ^^A todo: do nicer
\def\collargs@fix@VtoN@escape@z@i{%
  \collargs@fix@VtoN@escape@z@maybe@undefine@cs@begin
  \collargs@fix@VtoN@escape@z@ii
}%
\def\collargs@fix@VtoN@escape@z@maybe@undefine@cs@begin{%
  \ifcsname\collargs@csname\endcsname
    \@tempswatrue
  \else
    \@tempswafalse
  \fi
}
\def\collargs@fix@VtoN@escape@z@maybe@undefine@cs@end{%
  \if@tempswa
  \else
    \cslet{\collargs@csname}\collargs@undefined
  \fi
}
\def\collargs@fix@VtoN@escape@z@ii{%
  \expandafter\collargs@fix@VtoN@escape@z@maybe@undefine@cs@end
  \expandafter\collargs@fix@next\csname\collargs@csname\endcsname
}
% The second complication is much greater, but it only applies to control words
% and spaces, and that's why control symbols went directly to the macro above.
% Control words and spaces will only get there via a detour through the
% following macro.
% 
% The problem is that collecting the control word\slash space name peeked ahead
% in the stream, so the character following the control sequence (name) is
% already tokenized.  We will (at least partially) address this by requesting a
% ``double-fix'': until the control sequence we're about to create is consumed
% into some argument, each category code fix will fix two ``tokens'' rather
% than one.
\def\collargs@fix@VtoN@escape@z{%
  \collargs@if@one@more@fix{%
    % Some previous fixing has requested a double fix, so let's do it.
    % Afterwards, redirect to the control symbol code
    % |\collargs@fix@VtoN@escape@z@i|.  It will surely use the correct
    % |\collargs@csname| because we do the second fix in a group.
    \collargs@do@one@more@fix\collargs@fix@VtoN@escape@z@i
  }{%
    % Remember the collected control sequence.  It will be used in
    % |\collargs@cancel@double@fix|.
    \collargs@fix@VtoN@escape@z@maybe@undefine@cs@begin
    \xdef\collargs@double@fix@cs@i{\expandonce{\csname\collargs@csname\endcsname}}%
    \collargs@fix@VtoN@escape@z@maybe@undefine@cs@end
    % Request the double-fix.
    \global\collargs@double@fixtrue
    % The complication is addressed, redirect to the control symbol finish.
    \collargs@fix@VtoN@escape@z@ii
  }%
}
% When we have to ``redo'' a control sequence, because it was ping-ponged back
% into the verbatim mode, we cannot collect it by
% |\collargs@fix@VtoN@escape@i|, because it is spelled out entirely in
% verbatim.  However, we have seen this control sequence before, and remembered
% it, so we'll simply grab it.  Another complication is that we might be either
% at the ``first'' control sequence, whose fixing created all these double-fix
% trouble, or at the ``second'' control sequence, if the first one was
% immediately followed by another one.  But we have remembered both of them:
% the first one in |\collargs@fix@VtoN@escape@z|, the second one in
% |\collargs@fix@NtoV@secondfix|.
\def\collargs@fix@VtoN@escape@d{%
  \ifcollargs@in@second@fix
    \expandafter\collargs@fix@VtoN@escape@d@i
      \expandafter\collargs@double@fix@cs@ii
  \else
    \expandafter\collargs@fix@VtoN@escape@d@i
      \expandafter\collargs@double@fix@cs@i
  \fi
}
% We have the contents of either |\collargs@double@fix@cs@i| or
% |\collargs@double@fix@cs@ii| here, a control sequence in both cases.
\def\collargs@fix@VtoN@escape@d@i#1{%
  \expandafter\expandafter\expandafter\collargs@fix@VtoN@escape@d@ii
    \expandafter\string#1\relax
}
% We have the verbatimized control sequence name in |#2| (|#1| is the escape
% character).  By storing it into |\collargs@csname|, we pretend we have
% collected it.  By defining and executing |\collargs@fix@VtoN@escape@d@iii|,
% we actually gobble it from the input stream.  Finally, we reroute to
% |\collargs@fix@VtoN@escape@z|.
\def\collargs@fix@VtoN@escape@d@ii#1#2\relax{%
  \def\collargs@csname{#2}%
  \def\collargs@fix@VtoN@escape@d@iii#2{%
    \collargs@fix@VtoN@escape@z
  }%
  \collargs@fix@VtoN@escape@d@iii
}
% This conditional signals a double-fix request.  It should be always set
% globally, because it is cleared by |\collargs@double@fixfalse| in a group.
\newif\ifcollargs@double@fix
% This conditional signals that we're currently performing the second fix.
\newif\ifcollargs@in@second@fix
% Inspect the two conditionals above to decide whether we have to perform
% another fix: if so, execute the first argument, otherwise the second one.
% This macro is called only from |\collargs@fix@VtoN@escape@z| and
% |\collargs@fix@NtoV|, because these are the only two places where we might
% need the second fix, ping-ponging a control sequence between the verbatim and
% the non-verbatim mode.
\def\collargs@if@one@more@fix{%
  \ifcollargs@double@fix
    \ifcollargs@in@second@fix
      \expandafter\expandafter\expandafter\@secondoftwo
    \else
      \expandafter\expandafter\expandafter\@firstoftwo
    \fi
  \else
    \expandafter\@secondoftwo
  \fi
}
\def\collargs@do@one@more@fix#1{%
  % We perform the second fix in a group, signalling that we're performing
  % it.
  \begingroup
  \collargs@in@second@fixtrue
  % Reexecute the fixing routine, at the end, close the group and execute
  % the given code afterwards.
  \collargs@fix{%
    \endgroup
    #1%
  }%
}
% This macro is called from |\collargs@appendarg| to cancel the double-fix
% request.
\def\collargs@cancel@double@fix{%
  % |\collargs@appendarg| is only executed when something was actually
  % consumed.  We thus know that at least one of the problematic ``tokens'' is
  % gone, so the double fix is not necessary anymore.
  \global\collargs@double@fixfalse
  % What we have to figure out, still, is whether both problematic ``tokens''
  % we consumed.  If so, no more fixing is required.  But if only one of them
  % was consumed, we need to request the normal, single, fix for the remaining
  % ``token''.
  \begingroup
  % This will attach the delimiters directly to the argument, so we'll see what
  % was actually consumed.
  \collargs@process@arg
  % We compare what was consumed when collecting the current argument with the
  % control word that triggered double-fixing.  If they match, only the
  % offending control word was consumed, so we need to set the fix request to
  % true for the following token.
  \edef\collargs@temp{\the\collargsArg}%
  \edef\collargs@tempa{\expandafter\string\collargs@double@fix@cs@i}%
  \ifx\collargs@temp\collargs@tempa
    \global\collargs@fix@requestedtrue
  \fi
  \endgroup
}
% \end{macro}
%
%
% \begin{macro}{\collargs@insert@char,\collargs@make@char}
%   These macros create a character of character code |#2| and category code
%   |#3|.  The first macro inserts it into the stream behind the code in |#1|;
%   the second one defines the control sequence in |#1| to hold the created
%   character (clearly, it should not be used for categories 1 and 2).  
% 
%   We use the facilities of \hologo{LuaTeX}, \hologo{XeTeX} and \hologo{LaTeX}
%   where possible.  In the end, we only have to implement our own macros for
%   plain \hologo{pdfTeX}.
%<!context>\ifdefined\luatexversion
  \def\collargs@insert@char#1#2#3{%
    \edef\collargs@temp{\unexpanded{#1}}%
    \expandafter\collargs@temp\directlua{%
      tex.cprint(\number#3,string.char(\number#2))}%
  }%
  \def\collargs@make@char#1#2#3{%
    \edef#1{\directlua{tex.cprint(\number#3,string.char(\number#2))}}%
  }%
%<*!context>  
\else
  \ifdefined\XeTeXversion
    \def\collargs@insert@char#1#2#3{%
      \edef\collargs@temp{\unexpanded{#1}}%
      \expandafter\collargs@temp\Ucharcat #2 #3
    }%
    \def\collargs@make@char#1#2#3{%
      \edef#1{\Ucharcat#2 #3}%
    }%
  \else
    %<*latex>
    \ExplSyntaxOn
    \def\collargs@insert@char#1#2#3{%
      \edef\collargs@temp{\unexpanded{#1}}%
      \expandafter\expandafter\expandafter\collargs@temp\char_generate:nn{#2}{#3}%
    }%
    \def\collargs@make@char#1#2#3{%
      \edef#1{\char_generate:nn{#2}{#3}}%
    }%
    \ExplSyntaxOff
    %</latex>
    %<*plain>
    % The implementation is inspired by |expl3|'s implementation of
    % |\char_generate:nn|, but our implementation is not expandable, for
    % simplicity.  We first store an (arbitrary) character |^||^@| of category
    % code $n$ into control sequence |\collargs@charofcat@|$n$, for every
    % (implementable) category code.
    \begingroup
    \catcode`\^^@=1  \csgdef{collargs@charofcat@1}{%
      \noexpand\expandafter^^@\iffalse}\fi}
    \catcode`\^^@=2  \csgdef{collargs@charofcat@2}{\iffalse{\fi^^@}
    \catcode`\^^@=3  \csgdef{collargs@charofcat@3}{^^@}
    \catcode`\^^@=4  \csgdef{collargs@charofcat@4}{^^@}
    % As we have grabbed the spaces already, a remaining newline should surely be
    % fixed into a |\par|.
                     \csgdef{collargs@charofcat@5}{\par}
    \catcode`\^^@=6  \csxdef{collargs@charofcat@6}{\unexpanded{^^@}}
    \catcode`\^^@=7  \csgdef{collargs@charofcat@7}{^^@}
    \catcode`\^^@=8  \csgdef{collargs@charofcat@8}{^^@}
                     \csgdef{collargs@charofcat@10}{\noexpand\space}
    \catcode`\^^@=11 \csgdef{collargs@charofcat@11}{^^@}
    \catcode`\^^@=12 \csgdef{collargs@charofcat@12}{^^@}
    \catcode`\^^@=13 \csgdef{collargs@charofcat@13}{^^@}
    \endgroup
    \def\collargs@insert@char#1#2#3{%
      % Temporarily change the lowercase code of |^||^@| to the requested character
      % |#2|.
      \begingroup
      \lccode`\^^@=#2\relax
      % We'll have to close the group before executing the next-code.
      \def\collargs@temp{\endgroup#1}%
      % |\collargs@charofcat@|\meta{requested category code} is f-expanded first,
      % leaving us to lowercase |\expandafter\collargs@temp^||^@|.  Clearly,
      % lowercasing |\expandafter\collargs@temp| is a no-op, but lowercasing
      % |^||^@| gets us the requested character of the requested category.
      % |\expandafter| is executed next, and this gets rid of the conditional for
      % category codes 1 and 2.
      \expandafter\lowercase\expandafter{%
        \expandafter\expandafter\expandafter\collargs@temp
        \romannumeral-`0\csname collargs@charofcat@\the\numexpr#3\relax\endcsname
      }%
    }
    % This macro cannot not work for category code 6 (because we assign the
    % result to a macro), but no matter, we only use it for category code 12
    % anyway.
    \def\collargs@make@char#1#2#3{%
      \begingroup
      \lccode`\^^@=#2\relax
      % Define |\collargs@temp| to hold |^||^@| of the appropriate category.
      \edef\collargs@temp{%
        \csname collargs@charofcat@\the\numexpr#3\relax\endcsname}%
      % Preexpand the second |\collargs@temp| so that we lowercase
      % |\def\collargs@temp{^||^@}|, with |^||^@| of the appropriate category.
      \expandafter\lowercase\expandafter{%
        \expandafter\def\expandafter\collargs@temp\expandafter{\collargs@temp}%
      }%
      \expandafter\endgroup
      \expandafter\def\expandafter#1\expandafter{\collargs@temp}%
    }
    %</plain>
  \fi
\fi
%</!context>
% \end{macro}
% 
%<plain>\resetatcatcode
%<context>\stopmodule
%<context>\protect
%    \end{macrocode}
% 
% Local Variables:
% TeX-engine: luatex
% TeX-master: "doc/memoize-code.tex"
% TeX-auto-save: nil
% End: