自动清理辅助文件中收集的(大量)自定义宏

自动清理辅助文件中收集的(大量)自定义宏

我必须在一个源文件中收集来自多位作者的源文件,每个文件都有自己的(许多)\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

相关内容