Есть ли способ проверить, определена ли метка уже в LaTeX?
Вопрос
Я отредактировал вопрос после ответа Дэвида Ханака (кстати, спасибо!).Он помог с синтаксисом, но, похоже, я с самого начала использовал не ту функцию.
По сути, я хочу, чтобы компилятор игнорировал несколько определений определенной метки и просто использовал первое.Чтобы сделать это, я подумал, что просто сделаю что-то вроде этого:
\makeatletter \newcommand{\mylabel}[1]{ \@ifundefined{#1}{\label{#1}}{X} } \makeatother
Однако это не работает, потому что всегда выбирается первый вариант (не имеет значения, определена метка или нет).Я думаю, что \@ifundefined (и предлагаемый \ifundefined) работают только для команд, а не для меток, но я не очень много знаю о LaTeX.Любая помощь в этом была бы замечательной!Спасибо!
Гораздо более позднее обновление:Я отметил ответ Дэвида Ханака как правильный на мой вопрос, но это не полное решение, хотя оно действительно помогло мне.Проблема в том, я думаю, но я не специалист, что, хотя код David проверяет, определена ли метка, он работает только тогда, когда метка была определена в предыдущем запуске (т. Е.находится в файле .aux).Если две метки \mylabels с одинаковым именем определены в одном и том же запуске, вторая все равно будет определена.Кроме того, даже если вам удастся обойти это, это заставит LaTeX использовать первую метку, которую вы определили в хронологическом порядке, и не обязательно первую в тексте.В любом случае, ниже приведено мое быстрое и грязное решение.Он использует тот факт, что счетчики, похоже, определяются сразу.
\newcommand{\mylabel}[1]{% \@ifundefined{c@#1}{% \newcounter{#1}% \setcounter{#1}{0}% }{}% \ifthenelse{\value{#1} > 0}{}{% \label{#1}% \addtocounter{#1}{1}% }% }
Я не уверен, необходимо ли инициализировать счетчик равным 0, поскольку это кажется вероятным значением по умолчанию, но я не смог найти, так ли это, поэтому я просто перестраховываюсь.Кроме того, при этом используется пакет 'ifthen', который, я не уверен, необходим.
Решение
@
это специальный символ в LaTeX.Чтобы сделать ваше объявление синтаксически корректным, вам придется добавить еще две строки:
\makeatletter
\newcommand{\mylabel}[1]{
\@ifundefined{#1}{\label{#1}}{X}
}
\makeatother
Первая строка поворачивается @
в обычном письме последняя строка меняет свое действие на обратное.
Обновить: Возможно, вы также захотите взглянуть на "равнину" \ifundefined
Латексный макрос.
Обновление 2
Хорошо, я провел кое-какие исследования, чтобы найти ответ на реальный проблема.Дело в том, что определение метки не создает макрос с таким именем;к нему добавляется буква "r@".Итак, попробуйте следующее:
\makeatletter
\newcommand{\mylabel}[1]{
\@ifundefined{r@#1}{\label{#1}}{X}
}
\makeatother
Для получения более технических сведений обратитесь к строке 3863 latex.ltx в вашем дистрибутиве LaTeX (где говорится \def\newlabel{\@newl@bel r}
).
Другие советы
Я также не специалист по LaTeX, однако после одного дня попыток и поиска в Интернете у меня сработало следующее.Я использовал фиктивный счетчик, чтобы решить проблему.Надеюсь, это поможет, по-видимому, не многие люди ищут это.
\newcommand{\mylabel}[1]{
\ifcsname c@#1\endcsname%
\else%
\newcounter{#1}\label{#1}%
\fi%
}
Виктор Эйкхаут, "Текст по темам", стр.143:
\def\ifUnDefinedCs#1{\expandafter\ifx\csname#1\endcsname\relax}
Это может быть использовано для проверки того, определена ли метка;если нет, то этикетка будет напечатана:
\newcommand{\myautoref}[1]{\ifUnDefinedCs{r@#1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi}