![Definir uma variável de lista](https://rvso.com/image/309876/Definir%20uma%20vari%C3%A1vel%20de%20lista.png)
Estou usando etoolbox
para processamento de lista, especificamente \forcsvlist
.
Ao passar a lista separada por vírgula diretamente para \forcsvlist
, é possível analisar cada item da lista. Porém, se eu definir a variável da lista em outro lugar, \forcsvlist
não conseguirei distinguir entre cada item da lista e a considerarei como um argumento inteiro.
Por exemplo:
\newcommand\doforme[1]{#1 \\}
\forcsvlist\doforme{a,b,c}
O código acima funciona perfeitamente adicionando nova linha ao final de cada item. Mas o código a seguir não funciona
\newcommand\doforme[1]{#1 \\}
\def\@authors{a,b,c}
\forcsvlist\doforme{\@authors}
Isso me faz pensar que deve haver alguma outra maneira de definir a lista que \forcsvlist
pode ser interpretada.
Responder1
O problema no uso da forma variável era sua expansão anterior, que passaria então a considerar o todo a,b,c
como uma entidade. Por uma entidade, quero dizer o único elemento na lista.
Para resolver este problema, primeiro precisamos usar colchetes duplos aqui. Assim {a,b,c}
se torna {{a,b,c}}
, cuja razão ficará clara ao final desta resposta.
\expandafter
primitivo expande o argumento dado a ele após o próximo. Por exemplo, se houver \def\foo{A}, \def\bar{B}
e \expandafter\foo\bar
, primeiro ele se tornará \foo B
e, eventualmente, se tornará AB
.
Da mesma forma, posso resolver o problema acima na questão assim:
noindent\expandafter\forcsvlist\expandafter\doforme\authors
Se dermos uma olhada na expressão recursiva acima, o primeiro expandafter vai para seu primeiro argumento (\forcsvlist), pula-o por um tempo e tenta expandir o argumento próximo a ele, que neste caso é novamente \expandafter
. Então, o segundo \expandafter
pula novamente \doforme
por um tempo e depois se expande \authors.
\authors
atualmente {{a,b,c}}
. Após a expansão, torna-se {a,b,c}
. Então a expressão final agora se torna
\noident\forcsvlist\doforme{a,b,c}
o que equivale a passar o argumento como no primeiro caso da questão e, portanto, produzir os mesmos resultados.
Responder2
O pacote etoolbox
define um comando especial para lidar com listas internas: \forlistloop
. Essas listas usam um caractere especial como separador interno da lista. Então você tem que usar \listadd
(ou comandos similares - veja oetoolbox
documentação) para adicionar um item a essa lista.
\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand\doforme[1]{#1 \\}
\forcsvlist{\listadd\authors}{a,b,c}
\noindent\forlistloop\doforme{\authors}
\end{document}