diff options
Diffstat (limited to 'macros/latex/contrib/functional/functional.sty')
-rw-r--r-- | macros/latex/contrib/functional/functional.sty | 80 |
1 files changed, 78 insertions, 2 deletions
diff --git a/macros/latex/contrib/functional/functional.sty b/macros/latex/contrib/functional/functional.sty index c1eb69900f..800641976e 100644 --- a/macros/latex/contrib/functional/functional.sty +++ b/macros/latex/contrib/functional/functional.sty @@ -14,7 +14,7 @@ \NeedsTeXFormat{LaTeX2e}[2018-04-01] \RequirePackage{expl3} -\ProvidesExplPackage{functional}{2022-05-22}{2022G} +\ProvidesExplPackage{functional}{2022-06-18}{2022H} {^^JIntuitive Functional Programming Interface for LaTeX2} \cs_generate_variant:Nn \iow_log:n { V } @@ -667,9 +667,13 @@ } %%% -------------------------------------------------------- -%%> \subsection{Evaluating Functions inside Arguments} +%%> \subsection{Evaluating Functions inside Arguments, I} %%% -------------------------------------------------------- +%% The function \__fun_eval_all:n is only used for arguments to be passed +%% to \int_eval:n, \fp_eval:n, \dim_eval:n, and similar functions. +%% It will not keep spaces, and will not distinguish between { and \bgroup. + \tl_new:N \l__fun_eval_result_tl %% Evaluate all functions in #1 and replace them with their return values @@ -710,6 +714,78 @@ } %%% -------------------------------------------------------- +%%> \subsection{Evaluating Functions inside Arguments, II} +%%% -------------------------------------------------------- + +%% The function \evalWhole can be used in almost all use cases. +%% It will keep spaces, and will distinguish between { and \bgroup. + +\prgNewFunction \evalWhole {n} + { + \__fun_eval_whole:n {#1} + } + +\tl_new:N \l__fun_eval_whole_tl +\bool_new:N \l__fun_eval_none_bool + +%% Evaluate all functions in #1 and replace them with their return values +\cs_new_protected:Npn \__fun_eval_whole:n #1 + { + \fun_run_return_processor:nn + { + \bool_if:NTF \l__fun_eval_none_bool + { + \tl_put_right:Nx \l__fun_eval_whole_tl + { \exp_not:N \exp_not:n { \exp_not:V \gResultTl } } + \bool_set_false:N \l__fun_eval_none_bool + \__fun_eval_whole_aux: + } + { \exp_last_unbraced:NV \__fun_eval_whole_aux: \gResultTl } + } + { + \tl_clear:N \l__fun_eval_whole_tl + \__fun_eval_whole_aux: #1 \q_stop + %\tl_log:N \l__fun_eval_whole_tl + \tl_gset:Nx \gResultTl { \l__fun_eval_whole_tl } + } + } + +\cs_new_protected:Npn \__fun_eval_whole_aux: + { + %% ##1: <tokens> which both o-expand and x-expand to the current <token>; + %% ##2: <charcode>, a decimal number, −1 for a control sequence; + %% ##3: <catcode>, a capital hexadecimal digit, 0 for a control sequence. + \peek_analysis_map_inline:n + { + \int_compare:nNnTF {##2} = {-1} % control sequence + { + \exp_last_unbraced:No \token_if_eq_meaning:NNTF {##1} \q_stop + { \peek_analysis_map_break: } + { + \cs_if_exist:cTF + { __fun_defined_ \exp_last_unbraced:No \cs_to_str:N {##1} : w } + { + \exp_last_unbraced:No \cs_if_eq:NNT {##1} \evalNone + { \bool_set_true:N \l__fun_eval_none_bool } + \peek_analysis_map_break:n + { + %% since ##1 is of the form "\exp_not:N \someFunc", + %% we need to remove \exp_not:N first before evaluating + \use:x {##1} + } + } + { \tl_put_right:Nn \l__fun_eval_whole_tl {##1} } + } + } + { \tl_put_right:Nn \l__fun_eval_whole_tl {##1} } + } + } + +%% The function \evalNone prevent the evaluation of its argument + +\prgNewFunction \evalNone {n} { \tl_gset:Nn \gResultTl {#1} } + +%%% -------------------------------------------------------- %%> \subsection{Printing Contents to the Input Stream} %%% -------------------------------------------------------- |