我必须在一个源文件中收集来自多位作者的源文件,每个文件都有自己的(许多)\newcommand
,\newtheorem
等。我想限制每个自定义的范围,本着将宏/新命令范围限制在部分内. egreg 的很好的解决方案对\onlysectioncommands{...,...,...}
我来说有一个缺点,就是这些\newcommand
、\newtheorem
等等每次可能都很多。
因此,如果将每个自定义集放在辅助文件中,比如说
⟨author⟩-customization.tex
,我正在寻找一个聪明的\cleancustomization
宏,使我能够执行以下操作:
...
%
\input{author1-customization}
\input{author1-source}
\cleancustomization{author1-customization}
%
\input{author2-customization}
\input{author2-source}
\cleancustomization{author2-customization}
%
\input{author3-customization}
\input{author3-source}
\cleancustomization{author3-customization}
%
...
换句话说,\cleancustomization
应该给出一个固定的自定义宏列表(\newcommand
、\newtheorem
等等),然后能够解析参数中给出的文件并自动\undef
编译该文件内部定义的所有命令、定理等。
您认为有(LaTeX3
)种方法可以实现这一点吗?
答案1
您可以使用类似这样的方法:
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand*{\saved@ifdefinable}{}
\newcommand*{\saved@rc@ifdefinable}{}
\newcommand{\startcustomization}{
\def\@renewedcommands{}
\def\@newedcommands{}
\let\saved@ifdefinable\@ifdefinable
\let\saved@rc@ifdefinable\@rc@ifdefinable
\newcommand{\@saveforrestore}[1]{%
\ifinlist{##1}{\@renewedcommands}{}{%
\listadd\@renewedcommands##1%
\expandafter\let\csname saved@\string##1\endcsname##1%
}}
\renewcommand{\@ifdefinable}[2]{%
\listadd\@newedcommands##1%
\saved@ifdefinable{##1}{##2}%
}
\let\@@ifdefinable\@ifdefinable
\renewcommand{\@rc@ifdefinable}[2]{%
\@saveforrestore##1%
\saved@rc@ifdefinable{##1}{##2}%
}
}
\newcommand{\cleancustomization}{%
\newcommand{\saved@restore}[1]{\expandafter\let\expandafter##1\csname saved@\string##1\endcsname}%
\forlistloop{\saved@restore}{\@renewedcommands}%
\forlistloop{\undef}{\@newedcommands}%
\let\@ifdefinable\saved@ifdefinable%
\let\@rc@ifdefinable\saved@@ifdefinable%
}
\makeatother
\begin{document}
\startcustomization
\newcommand*{\blipo}{Jill}
\renewcommand\emph[1]{\textbf{#1}}
Hello \blipo{}. \blipo{} is \emph{blonde}
\cleancustomization
Not defined here. \emph{Attempt} to use it--- ``generates'' error.
\end{document}
我定义了两个命令\startcustomization
和,\cleancustomization
因此在两者之间定义的每个命令在之后都将未定义\cleancustomization
。我进行了修补\@ifdefinable
,如在中所述这个 TeX.SE 答案。
编辑:修补后,您可以在使用\@rc@ifdefinable
时保存原始宏(在此代码中,我在检查宏尚未保存后将其保存在中)。这样,就可以在使用时恢复命令。\renewcommand
\saved@\macro
\cleancustomization
答案2
可能为时已晚,但我发现我们可以通过分组来做到这一点
\begingroup
\input{author1-customization}
\input{author1-source}
\endgroup
%
\begingroup
\input{author2-customization}
\input{author2-source}
\endgroup
%
\begingroup
\input{author3-customization}
\input{author3-source}
\endgroup