Eu gostaria de usar \foreach
para 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 \toks
mas 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 \@for
que 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 \textbf
ou outros tokens semelhantes), o uso de registradores de tokens é necessário para evitar a expansão completa e seu caminho é bom. É melhor usar \toks2
e não \toks1
para 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 pgfkeys
e pgffor
(que é usado internamente pelo .list
manipulador), você pode simplesmente usar o .list
manipulador.
Se você precisar apenas da (b0)(b…)b(3)
composição de sequência, poderá configurarum .code
key e use essa chave com o .list
manipulador. (→ 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}