0

I am looking for an easy way to reference text I have in my document. Something like the following:

\documentclass{article}

\def\labeltext[#1]#2{#2}

\begin{document} Refer forward to (\ref{text:first}) and to (\ref{text:second}).

This is my \labeltext[text:first]{\textbf{First} item}. This is my \labeltext[text:second]{\textit{Second} item}.

Refer back to (\ref{text:first}) and to (\ref{text:second}).

\end{document}

I want the output

Refer forward to (First item) and to (Second item).

This is my First item. This is my Second item.

Refer back to (First item) and to (Second item).

Is there a way to achieve this? I would prefer to use the \ref command if possible (with the hope that other packages like cleveref and hyperref would work nicely with it) instead of creating a new custom referencing command.

EDIT: I found this solution which works for plain text, but not for bold/italic text.

Tohiko
  • 1,789
  • Yes, the text shouldn't contain any \par. zref looks to be what I need, though a bit complicated to figure out for this easy case. – Tohiko Jun 28 '22 at 12:09
  • I just wrote an answer where text can contain \par. I did not yet receive your comment about text not containing \par while writing it. – Ulrich Diez Jun 28 '22 at 12:19

1 Answers1

1

You can use the package zref for implementing your own referencing-commands.

With the following example a few things are reimplemented in terns of \long so that referenecable text-snippets can consist of several small paragraphs as well.

However referenceable text-snippets are written to .aux-file as a single line of .tex-input. Thus the amount of referenceable text is limited by the amount of text which TeX can read from a single line of .tex-input. This in turn is platform-dependent.

\documentclass{article}
\usepackage[user]{zref}

\makeatletter % Implement some zref-infrastructure in terms of \long : @ifdefinable\zref@setcurrentlong{% \protected\long\def\zref@setcurrentlong#1#2{% \zref@propexists{#1}{\expandafter\def\csname Z@C@#1\endcsname{#2}}% }% }% \protected\long\def\zref@newlabel{% @newl@bellong{Z@R}% }% \newcommand@newl@bellong[3]{% \ifx@newl@bel@testdef\expandafter@firstoftwo\else\expandafter@secondoftwo\fi {% \def\reserved@a{#3}% \expandafter\ifx\csname #1@#2\endcsname\reserved@a\else@tempswatrue\fi }{% {% @ifundefined{#1@#2}\relax{% \gdef@multiplelabels{@latex@warning@no@line{There were multiply-defined labels}}% @latex@warning@no@line {Label `#2' multiply defined}% }\global@namedef{#1@#2}{#3}% }% }% }% \def\ZREF@@@newprop#1{% \long\expandafter\gdef\csname Z@E@\ZREF@P\endcsname##1#1##2##3\ZREF@nil{##2}% }% %------------------------------------------------------------------------------------------ \zref@newprop{MyCurrentText}{}% \newcommand\MyTextref[1]{\zref[{MyCurrentText}]{#1}}% \newcommand\MyLabeltext[2]{% \zref@setcurrentlong{MyCurrentText}{#2}% \zref@labelbyprops{#1}{MyCurrentText}% \MyTextref{#1}% }% \makeatother

\begin{document} Refer forward to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

This is my \MyLabeltext{text:first}{\textbf{First} item}. This is my \MyLabeltext{text:second}{\textit{Second} item}.

Refer back to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

\medskip\hrule\medskip

Something with several paragraphs:

\medskip

Refer forward to \MyTextref{text:third}

This is my \MyLabeltext{text:third}{% \textbf{Third} item's first paragraph.\par \textbf{Third} item's second paragraph.\par \textbf{Third} item's third paragraph.% }

Refer back to \MyTextref{text:third}

\end{document}

enter image description here


If textphrases don't contain \par just do:

\documentclass{article}
\usepackage[user]{zref}

\makeatletter \zref@newprop{MyCurrentText}{}% \newcommand\MyTextref[1]{\zref[{MyCurrentText}]{#1}}% \newcommand\MyLabeltext[2]{% \zref@setcurrent{MyCurrentText}{#2}% \zref@labelbyprops{#1}{MyCurrentText}% \MyTextref{#1}% }% \makeatother

\begin{document} Refer forward to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

This is my \MyLabeltext{text:first}{\textbf{First} item}. This is my \MyLabeltext{text:second}{\textit{Second} item}.

Refer back to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

\end{document}

enter image description here


If you wish references to create hyperlinks to where the label was placed, you can try something like this—in order to see the scrolling-behavior after clicking a hyperlink view the resulting .pdf-file at a large zoom-factor:

\documentclass{article}
\usepackage[colorlinks=true]{hyperref}
\usepackage[user]{zref}

\makeatletter % Implement some zref-infrastructure in terms of \long : @ifdefinable\zref@setcurrentlong{% \protected\long\def\zref@setcurrentlong#1#2{% \zref@propexists{#1}{\expandafter\def\csname Z@C@#1\endcsname{#2}}% }% }% \protected\long\def\zref@newlabel{% @newl@bellong{Z@R}% }% \newcommand@newl@bellong[3]{% \ifx@newl@bel@testdef\expandafter@firstoftwo\else\expandafter@secondoftwo\fi {% \def\reserved@a{#3}% \expandafter\ifx\csname #1@#2\endcsname\reserved@a\else@tempswatrue\fi }{% {% @ifundefined{#1@#2}\relax{% \gdef@multiplelabels{@latex@warning@no@line{There were multiply-defined labels}}% @latex@warning@no@line {Label `#2' multiply defined}% }\global@namedef{#1@#2}{#3}% }% }% }% \def\ZREF@@@newprop#1{% \long\expandafter\gdef\csname Z@E@\ZREF@P\endcsname##1#1##2##3\ZREF@nil{##2}% }% %------------------------------------------------------------------------------------------ \zref@newprop{MyCurrentText}{}% \newcommand\MyTextref{@ifstar\MyTextrefnolink\MyTextreflink}% \newcommand\MyTextreflink[1]{\hyperlink{MyText.#1}{\zref[{MyCurrentText}]{#1}}}% \newcommand\MyTextrefnolink[1]{\zref[{MyCurrentText}]{#1}}% \newcommand\MyLabeltext[2]{% \zref@setcurrentlong{MyCurrentText}{#2}% \zref@labelbyprops{#1}{MyCurrentText}% \Hy@raisedlink{\hyper@anchorstart{MyText.#1}\hyper@anchorend}% \MyTextref*{#1}% }% \makeatother

\begin{document}

Links:

Refer forward to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

No links:

Refer forward to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

\vfill

This is my \MyLabeltext{text:first}{\textbf{First} item}.

This is my \MyLabeltext{text:second}{\textit{Second} item}.

\vfill

Links:

Refer back to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

No links:

Refer back to (\MyTextref{text:first}) and to (\MyTextref{text:second}).

\vfill

Something with several paragraphs:

\medskip

Links:

Refer forward to \MyTextref{text:third}

No links:

Refer forward to \MyTextref*{text:third}

\vfill

This is my \MyLabeltext{text:third}{% \textbf{Third} item's first paragraph.\par \textbf{Third} item's second paragraph.\par \textbf{Third} item's third paragraph.% }

\vfill

Links:

Refer back to \MyTextref{text:third}

No links:

Refer back to \MyTextref*{text:third}

\end{document}

enter image description here

Names of destinations within the .pdf-file are of pattern MyText.<referencing-label>.

Ulrich Diez
  • 28,770