
Quiero definir una macro que introduzca su contenido en una \foreach
declaración tikz, por ejemplo:
\newcommand\Macro[1]{ \foreach \x in {#1} {x=\x.} }
que luego se utiliza como \Macro{1,2,3,4}
. A veces quiero darle argumentos "vacíos", como \Macro{,,,4,5,5}
. Me gustaría poder detectar los argumentos "vacíos" y hacer algo diferente en tales casos. Pensé que algo como lo siguiente funcionaría:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize{\x}\relax Empty!
\else x=\x.
\fi
}
}
pero por alguna razón esto no detecta los argumentos vacíos y en su lugar produce:
He probado muchas otras cosas, como expandir \x
primero, pero todavía tengo que encontrar algo que funcione.
¿Alguien puede ver una manera de hacer esto?
[Mi código real está generando un tikzpicture
entorno, así que realmente quiero usarlo \foreach
desde `tikz.]
Respuesta1
Respuesta2
El problema en la macro de la pregunta:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize{\x}\relax Empty!
\else x=\x.
\fi
}
}
es que \detokenize
no expande su argumento y devuelve los dos tokens \
y x
. Esto se soluciona agregando un \expandafter
:
\detokenize\expandafter{\x}
La macro completa:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize\expandafter{\x}\relax Empty!
\else x=\x.
\fi
}
}
Respuesta3
La respuesta obligatoria expl3
(después de señalar que esa \detokenize\expandafter{\x}
sería la solución):
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\blankTF}{mmm}
{% #1 = text to test, #2 = blank case, #3 = non blank case
\str_if_eq_x:nnTF { #1 } { } { #2 } { #3 }
}
\NewDocumentCommand{\lforeach}{O{,}mm}
{% #1 = delimiter, #2 = list, #3 = code
\seq_set_split:Nnn \l_andrew_foreach_seq { #1 } { #2 }
\seq_map_inline:Nn \l_andrew_foreach_seq { #3 }
}
\ExplSyntaxOff
\newcommand\Macro[1]{%
\lforeach{#1}{%
\blankTF{##1}{Empty!}{$|$##1$|$.}
}
}
\begin{document}
\lforeach[-]{a-b--\texttt{c}}{%
\blankTF{#1}{Empty!}{$|$#1$|$.}
}
\lforeach{, ,,4, 5 ,5}{%
\blankTF{#1}{Empty!}{$|$#1$|$.}
}
\Macro{, ,,4, 5 ,5}
\end{document}
El elemento actual del ciclo se indica con #1
(que debe estar ##1
en la definición de \Macro
).