From f8e05edb088c3b5246e016f68df9c4cadccfd34d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Sun, 15 May 2022 03:00:49 +0000
Subject: CTAN sync 202205150300

---
 macros/latex/contrib/functional/functional.sty | 512 ++++++++++++++++++++-----
 1 file changed, 419 insertions(+), 93 deletions(-)

(limited to 'macros/latex/contrib/functional/functional.sty')

diff --git a/macros/latex/contrib/functional/functional.sty b/macros/latex/contrib/functional/functional.sty
index a7d97ebfb1..ab012e196d 100644
--- a/macros/latex/contrib/functional/functional.sty
+++ b/macros/latex/contrib/functional/functional.sty
@@ -1,6 +1,6 @@
 %%% -*- coding: utf-8 -*-
 %% ----------------------------------------------------------------------------
-%% Functional: LaTeX2 functional interfaces for LaTeX3 programming layer
+%% Functional: Intuitive Functional Programming Interface for LaTeX2
 %% Copyright : 2022 (c) Jianrui Lyu <tolvjr@163.com>
 %% Repository: https://github.com/lvjr/functional
 %% Repository: https://bitbucket.org/lvjr/functional
@@ -14,8 +14,8 @@
 \NeedsTeXFormat{LaTeX2e}[2018-04-01]
 
 \RequirePackage{expl3}
-\ProvidesExplPackage{functional}{2022-04-29}{2022E}
-  {^^JLaTeX2 functional interfaces for LaTeX3 programming layer}
+\ProvidesExplPackage{functional}{2022-05-14}{2022F}
+  {^^JIntuitive Functional Programming Interface for LaTeX2}
 
 \cs_generate_variant:Nn \iow_log:n { V }
 \cs_generate_variant:Nn \str_set:Nn { Ne }
@@ -33,6 +33,84 @@
 \cs_set_eq:NN \IgnoreSpacesOn \__fun_ignore_spaces_on:
 \cs_set_eq:NN \IgnoreSpacesOff \ExplSyntaxOff
 
+%%% --------------------------------------------------------
+%%> \subsection{Setting Functional Package}
+%%% --------------------------------------------------------
+
+\bool_new:N \l__fun_scoping_bool
+
+\cs_new_protected:Npn \__fun_scoping_true:
+  {
+    \cs_set_eq:NN \__fun_group_begin: \group_begin:
+    \cs_set_eq:NN \__fun_group_end: \group_end:
+  }
+
+\cs_new_protected:Npn \__fun_scoping_false:
+  {
+    \cs_set_eq:NN \__fun_group_begin: \scan_stop:
+    \cs_set_eq:NN \__fun_group_end: \scan_stop:
+  }
+
+\cs_new_protected:Npn \__fun_scoping_set:
+  {
+    \bool_if:NTF \l__fun_scoping_bool
+      { \__fun_scoping_true: } { \__fun_scoping_false: }
+  }
+
+\bool_new:N \l__fun_tracing_bool
+\tl_new:N \l__tracing_text_tl
+
+\cs_new_protected:Npn \__fun_tracing_log_on:n #1
+  {
+    \tl_set:Ne \l__tracing_text_tl
+      {
+        \prg_replicate:nn
+          { \int_eval:n { (\g__fun_nesting_level_int - 1) * 4 } } { ~ }
+      }
+    \tl_put_right:Nn \l__tracing_text_tl { #1 }
+    \iow_log:V \l__tracing_text_tl
+  }
+\cs_generate_variant:Nn \__fun_tracing_log_on:n { e, V }
+
+\cs_new_protected:Npn \__fun_tracing_log_off:n #1 { }
+\cs_new_protected:Npn \__fun_tracing_log_off:e #1 { }
+\cs_new_protected:Npn \__fun_tracing_log_off:V #1 { }
+
+\cs_new_protected:Npn \__fun_tracing_true:
+  {
+    \cs_set_eq:NN \__fun_tracing_log:n \__fun_tracing_log_on:n
+    \cs_set_eq:NN \__fun_tracing_log:e \__fun_tracing_log_on:e
+    \cs_set_eq:NN \__fun_tracing_log:V \__fun_tracing_log_on:V
+  }
+
+\cs_new_protected:Npn \__fun_tracing_false:
+  {
+    \cs_set_eq:NN \__fun_tracing_log:n \__fun_tracing_log_off:n
+    \cs_set_eq:NN \__fun_tracing_log:e \__fun_tracing_log_off:e
+    \cs_set_eq:NN \__fun_tracing_log:V \__fun_tracing_log_off:V
+  }
+
+\cs_new_protected:Npn \__fun_tracing_set:
+  {
+    \bool_if:NTF \l__fun_tracing_bool
+      { \__fun_tracing_true: } { \__fun_tracing_false: }
+  }
+
+\keys_define:nn { functional }
+  {
+    scoping .bool_set:N = \l__fun_scoping_bool,
+    tracing .bool_set:N = \l__fun_tracing_bool,
+  }
+
+\NewDocumentCommand \Functional { m }
+  {
+    \keys_set:nn { functional } { #1 }
+    \__fun_scoping_set:
+    \__fun_tracing_set:
+  }
+
+\Functional { scoping = false, tracing = false }
+
 %%% --------------------------------------------------------
 %%> \subsection{Creating New Functions and Conditionals}
 %%% --------------------------------------------------------
@@ -495,6 +573,17 @@
   }
 \cs_generate_variant:Nn \__fun_arguments_gput:n { e }
 
+%%% --------------------------------------------------------
+%%> \subsection{Creating Some Useful Functions}
+%%% --------------------------------------------------------
+
+\PrgNewFunction \PrgSetEqFunction { N N }
+  {
+    \cs_set_eq:NN #1 #2
+    \cs_set_eq:cc { __fun_defined_ \cs_to_str:N #1 : w }
+      { __fun_defined_ \cs_to_str:N #2 : w }
+  }
+
 \cs_if_exist:NF \Do { \PrgNewFunction \Do { n } { #1 } }
 \PrgNewFunction \PrgDo { n } { #1 }
 
@@ -519,6 +608,7 @@
     \__fun_put_result:n { #1 }
   }
 %% Obsolete function, will be removed in the future
+%% We can not define it with \PrgSetEqFunction
 \PrgNewFunction \Result { m }
   {
     \__fun_put_result:n { #1 }
@@ -608,6 +698,54 @@
       }
   }
 
+%%% --------------------------------------------------------
+%%> \subsection{Printing Contents to the Input Stream}
+%%% --------------------------------------------------------
+
+\PrgNewFunction \PrgPrint { m }
+  {
+    \tl_log:n {running PrgPrint}
+    \int_set_eq:NN \l__fun_return_level_int \g__fun_nesting_level_int
+    #1
+    \int_zero:N \l__fun_return_level_int
+    \tl_gclear:N \gResultTl
+  }
+
+\PrgSetEqFunction \Print \PrgPrint
+
+%%% --------------------------------------------------------
+%%> \subsection{Filling Arguments into Inline Commands}
+%%% --------------------------------------------------------
+
+%% To make better tracing log, we want to expand the return value once,
+%% but at the same time avoid evaluating the leading function in \gResultTl,
+%% therefore we need to use \tl_set:Nn command instead of \TlSet function.
+
+\PrgNewFunction \PrgRunOneArgCode { m n }
+  {
+    \cs_set:Npn \__fun_one_arg_cmd:n ##1 {#2}
+    \exp_args:NNo \tl_set:Nn \gResultTl { \__fun_one_arg_cmd:n {#1} }
+  }
+
+\PrgNewFunction \PrgRunTwoArgCode { m m n }
+  {
+    \cs_set:Npn \__fun_two_arg_cmd:nn ##1 ##2 {#3}
+    \exp_args:NNo \tl_set:Nn \gResultTl { \__fun_two_arg_cmd:nn {#1} {#2} }
+  }
+
+\PrgNewFunction \PrgRunThreeArgCode { m m m n }
+  {
+    \cs_set:Npn \__fun_three_arg_cmd:nnn ##1 ##2 ##3 {#4}
+    \exp_args:NNo \tl_set:Nn \gResultTl { \__fun_three_arg_cmd:nnn {#1} {#2} {#3} }
+  }
+
+\PrgNewFunction \PrgRunFourArgCode { m m m m n }
+  {
+    \cs_set:Npn \__fun_four_arg_cmd:nnnn ##1 ##2 ##3 ##4 {#5}
+    \exp_args:NNo \tl_set:Nn \gResultTl
+      { \__fun_four_arg_cmd:nnnn {#1} {#2} {#3} {#4} }
+  }
+
 %%% --------------------------------------------------------
 %%> \subsection{Checking for Local or Global Variables}
 %%% --------------------------------------------------------
@@ -659,84 +797,6 @@
     \__fun_group_begin:
   }
 
-%%% --------------------------------------------------------
-%%> \subsection{Setting Functional Package}
-%%% --------------------------------------------------------
-
-\bool_new:N \l__fun_scoping_bool
-
-\cs_new_protected:Npn \__fun_scoping_true:
-  {
-    \cs_set_eq:NN \__fun_group_begin: \group_begin:
-    \cs_set_eq:NN \__fun_group_end: \group_end:
-  }
-
-\cs_new_protected:Npn \__fun_scoping_false:
-  {
-    \cs_set_eq:NN \__fun_group_begin: \scan_stop:
-    \cs_set_eq:NN \__fun_group_end: \scan_stop:
-  }
-
-\cs_new_protected:Npn \__fun_scoping_set:
-  {
-    \bool_if:NTF \l__fun_scoping_bool
-      { \__fun_scoping_true: } { \__fun_scoping_false: }
-  }
-
-\bool_new:N \l__fun_tracing_bool
-\tl_new:N \l__tracing_text_tl
-
-\cs_new_protected:Npn \__fun_tracing_log_on:n #1
-  {
-    \tl_set:Ne \l__tracing_text_tl
-      {
-        \prg_replicate:nn
-          { \int_eval:n { (\g__fun_nesting_level_int - 1) * 4 } } { ~ }
-      }
-    \tl_put_right:Nn \l__tracing_text_tl { #1 }
-    \iow_log:V \l__tracing_text_tl
-  }
-\cs_generate_variant:Nn \__fun_tracing_log_on:n { e, V }
-
-\cs_new_protected:Npn \__fun_tracing_log_off:n #1 { }
-\cs_new_protected:Npn \__fun_tracing_log_off:e #1 { }
-\cs_new_protected:Npn \__fun_tracing_log_off:V #1 { }
-
-\cs_new_protected:Npn \__fun_tracing_true:
-  {
-    \cs_set_eq:NN \__fun_tracing_log:n \__fun_tracing_log_on:n
-    \cs_set_eq:NN \__fun_tracing_log:e \__fun_tracing_log_on:e
-    \cs_set_eq:NN \__fun_tracing_log:V \__fun_tracing_log_on:V
-  }
-
-\cs_new_protected:Npn \__fun_tracing_false:
-  {
-    \cs_set_eq:NN \__fun_tracing_log:n \__fun_tracing_log_off:n
-    \cs_set_eq:NN \__fun_tracing_log:e \__fun_tracing_log_off:e
-    \cs_set_eq:NN \__fun_tracing_log:V \__fun_tracing_log_off:V
-  }
-
-\cs_new_protected:Npn \__fun_tracing_set:
-  {
-    \bool_if:NTF \l__fun_tracing_bool
-      { \__fun_tracing_true: } { \__fun_tracing_false: }
-  }
-
-\keys_define:nn { functional }
-  {
-    scoping .bool_set:N = \l__fun_scoping_bool,
-    tracing .bool_set:N = \l__fun_tracing_bool,
-  }
-
-\NewDocumentCommand \Functional { m }
-  {
-    \keys_set:nn { functional } { #1 }
-    \__fun_scoping_set:
-    \__fun_tracing_set:
-  }
-
-\Functional { scoping = false, tracing = false }
-
 %%% --------------------------------------------------------
 %%> \section{Interfaces for Argument Using (Use)}
 %%% --------------------------------------------------------
@@ -745,28 +805,19 @@
   {
     \exp_args:Nc \__fun_put_result:n { #1 }
   }
-\PrgNewFunction \ExpName { m }
-  {
-    \exp_args:Nc \__fun_put_result:n { #1 }
-  }
+\PrgSetEqFunction \ExpName \Name
 
 \PrgNewFunction \Value { M }
   {
     \__fun_put_result:V #1
   }
-\PrgNewFunction \ExpValue { M }
-  {
-    \__fun_put_result:V #1
-  }
+\PrgSetEqFunction \ExpValue \Value
 
 \PrgNewFunction \Expand { m }
   {
     \__fun_put_result:e { #1 }
   }
-\PrgNewFunction \ExpWhole { m }
-  {
-    \__fun_put_result:e { #1 }
-  }
+\PrgSetEqFunction \ExpWhole \Expand
 
 \PrgNewFunction \ExpPartial { m }
   {
@@ -2275,6 +2326,281 @@
       { \Return { \cTrueBool } }  { \Return { \cFalseBool } }
   }
 
+%%% --------------------------------------------------------
+%%> \section{Interfaces for Regular Expressions (Regex)}
+%%% --------------------------------------------------------
+
+\regex_new:N \lTmpaRegex  \regex_new:N \lTmpbRegex  \regex_new:N \lTmpcRegex
+\regex_new:N \lTmpiRegex  \regex_new:N \lTmpjRegex  \regex_new:N \lTmpkRegex
+
+\regex_new:N \gTmpaRegex  \regex_new:N \gTmpbRegex  \regex_new:N \gTmpcRegex
+\regex_new:N \gTmpiRegex  \regex_new:N \gTmpjRegex  \regex_new:N \gTmpkRegex
+
+\regex_new:N \l@FunTmpxRegex  \regex_new:N \g@FunTmpxRegex
+\regex_new:N \l@FunTmpyRegex  \regex_new:N \g@FunTmpyRegex
+\regex_new:N \l@FunTmpzRegex  \regex_new:N \g@FunTmpzRegex
+
+\PrgNewFunction \RegexNew { M } { \regex_new:N #1 }
+
+\PrgNewFunction \RegexSet { M m }
+  {
+    \__fun_do_assignment:Nnn #1
+     { \regex_gset:Nn #1 {#2} } { \regex_set:Nn #1 {#2} }
+  }
+
+\PrgNewFunction \RegexConst { M m } { \regex_const:Nn #1 {#2} }
+
+\PrgNewFunction \RegexLog { m } { \regex_log:n {#1} }
+
+\PrgNewFunction \RegexVarLog { M } { \regex_log:N #1 }
+
+\PrgNewFunction \RegexShow { m } { \regex_show:n {#1} }
+
+\PrgNewFunction \RegexVarShow { M } { \regex_show:N #1 }
+
+\PrgNewConditional \RegexMatch { m m }
+  {
+    \regex_match:nnTF {#1} {#2}
+      { \Return { \cTrueBool } }  { \Return { \cFalseBool } }
+  }
+
+\PrgNewConditional \RegexVarMatch { M m }
+  {
+    \regex_match:NnTF #1 {#2}
+      { \Return { \cTrueBool } }  { \Return { \cFalseBool } }
+  }
+
+\PrgNewFunction \RegexCount { m m M }
+  {
+    \regex_count:nnN {#1} {#2} #3
+  }
+
+\PrgNewFunction \RegexVarCount { M m M }
+  {
+    \regex_count:NnN #1 {#2} #3
+  }
+
+\PrgNewFunction \RegexMatchCase { m m }
+  {
+    \regex_match_case:nn {#1} {#2}
+  }
+\PrgNewFunction \RegexMatchCaseT { m m n }
+  {
+    \regex_match_case:nnT {#1} {#2} {#3}
+  }
+\PrgNewFunction \RegexMatchCaseF { m m n }
+  {
+    \regex_match_case:nnF {#1} {#2} {#3}
+  }
+\PrgNewFunction \RegexMatchCaseTF { m m n n }
+  {
+    \regex_match_case:nnTF {#1} {#2} {#3} {#4}
+  }
+
+\PrgNewFunction \RegexExtractOnce { m m M }
+  {
+    \regex_extract_once:nnN {#1} {#2} #3
+  }
+\PrgNewFunction \RegexExtractOnceT { m m M n }
+  {
+    \regex_extract_once:nnNT {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexExtractOnceF { m m M n }
+  {
+    \regex_extract_once:nnNF {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexExtractOnceTF { m m M n n }
+  {
+    \regex_extract_once:nnNTF {#1} {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexVarExtractOnce { M m M }
+  {
+    \regex_extract_once:NnN #1 {#2} #3
+  }
+\PrgNewFunction \RegexVarExtractOnceT { M m M n }
+  {
+    \regex_extract_once:NnNT #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarExtractOnceF { M m M n }
+  {
+    \regex_extract_once:NnNF #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarExtractOnceTF { M m M n n }
+  {
+    \regex_extract_once:NnNTF #1 {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexExtractAll { m m M }
+  {
+    \regex_extract_all:nnN {#1} {#2} #3
+  }
+\PrgNewFunction \RegexExtractAllT { m m M n }
+  {
+    \regex_extract_all:nnNT {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexExtractAllF { m m M n }
+  {
+    \regex_extract_all:nnNF {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexExtractAllTF { m m M n n }
+  {
+    \regex_extract_all:nnNTF {#1} {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexVarExtractAll { M m M }
+  {
+    \regex_extract_all:NnN #1 {#2} #3
+  }
+\PrgNewFunction \RegexVarExtractAllT { M m M n }
+  {
+    \regex_extract_all:NnNT #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarExtractAllF { M m M n }
+  {
+    \regex_extract_all:NnNF #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarExtractAllTF { M m M n n }
+  {
+    \regex_extract_all:NnNTF #1 {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexSplit { m m M }
+  {
+    \regex_split:nnN {#1} {#2} #3
+  }
+\PrgNewFunction \RegexSplitT { m m M n }
+  {
+    \regex_split:nnNT {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexSplitF { m m M n }
+  {
+    \regex_split:nnNF {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexSplitTF { m m M n n }
+  {
+    \regex_split:nnNTF {#1} {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexVarSplit { M m M }
+  {
+    \regex_split:NnN #1 {#2} #3
+  }
+\PrgNewFunction \RegexVarSplitT { M m M n }
+  {
+    \regex_split:NnNT #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarSplitF { M m M n }
+  {
+    \regex_split:NnNF #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarSplitTF { M m M n n }
+  {
+    \regex_split:NnNTF #1 {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexReplaceOnce { m m M }
+  {
+    \regex_replace_once:nnN {#1} {#2} #3
+  }
+\PrgNewFunction \RegexReplaceOnceT { m m M n }
+  {
+    \regex_replace_once:nnNT {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexReplaceOnceF { m m M n }
+  {
+    \regex_replace_once:nnNF {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexReplaceOnceTF { m m M n n }
+  {
+    \regex_replace_once:nnNTF {#1} {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexVarReplaceOnce { M m M }
+  {
+    \regex_replace_once:NnN #1 {#2} #3
+  }
+\PrgNewFunction \RegexVarReplaceOnceT { M m M n }
+  {
+    \regex_replace_once:NnNT #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarReplaceOnceF { M m M n }
+  {
+    \regex_replace_once:NnNF #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarReplaceOnceTF { M m M n n }
+  {
+    \regex_replace_once:NnNTF #1 {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexReplaceAll { m m M }
+  {
+    \regex_replace_all:nnN {#1} {#2} #3
+  }
+\PrgNewFunction \RegexReplaceAllT { m m M n }
+  {
+    \regex_replace_all:nnNT {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexReplaceAllF { m m M n }
+  {
+    \regex_replace_all:nnNF {#1} {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexReplaceAllTF { m m M n n }
+  {
+    \regex_replace_all:nnNTF {#1} {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexVarReplaceAll { M m M }
+  {
+    \regex_replace_all:NnN #1 {#2} #3
+  }
+\PrgNewFunction \RegexVarReplaceAllT { M m M n }
+  {
+    \regex_replace_all:NnNT #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarReplaceAllF { M m M n }
+  {
+    \regex_replace_all:NnNF #1 {#2} #3 {#4}
+  }
+\PrgNewFunction \RegexVarReplaceAllTF { M m M n n }
+  {
+    \regex_replace_all:NnNTF #1 {#2} #3 {#4} {#5}
+  }
+
+\PrgNewFunction \RegexReplaceCaseOnce { m M }
+  {
+    \regex_replace_case_once:nN {#1} #2
+  }
+\PrgNewFunction \RegexReplaceCaseOnceT { m M n }
+  {
+    \regex_replace_case_once:nN {#1} #2 {#3}
+  }
+\PrgNewFunction \RegexReplaceCaseOnceF { m M n }
+  {
+    \regex_replace_case_once:nN {#1} #2 {#3}
+  }
+\PrgNewFunction \RegexReplaceCaseOnceTF { m M n n }
+  {
+    \regex_replace_case_once:nN {#1} #2 {#3} {#4}
+  }
+
+\PrgNewFunction \RegexReplaceCaseAll { m M }
+  {
+    \regex_replace_case_all:nN {#1} #2
+  }
+\PrgNewFunction \RegexReplaceCaseAllT { m M n }
+  {
+    \regex_replace_case_all:nN {#1} #2 {#3}
+  }
+\PrgNewFunction \RegexReplaceCaseAllF { m M n }
+  {
+    \regex_replace_case_all:nN {#1} #2 {#3}
+  }
+\PrgNewFunction \RegexReplaceCaseAllTF { m M n n }
+  {
+    \regex_replace_case_all:nN {#1} #2 {#3} {#4}
+  }
+
 %%% --------------------------------------------------------
 %%> \section{Interfaces for Token Manipulation (Token)}
 %%% --------------------------------------------------------
-- 
cgit v1.2.3

