TransWikia.com

Why is the output of pageref{label} not a string?

TeX - LaTeX Asked on August 28, 2021

I made a small macro to create crossreferences from one footnote to another. The page number of the referenced footnote should not be printed if both footnotes appear on the same page. That should be pretty straightforward, or so I thought:

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}

This works as expected. until we uncomment the line pagenumbering{roman} — then we’ll get a "Missing number" error, which is reasonable as roman numbers are letters and no normal numbers. So, if we really don’t care about the numeric value, it should be better to use string comparison. But if I uncomment the block under "String version" and comment out the block under "Numeric version", it still won’t work! I get no LaTeX error, but the page number is printed. Apparently, the two arguments are different although both footnotes are on the same page. What am I doing wrong?

One Answer

There is a trailing null in output of pageref{fn:test}, so to compare by string, comparepn{pageref{#2}}{thepagenull} would work. (Note this workaround is very fragile.)

Related definitions:

% latex.ltx, line 5553:
defpageref#1{expandafter@setrefcsname r@#1endcsname
                                   @secondoftwo{#1}}

% latex.ltx, line 5543:
def@setref#1#2#3{%
  ifx#1relax
   protectG@refundefinedtrue
   nfss@text{reset@fontbfseries ??}%
   @latex@warning{Reference `#3' on page thepage space
             undefined}%
  else
   expandafter#2#1null % <<< the null is inserted here
  fi}

Alternatively, there are expandable variants of pageref provided by packages which do not contain the trailing null. For example, getpagerefnumber from refcount package and crtcrefpage from crossreftools package. But then you might need to handle category code differences.

Here is a getpagerefnumber attempt:

documentclass{article}
usepackage{xifthen}
usepackage{refcount}

newcommand{footnotecrossref}[2]{%
  #1 footnote~ref{#2}%
  comparepn
    {detokenizeexpandafter{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}

Correct answer by muzimuzhi Z on August 28, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP