# \href is not working inside \xdef

this is my first question here. I've already spent a substantial amount of time searching this before posting it here.

This is my code:

\documentclass[]{article}
\usepackage{hyperref}

\def\test{First -- Void1}

\begin{document}
\xdef\test{\test\ \& Second -- Void2}
\test
\end{document}


which gives the desired output as:

But whenever I change my code as:

\documentclass[]{article}
\usepackage{hyperref}

\def\test{First -- \href{http://www.google.com}{Google}}

\begin{document}
\xdef\test{\test\ \& Second -- \href{http://www.wikibooks.org}{Wikibooks}}
\test
\end{document}


Latex gives an error & no output is produced of course.

I've done this replacement only for Void1, only for Void2 and for both (as in the 2nd snippet); but nothing worked.

Can anybody help me out with this. (If \href doesn't work with \xdef I need an alternative to append urls to an existing string)

Thanks.

Modified Code:

\documentclass[]{article}
\usepackage{multido}
\usepackage{arrayjob}

\newarray\Emails
\readarray{Emails}{abc@example.com&xyz@example.com&pqr@example.com&mno@example.com}
\def\test{}

\begin{document}
\multido{\idx=1+1}{4}{%
\checkEmails(\idx)
\noindent Email-\idx\ \ is \cachedata\\
% Here I want some way to store the emails as href in that global macro '\test'
% Something like --> \xdef\test{\unexpanded\expandafter{\test} \href{mailto:\cachedata}{\cachedata}}
\xdef\test{\unexpanded\expandafter{\test} Normal-Text -- \cachedata, }%
}

\test

\end{document}


## 1 Answer

You don't really want \xdef, because it can do really bad to your macros. In any case you don't really want to expand all the way through, which \xdef does.

There are already several ways for appending tokens to a parameterless macro:

\def\test{First -- Void1}

\makeatletter
\g@addto@macro\test{\ \& Second -- \href{http://www.wikibooks.org}{Wikibooks}}
\makeatother


uses a method defined in the LaTeX kernel.

A slightly different approach, but it's mostly equivalent, is

\def\test{First -- Void1}

\expandafter\gdef\expandafter\test\expandafter{%
\test\ \& Second -- \href{http://www.wikibooks.org}{Wikibooks}}


which is nearer to what you're trying to do. You see that the (global) redefinition of \test happens when \test in the replacement text has been already expanded.

With \usepackage{etoolbox} you have the alternatives

\def\test{First -- Void1}

\appto\test{\ \& Second -- \href{http://www.wikibooks.org}{Wikibooks}}
\gappto\test{\ \& Second -- \href{http://www.wikibooks.org}{Wikibooks}}


With \appto the action is local to the group where this happens, with \gappto the action is global (probably what you want).

For the \multido problem, you need something slightly different.

\documentclass[]{article}
\usepackage{multido}
\usepackage{arrayjobx}
\usepackage{hyperref}

\newarray\Emails
\readarray{Emails}{%
\href{abc@example.com}{abc}&%
\href{xyz@example.com}{xyz}&%
\href{pqr@example.com}{pqr}&%
\href{mno@example.com}{mno}}
\def\test{}

\begin{document}
\multido{\idx=1+1}{4}{%
\checkEmails(\idx)
\noindent Email-\idx\ \ is \cachedata\\
\xdef\test{\unexpanded\expandafter{\test}
Normal-Text --
\unexpanded\expandafter{\cachedata}, }%
}

\test

\end{document}


I've added \href just to show that it works also with it. Use arrayjobx rather than arrayjob that conflicts with some important LaTeX commands.

• your code worked, thanks. But the problem is I'm trying to do this inside a \multido loop, where any of the above tricks didn't work. Here is the screenshot of MWE taken from Gummi. This is what I'm trying to do. – dibyendu Jun 14 '13 at 13:05
• @dibyendu I don't see what \href has to do with the addition. – egreg Jun 14 '13 at 13:41
• Thanks egreg for patiently answering my questions. But now href is not working inside that multido. I've added the exact code that I'm working on at the bottom this time. – dibyendu Jun 14 '13 at 15:39