2

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?

1

May be defining your own 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
 }
  • Well, it's the point of my question: is it possible to construct this assignment without relying upon a middleman? – A.Ellett Nov 29 '14 at 1:52
  • Why the :w type argument? – A.Ellett Nov 29 '14 at 3:51
  • It's a dummy command, the more general signature is :w. You can redefine it wherever you want, and still be valid with :w, even if it doesn't have any arguments. – Manuel Nov 29 '14 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.