Emesta postagem, encontrei um bom truque para lidar com listas. O código abaixo permite imprimir listas com um argumento separador opcional.
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
\def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
\renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}
Porém, se eu usar \printlist
dentro do \author
comando, em combinação com newline \\
, isso não funcionará corretamente: A quebra de linha é definida apenas para o primeiro elemento da lista. Para todos os outros elementos, a quebra de linha é ignorada:
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][;]{%
\def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
\renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\title{Test}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
\begin{document}
\maketitle
\end{document}
Se eu usar um separador sem quebra de linha, por exemplo ::
, o procedimento acima funciona conforme o esperado.
Adicionar quebras de linha adicionais \\
no \author
comando também leva ao resultado esperado:
\author{\printlisti[::]{abc,def,ghi}\\123\\456\\789}
Parece que a combinação de \printlist
quebras de linha \\
está causando um problema. Por quê?
Responder1
O argumento para \author
será digitado em um arquivo tabular
. Cada célula forma seu próprio grupo, portanto, a definição interna \itemdelim
e a definição de \do
não sobreviverão à sua primeira linha.
Essencialmente, é isso que está acontecendo:
\begin{tabular}{c}
\def\itemdelim{test} \\
\itemdelim
\end{tabular}
e o mesmo for \do
, embora na segunda linha tenha a mesma definição que fora de tabular
e não leve a uma mensagem de erro.
Você precisará fazer as definições de \itemdelim
(para a não primeira entrada) e \do
global:
\newcommand{\printlist}[2][;]{%
\def\itemdelim{\gdef\itemdelim{#1}}%
\gdef\do##1{\itemdelim##1}%
\docsvlist{#2}}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
Porém, você pode aplicar o “truque” \itemdelim
diretamente para \do
e pular \itemdelim
usando #1
diretamente:
\newcommand{\printlist}[2][;]{%
\def\do##1{##1\gdef\do####1{#1####1}}%
\docsvlist{#2}}
\author{\printlist[,\\]{abc,def,ghi,jkl}}
Com outra macro auxiliar como \defdo
podemos evitar a definição \do
global (ao custo de outra macro definida para todo o documento):
\newcommand*\defdo[1]{%
\def\do##1{#1\defdo{#1}##1}}%
\newcommand{\printlist}[2][;]{%
\def\do##1{##1\defdo{#1}}%
\docsvlist{#2}}%
\author{\printlist[,\\]{abc,def,ghi,jkl}}
Isso oculta a definição de \do
linha em linha atrás de \\
para que esteja disponível na próxima linha.
Alternativamente, você pode pré-processar a lista e encaminhá-la para \author
:
\newcommand{\savelist}[3][;]{%
\renewcommand*\do[1]{%
\newcommand*#3{##1}%
\renewcommand*\do[1]{%
\appto#3{#1####1}%
}%
}%
\docsvlist{#2}}
\savelist[,\\]{abc,def,ghi,jkl}\authors
\author{\authors}
Neste caso, a definição de \do
também é “global” porque é definida no nível superior do documento.
Definir \do
global não deve criar um conflito, pois todos os outros códigos utilizados \do
deveriam tê-lo definido sem assumir qualquer definição. Misturando atribuições/definições globais e locaispoderia ser confuso, porém, usar \savelist
pode ser preferível.
Olhando além etoolbox
, o pacote do LaTeX3 l3clist
fornece \clist_use:Nn
que não precisa de nenhuma definição para apenas colocar algo ( #1
= ,\\
) entre as entradas de uma lista:
\documentclass{article}
\ExplSyntaxOn
\DeclareDocumentCommand{\printlist}{ O{;} m}{
\clist_set:Nn \l_tmpa_clist {#2}
\clist_use:Nn \l_tmpa_clist {#1}
}
\ExplSyntaxOff
\author{\printlist[,\\]{abc,def,ghi,jkl}}
\title{Test}
\begin{document}
\maketitle
\end{document}