我想将的输出\ref
与 LaTeX 中的数字进行比较。我认为这很容易,但在花了很多时间上网后,我仍然不知道答案。
我在这个网站上找到了类似的问题,但我更喜欢不需要包含其他包的解决方案,这样我就可以清楚地看到命令\ref
(和其他一些命令)是如何工作的。
我尝试了很多方法,其中一些我在下面分享,因此我的问题相当长,对此我很抱歉。
首先,我尝试了以下代码(生成的错误消息显示在 % 符号后):
\begin{equation} \label{eq:myeq}
a=b
\end{equation}
\ifnum\ref{eq:myeq}=1 true\else false\fi % error: "Missing number, treated as zero."
\expandafter\ifnum\ref{eq:myeq}=1 true\else false\fi % error: "Missing number, treated as zero."
\edef\blabla{\ref{eq:myeq}} % error: Incomplete \iffalse; all text was ignored after line 42.
\ifnum\blabla=1 true\else false\fi
\expandafter\ifnum\blabla=1 true\else false\fi
当然,\ref{eq:myeq}
给出了预期的结果,即1
。
\ref
然后,我找到了使用该命令的定义latexdef ref
:
\ref:
宏:#1->\expandafter \@setref \csname r@#1\endcsname \@firstoftwo {#1}
进一步检查\@setref
和\firstoftwo
,我得出结论,方程编号(连同页码)存储在名为的控制序列中\r@eq:myeq
。更准确地说,的内容\r@eq:myeq
是{1}{1}
其中第一个数字是方程编号,第二个数字是页码。(的输出是\expandafter{\csname r@eq:myeq\endcsname}
。11
)如果我理解正确的话,为了获得方程编号,我们只需扩展\csname r@eq:myeq\endcsname
两级即可获得{1}{1}
(第一级扩展产生\r@eq:myeq
),然后我们通过选择第一个参数\@firstoftwo
。由于没有简单的方法可以将控制序列仅扩展一级,因此可以通过一种相当迂回(可以说是棘手)的方式完成\ref
。我也可以通过以下代码重现这一点:
\def\sth#1#2{\expandafter #2#1}
\makeatletter
\expandafter\sth\csname r@eq:myeq\endcsname\@firstoftwo \quad
\ifnum1=\expandafter\sth\csname r@eq:myeq\endcsname\@firstoftwo true\else false\fi
\makeatother
结果是1 true
。
到目前为止一切顺利,但仍有几个问题。首先,如果上述代码有效,那么为什么代码会\ifnum1=\ref{eq:myeq}...
失败(见上文)?看起来,这两个“算法”在做同样的事情。
其次,仅当辅助文件(带有 aux 扩展名)包含标签定义时,上述代码才有效。如果不包含(引用未定义),则 LaTeX 会给出以下错误消息:Missing number, treated as zero.
我怎样才能编写即使引用未定义也能正常工作的代码?
感谢所有阅读我上述所有挣扎的人,如果有人能阐明我不清楚的地方,并纠正我的错误并确认我的正确之处,我将不胜感激。不幸的是,(La)TeX 的整个命令语法对我来说仍然非常陌生。
答案1
这正是refcount
是为此而生的,这里不需要重新发明轮子。它提供了\getrefnumber
一个可扩展的宏,您可以在计算中使用:
\documentclass{article}
\usepackage{refcount}
\begin{document}
\begin{equation} \label{eq:myeq}
a=b
\end{equation}
\ifnum\getrefnumber{eq:myeq}=1 true\else false\fi %true
\end{document}
如果您确实不想要任何包,请从refcount
源中提取相关的宏,然后将其添加到您的序言中:
\makeatletter
\newcommand*{\getrefnumber}[1]{%
\romannumeral
\@ifundefined{r@#1}{%
\expandafter\ltx@zero
\rc@default
}{%
\expandafter\expandafter\expandafter\rc@extract@
\expandafter\expandafter\expandafter!%
\csname r@#1\expandafter\endcsname
\expandafter{\rc@default}\@nil
}%
}
\def\rc@default{0}%
\long\def\rc@extract@#1#2#3\@nil{%
\ltx@zero
#2%
}
\chardef\ltx@zero=0
\makeatother
答案2
使用stringstrings
\documentclass{article}
%\usepackage{amsmath}
\usepackage{stringstrings}
\newcounter{myctr}
\newcommand\cmpeq[2]{%
\substring[e]{\ref{#1}}{1}{$-2}%
\setcounter{myctr}{\thestring}%
\ifnum\value{myctr}=#2 T\else F\fi%
}
\begin{document}
\begin{equation} \label{eq:myeq}
a=b
\end{equation}
\cmpeq{eq:myeq}{0}
\cmpeq{eq:myeq}{1}
\cmpeq{eq:myeq}{2}
\begin{equation} \label{eq:myeqA}
c=d
\end{equation}
\cmpeq{eq:myeqA}{0}
\cmpeq{eq:myeqA}{1}
\cmpeq{eq:myeqA}{2}
\end{document}