6

I am working on a package with a command which creates a new tikzpicture. I would like to pass a list of tikzpicture arguments to the command. For example, for my single argument command, I might pass scale=1.5,line width=20pt,ultra thick to it. Next, there is a replace all regex call. For this MWE, I have simplified is as replacing spaces with a ~ character.

The problem occurs when I try to use the token list which has been regex modified and put it into the optional argument list of the tikzpicture. For reasons I have yet to understand better, calling \tl_use:N in this setting creates an error where the entire token list is treated as a single pgf/tikz key. For example, scale=1.5,line width=20pt,ultra thick as the argument will generate this error:

! Package pgfkeys Error: I do not know the key 
'/tikz/scale=1.5,line~width=20pt,ultra~thick' and I am 
going to ignore it. Perhaps you misspelled it.

I am assuming this is a catcode problem? Anyway, I'm fairly new to latex3 and may be missing something or approaching this the wrong way. The following is a MWE showing the issue:

\documentclass{article}

\usepackage{expl3}%
\usepackage{l3regex}%
\usepackage{xstring}%
\usepackage{xparse}%
\usepackage{tikz}%

\DeclareDocumentCommand{\mycommand}{ m }
{%
    \tl_new:N \l_tikzvowel_fix_spaces_tl
    \tl_set:Nn \l_tikzvowel_fix_spaces_tl {#1}
    \regex_replace_all:nnN { \s } { \~ } \l_tikzvowel_fix_spaces_tl

    \begin{tikzpicture}[#2]% <--- this compiles fine
    %tikz stuff
    \end{tikzpicture}

    \begin{tikzpicture}[\tl_use:N \l_tikzvowel_fix_spaces_tl]% <--- this causes the error
    %tikz stuff
    \end{tikzpicture}
}

\begin{document}

    \mycommand{scale=1.5,line width=20pt,ultra thick}

\end{document}

Calling \tl_show_analysis:N \l_tikzvowel_fix_spaces_tl on the token list yields:

The token list \l_tikzvowel_fix_spaces_tl contains the tokens:
>  s (the letter s)
>  c (the letter c)
>  a (the letter a)
>  l (the letter l)
>  e (the letter e)
>  = (the character =)
>  1 (the character 1)
>  . (the character .)
>  5 (the character 5)
>  , (the character ,)
>  l (the letter l)
>  i (the letter i)
>  n (the letter n)
>  e (the letter e)
>    (blank space  )
>  w (the letter w)
>  i (the letter i)
>  d (the letter d)
>  t (the letter t)
>  h (the letter h)
>  = (the character =)
>  2 (the character 2)
>  0 (the character 0)
>  p (the letter p)
>  t (the letter t)
>  , (the character ,)
>  u (the letter u)
>  l (the letter l)
>  t (the letter t)
>  r (the letter r)
>  a (the letter a)
>    (blank space  )
>  t (the letter t)
>  h (the letter h)
>  i (the letter i)
>  c (the letter c)
>  k (the letter k).
<recently read> }

What am I doing wrong here? And what is the standard latex3 approach to this type of situation? Although this particular situation refers to tikzpicture environment options, I'm an interested in a solution that could apply to any command or environment's argument(s).

  • 1
    Not related to the issue, but \tl_new:N \l_tikzvowel_fix_spaces_tl should not be inside the document command definition. – Joseph Wright Mar 12 '17 at 16:17
  • @joseph-wright I'm sure this has been discussed elsewhere, so I'll just ask if you can point more towards an answer/discussion about whether there is "more local" latex3 method for something only used within a single document command. If not, let me know and I can create a new question. – whatisit Mar 12 '17 at 21:56
  • The team did explore (and decide against) 'local' allocators: scope in TeX is group-based not command-based so overall it 'felt' better not to give the misleading ideas that local allocation would have anything to do with commands. For that reason the recommended approach is to allocate at the top level even if setting within a group. – Joseph Wright Mar 12 '17 at 22:05
  • @joseph-wright I think there is discussion about this at https://tex.stackexchange.com/questions/14405/latex3-how-to-define-a-variable-locally regarding scope and when to create variables. Guess I'll just confirm that there is no proper way to define this variable within the document command? Basically, all variables should be created out preceding the document command definition. If I understand this incorrectly, please point me to more details or let me know to ask it as a new question. – whatisit Mar 12 '17 at 22:06
  • whoops, your response beat me to the follow-up. Good to know. I'll write my document commands accordingly. Thanks for the confirmation. – whatisit Mar 12 '17 at 22:07
6

This is the 'usual' issue with saving tokens for a keyval argument: keyval methods work very hard not to expand their arguments, so your setting are not seen. You therefore need to force expansion, for example

\use:x { \exp_not:N \begin{tikzpicture}
           [\exp_not:V \l_tikzvowel_fix_spaces_tl] }

(\begin is not engine robust so we need to avoid premature expansion).

  • Yes, this works. Thank you for the help. I wasn't aware that variants with the f option still don't help here and you need to force expansion in a different way. – whatisit Mar 12 '17 at 21:47

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.