[latex3-commits] [git/LaTeX3-latex3-latex3] main: Allow nesting of tl_analysis_map_inline (fixes #1073) (58a18eb42)
Bruno Le Floch
blflatex at gmail.com
Sat Mar 26 11:32:17 CET 2022
Repository : https://github.com/latex3/latex3
On branch : main
Link : https://github.com/latex3/latex3/commit/58a18eb422c96d045c77641ec38390466c9b3dd3
>---------------------------------------------------------------
commit 58a18eb422c96d045c77641ec38390466c9b3dd3
Author: Bruno Le Floch <blflatex at gmail.com>
Date: Sat Mar 26 11:19:56 2022 +0100
Allow nesting of tl_analysis_map_inline (fixes #1073)
One of the two auxiliaries used by tl_analysis_map_inline was numbered
and the other was not (hence was reused at all nesting levels). Now we
only use a single (numbered) auxiliary. Tests added.
>---------------------------------------------------------------
58a18eb422c96d045c77641ec38390466c9b3dd3
l3kernel/CHANGELOG.md | 3 ++
l3kernel/l3tl-analysis.dtx | 53 +++++++++++-----------
l3kernel/testfiles/m3tl-analysis002.lvt | 51 +++++++++++++++++++++
.../{m3seq009.tlg => m3tl-analysis002.tlg} | 27 +++++++----
4 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index 794417ecc..85ee617b8 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -17,6 +17,9 @@ this project uses date-based 'snapshot' version identifiers.
- Definition of `\legacy_if:n(TF)` to support primitive conditionals
- `\str_<type>case:n` now case changes codepoints above 127 with all engines
+### Fixed
+- Nesting of `\tl_analysis_map_inline:nn`
+
## [2022-02-24]
### Changed
diff --git a/l3kernel/l3tl-analysis.dtx b/l3kernel/l3tl-analysis.dtx
index 9f6527b50..550a1c9b2 100644
--- a/l3kernel/l3tl-analysis.dtx
+++ b/l3kernel/l3tl-analysis.dtx
@@ -90,7 +90,7 @@
% characters, and the value of registers.
% \end{function}
%
-% \begin{function}[added = 2018-04-09]
+% \begin{function}[added = 2018-04-09, updated = 2022-03-26]
% {\tl_analysis_map_inline:nn, \tl_analysis_map_inline:Nn}
% \begin{syntax}
% \cs{tl_analysis_map_inline:nn} \Arg{token list} \Arg{inline function}
@@ -935,47 +935,46 @@
%
% \subsection{Mapping through the analysis}
%
-% \begin{macro}{\tl_analysis_map_inline:nn, \tl_analysis_map_inline:Nn}
-% \begin{macro}{\@@_analysis_map_inline_aux:Nn}
-% \begin{macro}{\@@_analysis_map_inline_aux:nnn}
+% \begin{macro}{\tl_analysis_map_inline:Nn, \tl_analysis_map_inline:nn}
+% \begin{macro}{\@@_analysis_map:Nn}
+% \begin{macro}{\@@_analysis_map:NwNw}
% First obtain the analysis of the token list into
% \cs{g_@@_analysis_result_tl}. To allow nested mappings, increase the
-% nesting depth \cs{g__kernel_prg_map_int} (shared between all modules), then
-% define the looping macro, which has a name specific to that nesting
-% depth. That looping grabs the \meta{tokens}, \meta{catcode} and
-% \meta{char code}; it checks for the end of the loop with
-% \cs{use_none:n} |##2|, normally empty, but which becomes
-% \cs{tl_map_break:} at the end; it then performs the user's code
-% |#2|, and loops by calling itself. When the loop ends, remember to
-% decrease the nesting depth.
+% nesting depth \cs{g__kernel_prg_map_int} (shared between all
+% modules), then define the payload macro, which runs the user code
+% and has a name specific to that nesting depth. The looping macro
+% grabs the \meta{tokens}, \meta{catcode} and \meta{char code}; it
+% checks for the end of the loop with \cs{use_none:n} |##2|, normally
+% empty, but which becomes \cs{tl_map_break:} at the end; it then
+% calls the payload macro with the arguments in the correct order
+% (this is the reason why we cannot directly use the same macro for
+% looping and payload), and loops by calling itself. When the loop
+% ends, remember to decrease the nesting depth.
% \begin{macrocode}
+\cs_new_protected:Npn \tl_analysis_map_inline:Nn #1
+ { \exp_args:No \tl_analysis_map_inline:nn #1 }
\cs_new_protected:Npn \tl_analysis_map_inline:nn #1
{
\@@_analysis:n {#1}
\int_gincr:N \g__kernel_prg_map_int
- \exp_args:Nc \@@_analysis_map_inline_aux:Nn
+ \exp_args:Nc \@@_analysis_map:Nn
{ @@_analysis_map_inline_ \int_use:N \g__kernel_prg_map_int :wNw }
}
-\cs_new_protected:Npn \tl_analysis_map_inline:Nn #1
- { \exp_args:No \tl_analysis_map_inline:nn #1 }
-\cs_new_protected:Npn \@@_analysis_map_inline_aux:Nn #1#2
+\cs_new_protected:Npn \@@_analysis_map:Nn #1#2
{
- \cs_gset_protected:Npn #1 ##1 \s_@@ ##2 ##3 \s_@@
- {
- \use_none:n ##2
- \@@_analysis_map_inline_aux:nnn {##1} {##3} {##2}
- }
- \cs_gset_protected:Npn \@@_analysis_map_inline_aux:nnn ##1##2##3
- {
- #2
- #1
- }
- \exp_after:wN #1
+ \cs_gset_protected:Npn #1 ##1##2##3 {#2}
+ \exp_after:wN \@@_analysis_map:NwNw \exp_after:wN #1
\g_@@_analysis_result_tl
\s_@@ { ? \tl_map_break: } \s_@@
\prg_break_point:Nn \tl_map_break:
{ \int_gdecr:N \g__kernel_prg_map_int }
}
+\cs_new_protected:Npn \@@_analysis_map:NwNw #1 #2 \s_@@ #3 #4 \s_@@
+ {
+ \use_none:n #3
+ #1 {#2} {#4} {#3}
+ \@@_analysis_map:NwNw #1
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/l3kernel/testfiles/m3tl-analysis002.lvt b/l3kernel/testfiles/m3tl-analysis002.lvt
new file mode 100644
index 000000000..0c934af75
--- /dev/null
+++ b/l3kernel/testfiles/m3tl-analysis002.lvt
@@ -0,0 +1,51 @@
+%
+% Copyright (C) 2022 The LaTeX Project
+%
+
+\documentclass{minimal}
+\input{regression-test}
+\RequirePackage[enable-debug]{expl3}
+\ExplSyntaxOn
+\debug_on:n { check-declarations , deprecation , log-functions }
+\ExplSyntaxOff
+
+\begin{document}
+\START
+\AUTHOR{Bruno Le Floch}
+\ExplSyntaxOn
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { tl_analysis_map_inline~basic }
+ {
+ \tl_set:Nn \l_tmpa_tl { { \use:n } & # }
+ \tl_analysis_map_inline:Nn \l_tmpa_tl
+ {
+ \int_compare:nNnTF {#3} = 4
+ { \tl_map_break: }
+ { \TYPE { \tl_to_str:n { | #1 | #2 | #3 | } } }
+ }
+ \tl_analysis_map_inline:nn { a + # & }
+ {
+ \TYPE { \tl_to_str:n { | #1 | #2 | #3 | } }
+ }
+ }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { tl_analysis_map_inline~nesting }
+ {
+ \tl_analysis_map_inline:nn { a b }
+ { \tl_analysis_map_inline:nn { c d } { \TYPE { | #1 ~ ##1 | } } }
+ \tl_analysis_map_inline:nn { a b }
+ {
+ \clist_map_inline:nn { z , c }
+ {
+ \tl_analysis_map_inline:nn { c d }
+ {
+ \TYPE { | #1 ~ ##1 ~ ####1 | }
+ \int_compare:nNnT {####2} = { `##1 } { \clist_map_break: }
+ }
+ }
+ }
+ }
+
+\END
diff --git a/l3kernel/testfiles/m3seq009.tlg b/l3kernel/testfiles/m3tl-analysis002.tlg
similarity index 59%
copy from l3kernel/testfiles/m3seq009.tlg
copy to l3kernel/testfiles/m3tl-analysis002.tlg
index ec6661a9f..405af406e 100644
--- a/l3kernel/testfiles/m3seq009.tlg
+++ b/l3kernel/testfiles/m3tl-analysis002.tlg
@@ -2,16 +2,27 @@ This is a generated file for the LaTeX (2e + expl3) validation system.
Don't change this file in any respect.
Author: Bruno Le Floch
============================================================
-TEST 1: seq_shuffle
+TEST 1: tl_analysis_map_inline basic
============================================================
-7,1,8,9,3,10,4,6,2,5
-||
-4,5,3,9,6,7,2,1,10,8
+|\exp_after:wN {\if_false: }\fi: |123|1|
+|\exp_not:n {\use:n }|-1|0|
+|\if_false: {\fi: }|125|2|
+|\exp_not:n {a}|97|B|
+|\exp_not:n {+}|43|C|
+|\exp_not:n {##}|35|6|
+|\exp_not:n {&}|38|4|
============================================================
============================================================
-TEST 2: seq_shuffle nesting
+TEST 2: tl_analysis_map_inline nesting
============================================================
-a;{B}{A}{C}{D}
-b;{A}{B}{C}{D}
-c;{A}{C}{D}{B}
+|a c|
+|a d|
+|b c|
+|b d|
+|a z c|
+|a z d|
+|a c c|
+|b z c|
+|b z d|
+|b c c|
============================================================
More information about the latex3-commits
mailing list.