Как использовать \toks с \foreach

Как использовать \toks с \foreach

Я хотел бы использовать \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

Если вы используете pgfkeysand 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}

Связанный контент