vendredi 28 novembre 2014

In expl3, how do I smuggle in a three arguments when threading sequences?


I've got some code which essentially works as in this 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}


But things are too hard-wired in a manner I'd prefer to avoid. In particular, I would like to be better able to control which token list gets assigned to when calling \aellett_test_get_selected_value:.


So, I wrote a version which accomplishes this. But, I needed to create a dummy token to temporarily store my value in order to make the desired assignment. (Do notice that I've modified the names of control functions and how they operate.)



\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}


What I would like to be able to do is something like:



\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}


But this is not parsed in the manner I would like it to: namely, that \aellett_assign_b_according_to_value_of_a:Nnn absorb its first argument before \seq_mapthread_function:NNN passes it arguments from the two sequences.


Before posting here, I wanted to show how I would do this if I had a expl3 macro such as



\seq_mapthread_inline:NNn


such as



\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}
}
}
}


But, I would like to avoid such an inline approach if possible.


Is there a work-around that essentially captures the spirit of this third example without the need of a middleman token or macro?





Aucun commentaire:

Enregistrer un commentaire