我制作了一个小宏来创建从一个脚注到另一个脚注的交叉引用。如果两个脚注都出现在同一页上,则不应打印引用脚注的页码。这应该很简单,至少我是这么认为的:
\documentclass{article}
\usepackage{xifthen}
\newcommand{\footnotecrossref}[2]{%
#1 footnote~\ref{#2}\comparepn{\pageref{#2}}{\thepage}%
}
% String version
%~ \newcommand{\comparepn}[2]{%
%~ \ifthenelse{\equal{#1}{#2}}
%~ {}
%~ { on page~#1}%
%~ }
%Numeric version
\newcommand{\comparepn}[2]{%
\ifthenelse{#1=#2}
{}
{ on page~#1}%
}
\begin{document}
%~ \pagenumbering{roman}
This is some text.\footnote{\label{fn:test}This is a clever footnote.}
%~ \newpage
This is more text.\footnote{\footnotecrossref{See}{fn:test}}
\end{document}
这按预期工作。直到我们取消注释该行\pagenumbering{roman}
——然后我们会收到“缺少数字”错误,这是合理的,因为罗马数字是字母而不是普通数字。所以,如果我们真的不关心数值,最好使用字符串比较。但是,如果我取消注释“字符串版本”下的块并注释掉“数字版本”下的块,它仍然不起作用!我没有收到 LaTeX 错误,但页码被打印出来了。显然,尽管两个脚注都在同一页上,但这两个参数是不同的。我做错了什么?
答案1
\null
的输出中有尾随\pageref{fn:test}
,因此通过字符串进行比较\comparepn{\pageref{#2}}{\thepage\null}
是可行的。(请注意,此解决方法是非常脆弱。
相关定义:
% latex.ltx, line 5553:
\def\pageref#1{\expandafter\@setref\csname r@#1\endcsname
\@secondoftwo{#1}}
% latex.ltx, line 5543:
\def\@setref#1#2#3{%
\ifx#1\relax
\protect\G@refundefinedtrue
\nfss@text{\reset@font\bfseries ??}%
\@latex@warning{Reference `#3' on page \thepage \space
undefined}%
\else
\expandafter#2#1\null % <<< the \null is inserted here
\fi}
或者,有可扩展的由\pageref
不包含尾随 的包提供的变体\null
。例如,\getpagerefnumber
来自refcount
包和\crtcrefpage
来自crossreftools
包。但您可能需要处理类别代码差异。
以下是一次\getpagerefnumber
尝试:
\documentclass{article}
\usepackage{xifthen}
\usepackage{refcount}
\newcommand{\footnotecrossref}[2]{%
#1 footnote~\ref{#2}%
\comparepn
{\detokenize\expandafter{\expanded{\getpagerefnumber{#2}}}}
{\thepage}%
}
\newcommand{\comparepn}[2]{%
% compare by stings
\ifthenelse{\equal{#1}{#2}}
{}
{ on page~#1}%
}
\begin{document}
\pagenumbering{roman}
This is some text.\footnote{\label{fn:test}This is a clever footnote.}
%~ \newpage
This is more text.\footnote{\footnotecrossref{See}{fn:test}.}
\end{document}