\foreach
次のコードを置き換えるために使用したいと思います:
\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
目的は、マクロでこの結果を得ることです: (b0)(b1)(b2)(b3)
という結果が得られました\toks
が、おそらくこれを回避することは可能です。
\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}
このコードは良くないと思います。extern パッケージを使用せずに結果を取得するより良い方法は何ですか?
答え1
LaTeX カーネルは、\@for
次のようなグループでは動作しないことを提供します\foreach
。
\def\tmp{}
\@for\next:=0,1,2,3\do{\edef\tmp{\tmp(b\next)}}
コードでは以下は必要ありません\toks
:
\foreach \x in {0,1,2,3}{%
\xdef\tmp{\tmp(b\x)}%
}
同様に機能します。
しかし、アイテムが「危険」で、生き残れない場合\edef
(または他の同様のトークンのように)、トークンレジスタを使用することは完全な拡張を避けるために必要であり、あなたの方法は良いです。ローカル割り当てには使用せず、を使用する方が良いので\textbf
、次のようにする必要があります。\toks2
\toks1
\toksdef\toks@@=2
答え2
大きなパッケージループ構造を使用するのは、1つで\def
十分であるため、やりすぎです。
\def\x#1{\ifnum\numexpr#1\relax>0 \x{#1-1}\fi(b\the\numexpr#1\relax)}
\typeout{\x{3}}
生産する
(b0)(b1)(b2)(b3)
答え3
pgfkeys
およびpgffor
(ハンドラーによって内部的に使用される) を使用している場合は.list
、単にハンドラーを使用できます.list
。
シーケンス(b0)(b…)b(3)
タイプセットのみが必要な場合は、次のように設定できます。1つ .code
キーを作成し、そのキーを.list
ハンドラで使用します。(→ do
)
ただし、拡張可能なマクロが必要な場合は、このマクロを固定するか(→ doo
、 と同等\foreach \x in {0,...,3}{\xdef\tmp{\tmp(b\x)}}
)、複数のキー(→ dooo
、より柔軟)が必要になります。
コード
\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}