Me gustaría usar \foreach
para reemplazar el siguiente 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
El objetivo es obtener este resultado: (b0)(b1)(b2)(b3) con una macro
Obtuve el resultado \toks
pero quizás sea posible evitarlo.
\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}
Creo que este código no es agradable. ¿Cuál es la mejor manera de obtener el resultado sin un paquete externo?
Respuesta1
El kernel de LaTeX proporciona \@for
que no funciona en grupos como \foreach
:
\def\tmp{}
\@for\next:=0,1,2,3\do{\edef\tmp{\tmp(b\next)}}
En su código no hay necesidad de \toks
:
\foreach \x in {0,1,2,3}{%
\xdef\tmp{\tmp(b\x)}%
}
funcionaría también.
Sin embargo, si los elementos son "peligrosos" en el sentido de que no sobreviven \edef
(como \textbf
tokens u otros similares), es necesario usar registros de tokens para evitar la expansión completa y su camino es bueno. Es mejor usarlo \toks2
y no \toks1
para asignaciones locales, por lo que deberías hacerlo.
\toksdef\toks@@=2
Respuesta2
Usar una estructura de bucle de paquete grande es realmente excesivo para esto, ya que un solo paquete \def
es suficiente.
\def\x#1{\ifnum\numexpr#1\relax>0 \x{#1-1}\fi(b\the\numexpr#1\relax)}
\typeout{\x{3}}
produce
(b0)(b1)(b2)(b3)
Respuesta3
Si está utilizando pgfkeys
y pgffor
(que el controlador utiliza internamente .list
), simplemente puede utilizar el .list
controlador.
Si solo necesita la (b0)(b…)b(3)
tipografía de secuencia, puede configuraruno .code
clave y usar esa clave con el .list
controlador. (→ do
)
Sin embargo, si quieres tener una macro expandible, esta macro tiene que ser fija (→ doo
, equivalente a \foreach \x in {0,...,3}{\xdef\tmp{\tmp(b\x)}}
) o necesitas más de una tecla (→ dooo
, más flexible).
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}