summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/functional/functional.sty
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/functional/functional.sty')
-rw-r--r--macros/latex/contrib/functional/functional.sty512
1 files changed, 419 insertions, 93 deletions
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 }
@@ -34,6 +34,84 @@
\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 }
@@ -609,6 +699,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}
%%% --------------------------------------------------------
@@ -660,84 +798,6 @@
}
%%% --------------------------------------------------------
-%%> \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 }
{
@@ -2276,6 +2327,281 @@
}
%%% --------------------------------------------------------
+%%> \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)}
%%% --------------------------------------------------------