5

Practically, I would like to decide if a reference to a label begins 1 or not. The question has some relevance in Hungarian. The idea was to use xstring package:

\documentclass{article}
\usepackage{xstring}
\usepackage{polyglossia}\setdefaultlanguage{hungarian}
\usepackage[hungarian]{hyperref}
\begin{document}
\begin{equation}
   \label{eq:ab}
   a=b
\end{equation}
The reference to the label \texttt{eq:ab},
which is actually \ref{eq:ab},
\IfBeginWith{\ref{eq:ab}}{1}{starts}{does not start} 1.
\end{document}

It seems that the output of \ref{eq:ab} begins with some fancy character, definitely not 1.

I am looking for a solution using lualatex or xelatex. Even if I remove polyglossia, using pdflatex also produces a pdf file which is not the same as I expected. Do not use babel, please. Thank you for your time.

2
  • 2
    This MWE does not use hyperref. Is that also the case for your real document? Hyperref changes the definition and output of \ref, which would make a significant difference for answering this question, therefore it would be good to know if you indeed want a solution without hyperref.
    – Marijn
    Commented Aug 23, 2022 at 12:11
  • @marijn Thank you for the comment. Yes, yes finally I need hyperref. Even more I will use polyglossia. I change the mwe with a more realistic setup.
    – MGy
    Commented Aug 23, 2022 at 12:19

2 Answers 2

12

\ref is unsuitable to retrieve the data, the command is robust and with hyperref is also contains code to create a link. Use the refcount package and its \getrefnumber command:

\documentclass{article}
\usepackage{xstring}
\usepackage{refcount} %loaded by hyperref

\begin{document}
\begin{equation}
   \label{eq:ab}
   a=b
\end{equation}

\begin{equation}
   \label{eq:bb}
   a=b
\end{equation}
The reference to the label \texttt{eq:ab},
which is actually \ref{eq:ab},

\IfBeginWith{\getrefnumber{eq:ab}}{1}{starts}{does not start} 1.

\IfBeginWith{\getrefnumber{eq:bb}}{1}{starts}{does not start} 1.
\end{document}

enter image description here

4
  • An expl3 version would be welcome
    – egreg
    Commented Aug 24, 2022 at 14:08
  • @egreg an expl3 version from what? \getrefnumber? Commented Aug 24, 2022 at 14:12
  • No, in order to avoid xstring
    – egreg
    Commented Aug 24, 2022 at 14:13
  • @egreg I thought about that, but then decided the answer would be clearer if I change only the really relevant part. Commented Aug 24, 2022 at 14:18
1

A “packageless” implementation:

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\refstartswithoneTF}{mmm}
 {% #1 = label, #2 = true text, #3 = false text
  \mgy_ref_starts:nnn { #1 } { #2 } { #3 }
 }

\cs_new:Nn \mgy_ref_number:n
 {
  \cs_if_exist:cTF { r@#1 }
   { \exp_last_unbraced:Nf \use_i:nn { \use:c { r@#1 } } }
   { 0 }
 }

\cs_new:Nn \mgy_ref_starts:nnn
 {
  \str_if_eq:eeTF { \str_head:e { \mgy_ref_number:n { #1 } } } { 1 } { #2 } { #3 }
 }
\cs_generate_variant:Nn \str_head:n { e }

\ExplSyntaxOff


\begin{document}
\begin{equation}
   \label{eq:a}
   a=b
\end{equation}

\begin{equation}
   \label{eq:b}
   a=b
\end{equation}

\setcounter{equation}{9}

\begin{equation}
   \label{eq:c}
   a=b
\end{equation}

The reference to the label \texttt{eq:a},
which is actually \ref{eq:a},
\refstartswithoneTF{eq:a}{starts}{does not start} with 1.

The reference to the label \texttt{eq:b},
which is actually \ref{eq:b},
\refstartswithoneTF{eq:b}{starts}{does not start} with 1.

The reference to the label \texttt{eq:c},
which is actually \ref{eq:c},
\refstartswithoneTF{eq:c}{starts}{does not start} with 1.

\end{document}

enter image description here

What does the incantation

\exp_last_unbraced:Nf \use_i:nn { \use:c { r@#1 } }

do?

The first instruction tell TeX to jump over the next token, that is, \use_i:nn, and to recursively expand the contents of the braced group, leaving the unbraced result in the input stream.

Say that #1 is eq:c for the sake of the example. Then \use:c{r@eq:c} first produces \r@eq:c (a token that cannot be ordinarily written) which is expanded. Such expansion is always of the form

{<ref>}{<pageref>}

in the present case {10}{1}. Now TeX will see

\use_i:nn {10}{1}

and this just leaves 10 in the input stream. This is used in \mgy_ref_starts:nnn. Note that \str_head:e fully expands its argument, so 10 becomes 1, and we eventually get

\str_if_eq:nnTF { 1 } { 1 } {starts} {does not start}

which returns the true branch.

With eq:b we eventually get

\str_if_eq:nnTF { 2 } { 1 } {starts} {does not start}

which returns the false branch.

2
  • Thank you for your time. Could you, please, write a short sentence on the usage of use_i:nn above. (Where is the second argument?, etc.)
    – MGy
    Commented Sep 4, 2022 at 21:33
  • 1
    @MGy The expansion of \r@<label> has always the form {<ref>}{<pageref>}, so \use_i:nn chooses the first group. I added some other explanations.
    – egreg
    Commented Sep 4, 2022 at 22:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .