2

Passing a menemonic as an optional argument in a \NewDocumentCommand to set colours for use in a \tikzpicture environment works fine if the argument is a straight \tl variable. However, if passed as an item of a \tl pseudo array it seems to translate correctly to the desired mnemonic which then fails to be recognized in the \str_case:NnTF statement. Any clues why?

\documentclass{article}
% RN. 20/10/2025
% MWE_115
%=======================
\usepackage{tikz} 

\ExplSyntaxOn
\NewDocumentCommand\myCommandOne{O{R}}
%  PARAMETERS:
%    #1 tl  
    {
\group_begin:
    
    \tl_set:Nn \l_rn_mnemColour_tl {#1}
    tl~variable~set~by~argument~\#1:~\l_rn_mnemColour_tl \\
    
    \str_case:NnTF {\l_rn_mnemColour_tl}
        { 
            {R}{\tl_set:Nn \l_rn_Colour_tl {red}}
            {B}{\tl_set:Nn \l_rn_Colour_tl {blue}}
            {G}{\tl_set:Nn \l_rn_Colour_tl {green}}
            {Y}{\tl_set:Nn \l_rn_Colour_tl {yellow}}
        }
        {TRUE\\}
        {FALSE\\}

    \begin{tikzpicture} 
        \draw [fill=\l_rn_Colour_tl] (0,0) rectangle (1,1);
    \end{tikzpicture}
\group_end:
  }  %  \myCommand  
\ExplSyntaxOff
  
\begin{document}
1. \verb+\myCommandOne+\\
\myCommandOne

2. \verb+\myCommandOne[B]+\\
\myCommandOne[B]

3. \verb+\myCommandOne[G]+\\
\myCommandOne[G]

4. \verb+\myCommandOne[Y]+\\
\myCommandOne[Y]
\end{document} 
\documentclass{article}
% RN. 20/10/2025
% MWE_115_tl_array_case
%=======================
\usepackage{tikz} 

\ExplSyntaxOn
\NewDocumentCommand\myCommandTwo{O{{R}{B}{G}{Y}}}
%  PARAMETERS:
%    #1 tl posing as an array
    {
\group_begin:
    
    \tl_set:Nn \l_rn_mnemColour_Array_tl {#1}
    \tl_set:Nn \l_rn_mnemColourOne_tl {\tl_item:Nn \l_rn_mnemColour_Array_tl{1}}
    tl~variable~set~by~argument:~\l_rn_mnemColourOne_tl \\
    
    \str_case:NnTF {\l_rn_mnemColourOne_tl}
        { 
            {R}{\tl_set:Nn \l_rn_ColourOne_tl {red}}
            {B}{\tl_set:Nn \l_rn_ColourOne_tl {blue}}
            {G}{\tl_set:Nn \l_rn_ColourOne_tl {green}}
            {Y}{\tl_set:Nn \l_rn_ColourOne_tl {yellow}}
        }
        {TRUE\\}
        {FALSE\\}

    \begin{tikzpicture} 
        \draw [fill=\l_rn_ColourOne_tl] (0,0) rectangle (1,1);
%       \draw [fill=red] (0,0) rectangle (1,1);
    \end{tikzpicture}
\group_end:
  }  %  \myCommand  
\ExplSyntaxOff  
    
\begin{document}
1. \verb+\myCommandTwo+\\
\myCommandTwo

2. \verb+\myCommandTwo[B]+\\
\myCommandTwo[B]
\end{document} 
1
  • If you want to access an item using \tl_item:Nn you'll have to expand it fully before passing it on to a \str_case:NnTF call. Use \tl_set:Ne instead of \tl_set:Nn in that assignment. Also, since you're using tl instead of str it'd be more correct to use \str_case:VnTF instead of \str_case:NnTF. Commented Oct 20 at 8:21

2 Answers 2

2

If you do

\tl_set:Nn \l_rn_mnemColourOne_tl {\tl_item:Nn \l_rn_mnemColour_Array_tl{1}}

then the token list will not contain R as you hope, but

\tl_item:Nn \l_rn_mnemColour_Array_tl{1}

which is not the same. You want

\tl_set:Ne \l_rn_mnemColourOne_tl {\tl_item:Nn \l_rn_mnemColour_Array_tl{1}}

but, since you want to compare strings, use the str type.

\documentclass{article}
% RN. 20/10/2025
% MWE_115_tl_array_case
%=======================
\usepackage{tikz} 

\ExplSyntaxOn

\tl_new:N \l_rn_ColourOne_tl
\str_new:N \l_rn_mnemColourOne_str

\NewDocumentCommand\myCommandTwo{O{{R}{B}{G}{Y}}}
%  PARAMETERS:
%    #1 tl posing as an array
 {
   \group_begin:
    
    \str_set:Ne \l_rn_mnemColourOne_str {\tl_item:nn {#1}{1}}
    tl~variable~set~by~argument:~\l_rn_mnemColourOne_str \\
    
    \str_case:NnTF \l_rn_mnemColourOne_str
        { 
            {R}{\tl_set:Nn \l_rn_ColourOne_tl {red}}
            {B}{\tl_set:Nn \l_rn_ColourOne_tl {blue}}
            {G}{\tl_set:Nn \l_rn_ColourOne_tl {green}}
            {Y}{\tl_set:Nn \l_rn_ColourOne_tl {yellow}}
        }
        {TRUE\\}
        {FALSE\\}

    \begin{tikzpicture} 
       \draw [fill=\l_rn_ColourOne_tl] (0,0) rectangle (1,1);
    \end{tikzpicture}
    \group_end:
  }  %  \myCommand  
\ExplSyntaxOff  
    
\begin{document}

1. \verb+\myCommandTwo+\\
\myCommandTwo

2. \verb+\myCommandTwo[B]+\\
\myCommandTwo[B]

\end{document} 

Less assignments, too, are recommended, besides declaring the needed variables. Remember that N type arguments should not be braced.

output

3

The following fixes your code. Your code doesn't set your variable to only R or B as you don't expand the \tl_item:Nn call. If you do that you get correct results. I also changed your "check" what the tl contains by using \tl_to_str:N to print its contents. Also, since you're not passing a string variable to \str_case:NnTF I changed that to \str_case:VnTF which is the correct way to achieve this (if you don't change the variable to a string variable, which would be another correct change). Lastly I changed your "check" what the tl contains by using \tl_to_str:N to print its contents. That way you can actually see the result of your \tl_set:Nn if you change it back:

\documentclass{article}
% RN. 20/10/2025
% MWE_115_tl_array_case
%=======================
\usepackage{tikz}

\ExplSyntaxOn
\NewDocumentCommand\myCommandTwo{O{{R}{B}{G}{Y}}}
%  PARAMETERS:
%    #1 tl posing as an array
  {
    \group_begin:

      \tl_set:Nn \l_rn_mnemColour_Array_tl {#1}
      \tl_set:Ne \l_rn_mnemColourOne_tl { \tl_item:Nn \l_rn_mnemColour_Array_tl { 1 } }
      tl~variable~set~by~argument:~\tl_to_str:N \l_rn_mnemColourOne_tl \\

      \str_case:VnTF \l_rn_mnemColourOne_tl
        {
          { R } { \tl_set:Nn \l_rn_ColourOne_tl { red } }
          { B } { \tl_set:Nn \l_rn_ColourOne_tl { blue } }
          { G } { \tl_set:Nn \l_rn_ColourOne_tl { green } }
          { Y } { \tl_set:Nn \l_rn_ColourOne_tl { yellow } }
        }
        {TRUE\\}
        {FALSE\\}

      \begin{tikzpicture}
          \draw [fill=\l_rn_ColourOne_tl] (0,0) rectangle (1,1);
  %       \draw [fill=red] (0,0) rectangle (1,1);
      \end{tikzpicture}
    \group_end:
  }  %  \myCommand
\ExplSyntaxOff

\begin{document}
1. \verb+\myCommandTwo+\\
\myCommandTwo

2. \verb+\myCommandTwo[B]+\\
\myCommandTwo[B]
\end{document}

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.