expl3 命令的可扩展版本

expl3 命令的可扩展版本

我有以下命令,它可以提供我想要的输出。但我需要一个可扩展的版本。我知道我需要使用它,\seq_map_function:NN但我无法正确传递外部参数。

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn

\seq_new:N \l_uf_outer_seq \seq_set_from_clist:Nn \l_uf_outer_seq {key1,key2,key3}

\prop_new:N \l_uf_a_prop
     \prop_put:Nnn \l_uf_a_prop {key1}{aa}
     \prop_put:Nnn \l_uf_a_prop {key2}{ab}
     \prop_put:Nnn \l_uf_a_prop {keyX}{XX}

\prop_new:N \l_uf_b_prop
     \prop_put:Nnn \l_uf_b_prop {key1}{ba}
     \prop_put:Nnn \l_uf_b_prop {key3}{bb}


\cs_new:Nn \uf_handle_prop:n  
{
 \seq_map_inline:Nn \l_uf_outer_seq
  {
   \prop_if_in:cnT {l_uf_#1_prop} { ##1 } { \prop_item:cn{l_uf_#1_prop}{##1} \par }
  } 
}


\uf_handle_prop:n {a}


\cs_new:Nn \uf_handle_prop_exp:n
{
 ???
}

\tl_set:Nx \l_tmpa_tl { \uf_handle_prop_exp:n {a} } 


\ExplSyntaxOff
\end{document} 

答案1

一种方法是定义多个处理函数,每个处理函数一个prop

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn

\seq_new:N \l_uf_outer_seq
\seq_set_from_clist:Nn \l_uf_outer_seq {key1,key2,key3}

\prop_new:N \l_uf_a_prop
     \prop_put:Nnn \l_uf_a_prop {key1}{aa}
     \prop_put:Nnn \l_uf_a_prop {key2}{ab}
     \prop_put:Nnn \l_uf_a_prop {keyX}{XX}

\prop_new:N \l_uf_b_prop
     \prop_put:Nnn \l_uf_b_prop {key1}{ba}
     \prop_put:Nnn \l_uf_b_prop {key3}{bb}


\cs_new:Nn \uf_handle_prop:n  
{
 \seq_map_inline:Nn \l_uf_outer_seq
  {
    \prop_if_in:cnT {l_uf_#1_prop} { ##1 } { \prop_item:cn{l_uf_#1_prop}{##1} \par }
  } 
}


\uf_handle_prop:n {a}

\cs_new:Nn \uf_new_prop_handler:n
  {
    \cs_new:cn { uf_handling_prop_#1:n }
      {
        \prop_if_in:cnT { l_uf_#1_prop } { ##1 }
          { \prop_item:cn { l_uf_#1_prop } { ##1 } \par }
      }
  }
\uf_new_prop_handler:n { a }
\uf_new_prop_handler:n { b }

\cs_new:Nn \uf_handle_prop_exp:n
{
  \exp_args:NNc \seq_map_function:NN \l_uf_outer_seq { uf_handling_prop_#1:n }
}

\tl_set:Nx \l_tmpa_tl { \uf_handle_prop_exp:n {a} } 

\tl_show_analysis:N \l_tmpa_tl


\ExplSyntaxOff
\end{document} 

答案2

如果使用分隔参数将名称“传递”prop给底层,则可以做到\prop_item:cn

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn

\seq_new:N \l_uf_outer_seq
\seq_set_from_clist:Nn \l_uf_outer_seq { key1 , key2 , key3 }

\prop_new:N \l_uf_a_prop

\prop_put:Nnn \l_uf_a_prop { key1 } { aa }
\prop_put:Nnn \l_uf_a_prop { key2 } { ab }
\prop_put:Nnn \l_uf_a_prop { keyX } { XX }

\prop_new:N \l_uf_b_prop
\prop_put:Nnn \l_uf_b_prop { key1 } { ba }
\prop_put:Nnn \l_uf_b_prop { key3 } { bb }

\cs_new_protected:Nn \uf_handle_prop:n  
  {
    \seq_map_inline:Nn \l_uf_outer_seq
      {
       \prop_if_in:cnT { l_uf_ #1 _prop } {##1}
         {
           \prop_item:cn {l_uf_ #1 _prop } { ##1 }
           \par
         }
      } 
  }


\uf_handle_prop:n {a}

\cs_new:Npn \uf_handle_prop_exp:n #1
  {
    \seq_map_function:NN
      \l_uf_outer_seq
      \__uf_handle_prop_exp:nw
    \__uf_handle_prop_exp_end:n {#1}
  }
\cs_new:Npn \__uf_handle_prop_exp:nw #1#2 \__uf_handle_prop_exp_end:n #3
  {
    \prop_if_in:cnT { l_uf_ #3 _prop } {#1}
      {
        \prop_item:cn {l_uf_ #3 _prop } {#1}
        \par
      }
    #2 \__uf_handle_prop_exp_end:n {#3}
  }
\cs_new_eq:NN \__uf_handle_prop_exp_end:n \use_none:n

\tl_set:Nx \l_tmpa_tl { \uf_handle_prop_exp:n {a} } 
\tl_show:N \l_tmpa_tl

\ExplSyntaxOff
\end{document} 

通过进行查找并将结果传递下去,可以以稍微复杂一些为代价来避免两次映射:

\cs_new:Npn \__uf_handle_prop_exp:nw #1#2 \__uf_handle_prop_exp_end:n #3
  {
    \__uf_handle_prop_exp_aux:fnn
      { \prop_item:cn { l_uf_ #3 _prop } {#1} }
      {#2} {#3}
  }
\cs_new:Npn \__uf_handle_prop_exp_aux:nnn #1#2#3
  {
    \tl_if_blank:nF {#1}
      { #1 \par }
    #2 \__uf_handle_prop_exp_end:n {#3}
  }
\cs_generate_variant:Nn \__uf_handle_prop_exp_aux:nnn { f }

相关内容