1

Extending the solution to my previous question I would like to tell LaTeX to run multiple times until the variable is defined. In the demo example, I want section A and C to be identical in output. Any idea?

\documentclass{article}

\usepackage{hyperref} \usepackage{varioref}

\newcounter{mycounter} \makeatletter \newcommand{\defineAndPrintXX}[3]{% \refstepcounter{mycounter}% \begingroup\edef\x{\endgroup\noexpand@namedef{#1@id}{FSR \themycounter}}\x @namedef{#1@definition}{#2}

\hypertarget{#1}{% \subsection{\csname#1@id\endcsname}\label{#1}} % use the definition, i.e. #2
\csname#1@definition\endcsname

#3 }

\newcommand{\referToXX}[1]{ \protect\hyperlink{#1}{\csname#1@id\endcsname} (see section \vref{#1}) \newline \csname#1@definition\endcsname }

\begin{document}

\section{A} Test before definition: \referToXX{test-1}

\section{B} \defineAndPrintXX{test-1}{Definition 1}{Bla bla} \defineAndPrintXX{test-2}{Definition 2}{Bla bla}

\section{C} Test after definition: \referToXX{test-1}

\end{document}

enter image description here

Markus W.
  • 272
  • 2
    that isn't the job of latex, your editor or a makefile or simple shell or batch script can run latex (and makeindex and bibtex and ...) as often as needed to compile the document. – David Carlisle Dec 21 '20 at 22:54
  • 1
    when writing the document though this shouldn't be an issue at all, few people write the entire document in one go without running latex until the end, so the cross references resolve themselves well before the document is finished. – David Carlisle Dec 21 '20 at 22:58
  • There are several tools that are designed for this task (i.e., running LaTeX and related programs multiple times until the output is final), for example latexmk, arara, texi2pdf. – Marijn Dec 22 '20 at 09:12
  • Sad enough the code above does not yield the wanted result even after multiple runs, therefore my question. I tried manually and with latexmk. – Markus W. Dec 22 '20 at 10:42
  • It seems like I have to indicate to LaTeX that something has to be stored and retrieved from a later part in the document. – Markus W. Dec 22 '20 at 10:44
  • 1
    Ah, I misread your question (and David as well I guess). In this case you can use the globalvals package which allows you to reference something before it is defined. – Marijn Dec 22 '20 at 14:53
  • If it is about referencing things other than those that can be referenced via \label/\ref/\pageref from the kernel, the package hyperref (and the package refcount), I suggest the zref-package – Ulrich Diez Dec 29 '20 at 17:37

1 Answers1

2

Using the package zref you can specify your own properties (not just page-number, value of counter that was incremented via \refstepcounter, etc) whose values are to be recorded when placing a (zref-)label for cross-referencing.

As long as each of your XX-thingies both creates another subsection and places a label for cross-referencing you don't need to specify a \hypertarget/\hyperlink as the hyperref-package will automatically create a target/destination for each subsection which—in case of placing a cros-referencing-label—can be accessed for creating a hyperlink via \hyperref[{⟨cross-referencing-label⟩}]{⟨text of the hyperlink⟩}.

\documentclass{article}

\usepackage{zref} \usepackage{varioref} \usepackage{hyperref}

\newcounter{XXcounter}

\makeatletter \zref@newprop{XXid}{}% \zref@newprop{XXdefinition}{}% \newcommand{\defineAndPrintXX}[3]{% \refstepcounter{XXcounter}% \zref@setcurrent{XXid}{FSR\protect~\theXXcounter}% \zref@setcurrent{XXdefinition}{#2}% \par \subsection{FSR~\theXXcounter}% @bsphack \begingroup \let@bsphack\relax \let@esphack\relax \label{#1}% \zref@labelbyprops{#1}{XXid,XXdefinition}% \endgroup @esphack #2\par#3% }% \newcommand{\referToXX}[1]{% \zifrefundefined{#1}{\nfss@text{\reset@font\bfseries??}}{% \hyperref[{#1}]{% \zref@extractdefault{#1}{XXid}{}% } (see section \vref{#1})\newline \zref@extractdefault{#1}{XXdefinition}{}% }% }% \makeatother

\begin{document}

\section{Tests before definitions}

\noindent\verb|\referToXX{test-1}|:\ \referToXX{test-1}

\noindent\verb|\referToXX{test-2}|:\ \referToXX{test-2}

\section{Place of definitions} \defineAndPrintXX{test-1}{Definition 1}{Bla bla} \defineAndPrintXX{test-2}{Definition 2}{Bla bla}

\section{Tests after definitions}

\noindent\verb|\referToXX{test-1}|:\ \referToXX{test-1}

\noindent\verb|\referToXX{test-2}|:\ \referToXX{test-2}

\end{document}

enter image description here

If (for whatever reason) you insist in having another target/destination whose name corresponds to the name of the cross-referencing-label/to the first argument of \defineAndPrintXX, you can handle this via a zref-property as well:

\documentclass{article}

\usepackage{zref} \usepackage{hyperref} \usepackage{varioref}

\newcounter{XXcounter}

\makeatletter \zref@newprop{XXid}{}% \zref@newprop{XXdefinition}{}% \zref@newprop{XXdestination}{}% \newcommand{\defineAndPrintXX}[3]{% \refstepcounter{XXcounter}% \zref@setcurrent{XXid}{FSR\protect~\theXXcounter}% \zref@setcurrent{XXdefinition}{#2}% \zref@setcurrent{XXdestination}{#1}% \par \hypertarget{#1}{\subsection{FSR~\theXXcounter}}% @bsphack \begingroup \let@bsphack\relax \let@esphack\relax \label{#1}% \zref@labelbyprops{#1}{XXid,XXdefinition,XXdestination}% \endgroup @esphack #2\par#3% }% \newcommand{\referToXX}[1]{% \zifrefundefined{#1}{\nfss@text{\reset@font\bfseries??}}{% \hyperlink{\zref@extractdefault{#1}{XXdestination}{}}{% \zref@extractdefault{#1}{XXid}{}% } (see section \vref{#1})\newline \zref@extractdefault{#1}{XXdefinition}{}% }% }% \makeatother

\begin{document}

\section{Tests before definitions}

\noindent\verb|\referToXX{test-1}|:\ \referToXX{test-1}

\noindent\verb|\referToXX{test-2}|:\ \referToXX{test-2}

\section{Place of definitions} \defineAndPrintXX{test-1}{Definition 1}{Bla bla} \defineAndPrintXX{test-2}{Definition 2}{Bla bla}

\section{Tests after definitions}

\noindent\verb|\referToXX{test-1}|:\ \referToXX{test-1}

\noindent\verb|\referToXX{test-2}|:\ \referToXX{test-2}

\end{document}

enter image description here

Ulrich Diez
  • 28,770