[latex3-commits] [latex3/latex2e] verb-env: Introduce an f-specification argument in ltcmd (d55f3ba0c)

github at latex-project.org github at latex-project.org
Sat Nov 2 17:42:21 CET 2024


Repository : https://github.com/latex3/latex2e
On branch  : verb-env
Link       : https://github.com/latex3/latex2e/commit/d55f3ba0c40de32917d6d0550b7a82f8f8c36a0d

>---------------------------------------------------------------

commit d55f3ba0c40de32917d6d0550b7a82f8f8c36a0d
Author: Joseph Wright <joseph at texdev.net>
Date:   Mon Oct 28 13:12:50 2024 +0000

    Introduce an f-specification argument in ltcmd
    
    See latex3/latex3#591.


>---------------------------------------------------------------

d55f3ba0c40de32917d6d0550b7a82f8f8c36a0d
 base/changes.txt                         |   4 +
 base/doc/ltnews41.tex                    |  33 +++
 base/doc/usrguide.tex                    |  36 ++++
 base/ltcmd.dtx                           | 221 ++++++++++++++++++-
 base/testfiles-ltcmd/ltcmd005.luatex.tlg | 358 -------------------------------
 base/testfiles-ltcmd/ltcmd005.lvt        |  48 -----
 base/testfiles-ltcmd/ltcmd005.tlg        |  52 +----
 base/testfiles-ltcmd/ltcmd009.lvt        |  91 ++++++++
 base/testfiles-ltcmd/ltcmd009.tlg        |  53 +++++
 9 files changed, 433 insertions(+), 463 deletions(-)

diff --git a/base/changes.txt b/base/changes.txt
index 6321cf6fd..a9f6e65cc 100644
--- a/base/changes.txt
+++ b/base/changes.txt
@@ -6,6 +6,10 @@ to completeness or accuracy and it contains some references to files that are
 not part of the distribution.
 ================================================================================
 
+2024-11-01  Joseph Wright  <Joseph.Wright at latex-project.org>
+	* ltcmd.dtx, usrguide.tex
+	New "f"-type argument
+
 ================================================================================
 All changes above are only part of the development branch for the next release.
 ================================================================================
diff --git a/base/doc/ltnews41.tex b/base/doc/ltnews41.tex
index 0c9751704..c91ee0949 100644
--- a/base/doc/ltnews41.tex
+++ b/base/doc/ltnews41.tex
@@ -147,6 +147,39 @@
 
 \section{New or improved commands}
 
+\subsection{Collecting environment bodies verbatim}
+
+The mechanisms in \pkg{ltcmd} (\enquote{\pkg{xparse}}) offer a powerful way to
+specify a range of types of document command and environment syntax. This
+includes the ability to collect the entire body of an environment, for cases
+where treating it as a standard argument is useful. It is also possible in
+\pkg{ltcmd} to define argument which grab their content verbatim, another
+specialist argument form. To date, however, it was not possible to combine
+these two ideas.
+
+In this release, a new specifier~\texttt{f} is introduced, which collects the
+body of an environment in a verbatim-like way. Like the existing
+\texttt{v}~specification, each separate line is marked by the special
+\cs{obeyedline} marker, which as standard issues a normal paragraph. Thus, this
+new specifier is usable both for typesetting and collecting file contents (the
+\texttt{f} indicates \enquote{\texttt{filecontents}-like}). Thus, we may use
+\begin{verbatim}
+\NewDocumentEnvironment
+  {MyVerbatim}{!O{\ttfamily} +f}
+  {\begin{center} #1 #2\end{center}} {}
+\begin{MyVerbatim}[\ttfamily\itshape]
+  % Some code is show here
+  $y = mx + c$
+\end{MyVerbatim}
+\end{verbatim}
+to obtain
+\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} +f}
+  {\begin{center} #1 #2\end{center}} {}
+\begin{MyVerbatim}[\ttfamily\itshape]
+  % Some code is show here
+  $y = mx + c$
+\end{MyVerbatim}
+
 \section{Code improvements}
 
 \section{Bug fixes}
diff --git a/base/doc/usrguide.tex b/base/doc/usrguide.tex
index e4ea6e4e0..392b407cc 100644
--- a/base/doc/usrguide.tex
+++ b/base/doc/usrguide.tex
@@ -858,6 +858,42 @@ verbatim material, so will need to be set up using for example \cs{ttfamily}.
 Similarly, the \texttt{verbatim} environment sets up the meaning of \cs{par}
 suitable for breaking lines.
 
+\subsection{Verbatim environments}
+\label{sec:cmd:verbenv}
+
+In some cases, as well as grabbing an environment body you will want the
+contents to be treated verbatim. This is available using the argument
+specification~\texttt{f}. Like the \texttt{b} specification, this has to be the
+last one. Thus for example
+\begin{verbatim}
+\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} +f}
+  {\begin{center} #1 #2\end{center}} {}
+\begin{MyVerbatim}[\ttfamily\itshape]
+  % Some code is show here
+  $y = mx + c$
+\end{MyVerbatim}
+\end{verbatim}
+will typeset
+\NewDocumentEnvironment{MyVerbatim}{!O{\ttfamily} +f}
+  {\begin{center} #1 #2\end{center}} {}
+\begin{MyVerbatim}[\ttfamily\itshape]
+  % Some code is show here
+  $y = mx + c$
+\end{MyVerbatim}
+
+As grabbing the entire contents verbatim, newlines are always permitted: if you
+use \texttt{f} rather than \texttt{+f}, a warning will be issued and \LaTeX{}
+will assume you meant to include the \texttt{+}. As for the \texttt{v}
+specification, new lines are stored as \cs{ObeyedLine}. In a similar fashion to
+the \texttt{b}~specification, by default \emph{newlines} are trimmed at both
+ends of the body. Putting the prefix |!| before \texttt{f} suppresses
+space-trimming.
+
+Notice that for technical reasons, we recommend that an optional argument
+coming immediately before an \texttt{f} specification should not allow any
+spaces, achieved by adding the \texttt{!} as showing in the example. However,
+this is left as a choice for the user.
+
 \subsection{Performance}
 
 For document commands where the argument specification is entirely
diff --git a/base/ltcmd.dtx b/base/ltcmd.dtx
index eccb104bb..3879b100d 100644
--- a/base/ltcmd.dtx
+++ b/base/ltcmd.dtx
@@ -34,8 +34,8 @@
 %%% From File: ltcmd.dtx
 %
 %    \begin{macrocode}
-\def\ltcmdversion{v1.2f}
-\def\ltcmddate{2024-07-06}
+\def\ltcmdversion{v1.3a}
+\def\ltcmddate{2024-11-01}
 %    \end{macrocode}
 %
 %<*driver>
@@ -1331,28 +1331,47 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_normalize_type_b:w}
-%   This argument type is not allowed for commands.  This is only
+% \changes{v1.3a}{2024-11-01}{Extend to cover \texttt{f}-type grabbing}
+% \begin{macro}{\@@_normalize_type_f:w}
+% \changes{v1.3a}{2024-11-01}{New function}
+% \begin{macro}{\@@_normalize_type_b_or_f:nn}
+% \changes{v1.3a}{2024-11-01}{New function}
+%   These argument type is not allowed for commands.  They is only
 %   allowed at the end of the argument specification, hence we check
 %   that |#1| is the end.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_normalize_type_b:w #1
+  { \@@_normalize_type_b_or_f:nn {#1} { b } }
+\cs_new_protected:Npn \@@_normalize_type_f:w #1
+  {
+    \bool_if:NF \l_@@_long_bool
+      {
+        \msg_warning:nn { cmd } { verb-collection-always-long }
+        \bool_set_true:N \l_@@_long_bool
+      }
+    \@@_normalize_type_b_or_f:nn {#1} { f }
+  }
+\cs_new_protected:Npn \@@_normalize_type_b_or_f:nn #1#2
   {
     \bool_if:NF \l_@@_environment_bool
       {
         \msg_error:nnxx { cmd } { invalid-command-arg }
-          { \@@_environment_or_command: } { b }
+          { \@@_environment_or_command: } {#2}
         \@@_bad_def:wn
       }
     \tl_clear:N \l_@@_last_delimiters_tl
-    \@@_add_arg_spec:n { b }
+    \@@_add_arg_spec:n {#2}
     \quark_if_recursion_tail_stop:n {#1}
-    \msg_error:nnxx { cmd } { arg-after-body }
+    \msg_error:nnxxx { cmd } { arg-after-body }
+      {#2}
       { \@@_environment_or_command: }
       { \tl_to_str:n {#1} }
     \@@_bad_def:wn
   }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_single_token_check:n}
 %   Checks that the argument is a single (non-space) token (possibly
@@ -1658,16 +1677,27 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_add_type_b:w}
+% \changes{v1.3a}{2024-11-01}{Extend to cover \texttt{f}-type grabbing}
+% \begin{macro}{\@@_add_type_f:w}
+% \changes{v1.3a}{2024-11-01}{New function}
+% \begin{macro}{\@@_add_type_b_or_c:N}
+% \changes{v1.3a}{2024-11-01}{New function}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_type_b:w
+  { \@@_add_type_b_or_f:N b }
+\cs_new_protected:Npn \@@_add_type_f:w
+  { \@@_add_type_b_or_f:N f }
+\cs_new_protected:Npn \@@_add_type_b_or_f:N #1
   {
     \@@_flush_m_args:
     \@@_add_default:
-    \@@_add_grabber:N b
+    \@@_add_grabber:N #1
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_add_type_D:w}
 %    \begin{macrocode}
@@ -3002,6 +3032,173 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_grab_f_long:w}
+% \changes{v1.3a}{2024-11-01}{New \texttt{f}-type grabbing function}
+% \begin{macro}{\@@_grab_f_long_obey_spaces:w}
+% \begin{macro}{\@@_grab_f_aux:n}
+% \begin{macro}{\@@_grab_f_aux:w}
+% \begin{macro}{\@@_grab_f_check:w}
+% \begin{macro}{\@@_grab_f_loop:w}
+% \begin{macro}{\@@_grab_f_space_check:w}
+% \begin{macro}{\@@_grab_f_space_aux:w}
+% \begin{macro}{\@@_grab_f_end:nn}
+% \begin{macro}{\@@_grab_f_end:n}
+% \begin{macro}{\@@_grab_f_end_auxi:w}
+% \begin{macro}{\@@_grab_f_end_auxii:w}
+%   Collecting an environment body verbatim shares some ideas with the
+%   \texttt{v}-type grabber, and others with the standard \texttt{filecontents}
+%   environment. The start is to set the end-of-line to a predictable value
+%   and to deactivate the specials. We then define the end marker: this
+%   has to have the correct category codes, so is a token list not a string
+%   (\texttt{end} and the end-of-env name are catcode-11). We use this to set
+%   up the end-of-env test, then hand over to an auxiliary.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_f_long:w #1 \@@_run_code:
+  {
+    \bool_set_false:N \l_@@_obey_spaces_bool
+    \@@_grab_f_aux:n {#1}
+  }
+\cs_new_protected:Npn \@@_grab_f_long_obey_spaces:w #1 \@@_run_code:
+  {
+    \bool_set_true:N \l_@@_obey_spaces_bool
+    \@@_grab_f_aux:n {#1}
+  }
+\cs_new_protected:Npn \@@_grab_f_aux:n #1
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \group_begin:
+      \tl_clear:N \l_@@_v_arg_tl
+      \tex_escapechar:D = 92 \scan_stop:
+      \tex_endlinechar:D = `\^^M \scan_stop:
+      \cs_set_eq:NN \do \char_set_catcode_other:N
+      \dospecials
+      \tl_set:Ne \l_@@_tmpa_tl
+        {
+          \c_backslash_str end
+            \c_left_brace_str \@currenvir \c_right_brace_str
+        }
+      \use:e
+        {
+          \cs_set_protected:Npn \@@_grab_f_check:w
+            ##1 \l_@@_tmpa_tl ##2 \l_@@_tmpa_tl ##3
+            \scan_stop:
+        }
+        {
+          \tl_if_empty:nTF {##3}
+            {
+              \tl_put_right:Nn \l_@@_v_arg_tl
+                {
+                  ##1
+                  \obeyedline
+                }
+              \@@_grab_f_loop:w
+            }
+            { \@@_grab_f_end:nn {##1} {##2} }
+        }
+      \@@_grab_f_aux:w
+  }
+%    \end{macrocode}
+%   To allow for the need to change the category code of end-of-lines, we
+%   put this in a small auxiliary. At the end of this, we deal with the
+%   a special case for the first line before looping.
+%    \begin{macrocode}
+\group_begin:
+  \char_set_catcode_other:N \^^M %
+  \cs_new_protected:Npn \@@_grab_f_aux:w %
+    { %
+      \cs_set_protected:Npe \@@_grab_f_loop:w ##1 ^^M %
+        { %
+          \@@_grab_f_check:w ##1 %
+            \l_@@_tmpa_tl %
+            \l_@@_tmpa_tl %
+            \scan_stop: %
+        } %
+      \char_set_catcode_other:N \^^M %
+      \group_align_safe_begin: %
+      \peek_after:Nw \@@_grab_f_space_check:w
+    } %
+\group_end: %
+\cs_new_protected:Npn \@@_grab_f_check:w { }
+\cs_new_protected:Npn \@@_grab_f_loop:w { }
+%    \end{macrocode}
+%   If there was a potential optional argument before the \texttt{f}-type
+%   one, but it was missed out, the next character will already have been
+%   tokenized. The most common case will be a newline, which will have
+%   been converted to a space: that is picked up here. (It is impossible
+%   to filter out all possible cases, as the underlying behavior of
+%   \tn{futurelet} means that for example a \verb=%= would be a comment
+%   and be lost.) Alternative approaches require that a category code
+%   change for \verb=^^M= takes place before searching for any optional
+%   arguments (see for example \pkg{fancyvrb}).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_f_space_check:w
+  {
+    \if_meaning:w \l_peek_token \c_space_token
+      \exp_after:wN \@@_grab_f_space_aux:w
+    \else:
+      \group_align_safe_end:
+      \exp_after:wN \@@_grab_f_loop:w
+    \fi:
+  }
+\cs_new_protected:Npn \@@_grab_f_space_aux:w
+  {
+    \group_align_safe_end:
+    \tl_set:Nn \l_@@_v_arg_tl { \obeyedline }
+    \peek_remove_spaces:n
+      { \@@_grab_f_loop:w }
+  }
+\cs_new_protected:Npn \@@_grab_f_end:nn #1#2
+  {
+      \tl_if_blank:nF {#1#2}
+        \ERROR
+    \exp_args:NNNo \group_end:
+    \tl_set:Nn \l_@@_v_arg_tl { \l_@@_v_arg_tl }
+    \@@_add_arg:x
+      {
+        \bool_if:NTF \l_@@_obey_spaces_bool
+          { \exp_not:V }
+          { \exp_args:NV \@@_grab_f_end:n }
+          \l_@@_v_arg_tl
+      }
+    \exp_args:NV \end \@currenvir
+  }
+%    \end{macrocode}
+%   Look for line markers at each end and tidy up if required.
+%    \begin{macrocode}
+\cs_new:Npn \@@_grab_f_end:n #1
+  {
+    \@@_grab_f_end_auxi:w {#1} #1
+      \q_nil \obeyedline \q_nil \obeyedline \q_nil \q_stop
+  }
+\cs_new:Npn \@@_grab_f_end_auxi:w
+  #1#2 \obeyedline \q_nil \obeyedline \q_nil #3 \q_stop
+  {
+    \tl_if_empty:nTF {#3}
+      { \@@_grab_f_end_auxii:w {#1} #1 }
+      { \@@_grab_f_end_auxii:w {#2} #2 }
+        \obeyedline \q_stop
+  }
+\cs_new:Npn \@@_grab_f_end_auxii:w
+  #1#2 \obeyedline #3 \q_stop
+  {
+    \tl_if_blank:nTF {#2}
+      { \tl_tail:n {#1} }
+      { \exp_not:n {#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}
 %   {
 %     \@@_grab_D:w                          ,
@@ -4716,12 +4913,13 @@
 % \changes{v1.0f}{2021/06/04}{Normalize various error messages}
 % \changes{v1.2c}{2023/12/22}
 %         {Generalize message \texttt{invalid-bang} (gh/1198)}
+% \changes{v1.3a}{2024-11-01}{Generalize message \texttt{arg-after-body}}
 %    \begin{macrocode}
 \msg_new:nnnn { cmd } { arg-after-body }
-  { Argument~type~'b'~must~be~last~in~#1. }
+  { Argument~type~'#1'~must~be~last~in~#2. }
   {
-    The~'b'~argument~type~must~come~last~but~it~is~followed~
-    by~'#2'~in~the~argument~specification.~This~is~not~allowed.
+    The~'#1'~argument~type~must~come~last~but~it~is~followed~
+    by~'#3'~in~the~argument~specification.~This~is~not~allowed.
     \c_@@_ignore_def_tl
   }
 \msg_new:nnnn { cmd } { bad-arg-spec }
@@ -4934,6 +5132,7 @@
 %    \end{macrocode}
 %
 % Intended more for information.
+% \changes{v1.3a}{2024-11-01}{New message \texttt{verb-collection-always-long}}
 %    \begin{macrocode}
 \msg_new:nnn { cmd } { define-command }    % should be just ``define'' but dep in xparse
   {
@@ -4973,6 +5172,8 @@
     '#1~code'~and/or~'#1~defaults'.~Maybe~you~tried~using~
     \iow_char:N\\let.~This~may~lead~to~an~infinite~loop.
   }
+\msg_new:nnn { cmd } { verb-collection-always-long }
+  { Verbatim~body~collection~always~permits~newlines. }
 %    \end{macrocode}
 %
 % \subsection{User functions}
diff --git a/base/testfiles-ltcmd/ltcmd005.luatex.tlg b/base/testfiles-ltcmd/ltcmd005.luatex.tlg
deleted file mode 100644
index ad67a80c8..000000000
--- a/base/testfiles-ltcmd/ltcmd005.luatex.tlg
+++ /dev/null
@@ -1,358 +0,0 @@
-This is a generated file for the LaTeX2e validation system.
-Don't change this file in any respect.
-Author: Bruno Le Floch
-============================================================
-TEST 1: Invalid '!'
-============================================================
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The prefix '!' is only allowed for trailing optional arguments. You tried to apply it to an optional argument before mandatory 'R(){-NoValue-}'.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The prefix '!' is only allowed for trailing optional arguments. You tried to apply it to an optional argument before mandatory 'm'.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided for command '\testA' has two '!' markers applied to the same argument; one is redundant.
-! LaTeX cmd Error: Bad argument specification '!+!' for command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Bad argument specification '+!' for command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Bad argument specification '!' for command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '+' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided for command '\testA' has two '+' markers applied to the same argument; one is redundant.
-! LaTeX cmd Error: Bad argument specification '!o' for \testA.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-Expandable commands must have a final mandatory argument (or no arguments at all). You cannot have a terminal optional argument with expandable commands.
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The prefix '!' is only allowed for trailing optional arguments. You tried to apply it to 'm'.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 2: Valid '!' and avoid dropping spaces
-============================================================
-Runaway argument?
-! Paragraph ended before \testA  was complete.
-<to be read again> 
-\par 
-l. ...  }
-I suspect you've forgotten a `}', causing me to apply this
-control sequence to too much text. How can we recover?
-My plan is to forget the whole thing and hope for the best.
-|a|-NoValue-|b||
-|a|b|-NoValue-|  |
-|a|b|d||
-|a|b|c[d]| \c_space_token |
-Runaway argument?
-! Paragraph ended before \testB  was complete.
-<to be read again> 
-\par 
-l. ...  }
-I suspect you've forgotten a `}', causing me to apply this
-control sequence to too much text. How can we recover?
-My plan is to forget the whole thing and hope for the best.
-|a|\BooleanFalse |\BooleanTrue ||
-|a|\BooleanTrue |\BooleanFalse |  |
-|a|\BooleanTrue |\BooleanTrue ||
-|a|\BooleanTrue |\BooleanTrue | \c_space_token |
-============================================================
-============================================================
-TEST 3: Environment body valid
-============================================================
-============================================================
-|...|{\begin {any} \begin {unbalanced} \end {environments} \begin {provided}}{\end {nesting} \end {works} \begin {out} \end {!}}|
-|...|
-|-NoValue-| [...] \begin {any} \begin {unbalanced} \end {environments} \begin {provided} \end {nesting} \end {works} \begin {out} \end {!} |
-|-NoValue-|
-============================================================
-TEST 4: Body invalid
-============================================================
-|-NoValue-|{}|
-! LaTeX Error: \begin{env1} on input line ... ended by \end{env2}.
-See the LaTeX manual or LaTeX Companion for explanation.
-Type  H <return>  for immediate help.
- ...                                              
-l. ...  }
-Your command was ignored.
-Type  I <command> <return>  to replace it with another command,
-or  <return>  to continue without it.
-Runaway argument?
-\begin  
-! Paragraph ended before \environment env2  was complete.
-<to be read again> 
-\par 
-l. ...  }
-I suspect you've forgotten a `}', causing me to apply this
-control sequence to too much text. How can we recover?
-My plan is to forget the whole thing and hope for the best.
-! LaTeX cmd Error: Invalid argument type 'b' in command '\testE'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The letter 'b' can only be used in environment argument specifications, but not for commands.
-LaTeX will ignore the entire definition.
-! LaTeX cmd Error: Argument type 'b' must be last in environment 'env3'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The 'b' argument type must come last but it is followed by 'm' in the argument specification. This is not allowed.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 5: Invalid signatures
-============================================================
-! LaTeX cmd Error: Bad argument specification 'O' for command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Bad argument specification 'D[]' for environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Bad argument specification '!+>{\TrimSpaces }' for environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided is not valid: one or more mandatory parts are missing.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The prefix '!' is only allowed for trailing optional arguments. You tried to apply it to an optional argument before mandatory 'm'.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '!' in environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The prefix '!' is only allowed for trailing optional arguments. You tried to apply it to an optional argument before mandatory 'm'.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Too many arguments for command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification 'mmmmmmmmmmmm' asks for more than 9 arguments. This cannot be implemented.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Too many arguments for environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification 'mmmmmmmmmmmm' asks for more than 9 arguments. This cannot be implemented.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '!' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided for command '\testA' has two '!' markers applied to the same argument; one is redundant.
-! LaTeX cmd Error: Invalid argument prefix '!' in environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification provided for environment 'testA' has two '!' markers applied to the same argument; one is redundant.
-! LaTeX cmd Error: Invalid argument type 'X' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The letter 'X' does not specify a known argument type.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument type 'X' in environment 'testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The letter 'X' does not specify a known argument type.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 6: Already or not yet defined
-============================================================
-! LaTeX cmd Error: Command '\space' already defined.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-You have used \NewDocumentCommand with a command that already has a definition.
-The existing definition of '\space' will not be altered.
-|macro:-> |
-! LaTeX cmd Error: Environment 'foo' already defined.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-You have used \NewDocumentEnvironment with an environment that already has a definition.
-The existing definition of 'foo' will not be altered.
-foo
-! LaTeX cmd Error: Command '\testA' undefined.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-You have used \RenewDocumentCommand with a command that was never defined.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Environment 'testA' undefined.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-You have used \RenewDocumentEnvironment with an environment that was never defined.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 7: Not definable/multi-char
-============================================================
-! LaTeX cmd Error: First argument of '\NewDocumentCommand' must be a command.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The first argument of '\NewDocumentCommand' should be the document command that will be defined. The provided argument '+' is a character. Perhaps a backslash is missing?
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: First argument of '\NewDocumentCommand' must be a command.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The first argument of '\NewDocumentCommand' should be the document command that will be defined. The provided argument 'space' contains more than one token. Perhaps a backslash is missing?
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Argument delimiter 'ab' invalid in command '\testB'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification contains 'ab' in a place where a single token is required.
-LaTeX will ignore this entire definition.
-! Use of \??? doesn't match its definition.
-<argument> \???  
-      ! LaTeX cmd Error: Invalid argument {foo} to \IfBoolean...
-l. ...  }
-If you say, e.g., `\def\a1{...}', then you must always
-put `1' after `\a', since control sequence names are
-made up of letters only. The macro here has not been
-followed by the required stuff, so I'm ignoring it.
-FALSE
-! Use of \??? doesn't match its definition.
-<argument> \???  
-      ! LaTeX cmd Error: Invalid argument {\foo } to \IfBoolean...
-l. ...  }
-If you say, e.g., `\def\a1{...}', then you must always
-put `1' after `\a', since control sequence names are
-made up of letters only. The macro here has not been
-followed by the required stuff, so I'm ignoring it.
-! Use of \??? doesn't match its definition.
-<argument> \???  
-      ! LaTeX cmd Error: Invalid argument {?} to \IfBoolean...
-l. ...  }
-If you say, e.g., `\def\a1{...}', then you must always
-put `1' after `\a', since control sequence names are
-made up of letters only. The macro here has not been
-followed by the required stuff, so I'm ignoring it.
-FALSE
-============================================================
-============================================================
-TEST 8: Invalid signatures for expandable commands
-============================================================
-! LaTeX cmd Error: Bad argument specification 'mo' for \testA.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-Expandable commands must have a final mandatory argument (or no arguments at all). You cannot have a terminal optional argument with expandable commands.
-! LaTeX cmd Error: Invalid argument prefix '+' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The arguments for an expandable command must not involve short arguments after long arguments. You have tried to mix the two types when defining '\testA'.
-! LaTeX cmd Error: Invalid argument type 'v' in \testA.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The letter 'v' specifies an argument type which cannot be used in an expandable command.
-LaTeX will ignore this entire definition.
-! LaTeX cmd Error: Invalid argument prefix '>' in command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The argument specification for '\testA' contains the processor function '>{\TrimSpaces }'. This is only supported for robust commands, but not for expandable ones.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 9: Run-time errors
-============================================================
-! LaTeX cmd Error: Circular dependency in defaults of command '\testA'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The default values of two or more arguments of the command '\testA' depend on each other in a way that cannot be resolved.
-\C \E \C \E \C \E \C \E -NoValue-|\C \E \C \E \C \E \C \E -NoValue--NoValue-|\C |\C \E |\E 
-! LaTeX cmd Error: Circular dependency in defaults of environment 'testB'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The default values of two or more arguments of the environment 'testB' depend on each other in a way that cannot be resolved.
-\C \E \C \E \C \E \C \E -NoValue-|\C \E \C \E \C \E \C \E -NoValue--NoValue-|\C |\C \E |\E 
-! LaTeX cmd Error: Too many ',' separators in argument.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-LaTeX was asked to split the input 'a,b,c,d' at each occurrence of the separator ',' into 3 parts. Too many separators were found.
-! LaTeX cmd Error: Too many ',' separators in argument.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-LaTeX was asked to split the input 'a,b,c,d' at each occurrence of the separator ',' into 3 parts. Too many separators were found.
-! LaTeX cmd Error: Verbatim-like command '\testE' illegal in argument.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The command '\testE' takes a verbatim argument and should therefore normally not be used in arguments of other commands or environments. LaTeX found an illegal token (\TYPE ) after '+' and will drop everything up to this point.
-Expect further (low-level) errors.
--NoValue-
-+
-! LaTeX cmd Error: Verbatim-like environment 'testF' illegal in argument.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The environment 'testF' takes a verbatim argument and should therefore normally not be used in arguments of other commands or environments. LaTeX found an illegal token (\TYPE ) after '+' and will drop everything up to this point.
-Expect further (low-level) errors.
--NoValue-
-+
-============================================================
-! LaTeX cmd Error: Verbatim-like command '\testG' ended by end of line.
-For immediate help type H <return>.
- ...                                              
-l. ...\testG+
-The verbatim argument of the command '\testG' cannot contain more than one line, but the end of the current line has been reached. You may have forgotten the closing delimiter.
-LaTeX will ignore '+' and you may get some additional (low-level) errors.
--NoValue-
-+
-! LaTeX cmd Error: Verbatim-like environment 'testH' ended by end of line.
-For immediate help type H <return>.
- ...                                              
-l. ...\begin{testH}+
-The verbatim argument of the environment 'testH' cannot contain more than one line, but the end of the current line has been reached. You may have forgotten the closing delimiter.
-LaTeX will ignore '+' and you may get some additional (low-level) errors.
--NoValue-
-+
diff --git a/base/testfiles-ltcmd/ltcmd005.lvt b/base/testfiles-ltcmd/ltcmd005.lvt
index 08d4570f0..94c79952b 100644
--- a/base/testfiles-ltcmd/ltcmd005.lvt
+++ b/base/testfiles-ltcmd/ltcmd005.lvt
@@ -56,54 +56,6 @@
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-% The following tests are outside to allow \ExplSyntaxOff and \obeylines
-\TEST { Environment~body~valid } { }
-
-\NewDocumentEnvironment { env1 } { o >{\SplitList{\par}} + b }
-  { \TYPE { \tl_to_str:n {|#1|#2|} } }
-  { \TYPE { \tl_to_str:n {|#1|} } }
-\NewDocumentEnvironment { env2 } { ! o ! b }
-  { \TYPE { \tl_to_str:n {|#1|#2|} } }
-  { \TYPE { \tl_to_str:n {|#1|} } }
-\ExplSyntaxOff
-\begin{env1} [...]
-  \begin{any}
-    \begin{unbalanced}
-    \end{environments}
-    \begin{provided}
-
-    \end{nesting}
-  \end{works}
-  \begin{out}
-  \end{!}
-\end{env1}
-\begin{env2} [...]
-  \begin{any}
-    \begin{unbalanced}
-    \end{environments}
-    \begin{provided}
-    \end{nesting}
-  \end{works}
-  \begin{out}
-  \end{!}
-\end{env2}
-\ExplSyntaxOn
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\TEST { Body~invalid }
-  {
-    \begin{env1}\end{env2}
-    \begin{env2}
-      \par
-    \end{env2}
-    \NewDocumentCommand{\testE} { b } { }
-    \NewDocumentEnvironment{env3} { b m } { } { }
-  }
-
-% The rest of this test tests all of xparse's messages.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 \TEST { Invalid~signatures }
   {
     % Disabled: test requires deprecated xparse.sty
diff --git a/base/testfiles-ltcmd/ltcmd005.tlg b/base/testfiles-ltcmd/ltcmd005.tlg
index 1a20f4d3b..c085f0b5e 100644
--- a/base/testfiles-ltcmd/ltcmd005.tlg
+++ b/base/testfiles-ltcmd/ltcmd005.tlg
@@ -85,49 +85,7 @@ My plan is to forget the whole thing and hope for the best.
 |a|\BooleanTrue |\BooleanTrue | \c_space_token |
 ============================================================
 ============================================================
-TEST 3: Environment body valid
-============================================================
-============================================================
-|...|{\begin {any} \begin {unbalanced} \end {environments} \begin {provided}}{\end {nesting} \end {works} \begin {out} \end {!}}|
-|...|
-|-NoValue-| [...] \begin {any} \begin {unbalanced} \end {environments} \begin {provided} \end {nesting} \end {works} \begin {out} \end {!} |
-|-NoValue-|
-============================================================
-TEST 4: Body invalid
-============================================================
-|-NoValue-|{}|
-! LaTeX Error: \begin{env1} on input line ... ended by \end{env2}.
-See the LaTeX manual or LaTeX Companion for explanation.
-Type  H <return>  for immediate help.
- ...                                              
-l. ...  }
-Your command was ignored.
-Type  I <command> <return>  to replace it with another command,
-or  <return>  to continue without it.
-Runaway argument?
-\begin  
-! Paragraph ended before \environment env2  was complete.
-<to be read again> 
-                   \par 
-l. ...  }
-I suspect you've forgotten a `}', causing me to apply this
-control sequence to too much text. How can we recover?
-My plan is to forget the whole thing and hope for the best.
-! LaTeX cmd Error: Invalid argument type 'b' in command '\testE'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The letter 'b' can only be used in environment argument specifications, but not for commands.
-LaTeX will ignore the entire definition.
-! LaTeX cmd Error: Argument type 'b' must be last in environment 'env3'.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The 'b' argument type must come last but it is followed by 'm' in the argument specification. This is not allowed.
-LaTeX will ignore this entire definition.
-============================================================
-============================================================
-TEST 5: Invalid signatures
+TEST 3: Invalid signatures
 ============================================================
 ! LaTeX cmd Error: Bad argument specification 'O' for command '\testA'.
 For immediate help type H <return>.
@@ -195,7 +153,7 @@ The letter 'X' does not specify a known argument type.
 LaTeX will ignore this entire definition.
 ============================================================
 ============================================================
-TEST 6: Already or not yet defined
+TEST 4: Already or not yet defined
 ============================================================
 ! LaTeX cmd Error: Command '\space' already defined.
 For immediate help type H <return>.
@@ -225,7 +183,7 @@ You have used \RenewDocumentEnvironment with an environment that was never defin
 LaTeX will ignore this entire definition.
 ============================================================
 ============================================================
-TEST 7: Not definable/multi-char
+TEST 5: Not definable/multi-char
 ============================================================
 ! LaTeX cmd Error: First argument of '\NewDocumentCommand' must be a command.
 For immediate help type H <return>.
@@ -273,7 +231,7 @@ followed by the required stuff, so I'm ignoring it.
 FALSE
 ============================================================
 ============================================================
-TEST 8: Invalid signatures for expandable commands
+TEST 6: Invalid signatures for expandable commands
 ============================================================
 ! LaTeX cmd Error: Bad argument specification 'mo' for \testA.
 For immediate help type H <return>.
@@ -299,7 +257,7 @@ The argument specification for '\testA' contains the processor function '>{\Trim
 LaTeX will ignore this entire definition.
 ============================================================
 ============================================================
-TEST 9: Run-time errors
+TEST 7: Run-time errors
 ============================================================
 ! LaTeX cmd Error: Circular dependency in defaults of command '\testA'.
 For immediate help type H <return>.
diff --git a/base/testfiles-ltcmd/ltcmd009.lvt b/base/testfiles-ltcmd/ltcmd009.lvt
new file mode 100644
index 000000000..458bbc67d
--- /dev/null
+++ b/base/testfiles-ltcmd/ltcmd009.lvt
@@ -0,0 +1,91 @@
+
+\documentclass{minimal}
+\input{regression-test}
+
+\ExplSyntaxOn
+\debug_on:n { check-declarations , deprecation , log-functions }
+\ExplSyntaxOff
+% \RequirePackage{xparse}
+
+\begin{document}
+
+\START
+\AUTHOR{Bruno Le Floch, Joseph Wright}
+
+\ExplSyntaxOn
+
+% The following tests are outside to allow \ExplSyntaxOff and \obeylines
+\TEST { Environment~body~valid } { }
+
+\NewDocumentEnvironment { env1 } { o >{\SplitList{\par}} + b }
+  { \TYPE { \tl_to_str:n {|#1|#2|} } }
+  { \TYPE { \tl_to_str:n {|#1|} } }
+\NewDocumentEnvironment { env2 } { ! o ! b }
+  { \TYPE { \tl_to_str:n {|#1|#2|} } }
+  { \TYPE { \tl_to_str:n {|#1|} } }
+\ExplSyntaxOff
+\begin{env1} [...]
+  \begin{any}
+    \begin{unbalanced}
+    \end{environments}
+    \begin{provided}
+
+    \end{nesting}
+  \end{works}
+  \begin{out}
+  \end{!}
+\end{env1}
+\begin{env2} [...]
+  \begin{any}
+    \begin{unbalanced}
+    \end{environments}
+    \begin{provided}
+    \end{nesting}
+  \end{works}
+  \begin{out}
+  \end{!}
+\end{env2}
+\ExplSyntaxOn
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { Body~invalid }
+  {
+    \begin{env1}\end{env2}
+    \begin{env2}
+      \par
+    \end{env2}
+    \NewDocumentCommand{\testE} { b } { }
+    \NewDocumentEnvironment{env3} { b m } { } { }
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\TEST { Verbatim~body~collection } { }
+
+\NewDocumentEnvironment { env3 } { o +f }
+  { \TYPE { \tl_to_str:n {|#1|#2|} } }
+  { }
+\NewDocumentEnvironment { env4 } { !o !+f }
+  { \TYPE { \tl_to_str:n {|#1|#2|} } }
+  { }
+
+\ExplSyntaxOff
+\begin{env3}
+  Content
+  &\^
+\end{env3}
+\begin{env3}[...]
+  Content
+  &\^
+\end{env3}
+\begin{env4}
+  Content
+  &\^
+\end{env4}
+\begin{env4}[...]
+  Content
+  &\^
+\end{env4}
+\ExplSyntaxOn
+
+\END
diff --git a/base/testfiles-ltcmd/ltcmd009.tlg b/base/testfiles-ltcmd/ltcmd009.tlg
new file mode 100644
index 000000000..e31d4c286
--- /dev/null
+++ b/base/testfiles-ltcmd/ltcmd009.tlg
@@ -0,0 +1,53 @@
+This is a generated file for the LaTeX2e validation system.
+Don't change this file in any respect.
+Author: Bruno Le Floch, Joseph Wright
+============================================================
+TEST 1: Environment body valid
+============================================================
+============================================================
+|...|{\begin {any} \begin {unbalanced} \end {environments} \begin {provided}}{\end {nesting} \end {works} \begin {out} \end {!}}|
+|...|
+|-NoValue-| [...] \begin {any} \begin {unbalanced} \end {environments} \begin {provided} \end {nesting} \end {works} \begin {out} \end {!} |
+|-NoValue-|
+============================================================
+TEST 2: Body invalid
+============================================================
+|-NoValue-|{}|
+! LaTeX Error: \begin{env1} on input line ... ended by \end{env2}.
+See the LaTeX manual or LaTeX Companion for explanation.
+Type  H <return>  for immediate help.
+ ...                                              
+l. ...  }
+Your command was ignored.
+Type  I <command> <return>  to replace it with another command,
+or  <return>  to continue without it.
+Runaway argument?
+\begin  
+! Paragraph ended before \environment env2  was complete.
+<to be read again> 
+                   \par 
+l. ...  }
+I suspect you've forgotten a `}', causing me to apply this
+control sequence to too much text. How can we recover?
+My plan is to forget the whole thing and hope for the best.
+! LaTeX cmd Error: Invalid argument type 'b' in command '\testE'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+The letter 'b' can only be used in environment argument specifications, but not for commands.
+LaTeX will ignore the entire definition.
+! LaTeX cmd Error: Argument type 'b' must be last in environment 'env3'.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+The 'b' argument type must come last but it is followed by 'm' in the argument specification. This is not allowed.
+LaTeX will ignore this entire definition.
+============================================================
+============================================================
+TEST 3: Verbatim body collection
+============================================================
+============================================================
+|-NoValue-|Content\obeyedline   &\^|
+|...|  Content\obeyedline   &\^|
+|-NoValue-|\obeyedline   Content\obeyedline   &\^\obeyedline |
+|...|\obeyedline   Content\obeyedline   &\^\obeyedline |





More information about the latex3-commits mailing list.