报告 \newcommand 定义的所有重复的宏名称

报告 \newcommand 定义的所有重复的宏名称

我有一个 shell 脚本,它在外部文件中生成大量宏列表,其形式如下:

\expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 1}
\expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX a}
\expandafter\newcommand\csname XX Name XYZ\endcsname{some text XYZ}
...

宏的名称基于各个目录中的文件名。由于文件位于不同的目录中,因此它们可以具有相同的名称,在这种情况下 TeX 会出现问题并停止在第一个重复的宏上。

我想通过重新定义来检测重复项并提供这些重复项的完整列表\newcommand。 但是,我的尝试存在一些问题:

  1. 它不起作用——所有内容都被报告为重复。
  2. 的定义文本\newcommand打印在文档中。希望它不出现在那里,因为它没有任何价值。我可以接受输出中的这段文本,只是不明白它是怎么到达那里的。

代码:

\documentclass{article}
\usepackage{etoolbox}

%\usepackage{filecontents}% <--- Commented so that foo.tex is not accidentally overwritten.
\begin{filecontents*}{foo.tex}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 1}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX a}
    \expandafter\newcommand\csname XX Name XYZ\endcsname{some text XYZ}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 2}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX b}
\end{filecontents*}

\newcounter{ErrorCount}

\let\OldNewcommand\newcommand

\begin{document}
    \renewcommand*{\newcommand}[2][]{%
        \ifdefined#2
            \stepcounter{ErrorCount}%
            \typeout{**** Error: "#1" is a duplicate.}%
            \par Error: ``#1" is a duplicate
        \else
            \OldNewcommand[#1]{#2}%
        \fi
%       \ifcsname{#2}{%
%           \stepcounter{ErrorCount}%
%           \typeout{**** Error: "#1" is a duplicate.}%
%           \par Error: ``#1" is a duplicate
%       }{%
%           \OldNewcommand[#1]{#2}%
%       }%
    }%
    % -------------
    \input{foo.tex}
    \let\newcommand\OldNewcommand
    % -------------
    \ifnum\arabic{ErrorCount}=0
        \typeout{**** Error: 0.}%
        \par All good. No errors.
    \else
        \typeout{**** Error: Duplicates found.}%
        \par Error: \arabic{ErrorCount} duplicates found.
    \fi
\end{document} 

答案1

latex 已经在进行检查,因此只需将错误更改为警告并增加:

\documentclass{article}


%\usepackage{filecontents}% <--- Commented so that foo.tex is not accidentally overwritten.
\begin{filecontents*}{foo.tex}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 1}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX a}
    \expandafter\newcommand\csname XX Name XYZ\endcsname{some text XYZ}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 2}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX b}
\end{filecontents*}

\makeatletter
\gdef\@notdefinable{%
  \stepcounter{ErrorCount}%
  \@latex@warning@no@line{%
   Command \@backslashchar\reserved@a\space
   already defined.\MessageBreak
   Or name \@backslashchar\@qend... illegal,
   see p.192 of the manual}}

%\makeatother
\newcounter{ErrorCount}

\begin{document}
    % -------------
    \input{foo.tex}
    \let\newcommand\OldNewcommand
    % -------------
    \ifnum\value{ErrorCount}=0
        \typeout{**** Error: 0.}%
        \par All good. No errors.
    \else
        \typeout{**** Error: Duplicates found.}%
        \par Error: \theErrorCount{} duplicates found.
    \fi


\end{document} 

答案2

我使用了\@namedef而不是。让生活更轻松。如果您确实需要 at 符号,\expandafter\csname...也可以设置:\let\namedef\@namedef

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{foo.tex}
    \@namedef{XX Name ABC}{some text ABC 1}
    \@namedef{XX Name XYX}{some text XYX a}
    \@namedef{XX Name XYZ}{some text XYZ}
    \@namedef{XX Name ABC}{some text ABC 2}
    \@namedef{XX Name XYX}{some text XYX b}
\end{filecontents*}

\newcounter{ErrorCount}
\makeatletter
\let\Old@namedef\@namedef
\def\@namedef#1#2{%
        \if\@nameuse{#1}\relax
          \Old@namedef{#1}{#2}
        \else
          \stepcounter{ErrorCount}%
            \typeout{**** Error: "#1" is a duplicate.}%
            \par Error: ``#1" is a duplicate
        \fi
}
\makeatother
\begin{document}
\makeatletter
\input{foo.tex}
\makeatother
    \ifnum\arabic{ErrorCount}=0
        \typeout{**** Error: 0.}%
        \par All good. No errors.
    \else
        \typeout{**** Error: Duplicates found.}%
        \par Error: \arabic{ErrorCount} duplicates found.
    \fi
\end{document} 

在此处输入图片描述

答案3

好吧,你可以从内核借用一些代码,其主要思想是将命令名称捕获为字符串。

示例输出

\documentclass{article}
\usepackage{etoolbox}

\usepackage{filecontents}
\begin{filecontents*}{foo.tex}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 1}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX a}
    \expandafter\newcommand\csname XX Name XYZ\endcsname{some text XYZ}
    \expandafter\newcommand\csname XX Name ABC\endcsname{some text ABC 2}
    \expandafter\newcommand\csname XX Name XYX\endcsname{some text XYX b}
\end{filecontents*}

\newcounter{ErrorCount}

\let\OldNewcommand\newcommand

\begin{document}
\makeatletter
\renewcommand*{\newcommand}[2]{%
  \begingroup \escapechar\m@ne\xdef\@mytempa{{\string#1}}\endgroup
  \expandafter\@ifundefined\@mytempa
  {OK \OldNewcommand{#1}{#2}%
  }{\stepcounter{ErrorCount}%
    \typeout{**** Error: "\string#1" is a duplicate.}%
    \par Error: ``\string#1" is a duplicate
  }%
}%
\makeatother
    % -------------
    \input{foo.tex}
    \let\newcommand\OldNewcommand
    % -------------
    \ifnum\arabic{ErrorCount}=0
        \typeout{**** Error: 0.}%
        \par All good. No errors.
    \else
        \typeout{**** Error: Duplicates found.}%
        \par Error: \arabic{ErrorCount} duplicates found.
    \fi
\end{document} 

我不确定你的可选参数的作用是什么。

相关内容