Estoy tratando de crear un pic
que acepte un argumento que codifique qué elementos del archivo pic
deben dibujarse en un color diferente. El problema, sin embargo, parece no ser el pic
; por lo tanto, se me ocurrió el MNWE:
\documentclass{article}
\usepackage{tikz,xstring}
\begin{document}
\tikzset{t/.style={
s/.style={fill=\IfSubStr{##1}{#1}{black}{}}
}}
\begin{tikzpicture}[t={a,b}]
\node[s={a}] {};
\node[s={b}] {};
\node[s={c}] {};
\end{tikzpicture}
\end{document}
aparentemente a tikz no le gusta IfSubStr
el relleno. ¿Cómo puedo hacer que la propiedad de relleno dependa de los parámetros?
Respuesta1
El principal problema es que no se puede tener código como \IfSubStr
en un estilo s
o en una clave de valor fill
.
Sugiero convertirse s
en una clave que procese código y solicite \tikzset
configuración fill
, pero dudo que eso \IfSubStr
sea realmente lo que desea:
\documentclass{article}
\usepackage{tikz,xstring}
\begin{document}
\tikzset{t/.style={
s/.code={\IfSubStr{#1}{##1}{\tikzset{fill=green}}{\tikzset{fill=red}}}
}}
\begin{tikzpicture}[t={a,b}]
\node[s={a,}] at (0,0) {`a,' is in `a,b'};
\node[s={,}] at (0,1) {`,' is in `a,b'};
\node[s={,b}] at (0,2) {`,b' is in `a,b'};
\node[s={a,b}] at (0,3) {`a,b' is in `a,b'};
\node[s={a}] at (0,4) {`a' is in `a,b'};
\node[s={b}] at (0,5) {`b' is in `a,b'};
\node[s={c}] at (0,6) {`c' is not in `a,b'};
\end{tikzpicture}
\end{document}
Paquete de Expl3l3clistaproporciona infraestructura para verificar elementos de listas de comas:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\ExplSyntaxOn
\tikzset{t/.style={
s/.code={\clist_if_in:nnTF{#1}{##1}{\tikzset{fill=green}}{\tikzset{fill=red}}}
}}
\ExplSyntaxOff
\begin{tikzpicture}[t={a,b}]
\node[s={a,}] at (0,0) {`a,' is not an element of the list `a,b'};
\node[s={,}] at (0,1) {`,' is not an element of the list `a,b'};
\node[s={,b}] at (0,2) {`,b' is not an element of the list `a,b'};
\node[s={a,b}] at (0,3) {`a,b' is not an element of the list `a,b'};
\node[s={a}] at (0,4) {`a' is an element of the list `a,b'};
\node[s={b}] at (0,5) {`b' is an element of the list `a,b'};
\node[s={c}] at (0,6) {`c' is not an element of the list `a,b'};
\end{tikzpicture}
\end{document}
También puedes implementar el mapeo de colores de relleno:
\documentclass{article}
\usepackage{tikz}
\ExplSyntaxOn
\tl_new:N \l__mymodule_scratch_tl
\cs_new:Nn \__mymodule_map_kvpair:Nnnn {\tl_put_right:Nn #1 {{#3}{\tikzset{#2#4}}}}
\cs_new:Nn \__mymodule_i_iii_ii:nnn {#1{#3}{#2}}
\cs_new:Nn \__mymodule_tl_braces:nn {#1 {{#2}}}
\cs_generate_variant:Nn \__mymodule_tl_braces:nn { nV }
\tikzset{
t/.code~2~args={
\group_begin:
\tl_set:Nn \l__mymodule_scratch_tl { \tl_clear:N \l__mymodule_scratch_tl }
\clist_map_tokens:nn {#1} {
\tl_put_right:Nn \l__mymodule_scratch_tl {\__mymodule_map_kvpair:Nnnn \l__mymodule_scratch_tl {fill=} }
\__mymodule_i_iii_ii:nnn { \tl_map_tokens:nn } { \__mymodule_tl_braces:nn { \tl_put_right:Nn \l__mymodule_scratch_tl } }
}
\tl_use:N \l__mymodule_scratch_tl
\__mymodule_tl_braces:nV {\tl_set:Nn\l__mymodule_scratch_tl} \l__mymodule_scratch_tl
\tl_put_left:Nn \l__mymodule_scratch_tl { \str_case:nnF {##1} }
\tl_put_right:Nn \l__mymodule_scratch_tl {\tikzset{fill=#2} }
\__mymodule_tl_braces:nV {\tl_set:Nn\l__mymodule_scratch_tl} \l__mymodule_scratch_tl
\tl_put_left:Nn \l__mymodule_scratch_tl { s/.code= }
\__mymodule_tl_braces:nV {\tl_set:Nn\l__mymodule_scratch_tl} \l__mymodule_scratch_tl
\tl_put_left:Nn \l__mymodule_scratch_tl {\group_end: \tikzset }
\tl_use:N \l__mymodule_scratch_tl
},
t={{a}{cyan},{c}{green}}{none},
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\node[s={a,}] at (0,0) {`a,' is not mapped, thus fill=none is used.};
\node[s={,}] at (0,1) {`,' is not mapped, thus fill=none is used.};
\node[s={,b}] at (0,2) {`,b' is not mapped, thus fill=none is used.};
\node[s={a,b}] at (0,3) {`a,b' is not mapped, thus fill=none is used.};
\node[s={a}] at (0,4) {`a' is mapped to fill=cyan.};
\node[s={b}] at (0,5) {`b' is not mapped, thus fill=none is used.};
\node[s={c}] at (0,6) {`c' is mapped to fill=green.};
\end{tikzpicture}
\vfill
\begin{tikzpicture}[t={{a}{green},{b}{blue}}{none}]
\node[s={a,}] at (0,0) {`a,' is not mapped, thus fill=none is used.};
\node[s={,}] at (0,1) {`,' is not mapped, thus fill=none is used.};
\node[s={,b}] at (0,2) {`,b' is not mapped, thus fill=none is used.};
\node[s={a,b}] at (0,3) {`a,b' is not mapped, thus fill=none is used.};
\node[s={a}] at (0,4) {`a' is mapped to fill=green.};
\node[s={b}] at (0,5) {`b' is mapped to fill=blue.};
\node[s={c}] at (0,6) {`c' is not mapped, thus fill=none is used.};
\end{tikzpicture}
\vfill
\begin{tikzpicture}[t={{a}{orange},{b}{green},{c}{cyan}}{red}]
\node[s={a,}] at (0,0) {`a,' is not mapped, thus fill=red is used.};
\node[s={,}] at (0,1) {`,' is not mapped, thus fill=red is used.};
\node[s={,b}] at (0,2) {`,b' is not mapped, thus fill=red is used.};
\node[s={a,b}] at (0,3) {`a,b' is not mapped, thus fill=red is used.};
\node[s={a}] at (0,4) {`a' is mapped to fill=orange.};
\node[s={b}] at (0,5) {`b' is mapped to fill=green.};
\node[s={c}] at (0,6) {`c' is mapped to fill=cyan.};
\end{tikzpicture}
\vfill
\end{document}
Probablemente prefieras las claves de elección:
\documentclass{article}
\usepackage{tikz}
\tikzset{
/utils/exec=\newcommand*\codephrase{.code},
s/.is choice,
s/.unknown/.code={\tikzset{fill=none}},
t/MyForbiddenPath/.unknown/.code={%
\tikzset{s/\ifx\pgfkeyscurrentname\codephrase .unknown\else\pgfkeyscurrentname\fi/.code={\tikzset{fill=#1}}}%
},
t/.code={\tikzset{t/MyForbiddenPath/.cd, #1}}
}
\begin{document}
\begin{tikzpicture}[t={a=orange,b=green,c=cyan,.unknown=red}]
\node[s=a] at (0,0) {`a' is mapped to fill=orange.};
\node[s=b] at (0,1) {`b' is mapped to fill=green.};
\node[s=c] at (0,2) {`c' is mapped to fill=cyan.};
\node[s=d] at (0,3) {`d' is not mapped, thus mapping to default .unknown=red.};
\end{tikzpicture}
\end{document}
Pero las claves de elección se comportan de manera extraña cuando el valor de elección (erróneamente) contiene una coma.
En el ejemplo, la t
clave se utiliza para definir las subclaves de elección para s
.
El problema es que no puede usar esto fuera de un ámbito local como un tikzpicture
entorno y no puede anidar ámbitos locales con llamadas a la t
clave ya que las subclaves de elección ya definidas no se anularán.
Respuesta2
Podrías hacer algo como lo siguiente, pero sería mejor si pudieras explicar lo que realmente intentas hacer, ya que podría haber una mejor solución para esto.
\documentclass[border=10pt]{standalone}
\usepackage{tikz, xstring}
\colorlet{mycolor}{black}
\def\mycolorlist{}
\begin{document}
\tikzset{
t/.code={\def\mycolorlist{#1}},
s/.code={
\IfSubStr{\mycolorlist}{#1}{
\colorlet{mycolor}{black}
}{
\colorlet{mycolor}{red}
}
\tikzset{fill=mycolor}
}
}
\begin{tikzpicture}[t={a,b}]
\node[s={a}] at (0,0) {};
\node[s={b}] at (1,0) {};
\node[s={c}] at (2,0) {};
\end{tikzpicture}
\end{document}