Como usar \toks com \foreach

Como usar \toks com \foreach

Eu gostaria de usar \foreachpara substituir o próximo código:

\def\x{0}
\edef\y{\x}     
\xdef\z{(b\y)}       

\def\x{1}
\edef\y{\x}
\xdef\w{\z(b\y)}     

\def\x{2}
\edef\y{\x}
\xdef\z{\w(b\y)}  

\def\x{3}
\edef\y{\x}
\xdef\w{\z(b\y)}     
\w 

O objetivo é obter este resultado: (b0)(b1)(b2)(b3) com uma macro

Consegui o resultado com \toksmas talvez seja possível evitar isso.

\documentclass{article}
\usepackage{tikz}

\begin{document}

\makeatletter
\toksdef\toks@=0 %  ?
\toksdef\toks@@=1 % 
\xdef\tmp{}%

\foreach \x in {0,1,2,3}{%
    \toks@\expandafter{\x}%
    \toks@@\expandafter{\tmp}%
    \xdef\tmp{\the\toks@@(b\the\toks@)}%
 }
\makeatother 
\tmp
\end{document} 

Acho que esse código não é legal. Qual é a melhor maneira de obter o resultado sem um pacote externo?

Responder1

O kernel LaTeX fornece \@forque não funciona em grupos como \foreach:

\def\tmp{}
\@for\next:=0,1,2,3\do{\edef\tmp{\tmp(b\next)}}

No seu código não há necessidade de \toks:

\foreach \x in {0,1,2,3}{%
    \xdef\tmp{\tmp(b\x)}%
 }

funcionaria também.

Porém, se os itens forem "perigosos" no sentido de que não sobrevivem \edef(como \textbfou outros tokens semelhantes), o uso de registradores de tokens é necessário para evitar a expansão completa e seu caminho é bom. É melhor usar \toks2e não \toks1para tarefas locais, então você deve fazer

\toksdef\toks@@=2

Responder2

Usar uma grande estrutura de loop de pacotes é realmente um exagero para isso, já que um único \defé suficiente

\def\x#1{\ifnum\numexpr#1\relax>0 \x{#1-1}\fi(b\the\numexpr#1\relax)}

\typeout{\x{3}}

produz

(b0)(b1)(b2)(b3)

Responder3

Se você estiver usando pgfkeyse pgffor(que é usado internamente pelo .listmanipulador), você pode simplesmente usar o .listmanipulador.

Se você precisar apenas da (b0)(b…)b(3)composição de sequência, poderá configurarum .codekey e use essa chave com o .listmanipulador. (→ do)

Porém, se você deseja ter uma macro expansível, esta macro deve ser fixa (→ doo, equivalente a \foreach \x in {0,...,3}{\xdef\tmp{\tmp(b\x)}}) ou você precisa de mais de uma tecla (→ dooo, mais flexível).

Código

\documentclass{article}
\usepackage{pgfkeys,pgffor}
\makeatletter
\pgfkeys{/alain/do/.code=(b#1)}
\pgfkeys{/alain/doo/.code=\edef\tmp{\tmp(b#1)}}
\pgfkeys{/alain/dooo ini/.code=\let\qrr@doo@temp\pgfutil@empty,
         /alain/dooo/.code=\edef\qrr@doo@temp{\qrr@doo@temp(b#1)},
         /alain/dooo set/.code=\let#1\qrr@doo@temp}
\makeatletter
\begin{document}
\pgfkeys{/alain/do/.list={0,...,3}}

\def\tmp{}
\pgfkeys{/alain/doo/.list={0,...,3}}
\tmp

\pgfkeys{/alain/.cd,
         dooo ini,
         dooo/.list={0,...,3},
         dooo set=\myTemp}
\myTemp
\end{document}

informação relacionada