Faltam quebras de linha em \author se ele processar a saída de outro comando

Faltam quebras de linha em \author se ele processar a saída de outro comando

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 \printlistdentro do \authorcomando, 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}

Caso de falha

Se eu usar um separador sem quebra de linha, por exemplo ::, o procedimento acima funciona conforme o esperado.

Teste 1 bem-sucedido

Adicionar quebras de linha adicionais \\no \authorcomando também leva ao resultado esperado:

\author{\printlisti[::]{abc,def,ghi}\\123\\456\\789}

Teste 2 bem-sucedido

Parece que a combinação de \printlistquebras de linha \\está causando um problema. Por quê?

Responder1

O argumento para \authorserá digitado em um arquivo tabular. Cada célula forma seu próprio grupo, portanto, a definição interna \itemdelime a definição de \donã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 tabulare não leve a uma mensagem de erro.


Você precisará fazer as definições de \itemdelim(para a não primeira entrada) e \doglobal:

\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” \itemdelimdiretamente para \doe pular \itemdelimusando #1diretamente:

\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 \defdopodemos evitar a definição \doglobal (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 \dolinha 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 \dotambém é “global” porque é definida no nível superior do documento.

Definir \doglobal não deve criar um conflito, pois todos os outros códigos utilizados \dodeveriam tê-lo definido sem assumir qualquer definição. Misturando atribuições/definições globais e locaispoderia ser confuso, porém, usar \savelistpode ser preferível.


Olhando além etoolbox, o pacote do LaTeX3 l3clistfornece \clist_use:Nnque 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}

informação relacionada