我有一些代码,其基本工作原理与此 MWE 相同:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_aellett_current_choice_tl
\tl_new:N \l_aellett_selection_result_tl
\seq_new:N \l_aellett_test_a_seq
\seq_new:N \l_aellett_test_b_seq
\seq_set_split:Nnn \l_aellett_test_a_seq {,} {a,b,c,d}
\seq_set_split:Nnn \l_aellett_test_b_seq {,} {apple,banana,carrot,dill}
\NewDocumentCommand\aeMakeSelection{m}
{
\tl_set:Nn \l_aellett_current_choice_tl {#1}
\aellett_test_get_selected_value:
\l_aellett_selection_result_tl
}
\cs_new:Nn \aellett_test_get_selected_value:
{
\seq_mapthread_function:NNN
\l_aellett_test_a_seq
\l_aellett_test_b_seq
\aellett_select_b_according_to_value_of_a:nn
}
\cs_new:Npn \aellett_select_b_according_to_value_of_a:nn #1#2
{
\str_if_eq:nVT {#1} \l_aellett_current_choice_tl
{
\tl_set:Nn \l_aellett_selection_result_tl {#2}
}
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\aeMakeSelection{b}
\aeMakeSelection{a}
\end{document}
但事情太过僵化,我宁愿避免。特别是,我希望能够更好地控制在调用时将哪个标记列表分配给它\aellett_test_get_selected_value:
。
因此,我编写了一个可以实现此目的的版本。但是,我需要创建一个虚拟令牌来临时存储我的值,以便进行所需的分配。(请注意,我修改了控制函数的名称及其操作方式。)
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_aellett_current_choice_tl
\tl_new:N \l_aellett_selection_result_tl
\tl_new:N \l_aellett_tmp_tl
\seq_new:N \l_aellett_test_a_seq
\seq_new:N \l_aellett_test_b_seq
\seq_set_split:Nnn \l_aellett_test_a_seq {,} {a,b,c,d}
\seq_set_split:Nnn \l_aellett_test_b_seq {,} {apple,banana,carrot,dill}
\NewDocumentCommand\aeMakeSelection{m}
{
\tl_set:Nn \l_aellett_current_choice_tl {#1}
\aellett_test_assign_selected_value:N \l_aellett_selection_result_tl
\l_aellett_selection_result_tl
}
\cs_new:Npn \aellett_test_assign_selected_value:N #1
{
\seq_mapthread_function:NNN
\l_aellett_test_a_seq
\l_aellett_test_b_seq
\aellett_select_b_according_to_value_of_a:nn
\tl_set_eq:NN #1 \l_aellett_tmp_tl
}
\cs_new:Npn \aellett_select_b_according_to_value_of_a:nn #1#2
{
\str_if_eq:nVT {#1} \l_aellett_current_choice_tl
{
\tl_set:Nn \l_aellett_tmp_tl {#2}
}
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\aeMakeSelection{b}
\aeMakeSelection{a}
\end{document}
我希望能够做的事情如下:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_aellett_current_choice_tl
\tl_new:N \l_aellett_selection_result_tl
\tl_new:N \l_aellett_tmp_tl
\seq_new:N \l_aellett_test_a_seq
\seq_new:N \l_aellett_test_b_seq
\seq_set_split:Nnn \l_aellett_test_a_seq {,} {a,b,c,d}
\seq_set_split:Nnn \l_aellett_test_b_seq {,} {apple,banana,carrot,dill}
\NewDocumentCommand\aeMakeSelection{m}
{
\tl_set:Nn \l_aellett_current_choice_tl {#1}
\aellett_test_assign_selected_value:N \l_aellett_selection_result_tl
\l_aellett_selection_result_tl
}
\cs_new:Npn \aellett_test_assign_selected_value:N #1
{
\seq_mapthread_function:NNN
\l_aellett_test_a_seq
\l_aellett_test_b_seq
\aellett_assign_b_according_to_value_of_a:Nnn #1
}
\cs_new:Npn \aellett_assign_b_according_to_value_of_a:Nnn #1#2#3
{
\str_if_eq:nVT {#2} \l_aellett_current_choice_tl
{
\tl_set:Nn #1 {#3}
}
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\aeMakeSelection{b}
\aeMakeSelection{a}
\end{document}
但这并不是我希望的解析方式:即\aellett_assign_b_according_to_value_of_a:Nnn
吸收它之前的第一个参数\seq_mapthread_function:NNN
是将两个序列的参数传递给它。
在发布之前,我想先演示一下如果我有一个expl3
宏,我将如何做到这一点,例如
\seq_mapthread_inline:NNn
例如
\cs_new:Npn \aellett_test_assign_selected_value:N #1
{
\seq_mapthread_inline:NNn
\l_aellett_test_a_seq
\l_aellett_test_b_seq
{
\str_if_eq:nVT {##1} \l_aellett_current_choice_tl
{
\tl_set:Nn #1 {##2}
}
}
}
但如果可能的话,我想避免这种inline
方法。
是否有一种解决方法可以基本上体现第三个示例的精神,而不需要中间人令牌或宏?
答案1
可以定义你自己的seq_mapthread_inline
吗?
\cs_new_protected:Npn \aellet_seq_mapthread_inline:NNn #1 #2 #3
{
\cs_set:Npn \__aellet_tmp:w ##1 ##2 { #3 }
\seq_mapthread_function:NNN #1 #2 \__aellet_tmp:w
}