tikz expl3 add tag
samcarter
Inspired by [this question](https://topanswers.xyz/tex?q=2028), I wanted to add pics for the TikZlings. Some code like

```
\documentclass{standalone}
\usepackage{tikzlings}

\tikzset{
  anteater/.pic={\anteater},
  anteater/.search also={,/tikz,/pgf,/thing},
  bear/.pic={\bear},
  bear/.search also={,/tikz,/pgf,/thing},
  cat/.pic={\cat},
  cat/.search also={,/tikz,/pgf,/thing}, 
  % ...
}


\tikzset{
  thing/.search also={,/tikz,/pgf},  
}

\begin{document}
\begin{tikzpicture}[scale=2]
  \draw(0,0) grid(4,4);
  \draw(0,0) --++(0.5,0.5) pic{bear}
             --++(1,1)     pic[cat/body=red,scale=0.5]{cat}
             --++(1,1)     pic[thing/hat=red]{bear};
\end{tikzpicture}
\end{document}  
```

seems to work fine, but having a long hard coded list of tikzlings makes adding new ones error prone. 

So I thought that maybe one could use something similar to

https://github.com/samcarter/tikzlings/blob/main/tikzlings.sty#L68-L90

which would iterate over a list that looks similar to this:

```
\def\tikzling@list{
  anteater/anteaters,
  bear/bears,
  cat/cats%
}
```

I tried to modify the code, but I must do something horrible wrong because it exploded quite spectacularly: 

```
\documentclass{standalone}
\usepackage{tikzlings}

\makeatletter
\ExplSyntaxOn

\cs_new:Npn \tikzlings_iterate_pic:N #1 { 
  \clist_map_function:NN #1 \__tikzlings_pic_items:n 
}

\cs_new:Npn \__tikzlings_pic_items:n #1 {
    \exp_not:N { 
      \__tikzlings_before_slash:w #1 / \s_stop 
    }
  /.pic{ 
    \exp_not:c { 
      \__tikzlings_before_slash:w #1 / \s_stop 
    }
  },
    \exp_not:N { 
      \__tikzlings_before_slash:w #1 / \s_stop 
    }
  /.search also={,/tikz,/pgf,/thing},  
}
\cs_new_eq:NN \tikzling@iterate_pic \tikzlings_iterate_pic:N

\ExplSyntaxOff

\ExpArgsNnx\tikzset{\tikzling@iterate_pic\tikzling@list}
\makeatother

\begin{document}
\begin{tikzpicture}[scale=2]
  \draw(0,0) grid(4,4);
  \draw(0,0) --++(0.5,0.5) pic{bear};
\end{tikzpicture}
\end{document}  
```
Top Answer
Phelype Oleinik
The first error:
```
! Undefined control sequence.
\pgfkeyscurrentkey ->\tikzling@iterate 
                                       _pic\tikzling@list 
l.32 \makeatother
                 
?
```
is because you are mixing `expl3` syntax with 2e syntax in `\tikzset{\tikzling@iterate_pic\tikzling@list}`, but you did `\ExplSyntaxOff` just before that, so `\tikzling@iterate_pic` is seen as `\tikzling@iterate _pic`.  Avoid mixing syntaxes; use `\tikzling@iterate@pic` here.

---

After fixing that, the next error is more cryptic:
```
! Argument of \reserved@a has an extra }.
<inserted text> 
                \par 
l.32 \makeatother
                 
?
```
which shows the error in the `\makeatother` line, but it is actually because of `\ExpArgsNnx`.  It takes three arguments:  an `N` argument (a single token which will not be expanded), an `n` argument (a braced group of tokens which will not be expanded), and an `x` argument (a braced group of tokens that will be `x`-(`\edef`-)expanded).  If you look at the code (newlines added for clarity):
```

\makeatother                            % x
```
you can see that what is actually being `x`-expanded is `\makeatother`, and not `\tikzling@iterate@pic` as you wanted (that's why the error shows in the `\makeatother` line).

Here you want `\ExpArgsNx`, so you can do `\cs_new_eq:NN \ExpArgsNx \exp_args:Nx` or if you don't care about compatibility with older LaTeX you can use the newly added `\ExpArgs{x}` (the first argument is always `N` so it is assumed for `\ExpArgs`):

```
\ExpArgs{x}\tikzset{\tikzling@iterate@pic\tikzling@list}
% or \cs_new_eq:NN \ExpArgsNx \exp_args:Nx then
% \ExpArgsNx\tikzset{\tikzling@iterate@pic\tikzling@list}
```

---

After that, the error is because you wrote:
```
  \exp_not:N { 
      \__tikzlings_before_slash:w #1 / \s_stop 
    }
  /.pic{ 
    \exp_not:c { 
      \__tikzlings_before_slash:w #1 / \s_stop 
    }
  }
```
If you replace `\__tikzlings_before_slash:w #1 / \s_stop` by (say) `anteater`, you get:
```
  \exp_not:N { anteater } /.pic{ \exp_not:c { anteater } }
```
The `\exp_not:N` here is doing nothing because it's acting on `{`, which doesn't expand anyway, so it can go.  Then you have `{anteater}` as a key, but keys don't go in braces, so you can remove those too.  Then you are missing a `=` after `.pic`.

---

Finally you have an easy one:
```
! Package pgfkeys Error: I do not know the key '/tikz/anteater/.searchalso', to
 which you passed ',/tikz,/pgf,/thing', and I am going to ignore it. Perhaps yo
u misspelled it.
```
Remember that spaces matter in PGF keys, but not in `expl3` syntax, so you have to write `.search~also`, and after that the code will work.

---

You can make your code easier to read if you first expand `\__tikzlings_before_slash:w #1 / \s_stop` to get the TikZling name, and pass that to an auxiliary:
```
\cs_new:Npn \__tikzlings_pic_items:n #1
  {
    \exp_args:No \__tikzlings_pic_items_aux:n
      { \__tikzlings_before_slash:w #1 / \s_stop }
  }
\cs_new:Npn \__tikzlings_pic_items_aux:n #1
  {
    #1/.pic = { \exp_not:c {#1} },
    #1/.search~also = {,/tikz,/pgf,/thing},
  }
```

---

Full code:
```
\documentclass{standalone}
\usepackage{tikzlings}

\makeatletter
\ExplSyntaxOn

\cs_new:Npn \tikzlings_iterate_pic:N #1
  { \clist_map_function:NN #1 \__tikzlings_pic_items:n }

\cs_new:Npn \__tikzlings_pic_items:n #1
  {
    \exp_args:No \__tikzlings_pic_items_aux:n
      { \__tikzlings_before_slash:w #1 / \s_stop }
  }
\cs_new:Npn \__tikzlings_pic_items_aux:n #1
  {
    #1/.pic = { \exp_not:c {#1} },
    #1/.search~also = {,/tikz,/pgf,/thing},
  }
\cs_new_eq:NN \tikzling@iterate@pic \tikzlings_iterate_pic:N

\ExplSyntaxOff

\ExpandArgs{x}\tikzset{\tikzling@iterate@pic\tikzling@list}
% or \cs_new_eq:NN \ExpArgsNx \exp_args:Nx then
% \ExpArgsNx\tikzset{\tikzling@iterate@pic\tikzling@list}
\makeatother

\begin{document}
\begin{tikzpicture}[scale=2]
  \draw(0,0) grid(4,4);
  \draw(0,0) --++(0.5,0.5) pic{bear};
\end{tikzpicture}
\end{document}
```

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.