4

I am trying to write a small package that (as a minor sub-feature) incorporates some usage of hyperref to get internal cross-references. To be precise, I want to do provide functionality like the following:

\mytarget{Äö üß} % prints "Äö üß" in a section-like style

some text goes here

\mylink{Äö üß} % clickable reference to the above

It is important that the user need not specify a label, this should be handled automagically.

This is an minimal (non)-working example of what I'm thinking about so far:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

\makeatletter
\newcounter{@hash@id}
\newcommand\hashstring[1]{%
  \ifcsname #1\endcsname%
  \typeout{#1 already defined}%
  \else
    \expandafter\xdef\csname #1\endcsname{\the@hash@id}%
    \stepcounter{@hash@id}%
    \typeout{defining #1 now}%
    \fi
  \csname #1\endcsname%
}
\makeatother

\newcommand\mytarget[1]{\hypertarget{\hashstring{#1}}{\section{#1}}}
\newcommand\mylink[1]{\hyperlink{\hashstring{#1}}{\textit{#1}}}

\begin{document}
\mytarget{Äö üß}
some text goes here
\newpage
\mylink{Äö üß}
\end{document}

As you can see, I am trying to auto-generate a label simply by enumerating the distinct "targets" in a global counter, the resulting number being the label. This might not be the most clever way to do it, but I hoped it would be simple to implement. (In the final version, I would of course add some package-specific prefix to the label in order to not interfere with user-defined labels).

However, it doesnt work due to a "missing \endcsname" error, which I do not fully understand - but from browsing the documentation, I can guess that it has something to do with the expansion order of the arguments for hyperlink and hypertarget.

Any help and/or suggestions how to achieve this functionality by other means would be appreciated.

1

1 Answer 1

5

There were actually two problems/errors in your approach:

  1. The \hyper… macros expect a fully expandable first parameter. Your \hashstring macro isn’t one. (\typeout? \stepcounter?)

    But your \csname #1\endcsname is one (it only holds the counter).

    My solution: Your \my… macros process #1 outside of the \hyper… macros (i.e. creating \csname #1\endcsname if necessary) and the \hyper… use \csname #1\endcsname directly.

  2. The umlaut problem. How TeX/inputenc deals with characters outside the ASCII range is tricky and I guess those characters are not as expandable as \csname needs them to be.

    My solution: \detokenize the parameter.

Code

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

\makeatletter
\newcounter{@hash@id}
\newcommand\hashstring[1]{%
  \ifcsname\detokenize{#1}\endcsname%
    \typeout{#1 already defined}%
  \else
    \expandafter\xdef\csname\detokenize{#1}\endcsname{\the@hash@id}%
    \stepcounter{@hash@id}%
    \typeout{defining #1 now}%
  \fi
}
\makeatother

\newcommand\mytarget[1]{%
  \hashstring{#1}\hypertarget{\csname\detokenize{#1}\endcsname}{\section{#1}}}
\newcommand\mylink[1]{%
  \hashstring{#1}\hyperlink{\csname\detokenize{#1}\endcsname}{\textit{#1}}}


\begin{document}
\mytarget{Äö üß}
some text goes here
\newpage
\mylink{Äö üß}
\end{document}
1
  • works like a charm!
    – carsten
    Commented Mar 3, 2013 at 10:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .