[latex3-commits] [l3svn] 01/02: First phase of rounding out l3str

noreply at latex-project.org noreply at latex-project.org
Sun Oct 8 23:33:50 CEST 2017


This is an automated email from the git hooks/post-receive script.

joseph pushed a commit to branch master
in repository l3svn.

commit aa5df050edbf65cbd1daaf8dbe1afb820e3d2656
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Sun Oct 8 22:13:35 2017 +0100

    First phase of rounding out l3str
    
    This covers all of the suggested additions from Enrico example \str_reverse:(n|N).
    For the latter I'm not 100% sure of whether space preservation is needed.
---
 l3kernel/l3str.dtx                      |  414 ++++++++++++++++++++++++++++++-
 l3kernel/testfiles/m3expl001.luatex.tlg |   39 +++
 l3kernel/testfiles/m3expl001.ptex.tlg   |   39 +++
 l3kernel/testfiles/m3expl001.tlg        |   39 +++
 l3kernel/testfiles/m3expl001.uptex.tlg  |   39 +++
 l3kernel/testfiles/m3expl001.xetex.tlg  |   39 +++
 l3kernel/testfiles/m3expl003.luatex.tlg |   39 +++
 l3kernel/testfiles/m3expl003.ptex.tlg   |   39 +++
 l3kernel/testfiles/m3expl003.tlg        |   39 +++
 l3kernel/testfiles/m3expl003.uptex.tlg  |   39 +++
 l3kernel/testfiles/m3expl003.xetex.tlg  |   39 +++
 l3kernel/testfiles/m3str001.lvt         |   54 ++++
 l3kernel/testfiles/m3str001.tlg         |   34 +++
 13 files changed, 888 insertions(+), 4 deletions(-)

diff --git a/l3kernel/l3str.dtx b/l3kernel/l3str.dtx
index b8d2827..faa37b0 100644
--- a/l3kernel/l3str.dtx
+++ b/l3kernel/l3str.dtx
@@ -76,10 +76,6 @@
 % This data type simplifies comparison of variables since there are no concerns
 % about expansion of their contents.
 %
-% Note that as string variables are a special case of token list variables
-% the coverage of \cs[no-index]{str_\ldots{}:N} functions is somewhat smaller than
-% \cs[no-index]{tl_\ldots{}:N}.
-%
 % The functions \cs{cs_to_str:N}, \cs{tl_to_str:n}, \cs{tl_to_str:N} and
 % \cs{token_to_str:N} (and variants) generate strings from the appropriate
 % input: these are documented in \pkg{l3basics}, \pkg{l3tl} and \pkg{l3token},
@@ -148,6 +144,19 @@
 %   \meta{str~var_2}.
 % \end{function}
 %
+% \begin{function}[added = 2017-10-08]
+%   {
+%     \str_concat:NNN,  \str_concat:ccc,
+%     \str_gconcat:NNN, \str_gconcat:ccc
+%   }
+%   \begin{syntax}
+%     \cs{str_concat:NNN} \meta{str~var_1} \meta{str~var_2} \meta{str~var_3}
+%   \end{syntax}
+%   Concatenates the content of \meta{str~var_2} and \meta{str~var_3}
+%   together and saves the result in \meta{str~var_1}. The \meta{str~var_2}
+%   is placed at the left side of the new string variable.
+% \end{function}
+%
 % \section{Adding data to string variables}
 %
 % \begin{function}[added = 2015-09-18]
@@ -192,6 +201,68 @@
 %     var} are not automatically converted to a string.
 % \end{function}
 %
+% \subsection{Modifying string variables}
+%
+% \begin{function}[added = 2017-10-08]
+%   {
+%     \str_replace_once:Nnn,  \str_replace_once:cnn,
+%     \str_greplace_once:Nnn, \str_greplace_once:cnn
+%   }
+%   \begin{syntax}
+%     \cs{str_replace_once:Nnn} \meta{str~var} \Arg{old string} \Arg{new string}
+%   \end{syntax}
+%   Replaces the first (leftmost) occurrence of \meta{old str} in the
+%   \meta{str~var} with \meta{new str}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {
+%     \str_replace_all:Nnn, \str_replace_all:cnn,
+%     \str_greplace_all:Nnn, \str_greplace_all:cnn
+%   }
+%   \begin{syntax}
+%     \cs{str_replace_all:Nnn} \meta{str~var} \Arg{old string} \Arg{new string}
+%   \end{syntax}
+%   Replaces all occurrences of \meta{old string} in the
+%   \meta{str~var} with \meta{new tokens}.
+%   As this function
+%   operates from left to right, the pattern \meta{old str}
+%   may remain after the replacement (see \cs{str_remove_all:Nn}
+%   for an example).
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {
+%     \str_remove_once:Nn,  \str_remove_once:cn,
+%     \str_gremove_once:Nn, \str_gremove_once:cn
+%   }
+%   \begin{syntax}
+%     \cs{str_remove_once:Nn} \meta{str~var} \Arg{string}
+%   \end{syntax}
+%   Removes the first (leftmost) occurrence of \meta{string} from the
+%   \meta{str~var}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {
+%     \str_remove_all:Nn,  \str_remove_all:cn,
+%     \str_gremove_all:Nn, \str_gremove_all:cn
+%   }
+%   \begin{syntax}
+%     \cs{str_remove_all:Nn} \meta{str~var} \Arg{string}
+%   \end{syntax}
+%   Removes all occurrences of \meta{string} from the
+%   \meta{tl~var}.
+%   As this function
+%   operates from left to right, the pattern \meta{tokens}
+%   may remain after the removal, for instance,
+%   \begin{quote}
+%     \cs{str_set:Nn} \cs{l_tmpa_str} |{abbccd}|
+%     \cs{str_remove_all:Nn} \cs{l_tmpa_str} |{bc}|
+%   \end{quote}
+%   results in \cs{l_tmpa_str} containing \texttt{abcd}.
+% \end{function}
+%
 % \subsection{String conditionals}
 %
 % \begin{function}[EXP, pTF, added = 2015-09-18]
@@ -256,6 +327,22 @@
 %   is logically \texttt{true}.
 % \end{function}
 %
+% \begin{function}[TF, added = 2017-10-08]{\str_if_in:Nn, \str_if_in:cn}
+%   \begin{syntax}
+%     \cs{str_if_in:NnTF} \meta{str~var} \Arg{string} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Tests if the \meta{string} is found in the content of the
+%   \meta{str~var}.
+% \end{function}
+%
+% \begin{function}[TF, added = 2017-10-08]{\str_if_in:nn}
+%   \begin{syntax}
+%     \cs{str_if_in:NnTF} \meta{string_1} \Arg{string_2} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Tests if \meta{string_2} is found in the content of the
+%   \meta{string_1}.
+% \end{function}
+%
 % \begin{function}[added = 2013-07-24, updated = 2015-02-28, EXP, noTF]
 %   {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv}
 %   \begin{syntax}
@@ -307,6 +394,123 @@
 %   not be used within this string.
 % \end{function}
 %
+% \section{Mapping to strings}
+%
+% \begin{function}[added = 2017-10-08, rEXP]
+%   {\str_map_function:NN, \str_map_function:cN}
+%   \begin{syntax}
+%     \cs{str_map_function:NN} \meta{str~var} \meta{function}
+%   \end{syntax}
+%   Applies \meta{function} to every \meta{item} in the \meta{str~var}.
+%   See also \cs{str_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08, rEXP]
+%   {\str_map_function:nN}
+%   \begin{syntax}
+%     \cs{str_map_function:nN} \meta{string} \meta{function}
+%   \end{syntax}
+%   Applies \meta{function} to every \meta{item} in the \meta{string}.
+%   See also \cs{str_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {\str_map_inline:Nn, \str_map_inline:cn}
+%   \begin{syntax}
+%     \cs{str_map_inline:Nn} \meta{str~var} \Arg{inline function}
+%   \end{syntax}
+%   Applies the \meta{inline function} to every \meta{item} stored within the
+%   \meta{str~var}. The \meta{inline function} should consist of code which
+%   receives the \meta{item} as |#1|. One in line mapping can be nested
+%   inside another. See also \cs{str_map_function:NN}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {\str_map_inline:nn}
+%   \begin{syntax}
+%     \cs{str_map_inline:Nn} \meta{string} \Arg{inline function}
+%   \end{syntax}
+%   Applies the \meta{inline function} to every \meta{item} in the
+%   \meta{string}. The \meta{inline function} should consist of code which
+%   receives the \meta{item} as |#1|. One in line mapping can be nested
+%   inside another. See also \cs{str_map_function:NN}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {\str_map_variable:NNn, \str_map_variable:cNn}
+%   \begin{syntax}
+%     \cs{str_map_variable:NNn} \meta{str~var} \meta{variable} \Arg{function}
+%   \end{syntax}
+%   Applies the \meta{function} to every \meta{item} stored
+%   within the \meta{str~var}. The \meta{function} should consist of code
+%   which receives the \meta{item} stored in the \meta{variable}.
+%   One variable mapping can be nested inside another. See also
+%   \cs{str_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08]
+%   {\str_map_variable:nNn}
+%   \begin{syntax}
+%     \cs{str_map_variable:nNn} \meta{string} \meta{variable} \Arg{function}
+%   \end{syntax}
+%   Applies the \meta{function} to every \meta{item} in the \meta{string}.
+%   The \meta{function} should consist of code
+%   which receives the \meta{item} stored in the \meta{variable}.
+%   One variable mapping can be nested inside another. See also
+%   \cs{str_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:}
+%   \begin{syntax}
+%     \cs{str_map_break:}
+%   \end{syntax}
+%   Used to terminate a \cs[no-index]{str_map_\ldots} function before all
+%   entries in the \meta{string} have been processed. This
+%   normally takes place within a conditional statement, for example
+%   \begin{verbatim}
+%     \str_map_inline:Nn \l_my_str
+%       {
+%         \str_if_eq:nnT { #1 } { bingo } { \str_map_break: }
+%         % Do something useful
+%       }
+%   \end{verbatim}
+%   See also \cs{str_map_break:n}.
+%   Use outside of a \cs[no-index]{str_map_\ldots} scenario leads to low
+%   level \TeX{} errors.
+%   \begin{texnote}
+%     When the mapping is broken, additional tokens may be inserted by the
+%     internal macro \cs{__prg_break_point:Nn} before the \meta{tokens} are
+%     inserted into the input stream.
+%     This depends on the design of the mapping function.
+%   \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:n}
+%   \begin{syntax}
+%     \cs{str_map_break:n} \Arg{tokens}
+%   \end{syntax}
+%   Used to terminate a \cs[no-index]{str_map_\ldots} function before all
+%   entries in the \meta{string} have been processed, inserting
+%   the \meta{tokens} after the mapping has ended. This
+%   normally takes place within a conditional statement, for example
+%   \begin{verbatim}
+%     \str_map_inline:Nn \l_my_str
+%       {
+%         \str_if_eq:nnT { #1 } { bingo }
+%           { \str_map_break:n { <tokens> } }
+%         % Do something useful
+%       }
+%   \end{verbatim}
+%   Use outside of a \cs[no-index]{str_map_\ldots} scenario leads to low
+%   level \TeX{} errors.
+%   \begin{texnote}
+%     When the mapping is broken, additional tokens may be inserted by the
+%     internal macro \cs{__prg_break_point:Nn} before the \meta{tokens} are
+%     inserted into the input stream.
+%     This depends on the design of the mapping function.
+%   \end{texnote}
+% \end{function}
+%
 % \section{Working with the content of strings}
 %
 % \begin{function}[EXP, added = 2015-09-18]{\str_use:N, \str_use:c}
@@ -672,6 +876,8 @@
 %     \str_set_eq:NN,  \str_set_eq:cN,  \str_set_eq:Nc,  \str_set_eq:cc,
 %     \str_gset_eq:NN, \str_gset_eq:cN, \str_gset_eq:Nc, \str_gset_eq:cc
 %   }
+% \begin{macro}
+%   {\str_concat:NNN, \str_concat:ccc, \str_gconcat:NNN, \str_gconcat:ccc}
 %   A string is simply a token list. The full mapping system isn't set up
 %   yet so do things by hand.
 %    \begin{macrocode}
@@ -698,9 +904,14 @@
 \cs_new_eq:NN \str_gset_eq:NN \tl_gset_eq:NN
 \cs_generate_variant:Nn \str_set_eq:NN  { c , Nc , cc }
 \cs_generate_variant:Nn \str_gset_eq:NN { c , Nc , cc }
+\cs_new_eq:NN \str_concat:NNN \tl_concat:NNN
+\cs_new_eq:NN \str_gconcat:NNN \tl_gconcat:NNN
+\cs_generate_variant:Nn \str_concat:NNN  { ccc }
+\cs_generate_variant:Nn \str_gconcat:NNN { ccc }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}
 %   {
@@ -745,6 +956,96 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Modifying string variables}
+%
+% \begin{macro}
+%   {
+%     \str_replace_all:Nnn,   \str_replace_all:cnn,
+%     \str_greplace_all:Nnn,  \str_greplace_all:cnn,
+%     \str_replace_once:Nnn,  \str_replace_once:cnn,
+%     \str_greplace_once:Nnn, \str_greplace_once:cnn
+%   }
+% \begin{macro}
+%   {
+%     \str_remove_all:Nn,   \str_remove_all:cn,
+%     \str_gremove_all:Nn,  \str_gremove_all:cn,
+%     \str_remove_once:Nn,  \str_remove_once:cn,
+%     \str_gremove_once:Nn, \str_gremove_once:cn
+%   }
+% \begin{macro}[aux]{\@@_replace:NNNnn}
+% \begin{macro}[aux]{\@@_replace_auxi:NNNnn}
+% \begin{macro}[aux]{\@@_replace_auxii:NNNnn}
+% \begin{macro}[aux]{\@@_replace_wrap:w, \@@_replace_next:w}
+%   The code here is a simplified version of the token list code: as
+%   there is no issue with the delimiter (which is a non-string token)
+%   we do not have to do the preliminaries. There is also a built-in
+%   application of \cs{tl_to_str:N} to avoid any issues if we are fed a
+%   token list.
+%    \begin{macrocode}
+\cs_new_protected:Npn \str_replace_once:Nnn
+  { \@@_replace:NNNnn \@@_replace_wrap:w \tl_set:Nx  }
+\cs_new_protected:Npn \str_greplace_once:Nnn
+  { \@@_replace:NNNnn \@@_replace_wrap:w \tl_gset:Nx }
+\cs_new_protected:Npn \str_replace_all:Nnn
+  { \@@_replace:NNNnn \@@_replace_next:w \tl_set:Nx  }
+\cs_new_protected:Npn \str_greplace_all:Nnn
+  { \@@_replace:NNNnn \@@_replace_next:w \tl_gset:Nx }
+\cs_generate_variant:Nn \str_replace_once:Nnn  { c }
+\cs_generate_variant:Nn \str_greplace_once:Nnn { c }
+\cs_generate_variant:Nn \str_replace_all:Nnn   { c }
+\cs_generate_variant:Nn \str_greplace_all:Nnn  { c }
+\cs_new_protected:Npn \@@_replace:NNNnn #1#2#3#4#5
+  {
+    \use:x
+      {
+        \@@_replace_auxi:NNNnn \exp_not:N #1 #2 \exp_not:N #3
+          { \tl_to_str:n {#4} } { \tl_to_str:n {#5} }
+      }
+  }
+ \cs_new_protected:Npn \@@_replace_auxi:NNNnn #1#2#3#4#5
+  {
+    \tl_if_empty:nTF {#4}
+      {
+        \__msg_kernel_error:nnx { kernel } { empty-search-pattern } {#5}
+      }
+      { \@@_replace_auxii:NNNnn #1 #2 #3 {#4} {#5} }
+  }
+\cs_new_protected:Npn \@@_replace_auxii:NNNnn #1#2#3#4#5
+  {
+    \cs_set:Npn \@@_replace_wrap:w ##1 \q_mark ##2
+      { \exp_not:o { \use_none:nn ##1 } ##2 }
+    \cs_set:Npx \@@_replace_next:w ##1 #4
+      {
+        \exp_not:N \@@_replace_wrap:w ##1
+        \exp_not:N \q_mark
+        \exp_not:n { \exp_not:n {#5} }
+        \exp_not:n { #1 { } { } }
+      }
+    #2 #3 { \tl_to_str:N #3 }
+    #2 #3
+      {
+        \exp_after:wN \@@_replace_next:w
+        \exp_after:wN { \exp_after:wN }
+        \exp_after:wN { \exp_after:wN }
+        #3
+        \q_mark
+        {
+          \if_false: { \fi: }
+          \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+        }
+        #4
+      }
+  }
+\cs_new_eq:NN \@@_replace_wrap:w ?
+\cs_new_eq:NN \@@_replace_next:w ?
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{String comparisons}
 %
 % \begin{macro}[pTF, EXP]
@@ -871,6 +1172,46 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[TF]{\str_if_in:Nn, \str_if_in:cn \str_if_in:nn}
+%   Everything here needs to be detokenized but beyond that it is a simple
+%   token list test.
+%    \begin{macrocode}
+\cs_new_protected:Npn \str_if_in:NnT #1#2
+  {
+    \use:x
+      { \tl_if_in:nnT { \tl_to_str:N #1 } { \tl_to_str:n {#2} } }
+  }
+\cs_new_protected:Npn \str_if_in:NnF #1#2
+  {
+    \use:x
+      { \tl_if_in:nnF { \tl_to_str:N #1 } { \tl_to_str:n {#2} } }
+  }
+\cs_new_protected:Npn \str_if_in:NnTF #1#2
+  {
+    \use:x
+      { \tl_if_in:nnTF { \tl_to_str:N #1 } { \tl_to_str:n {#2} } }
+  }
+\cs_generate_variant:Nn \str_if_in:NnT { c }
+\cs_generate_variant:Nn \str_if_in:NnF  { c }
+\cs_generate_variant:Nn \str_if_in:NnTF { c }
+\cs_new_protected:Npn \str_if_in:nnT #1#2
+  {
+    \use:x
+      { \tl_if_in:nnT { \tl_to_str:n {#1} } { \tl_to_str:n {#2} } }
+  }
+\cs_new_protected:Npn \str_if_in:nnF #1#2
+  {
+    \use:x
+      { \tl_if_in:nnF { \tl_to_str:n {#1} } { \tl_to_str:n {#2} } }
+  }
+\cs_new_protected:Npn \str_if_in:nnTF #1#2
+  {
+    \use:x
+      { \tl_if_in:nnTF { \tl_to_str:n {#1} } { \tl_to_str:n {#2} } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}[EXP, noTF]
 %   {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_x:nn}
 % \begin{macro}[EXP, aux]{\@@_case:nnTF, \@@_case_x:nnTF}
@@ -945,6 +1286,71 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Mapping to strings}
+%
+% \begin{macro}[rsEXP]{\str_map_function:NN, \str_map_function:cN}
+% \begin{macro}{\str_map_inline:Nn, \str_map_inline:cn}
+% \begin{macro}{\str_map_variable:NNn, \str_map_variable:cNn}
+% \begin{macro}{\str_map_break:}
+% \begin{macro}{\str_map_break:n}
+%   Slightly awkward as we need to ensure detokenization: beyond that
+%   just the usual token list mappings.
+%    \begin{macrocode}
+\cs_new:Npn \str_map_function:nN #1#2
+  {
+    \exp_after:wN \@@_map_function:Nn \exp_after:wN #2
+      \etex_detokenize:n {#1}
+      \q_recursion_tail
+    \__prg_break_point:Nn \str_map_break: { }
+  }
+\cs_new:Npn \str_map_function:NN
+  { \exp_args:No \str_map_function:nN }
+\cs_new:Npn \@@_map_function:Nn #1#2
+  {
+    \__quark_if_recursion_tail_break:nN {#2} \str_map_break:
+    #1 {#2} \@@_map_function:Nn #1
+  }
+\cs_generate_variant:Nn \str_map_function:NN { c }
+\cs_new_protected:Npn \str_map_inline:nn #1#2
+  {
+    \int_gincr:N \g__prg_map_int
+    \cs_gset_protected:cpn
+      { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2}
+    \exp_args:Nc \@@_map_function:Nn
+      { __prg_map_ \int_use:N \g__prg_map_int :w }
+      #1 \q_recursion_tail
+    \__prg_break_point:Nn \str_map_break: { \int_gdecr:N \g__prg_map_int }
+  }
+\cs_new_protected:Npn \str_map_inline:Nn
+  { \exp_args:No \str_map_inline:nn }
+\cs_generate_variant:Nn \str_map_inline:Nn { c }
+\cs_new_protected:Npn \str_map_variable:nNn #1#2#3
+  {
+    \@@_map_variable:Nnn #2 {#3} #1
+      \q_recursion_tail
+    \__prg_break_point:Nn \str_map_break: { }
+  }
+\cs_new_protected:Npn \str_map_variable:NNn
+  { \exp_args:No \str_map_variable:nNn }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+  {
+    \str_set:Nn #1 {#3}
+    \__quark_if_recursion_tail_break:NN #1 \str_map_break:
+    \use:n {#2}
+    \@@_map_variable:Nnn #1 {#2}
+  }
+\cs_generate_variant:Nn \str_map_variable:NNn { c }
+\cs_new:Npn \str_map_break:
+  { \__prg_map_break:Nn \str_map_break: { } }
+\cs_new:Npn \str_map_break:n
+  { \__prg_map_break:Nn \str_map_break: }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Accessing specific characters in a string}
 %
 % \begin{macro}[EXP, int]{\@@_to_other:n}
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 6838a66..aeb6979 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -606,6 +606,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -634,6 +638,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -697,6 +714,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -723,6 +749,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index b9560d7..14d1df0 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index 94d7f18..80be404 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index f767192..b93eda1 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index 0006026..a3ef8cd 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 6838a66..aeb6979 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -606,6 +606,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -634,6 +638,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -697,6 +714,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -723,6 +749,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index b9560d7..14d1df0 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index 94d7f18..80be404 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index f767192..b93eda1 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index 0006026..a3ef8cd 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -605,6 +605,10 @@ Defining \str_set_eq:cc on line ...
 Defining \str_gset_eq:cN on line ...
 Defining \str_gset_eq:Nc on line ...
 Defining \str_gset_eq:cc on line ...
+Defining \str_concat:NNN on line ...
+Defining \str_gconcat:NNN on line ...
+Defining \str_concat:ccc on line ...
+Defining \str_gconcat:ccc on line ...
 Defining \str_set:Nn on line ...
 Defining \str_set:Nx on line ...
 Defining \str_set:cn on line ...
@@ -633,6 +637,19 @@ Defining \str_gput_right:Nn on line ...
 Defining \str_gput_right:Nx on line ...
 Defining \str_gput_right:cn on line ...
 Defining \str_gput_right:cx on line ...
+Defining \str_replace_once:Nnn on line ...
+Defining \str_greplace_once:Nnn on line ...
+Defining \str_replace_all:Nnn on line ...
+Defining \str_greplace_all:Nnn on line ...
+Defining \str_replace_once:cnn on line ...
+Defining \str_greplace_once:cnn on line ...
+Defining \str_replace_all:cnn on line ...
+Defining \str_greplace_all:cnn on line ...
+Defining \__str_replace:NNNnn on line ...
+Defining \__str_replace_auxi:NNNnn on line ...
+Defining \__str_replace_auxii:NNNnn on line ...
+Defining \__str_replace_wrap:w on line ...
+Defining \__str_replace_next:w on line ...
 Defining \str_if_exist_p:N on line ...
 Defining \str_if_exist:NT on line ...
 Defining \str_if_exist:NF on line ...
@@ -695,6 +712,15 @@ Defining \str_if_eq:ccTF on line ...
 Defining \str_if_eq_p:cN on line ...
 Defining \str_if_eq_p:Nc on line ...
 Defining \str_if_eq_p:cc on line ...
+Defining \str_if_in:NnT on line ...
+Defining \str_if_in:NnF on line ...
+Defining \str_if_in:NnTF on line ...
+Defining \str_if_in:cnT on line ...
+Defining \str_if_in:cnF on line ...
+Defining \str_if_in:cnTF on line ...
+Defining \str_if_in:nnT on line ...
+Defining \str_if_in:nnF on line ...
+Defining \str_if_in:nnTF on line ...
 Defining \str_case:nn on line ...
 Defining \str_case:nnT on line ...
 Defining \str_case:nnF on line ...
@@ -721,6 +747,19 @@ Defining \str_case_x:nnTF on line ...
 Defining \__str_case_x:nnTF on line ...
 Defining \__str_case_x:nw on line ...
 Defining \__str_case_end:nw on line ...
+Defining \str_map_function:nN on line ...
+Defining \str_map_function:NN on line ...
+Defining \__str_map_function:Nn on line ...
+Defining \str_map_function:cN on line ...
+Defining \str_map_inline:nn on line ...
+Defining \str_map_inline:Nn on line ...
+Defining \str_map_inline:cn on line ...
+Defining \str_map_variable:nNn on line ...
+Defining \str_map_variable:NNn on line ...
+Defining \__str_map_variable:Nnn on line ...
+Defining \str_map_variable:cNn on line ...
+Defining \str_map_break: on line ...
+Defining \str_map_break:n on line ...
 Defining \__str_to_other:n on line ...
 Defining \__str_to_other_loop:w on line ...
 Defining \__str_to_other_end:w on line ...
diff --git a/l3kernel/testfiles/m3str001.lvt b/l3kernel/testfiles/m3str001.lvt
index 59a7e91..d71650b 100644
--- a/l3kernel/testfiles/m3str001.lvt
+++ b/l3kernel/testfiles/m3str001.lvt
@@ -70,5 +70,59 @@
     \str_if_eq:nnF { # }          { # }   { \ERROR } \NEWLINE
   }
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\str_set:Nn \l_tmpa_str {a{bb}cdzyx\q_mark\q_stop\par\par ## cdzyx{y}}
+
+\TEST { replace_once }
+  {
+    \str_replace_once:Nnn \l_tmpa_str {cdz} {cc~dd~zz}
+    \TYPE { \l_tmpa_str }
+    \str_replace_once:cnn {l_tmpa_str} {yx} {yy~\xx~#}
+    \TYPE { \l_tmpa_str }
+  }
+
+\str_gset_eq:NN \g_tmpa_str \l_tmpa_str
+
+\TEST { greplace_once }
+  {
+    \TYPE { \g_tmpa_str }
+    \str_greplace_once:Nnn \g_tmpa_str {cdz} {cc~dd~zz}
+    \TYPE { \g_tmpa_str }
+    \str_greplace_once:cnn {g_tmpa_str} {yx} {yy~\xx~#}
+    \TYPE { \g_tmpa_str }
+  }
+
+\str_set_eq:NN \l_tmpa_str \g_tmpa_str
+
+\TEST { replace_all }
+  {
+    \TYPE { \l_tmpa_str }
+    \str_replace_all:Nnn \l_tmpa_str {\par} {{Z#}}
+    \TYPE { \l_tmpa_str }
+    \str_replace_all:cnn {l_tmpa_str} {y} {{Y}}
+    \TYPE { \l_tmpa_str }
+  }
+
+\TEST { greplace_all }
+  {
+    \TYPE { \g_tmpa_str }
+    \str_greplace_all:Nnn \g_tmpa_str {\par} {{Z#}}
+    \TYPE { \g_tmpa_str }
+    \str_greplace_all:cnn {g_tmpa_str} {y} {{Y}}
+    \TYPE { \g_tmpa_str }
+  }
+
+\str_gset_eq:NN \g_tmpa_str \l_tmpa_str
+
+\TEST { greplace_all~no~expansion~and~par }
+  {
+    \TYPE { \g_tmpa_str }
+    \str_greplace_all:Nnn \g_tmpa_str {\q_mark} {=/mark=}
+    \TYPE { \g_tmpa_str }
+    \str_greplace_all:Nnn \g_tmpa_str {\par} {~#{}\par/~}
+    \TYPE { \g_tmpa_str }
+  }
+
 \END
 
diff --git a/l3kernel/testfiles/m3str001.tlg b/l3kernel/testfiles/m3str001.tlg
index 3f2d655..2c95fd6 100644
--- a/l3kernel/testfiles/m3str001.tlg
+++ b/l3kernel/testfiles/m3str001.tlg
@@ -33,3 +33,37 @@ TRUE
 FALSE
 FALSE
 ============================================================
+============================================================
+TEST 3: replace_once
+============================================================
+a{bb}cc dd zzyx\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop \par \par ####cdzyx{y}
+============================================================
+============================================================
+TEST 4: greplace_once
+============================================================
+a{bb}cdzyx\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyx\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop \par \par ####cdzyx{y}
+============================================================
+============================================================
+TEST 5: replace_all
+============================================================
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop {Z##}{Z##}####cdzyx{y}
+a{bb}cc dd zz{Y}{Y} \xx ##\q_mark \q_stop {Z##}{Z##}####cdz{Y}x{{Y}}
+============================================================
+============================================================
+TEST 6: greplace_all
+============================================================
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop {Z##}{Z##}####cdzyx{y}
+a{bb}cc dd zz{Y}{Y} \xx ##\q_mark \q_stop {Z##}{Z##}####cdz{Y}x{{Y}}
+============================================================
+============================================================
+TEST 7: greplace_all no expansion and par
+============================================================
+a{bb}cc dd zzyy \xx ##\q_mark \q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##=/mark=\q_stop \par \par ####cdzyx{y}
+a{bb}cc dd zzyy \xx ##=/mark=\q_stop  ##{}\par /  ##{}\par / ####cdzyx{y}
+============================================================

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the latex3-commits mailing list