我需要一个完全可扩展的函数来扩展“f”类型的参数

我需要一个完全可扩展的函数来扩展“f”类型的参数

我真的希望我问的是正确的问题。我实际上正在研究的问题比 MWE 中发生的事情要复杂得多。我想我已经把问题缩小到了真正的问题。

我有一些旧代码,可以完美地实现我的要求。现在我想在新情况下使用该代码,在输出任何内容之前,我会使用旧代码进行多次迭代。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
%%--------------------------------------------------------------------------------
%% In theory, this first section of code works correctly and gives me the desired 
%% result.                                                                        
%%--------------------------------------------------------------------------------
%% This next macro does some complicated things:                                  
%%                                                                                
%%    testing booleans, setting token lists, \int_compare, \int_case              
%%                                                                                
%% But, regardless, everything it does--I believe--is fully expandable.  That is  
%% it should work whether in an "x" or "f" type argument.                         
\cs_new:Npn  \_format_expression:n #1 { #1 x 2 - }

\seq_new:N \l_collection_of_expressions_seq
\cs_new:Npn \_parse_expressions:n #1
  { \seq_set_split:Nnn \l_collection_of_expressions_seq {,} {#1} }


%% This next function, while fully expandable is not expandable in an "f"     
%% tyep argument.                                                             
\cs_new:Nn \_write_expression:
  {
    \seq_map_inline:Nn \l_collection_of_expressions_seq
      { \_format_expression:n { ##1 } }
  }

\NewDocumentCommand{\trialFunctionA}{ m }
    { \_parse_expressions:n { #1 } 
      \_write_expression:
    }

%%--------------------------------------------------------------------------------
%% Here starts the problematic code                                               
%%--------------------------------------------------------------------------------
%% The start of more complicated things.                                          
\seq_new:N \l_outer_collection_of_expressions_seq
\tl_new:N  \l_numerator_tl
\seq_new:N \l_formatted_expressions_seq   
\seq_new:N \l_denominator_seq

\cs_new:Npn \_parse_outer:nn #1#2
  { 
    \tl_put_right:Nn \l_numerator_tl {#2}
    \_parse_expressions:n {#1}
    %% This is where my problem step seems to be. I need the                  
    %% expansion of \_write_expression: but can't get it.  However,           
    %% since \_write_expression: uses \seq_map_inline, this is not            
    %% expandable in an "f" type argument.  But neither do I want to blast    
    %% this with "x" because I might have some unexpandable stuff in here     
    \seq_put_right:Nn \l_formatted_expressions_seq { 3^{\_write_expression:} }
  }

\cs_new:Npn \parse_outer:n #1
  { 
    \seq_set_split:Nnn \l_outer_collection_of_expressions_seq {,} { #1 }
    \seq_map_inline:Nn \l_outer_collection_of_expressions_seq 
      { \_parse_outer:nn  ##1 } 
    \frac{\l_numerator_tl}{\seq_use:Nn \l_formatted_expressions_seq {\,}}
  }   

\NewDocumentCommand{\trialFunctionB}{ m }
    { \parse_outer:n { #1 } }

%%--------------------------------------------------------------------------------
%% This is here just so I can easily demo the desired final result.               
\def\cheat#1{\_format_expression:n{#1}}

\ExplSyntaxOff
\begin{document}

\[
  \trialFunctionA{1,2,3}
\]

\[
  \frac{ABC}{3^{\cheat{1}\cheat{2}\cheat{3}}\,
             3^{\cheat{a}\cheat{b}\cheat{c}}\,
             3^{\cheat{M}\cheat{N}\cheat{P}}}
\]

\[
  \trialFunctionB{{1,2,3}{A},
                  {a,b,c}{B},
                  {M,N,P}{C}}
\]

\end{document}

在此处输入图片描述

上述代码确实可以编译,这比我的实际文档要好。但是我没有得到想要的结果,因为扩展发生得太晚了。

有没有什么方法可以让它\_write_expression:扩张得足够远,但又不会扩张得太远?

答案1

我建议您:x无论如何都要用 爆破它,并用 保护易碎内容\exp_not:n

另外,你对 做出了错误的假设\seq_map_inline:Nn。任何_map_inline函数都必须在后台进行定义,因此不符合:x扩展条件。所以你需要使用\seq_map_function:NN

以下代码应该可以工作。我添加了一些脆弱的内容,以表明它在适当的时候之前不会扩展。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Npn  \_format_expression:n #1 { \exp_not:n{#1} x 2 - } % CHANGED

\seq_new:N \l_collection_of_expressions_seq
\cs_new:Npn \_parse_expressions:n #1
  { \seq_set_split:Nnn \l_collection_of_expressions_seq {,} {#1} }

\cs_new:Nn \_write_expression:
  {
    \seq_map_function:NN
        \l_collection_of_expressions_seq
        \_format_expression:n  % CHANGED
  }

%%--------------------------------------------------------------------------------
%% Here starts the problematic code                                               
%%--------------------------------------------------------------------------------

\seq_new:N \l_outer_collection_of_expressions_seq
\tl_new:N  \l_numerator_tl
\seq_new:N \l_formatted_expressions_seq   
\seq_new:N \l_denominator_seq

\cs_new:Npn \_parse_outer:nn #1#2
  { 
    \tl_put_right:Nn \l_numerator_tl {\exp_not:n{#2}}  % CHANGED
    \_parse_expressions:n {#1} 
    \seq_put_right:Nx
        \l_formatted_expressions_seq
        { 3^{\_write_expression:} }  % CHANGED
  }

\cs_new:Npn \parse_outer:n #1
  { 
    \seq_set_split:Nnn \l_outer_collection_of_expressions_seq {,} { #1 }
    \seq_map_inline:Nn \l_outer_collection_of_expressions_seq 
      { \_parse_outer:nn  ##1 }
    \frac{\l_numerator_tl}{\seq_use:Nn \l_formatted_expressions_seq {\,}}
  }   

\NewDocumentCommand{\trialFunctionB}{ m }
    { \parse_outer:n { #1 } }


%%% Example don't-want-this-to-expand content
\int_new:N \g_counter_int
\cs_new:Npn \DontExpandPlease {
    \int_gincr:N \g_counter_int
    \int_use:N \g_counter_int
}

\ExplSyntaxOff
\begin{document}

\[
  \trialFunctionB{{\DontExpandPlease,\DontExpandPlease,\DontExpandPlease}{A},
                  {a,b,c}{B},
                  {M,N,P}{C}}
\]

\end{document}

相关内容