1

I've studied a fair number of cross-referencing (or linking) entries here on the exchange, but I haven't found one that meets my need. Apologies in advance if I have somehow missed the solution.

I want to cross-reference text, not counters. I want the cross-reference link text to automatically pick up any changes in the target declaration. (I specifically do NOT want to have to adjust the link text if I change the target text. The change in the target text should automatically be reflected by any link to it.) Finally, I want to do this for a custom declaration, not a built-in one.

Here is an example custom declaration definition along with an instance of it:

% it is not important how this declaration is defined, 
% only that it have link-able text.
\newcommand{\heading}[2]{
\vspace{#2}
{\begin{center}\Large\textbf{#1}\end{center}}
\vspace{#2}
}

...

\heading{Target Link Text}{6pt} % I want to link to this text

Now I want to cross-reference this declaration instance using some form of label and a cross-referencing command. So something like this:

\heading{Target Link Text}{6pt} \label{foo}

...

The linked text is: \somelinkcommand{foo} % replace somelinkcommand by a real command

And in the generated output, we would see this (without quotes):

"The linked text is: Target Link Text"

So the behavior is somewhat akin to the \nameref option in the hyperref package, only it supports custom/user commands. How can I do this, please? Thanks in advance.

  • I guess you will benefit from working out how your question differs from what is achieved here. – user121799 Aug 11 '18 at 0:12
  • @marmot -- That solution refers to \section, which is a built-in declaration. Built-ins are fairly easy to figure out. Custom declarations such as what I show are my issue. – hilbert Aug 11 '18 at 0:16
3

(This is a major edit to my answer as I overlooked that people might place \label-commands into the first argument of the \heading command instead of placing them behind that command.)

Just a few weeks ago there was a question here on TeX - LaTeX StackExchange "How to prevent reference to enumeration inside new environment?" where I saw the opportunity of elaborating on the ways in which things related to the \label..\ref-mechanism interact in LaTeX 2ε. My answer from back then can be found here: https://tex.stackexchange.com/a/442118/118714

Have your \heading-command using \NR@gettitle for redefining the macro \@currentlabelname to expand to the textual phrase needed for \nameref-references and keep using the \refstepcounter-\label-\nameref-mechanism. (\NR@gettitle does "neutralize" commands like \label which should not occur within data for the \label-command as this would lead to having each reference attempt to also create the already existing label.) In your scenario \refstepcounter is used only for its "side effect" of—besides incrementing a counter—placing an anchor and making the name of that anchor available to the \label-command. You can do \let\@currentlabel=\@currentlabelname for turning the \nameref-referencing-data into the \ref-referencing-data as well.

\documentclass{article}
\usepackage{hyperref}
\usepackage{lipsum}

\makeatletter
\newcounter{heading}
\newcommand\heading[2]{%
  % \refstepcounter is only used for is side-effect of placing an anchor for hyperlinks
  % and making that anchor's name available to \label.
  \vspace{#2}%
  {\begin{center}%
  \refstepcounter{heading}% <- This places an anchor for hyperlinks.
  \NR@gettitle{#1}%<- This extracts disturbing things like \label-commands from the title
                  %   and defines \@currentlabelname which in turn is used by sectioning
                  %   commands for providing to the `\label`-command data for \nameref-
                  %   references.
  \let\@currentlabel=\@currentlabelname %<-This makes the data for \nameref-references also
                                        %  data for \ref-references.
  \Large\textbf{#1}%
  \end{center}}%
  % Do it again outside the scope as users might wish to place the \label-command not
  % into the argument of the \heading-command but behind the headingt command:
  \NR@gettitle{#1}\let\@currentlabel=\@currentlabelname
  \vspace{#2}%
}%
\makeatother

\begin{document}

\nameref{firstheading}

\nameref{secondheading}

\ref{firstheading}

\ref{secondheading}

\section{A section}
\lipsum[1]

\heading{This is the first heading}{6pt}\label{firstheading}

\newpage
\section{A section}
\lipsum[2]

\heading{This is the second heading}{6pt}\label{secondheading}

\end{document}
  • Thank you Ulrich. Your example has the desired behavior and is instructive in other interesting ways. I will test this in some other contexts. – hilbert Aug 12 '18 at 2:26
2

Does the following satisfy your requirements?

\documentclass[12pt]{article}
\usepackage{titlesec} 
\usepackage{hyperref}
\usepackage{lipsum}
\makeatletter % https://tex.stackexchange.com/a/123667/121799
\def\ttl@useclass#1#2{%
  \@ifstar
    {\ttl@labelfalse\@dblarg{#1{#2}}}% {\ttl@labelfalse#1{#2}[]}%
    {\ttl@labeltrue\@dblarg{#1{#2}}}}
\makeatother
\titleformat{\paragraph}[block]{\Large\normalfont\bfseries\filcenter}{\theparagraph}{0em}{}
\newcommand{\heading}[2][5pt]{
\titlespacing*{\paragraph}{0pt}{#1}{#1}
\paragraph{#2}}
\newcommand{\somelinkcommand}[2][]{\nameref{#2}}
\begin{document}

\heading{koala bear\label{koala}}

\lipsum[1-5]

\somelinkcommand{koala}s are cute

\end{document}
  • One of my stated criteria is, the cross-reference link must automatically pick up changes in the target text. If I change \koala{koala bear\label{koala}} to \koala{foobar\label{koala}}, "foobar" doesn't get picked up automatically in the link. So I must change both the \heading text and any link to it. I want to avoid that. With the hyperref package, there are things like \nameref that have some level of automatic detection of target text for built-in declarations like \section and \subsection. But I don't know how to do this for a user/custom declaration as I have. Thanks for responding. – hilbert Aug 11 '18 at 1:06
  • @hilbert That's why I said you would benefit from explaining in detail how that is different from the link.... ;-) why don't you just disclose what you have tried and where you are stuck? – user121799 Aug 11 '18 at 1:09
  • My original comment: "(I specifically do NOT want to have to adjust the link text if I change the target text. The change in the target text should automatically be reflected by any link to it.)" is the sticking point. I know of no package that supports this behavior for custom commands. I have looked at these mechanisms: en.wikibooks.org/wiki/LaTeX/Labels_and_Cross-referencing in addition to prettyref. No joy. Thanks again. – hilbert Aug 11 '18 at 1:47
  • @hilbert Made an update. Note that uppercase text like in NOT is considered shouting on this site. (I understand you didn't mean to shout, just to tell you others may get offended.) – user121799 Aug 11 '18 at 4:09
  • Think if it as a Boolean operator. If I really want to shout, I'll use an exclamation point. – hilbert Aug 12 '18 at 0:15

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.