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.

1 Answers1

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}

Ulrike Fischer
  • 327,261
  • 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? – Linear Christmas May 10 '21 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. – Ulrike Fischer May 10 '21 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) – Linear Christmas May 10 '21 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? – Linear Christmas May 10 '21 at 19:32
  • (2/2) :) + Extra: May I ask you to point to a specific part of the code which is "convoluted"? Perhaps I can do something then (on my own) to try to improve that part. (Of course, this would be another edit :)). – Linear Christmas May 10 '21 at 19:34
  • If I wanted to create a starred command I would use \NewDocumentCommand and the the s argument specifier. And I would certainly never define a command that I have to patch two lines later with \apptocmd. – Ulrike Fischer May 10 '21 at 19:35
  • Thank you for replying. I did not understand how to use \NewDocumentCommand but I did try to incorporate your second suggestion. If you have the patience, you may glance at the code again (and updated form of questions). I sincerely apologise in advance if the edit made some things worse. I can roll it back; just let me know in a comment. – Linear Christmas May 10 '21 at 20:47
  • well I took a short look at your last code and it doesn't work because you mix up label names and destination names. There are not the same. But I don't want to did into crossreftools correct this, imho using the hyperref commands directly should be quite enough. – Ulrike Fischer May 11 '21 at 13:01
  • Could you be more specific? If my error is that fundamental, howcome \mylink{anchor}{} works and \mylink{anchor}{ullallaa} doesn't? – Linear Christmas May 11 '21 at 13:50
  • 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 https://tex.stackexchange.com/a/553769/2388 – Ulrike Fischer May 11 '21 at 14:04
  • Hooray! Now I at least understand a tiny bit of something! I will try to fix this if I can, and then return :) – Linear Christmas May 11 '21 at 14:29
  • It seems that \crthyperlink{\crtrefanchor{#1}}{#2} instead of \crthyperlink{#1}{#2} fixes the problem! Apparently, I cannot give umlauted characters öäü (or chr. õ) as the second argument of \Mylink{}{} but can give for \mylink{}{}. Thus I conclude this is only because \MakeUpperCase breaks down. Is that correct? – Linear Christmas May 11 '21 at 14:51
  • Package xspace and its \xspace is a good substitute for \@ifnextchar\space{\hspace{-1sp}}{} business, it seems. This answers part 3 (non-compulsory question). – Linear Christmas May 11 '21 at 21:28
  • I never use xspace and its author doesn't recommend it either https://tex.stackexchange.com/a/86620/2388 – Ulrike Fischer May 11 '21 at 22:00
  • It worked for me :). I am not convinced that using it (xspace) is harmful, especially after the updates to the package. My problem was also an additional space (not a missing or forgotten space as in mentioned link). 2. By the way, would you consider commenting on the non-compulsory part, part 2 (changing newcommands into DeclareRobustcommand)? 3. After that, I would propose an edit to your answer (with info from comments and my working effort) so I could award the bounty. Currently, the answer by itself does not answer the OP (including previous versions before any edit).
  • – Linear Christmas May 17 '21 at 18:01
  • I don't need a bounty. Please don't edit my answer and change its sense. I don't want to have to review it. – Ulrike Fischer May 17 '21 at 18:13
  • That's fair enough, thanks for replying. I do not wish to pressure you into anything at all. It simply means (because I will only accept posts that are direct answers to OP (or previous versions)) that 1) I will probably post my own answer; 2) accept that "my" answer; 3) bounty cannot be awarded. I intend no malice; I thought it was polite to let you know before moving forward. Thank you for all your help in comments regardless! – Linear Christmas May 17 '21 at 18:18