從循環內的群組內取得 \let 定義

從循環內的群組內取得 \let 定義

我有以下嵌套循環情況:

\begingroup
  \def\do##1{%
    \begingroup
      \def\do####1{%
         \csletcs{somemacro@##1@####1}{someothermacro@##1@####1}}%
      \dolistloop\somelista
    \endgroup}%
  \dolistloop\somelistb
\endgroup

我需要的地方\csletcs定義存在於兩個組之外,但是不是全球。 Martin Scharrer 在對此問題的評論中提出了一個很好的技巧:

如何從群體中獲取價值?

但它在這樣的循環中不起作用,因為將\endgroups 放入內部循環中確實會擾亂下一個循環迭代。有沒有什麼方法(etoolbox 可以)\csletcs從群組中取得定義而不破壞循環的進一步迭代?我假設我需要這些組,否則 do 循環參數無法正確引用。

為了完整起見,這裡是使用 Martin Sharrer 技巧的嘗試解決方案:

\begingroup
  \def\do##1{%
    \begingroup
      \def\do####1{%
         \edef\@z{\endgroup\endgroup\csletcs{somemacro@##1@####1}{someothermacro@##1@####1}}\@z}%
      \dolistloop\somelista
    \endgroup}%
  \dolistloop\somelistb
\endgroup

這適用於第一次嵌套迭代,並且生成的 cs 在群組之外正確定義。不幸的是,這些小組隨後被關閉,接下來的迭代真是一團糟。

答案1

您的範例有點不完整(我必須進行一些更改才能編譯),但答案的要點是將您的定義收集到令牌清單中(全域設定),然後在第二組之後展開清單(導致局部定義)。

\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\makeatletter
\def\somelista{x}
\def\somelistb{y}

\texttt{\meaning\somemacro@y@x}
\def\someothermacro@y@x{a}
\begingroup
  \def\do#1{%
    \begingroup
    \def\do##1{%
      \global\toks1=\expandafter{\the\toks1 \csletcs{somemacro@#1@##1}{someothermacro@#1@##1}}}%
    \dolistloop\somelista
    \endgroup}%
  \dolistloop\somelistb
\endgroup
\the\toks1
\texttt{\meaning\somemacro@y@x}

\makeatother
\end{document}

給出:「未定義的巨集:->a」作為排版輸出。

答案2

您可以使用任何您想要的處理程序來處理列表,\forlistloop而不是使用\dolistloop;因此,您不需要\do在群組中重新定義,以免破壞外部循環定義:只需使用兩個不同的處理程序。

\documentclass{article}
\usepackage{etoolbox}

\newcommand\processlistb[1]{%
  \def\temp{#1}%
  \forlistloop\processlista\somelista
}
\newcommand\processlista[1]{%
  \csletcs{somemacro@\temp @#1}{someothermacro@\temp @#1}%
  \csshow{somemacro@\temp @#1}%
}

\listadd\somelista{a}
\listadd\somelista{b}
\listadd\somelista{c}

\listadd\somelistb{x}
\listadd\somelistb{y}

% Just to add some mock definitions
\csdef{someothermacro@x@a}{xa}
\csdef{someothermacro@x@b}{xb}
\csdef{someothermacro@x@c}{xc}
\csdef{someothermacro@y@a}{ya}
\csdef{someothermacro@y@b}{yb}
\csdef{someothermacro@y@c}{yc}

% Do the iterations
\forlistloop\processlistb\somelistb

\stop

日誌檔案的相關部分:

> \somemacro@x@a=macro:
->xa.
<recently read> \somemacro@x@a

l.29 \forlistloop\processlistb\somelistb

?
> \somemacro@x@b=macro:
->xb.
<recently read> \somemacro@x@b

l.29 \forlistloop\processlistb\somelistb

?
> \somemacro@x@c=macro:
->xc.
<recently read> \somemacro@x@c

l.29 \forlistloop\processlistb\somelistb

?
> \somemacro@y@a=macro:
->ya.
<recently read> \somemacro@y@a

l.29 \forlistloop\processlistb\somelistb

?
> \somemacro@y@b=macro:
->yb.
<recently read> \somemacro@y@b

l.29 \forlistloop\processlistb\somelistb

?
> \somemacro@y@c=macro:
->yc.
<recently read> \somemacro@y@c

l.29 \forlistloop\processlistb\somelistb

?

相關內容