
Quero definir uma macro que alimente seu conteúdo em uma \foreach
instrução tikz, por exemplo:
\newcommand\Macro[1]{ \foreach \x in {#1} {x=\x.} }
que é então usado como \Macro{1,2,3,4}
. Às vezes, quero fornecer argumentos "vazios", como \Macro{,,,4,5,5}
. Gostaria de poder detectar os argumentos "vazios" e fazer algo diferente nesses casos. Achei que algo como o seguinte funcionaria:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize{\x}\relax Empty!
\else x=\x.
\fi
}
}
mas por alguma razão isso não detecta os argumentos vazios e produz:
Tentei muitas outras coisas, como expandir \x
primeiro, mas ainda não encontrei nada que funcionasse.
Alguém pode ver uma maneira de fazer isso?
[Meu código real está gerando um tikzpicture
ambiente, então eu realmente quero usar \foreach
from `tikz.]
Responder1
Responder2
O problema na macro da pergunta:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize{\x}\relax Empty!
\else x=\x.
\fi
}
}
é que \detokenize
não expande seu argumento e retorna os dois tokens \
e x
. Isso é curado adicionando um \expandafter
:
\detokenize\expandafter{\x}
A macro completa:
\newcommand\Macro[1]{%
\foreach \x in {#1} {
\if\relax\detokenize\expandafter{\x}\relax Empty!
\else x=\x.
\fi
}
}
Responder3
A resposta obrigatória expl3
(depois de observar que \detokenize\expandafter{\x}
seria a solução):
\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}
O item atual no ciclo é denotado por #1
(que deve estar ##1
na definição de \Macro
).