2

The goal is to get a pair of commands, \mytarget(*) and \mylink/\Mylink. Specifically, I am interested why "my" solution does NOT work, and how to fix it (if possible).


Syntax

  • \mytarget{<label name>}{<Text to display>}

    \mytarget*{<label name>}{<Text to display>}

  • \mylink{<label name>}{<Text to instead display / could be empty>}

    \mylink{<label name>}{<Text to instead display / could be empty>}

Usage

  1. The command \mytarget is intended as an anchor that can be referenced before/after its usage in document.

    • Unstarred version, \mytarget, is also part of the text. For example, bla bla \mytarget{label name here}{123} uh uh should give bla bla 123 uh uh, and the "123" part could be referenced earlier/later by \mylink/\Mylink.
    • Starred version, \mytarget*, is not part of the text. So bla bla \mytarget*{label name here}{123} uh uh should give bla bla uh uh, and the "123" part could be referenced earlier/later by \mylink/\Mylink. Notice there is no "123" visible here.
  2. The commands \mylink/\Mylink display the links to a corresponding \mytarget.

    • For example, bla bla \mytarget*{label name here}{123} uh uh \mylink{label name here}{} would yield bla bla uh uh 123. The "123" part here is a link to the spot between "bla bla" and "uh uh". (Of course, this example is ridiculous and, of course, in reality the link leads to the line itself).
    • If the second argument for \mylink{}{}/\Mylink{}{} is given, it should override the original second argument of \mytarget(*). For instance, bla bla \mytarget*{label name here}{123} uh uh \mylink{label name here}{654} should give bla bla uh uh 654. The "654" part is again a link.
    • The difference between \mylink/\Mylink is that \mylink is faithful to the second argument of \mytarget(*){}{}. Whereas \Mylink does everything the same way expect \Mylink capitalises the first letter of the second argument. So bla bla \mytarget*{label name here}{turtle} uh uh \mylink{label name here}{} would give bla bla uh uh turtle; whereas bla bla \mytarget*{label name here}{turtle} uh uh \Mylink{label name here}{} yields bla bla uh uh Turtle. Notice that "turtle" is capitalised to "Turtle" in the second case. In both cases, "turtle" and "Turtle" are links.

Effort

Based on helpful comments from Marijn, I was led to this answer and package crossreftools. Here is what I tried:

\documentclass[12pt]{book}

\usepackage{amsmath}
\usepackage{aligned-overset}
\usepackage{commath}
\usepackage[shortlabels]{enumitem}
\usepackage[colorlinks=true, linkcolor=blue, hypertexnames=false]{hyperref}
\usepackage{crossreftools}

\makeatletter
    \newcommand{\mytarget}{\@ifstar{\@mytargetstar}{\@mytargetnostar}}
    \newcommand{\@mytargetstar}[2]{\crtcrossreflabel*{#2}[#1]\@ifnextchar\space{\hspace{-1sp}}{}}
    \newcommand{\@mytargetnostar}[2]{\crtcrossreflabel{#2}[#1]\@ifnextchar\space{\hspace{-1sp}}{}}

    \DeclareRobustCommand{\mylink}[2]{%
        \if\relax\detokenize{#2}\relax
            \crtnameref{#1}
        \else
            \crthyperlink{#1}{#2}
        \fi
        \@ifnextchar\space{\hspace{-1sp}}{}
        }
    
    \DeclareRobustCommand{\Mylink}[2]{%
        \if\relax\detokenize{#2}\relax
            \crtunameref{#1}
        \else
            \crthyperlink{#1}{\MakeUppercase #2}
        \fi
        \@ifnextchar\space{\hspace{-1sp}}{}
        }
\makeatother

\begin{document}

    a b c \mytarget*{anchor}{I0--I1} d e f
    
    \newpage
    Why doesn't the link of \mylink{anchor}{ullallaa} lead anywhere?

\end{document}

Problems with my effort

  1. Why doesn't the link of \mylink{anchor}{ullallaa} lead anywhere?
  2. (Not compulsory) Should I change the remaining three newcommands into \DeclareRobustCommands?
  3. (Not compulsory) Is there a better way to get rid of spaces than putting \@ifnextchar\space{\hspace{-1sp}}{} everywhere?

I am running pdflatex 3.141592653-2.6-1.40.22 (MikTeX 21.3), and every package in my local distrubution was updated on 28/04/2021. Output is identical (in terms of errors, and what link doesn't work without the 3 packages) on Overleaf with default settings.

2
1

At some time your question was readable but with all the edits you are overstressing me.

I guess you are looking for \nameref, so something like this (without all the stars and variants):

\documentclass{article}
\usepackage{hyperref}

\makeatletter
\newcommand\mytarget[2]{\phantomsection\NR@gettitle{#2}\label{#1}#2}
\newcommand\mylink[1]{\nameref{#1}}
\makeatother
\begin{document}
\mytarget{blub}{TARGET}

\newpage
\mylink{blub}

\end{document}
17
  • Thank you for answering. While 1 of the 2 large edits was to reopen the question, I take responsibility for the large number of edits & the length of the quesiton. Apologies. 1. If I were to choose a spec. variant, the one with the \mytarget{blub}{TARGET} invisible would be most helpful. 2. I am still very interested in why my MWE is faulty. May I ask you to take a look? As a first approximation, you may ignore everything about what its aim is to do. Instead, maybe there is something that an experienced user like yourself would immediately say is wrong/unrecommended on a cursory glance? May 10 at 18:12
  • sorry no I don't the time to debug your code. But my "cursory" impression is that it is much to complicated. You want to reference a text in another place and create a link and have a few optional arguments. All this are standard things, and there shouldn't be a need for such convoluted code. May 10 at 18:20
  • That's okay. No worries. Unfortunately, that also means we are worlds apart. I do not even understand why the code is "convoluted". If one wants a \command and \command*, the standard option is to use \@ifstar (which I have). That requires the commands inside to be @-protected (so I define interim commands \@labeltextstarred and \@labeltext) which I turn into \mytarget* and \mytarget, respectively (also standard afaik). (1/2) May 10 at 19:28
  • Next I define \mylink and \Mylink with a possibility of empty argument. So I use the "classical" approach: \if\relax\detokenize{#num}\relax ... \else ... \fi approach. Finally, there are cases where an extra space is added, namely when one does something like bla bla \mylink{}{} bla bla (notice space after \mylink). To account for this possibility, I use (again standard, afaik) \apptocmd{\mylink}{\@ifnextchar\space{\hspace{-1sp}}{}}{}{} which checks if the next character is a \space(and removes). I could join some parts together but would it be easier to understand? May 10 at 19:32
  • 1
    because in the first case you use \crtnameref and in the second \crthyperlink{#1}{#2}, and the second use is wrong. #1 should be destination name not a label name. See also tex.stackexchange.com/a/553769/2388 May 11 at 14:04

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.