# How can I enable non-standard characters such as blanks or german Umlaute (ä,ö,ü) for hyperref labels?

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.

-
Though it’s not exactly the same: Please, read Hyperref within hyperref‌​. –  Speravir Mar 3 '13 at 2:25
add comment

## 1 Answer

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}

-
works like a charm! –  carsten Mar 3 '13 at 10:07
add comment