Есть ли способ проверить, определена ли уже метка в LaTeX? - PullRequest
4 голосов
/ 30 января 2009

Я отредактировал вопрос после ответа Дэвида Ханака (спасибо, кстати!). Он помог с синтаксисом, но похоже, что я не использовал правильную функцию для начала.

По сути, я хочу, чтобы компилятор игнорировал несколько определений определенной метки и просто использовал первую. Для этого я подумал, что просто сделаю что-то вроде этого:

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

Это не работает, потому что всегда выбирается первый вариант (не имеет значения, определена метка или нет). Я думаю, что \ @ifundefined (и предлагаемый \ ifundefined) работают только для команд, а не для меток, но я не очень много знаю о LaTeX. Любая помощь с этим была бы великолепна! Спасибо!

Намного позже обновление: Я отметил ответ Дэвида Ханака как правильный ответ на мой вопрос, но это не полное решение, хотя оно действительно помогло мне. Проблема, я думаю, но я не специалист, в том, что, хотя код Дэвида проверяет, определена ли метка, он работает только тогда, когда метка была определена в предыдущем запуске (то есть в файле .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, который, я не уверен, необходим.

Ответы [ 3 ]

4 голосов
/ 10 декабря 2012

Я также не эксперт LaTeX, однако после одного дня попыток поиска в интернете у меня сработало следующее. Я использовал фиктивный счетчик, чтобы решить проблему. Надеюсь, это поможет, видимо, не многие ищут это.

\newcommand{\mylabel}[1]{
    \ifcsname c@#1\endcsname%
    \else%
        \newcounter{#1}\label{#1}%
    \fi%
}
4 голосов
/ 30 января 2009

@ - это специальный символ в LaTeX. Чтобы сделать ваше объявление синтаксически правильным, вам нужно добавить еще две строки:

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

Первая строка превращает @ в обычную букву, последняя строка меняет свой эффект.

Обновление: Возможно, вы захотите взглянуть на "простой" \ifundefined макрос LaTeX .

Обновление 2

Хорошо, я провел некоторое исследование, чтобы выяснить ответ на проблему real . Дело в том, что определение метки не создает макрос с таким именем; к нему добавляется "r @". Поэтому попробуйте следующее:

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

Для получения дополнительной технической информации обратитесь к строке 3863 файла latex.ltx в вашем дистрибутиве LaTeX (где написано \def\newlabel{\@newl@bel r}).

0 голосов
/ 07 октября 2015

Виктор Эйххоут, «TeX by Topic», с.143:

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

Это можно использовать для проверки, определена ли метка; если нет, этикетка печатается:

\newcommand{\myautoref}[1]{\ifUnDefinedCs{r@#1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi} 
...