如何测试标签是否已被标记?

如何测试标签是否已被标记?

我有一份包含多个文件的长文档。在某些情况下,我可能希望以不同的顺序包含这些文件。在某些情况下,我可能希望根据\label文档中是否传递了特定内容来调整文本。

我考虑的接口是一个宏\iflabelexists{label}{foo}{bar},它决定是否\label{foo}已经发生。如果是,则宏展开foo;如果不是,则展开bar

我目前正在尝试的方法是修补(展开\newlabel时写入辅助文件的命令),为每个标签提供一个切换开关。然后打开该切换开关。\label\label

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\patchcmd{\@newl@bel}{\global\@namedef{#1@#2}{#3}}{%
  \global\@namedef{#1@#2}{#3}%
  \global\providetoggle{l#1@#2}%
}
{\message{patching of \string\@newl@bel\space succeeded.}}
{\message{patching of \string\@newl@bel\space failed}}

\patchcmd{\label}{\@esphack}{%
  \pastlabel{#1}%
  \@esphack%
}
{\message{patching of \string\label\space succeeded}}
{\message{patching of \string\label\space failed}}

% each label ``foo'' results in a toggle ``lr@foo'' (label reference), 
% and \label{foo} sets \toggletrue{lr@foo}
\newcommand{\pastlabel}[1]{%
  \providetoggle{lr@#1}%
  \toggletrue{lr@#1}%
}

\newcommand{\iftoggleexists}[1]{%
    \ifcsdef{etb@tgl@#1}%
}
\newcommand{\gobble@two}[2]{\relax}

\newcommand{\ifpastlabel}[1]{%
  \iftoggleexists{lr@#1}{%
    \iftoggle{lr@#1}%
  }
  {% toggle does not exist so ambiguous
    \message{Warning: label reference toggle `#1' unknown.  Rerun to get toggles right.}%
    \textbf{??}%
    \gobble@two%
  }%
}
\makeatother

\begin{document}

\section{Bar}
\label{sec:bar}
Section \ref{sec:foo} \ifpastlabel{sec:foo}{has}{has NOT} been covered.

\section{Foo}
\label{sec:foo}
Section \ref{sec:bar} \ifpastlabel{sec:bar}{has}{has NOT} been covered.

\end{document}

如果您重新排列两个文档部分并进行编译(两次),则条件将正确更新。

在我将我的整个文档改编为此之前,我想问一下社区:有没有更聪明的方法来做到这一点,或者我可以使用一个包来代替?

答案1

我看不出\newlabel插入“切换”有什么意义。只需定义一个宏标记\label即可:

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\patchcmd{\label}{\@esphack}{%
  \pastlabel{#1}%
  \@esphack%
}
{\message{patching of \string\label\space succeeded}}
{\message{patching of \string\label\space failed}}

% each label ``foo'' results in a toggle ``lr@foo'' (label reference),
% and \label{foo} sets \toggletrue{lr@foo}
\newcommand{\pastlabel}[1]{%
  \global\expandafter\let\csname lr@#1\endcsname\@empty
}

\newcommand{\ifpastlabel}[1]{%
  \@ifundefined{lr@#1}{%
    \@ifundefined{r@#1}{%
      % toggle does not exist so ambiguous
      \message{Warning: label reference toggle `#1' unknown. %
        Rerun to get toggles right.}%
      \textbf{??}%
      \@gobbletwo
    }\@secondoftwo
  }\@firstoftwo
}
\makeatother

\begin{document}

\section{Bar}
\label{sec:bar}
Section \ref{sec:foo} \ifpastlabel{sec:foo}{has}{has NOT} been covered.

\section{Foo}
\label{sec:foo}
Section \ref{sec:bar} \ifpastlabel{sec:bar}{has}{has NOT} been covered.

\end{document}

相关内容