Eu tenho uma string separada por vírgulas. Com isso quero pegar cada elemento e aplicar um comando. Eu tenho o seguinte, que funciona.
\documentclass[12pt]{article}
\usepackage[trim]{tokenizer}
\newcommand{\cadd}[1]{
\def\Source{#1}
\whiledo{\not\equal{\Source}{}}
{
\GetTokens{TokenOne}{TokenTwo}{\Source}
\textbf{\TokenOne}
\let\Source\TokenTwo
}
}
\begin{document}
\cadd{a,b,c}
\end{document}
Mas eu gostaria de ter o seguinte
\documentclass[12pt]{article}
\usepackage[trim]{tokenizer}
\newcommand{\cadd}[1]{
\whiledo{\not\equal{#1}{}}
{
\GetTokens{TokenOne}{TokenTwo}{#1}
\textbf{\TokenOne}
\let\#1\TokenTwo
}
}
\begin{document}
\cadd{a,b,c}
\end{document}
Mas \let\#1\TokenTwo
está dando um erro. Como posso usar #1
com\let
Responder1
#1
é substituído na primeira chamada da macro. Se macro\cadd
\newcommand{\cadd}[1]{
\whiledo{\not\equal{#1}{}}
{
\GetTokens{TokenOne}{TokenTwo}{#1}
\textbf{\TokenOne}
\let\#1\TokenTwo
}
}
é chamado como \cadd{a,b,c}
, então se torna:
<space>
\whiledo{\not\equal{a,b,c}{}}<space>
{<space>
\GetTokens{TokenOne}{TokenTwo}{a,b,c}<space>
\textbf{\TokenOne}<space>
\let\#1\TokenTwo
}<space>
- A linha
\let\#1\TokenTwo
consiste na\let
atribuição\let\#=1
e\TokenTwo
.#1
só é substituído na expansão macro pelo primeiro argumento. Existem muitos tokens de espaço (causados pelo final da linha):
- O primeiro é ignorado no modo vertical, pois o parágrafo ainda não começou.
- O segundo é ignorado se
\whiledo
ler o corpo do loop como argumento indelimitado. - O terceiro e o quarto estarão presentes na saída.
- O último é removido por causa do final do parágrafo.
Os tokens de espaço no final da linha podem ser evitados usando o caractere de comentário, como visto no exemplo a seguir.
Existem muitos analisadores para listas separadas por vírgulas. Um deles é fornecido por pacote kvsetkeys
:
\documentclass[12pt]{article}
\usepackage{kvsetkeys}
\makeatletter
\newcommand{\cadd}[1]{%
\comma@parse{#1}{\caddentry}%
}
\newcommand*{\caddentry}[1]{%
\textbf{[#1]}%
}
\makeatother
\begin{document}
\cadd{a,b,c}
\cadd{ a , b , c }
\cadd{abc, def, ghi}
\cadd{{ with spaces }, {a b c}}
\end{document}
Responder2
Heiko cobriu bem os detalhes aqui. Para completar, uma solução usando a função de mapeamento de lista de vírgulas LaTeX3\clist_map_inline:nn
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \cadd } { m }
{ \clist_map_inline:nn {#1} { [ \textbf {##1} ] } }
\ExplSyntaxOff
\begin{document}
\cadd{a,b,c}
\cadd{ a , b , c }
\cadd{abc, def, ghi}
\cadd{{ with spaces }, {a b c}}
\end{document}
A ideia subjacente é praticamente a mesma da resposta de Heiko: em vez de ter que fazer o mapeamento manualmente, use um comando pré-construído que trata de encontrar o final da lista.