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