我从中学到这个帖子如何使用let
原语交换两个命令:
\let\temp\first
\let\first\second
\let\second\temp
\let\temp\undefined
现在,为了不让我的序言充斥这种模式,并为了简化文档的维护,我希望循环执行这个操作以一次执行所有交换,如下所示:
\foreach \lhs/\rhs in {%
phi/varphi,% easier to..
sim/thicksim,% .. tweak and maintain ..
% ... .. with a long list of swaps
} {%
% .. what to input here?
% \expandafter\let\csname\lhs\endcsname\csname\rhs\endcsname
% does not work, because \let seems confined inside the loop scope
}
我如何像这样连续执行所有交换?
为什么没有\xlet
像那样的\xdef
?
答案1
\first/\second
它的工作原理是使用 解析以逗号分隔的宏列表listofitems
。对于特定示例,\swap{\phi/\varphi,\alpha/\beta}
,这会将\phi
放入\swaplist[1,1]
(在将后一个宏展开两次之后),\varphi
放入\swaplist[1,2]
,\alpha
放入\swaplist[2,1]
和\beta
放入\swaplist[2,2]
。
现在,只需要循环遍历第一个索引(用 执行\foreachitem
)即可完成 OP 在顶部显示的操作……一系列\global\let
s。细节是一场扩展游戏,因此\swaplist
宏在执行时会扩展两次\let.
\documentclass{article}
\usepackage{listofitems}
\def\swapA{\let\temp}
\newcommand\swap[1]{%
\setsepchar[-]{,-/}%
\readlist*\swaplist{#1}%
\foreachitem\x\in\swaplist{%
\expandafter\expandafter\expandafter\swapA\swaplist[\xcnt,1]%
\edef\swapB{\noexpand\global\noexpand\let\swaplist[\xcnt,1]}%
\expandafter\expandafter\expandafter\swapB\swaplist[\xcnt,2]%
\edef\swapC{\noexpand\global\noexpand\let\swaplist[\xcnt,2]}%
\expandafter\swapC\temp%
}%
}
\begin{document}
\swap{\phi/\varphi,\alpha/\beta}
\noindent phi: $\phi$\\
varphi: $\varphi$\\
alpha: $\alpha$\\
beta: $\beta$
\end{document}
如果需要替代语法,即省略反斜杠,\swap{phi/varphi,alpha/beta}
那么这就足够了,可以完成相同的任务。不再需要双重扩展,因为\csname
将完全扩展其\swaplist
参数。
\documentclass{article}
\usepackage{listofitems}
\def\swapA{\let\temp}
\newcommand\swap[1]{%
\setsepchar[-]{,-/}%
\readlist*\swaplist{#1}%
\foreachitem\x\in\swaplist{%
\expandafter\swapA\csname\swaplist[\xcnt,1]\endcsname%
\edef\swapB{\noexpand\global\noexpand\let\csname\swaplist[\xcnt,1]\endcsname}%
\expandafter\swapB\csname\swaplist[\xcnt,2]\endcsname%
\edef\swapC{\noexpand\global\noexpand\let\csname\swaplist[\xcnt,2]\endcsname}%
\expandafter\swapC\temp%
}%
}
\begin{document}
\swap{phi/varphi,alpha/beta}
\noindent phi: $\phi$\\
varphi: $\varphi$\\
alpha: $\alpha$\\
beta: $\beta$
\end{document}