From f8e05edb088c3b5246e016f68df9c4cadccfd34d Mon Sep 17 00:00:00 2001 From: Norbert Preining 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 %% 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