Я хотел бы использовать \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}
Я думаю, что этот код не очень хорош. Как лучше получить результат без внешнего пакета?
решение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
Использование большой структуры цикла пакетов для этого действительно излишне, так как \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
and pgffor
(который используется внутри обработчика .list
), вы можете просто использовать .list
обработчик.
Если вам нужна только последовательность (b0)(b…)b(3)
набора, вы можете настроитьодин .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}