2009-01-30 127 views
3

我在David Hanak的回答后编辑了这个问题(谢谢btw!)。他在语法方面提供了帮助,但似乎我并没有使用正确的功能开始。有没有办法检查标签是否已经在LaTeX中定义?

基本上我想让编译器忽略某个标签的多个定义,只使用第一个。为了做到这一点,我想我只是做这样的事情:

 
    \makeatletter 
    \newcommand{\mylabel}[1]{ 
     \@ifundefined{#1}{\label{#1}}{X} 
    } 
    \makeatother 

这不工作,虽然,因为第一种选择总是选择(如果标签被定义或没有也没关系)。我认为\ @ifundefined(和建议的\ ifundefined)仅适用于命令,不适用于标签,但我对LaTeX并不十分了解。任何帮助,这将是伟大的!谢谢!

稍后更新: 我将David Hanak的回答标记为我的问题的正确答案,但它不是一个完整的解决方案,但它确实帮助了我。 问题是,我认为但我不是专家,即使David的代码检查是否定义了标签,它也只适用于在之前的运行中定义了标签(即在.aux文件中)的情况。如果在同一运行中定义了两个具有相同名称的\ mylabel,则第二个将仍然被定义。此外,即使您设法解决此问题,它也会使LaTeX使用您按时间顺序定义的第一个标签,而不一定是文本中的第一个标签。 无论如何,下面是我的快速和肮脏的解决方案。它使用计数器似乎立即被定义的事实。

 
\newcommand{\mylabel}[1]{% 
    \@ifundefined{[email protected]#1}{% 
     \newcounter{#1}% 
     \setcounter{#1}{0}% 
    }{}% 
    \ifthenelse{\value{#1} > 0}{}{% 
     \label{#1}% 
     \addtocounter{#1}{1}% 
    }% 
} 

我不知道是否需要到柜台初始化为0,因为它似乎是一个可能的默认设置,但我找不到,如果是这样的话,所以我只是暂时安全。 此外,这使用'ifthen'包,我不知道是必要的。

回答

3

@是LaTeX中的一个特殊字符。为了使您的声明语法正确,你就必须添加两行:

\makeatletter 
\newcommand{\mylabel}[1]{ 
    \@ifundefined{#1}{\label{#1}}{X} 
} 
\makeatother 

第一行变成@成一个正常的信,最后一行逆转其效果。

更新:您可能还想看看“普通”\ifundefined LaTeX macro

更新2

好吧,我做了一些研究,以找出答案真正问题。关键是定义一个标签不会通过该名称创建一个宏;它预先给它一个“r @”。因此,尝试以下操作:

\makeatletter 
\newcommand{\mylabel}[1]{ 
    \@ifundefined{[email protected]#1}{\label{#1}}{X} 
} 
\makeatother 

更多技术详情,请参阅latex.ltx的3863线在您的LaTeX的分布(在那里说:\def\newlabel{\@[email protected] r})。

+0

\ ifundefined未在LaTeX中定义,恐怕。 – 2009-01-31 01:26:47

4

我也不是乳胶专家,但是经过一天的尝试和搜索互联网,以下为我工作。我用了一个虚拟柜台来解决问题。希望这有助于,显然没有多少人正在寻找这个。

\newcommand{\mylabel}[1]{ 
    \ifcsname [email protected]#1\endcsname% 
    \else% 
     \newcounter{#1}\label{#1}% 
    \fi% 
} 
0

作者:Victor Eijkhout,“TeX by Topic”,p。143:

\def\ifUnDefinedCs#1{\expandafter\ifx\csname#1\endcsname\relax} 

这可以用来检查标签是否被定义;如果没有,则打印标签:

\newcommand{\myautoref}[1]{\ifUnDefinedCs{[email protected]#1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi} 
相关问题