1

I am using some of my LaTeX files in multiple documents. And thus in some documents my references will be defined and in others not. I would like to have a way to make \ref degrade gracefully.

Thus (many years back) I made a package sref.sty that allowed references of the form

as shown \sref[pre=in,fallback=above]{thm.foo}.'

pdflatex formats this to "as shown in Theorem 3.2.1." if a \label{thm.foo} was in the document and to "as shown above." else.

BUT the qualified references "Theorem 3.2.1" is (much better) covered in the cleveref package, and I am thinking of re-implementing sref.sty using cleveref.sty. Or alternatively making an extension to cleveref.sty with the functionality above. Or I may be unaware of an existing implementation of what I need that could be used directly.

Any feedback would be appreciated.

1
0

As a naive approach maybe you can use sref but 'outsource' the non-fallback referencing to cleveref. Something like:

\documentclass{article}
\usepackage[colorlinks]{hyperref}
\usepackage{cleveref}
\usepackage{sref}

\makeatletter
\renewcommand\sref@hlink[5][]{%
  \edef\@fallback{#3}%
  \@ifundefined{r@#2}{%
    \ifx\@fallback\@empty% warn about undefined links and show a substitute
      \protect\G@refundefinedtrue\PackageWarning{sref}{reference #2 undefined}%
      \cref{#2}%
    \else%
      \protect\G@refundefinedtrue\PackageWarning{sref}{using fallback for undefined reference #2}%
      \@fallback%
    \fi
  }{%
    #4 \cref{#2}%
  }%
}%
\makeatother

\begin{document}
\section{A section}
\label{sec}

\begin{figure}
\centering\fbox{A figure}
\caption{with caption}
\label{fig}
\end{figure}

\begin{table}
\fbox{A table}
\centering\caption{with caption}
\label{tab}
\end{table}

As shown \sref[pre=in,fallback=nowhere]{fig}, see also\sref{tab}\sref[pre=in]{sec}.\\
As shown \sref[pre=in,fallback=nowhere]{fig2}, see also\sref{tab}\sref[pre=in]{sec}.

\end{document}

enter image description here

0

You can exploit that \getrefnumber{<label>} expands to a string that can be customized when the <label> does not exist.

The default string is 0, which might be safe enough, but here I use a different one that's unlikely to appear as a cross-reference.

\documentclass{article}
\usepackage{refcount}
\usepackage{cleveref}

\setrefcountdefault{DNE}

\ExplSyntaxOn

\NewDocumentCommand{\sref}{O{}m}
 {
  \group_begin:
  \keys_set:nn { kohlhase/sref } { #1 }
  \str_if_eq:eeTF { \getrefnumber{#2} } { DNE }
   {% no ref
    \l__kohlhase_sref_fallback_tl
   }
   {% call \cref
    \l__kohlhase_sref_pre_tl \c_space_tl \cref{#2}
   }
   \group_end:
 }

\keys_define:nn { kohlhase/sref }
 {
  pre      .tl_set:N = \l__kohlhase_sref_pre_tl,
  fallback .tl_set:N = \l__kohlhase_sref_fallback_tl,
 }

\ExplSyntaxOff

\newtheorem{theorem}{Theorem}

\begin{document}

\begin{theorem}\label{existent}
$1+1=2$
\end{theorem}

As shown \sref[pre=in,fallback=above]{existent}

As shown \sref[pre=in,fallback=above]{nonexistent}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.