# Macro expansion inside \href

I want to make a shortcut for

\href{tel:0123456789}{01\,23\,45\,67\,89}


I can use \StrSubstitute from the xstring package as

\StrSubstitute{01 23 45 67 89}{ }{\,}


inside the second argument to href. But the same thing with

\StrSubstitute{01 23 45 67 89}{ }{}


in the first argument won't work.

I think, I understand that this is an issue with macro expansion order. But how can I get LaTeX to first expand \StrSubstitute into a string that can be parsed by \href?

Here is a minimal example of what I actually want to achieve:

\documentclass{minimal}

\usepackage{xstring}
\usepackage{hyperref}

\newcommand\phone[1]{\href{tel:\StrSubstitute{#1}{ }{}}{\StrSubstitute{#1}{ }{\,}}}

\begin{document}

\href{tel:0123456789}{01\,23\,45\,67\,89}

\href{\StrSubstitute{01 23 45 67 89}{ }{}}{\StrSubstitute{01 23 45 67 89}{ }{\,}}

\phone{01 23 45 67 89}

\end{document}


Edit: The pairwise pattern is not important, since different countries have different number format conventions. I really only want to replace/remove spaces (and maybe other things).

Expand the string substitution first by storing it in an argument, which you can then use with hyperref's \href:

\documentclass{article}

\usepackage{xstring}
\usepackage{hyperref}

\newcommand\phone[1]{%
\StrSubstitute{#1}{ }{}[\firstarg]% Store first substitution in \firstarg
\StrSubstitute{#1}{ }{\,}[\secondarg]% Store second substitution in \secondarg
\href{tel:\firstarg}{\secondarg}% Use stored arguments in \href
}

\begin{document}

\href{tel:0123456789}{01\,23\,45\,67\,89}

\phone{01 23 45 67 89}

\end{document}


The xstring commands are not expandable so can't in general be used inline in other commands. You can use a simple expandable replacement here.

\documentclass{minimal}

\usepackage{hyperref}

\makeatletter
\def\zza#1 {#1\zza}
\def\zzb#1 {#1\,\zzb}
\newcommand\phone[1]{{\def\!##1{}\def\$##1##2{}\href{tel:\zza#1\! }{\zzb#1\$ }}}
\makeatother

\begin{document}

\href{tel:0123456789}{01\,23\,45\,67\,89}

\phone{01 23 45 67 89}

\end{document}


You can't use \StrSubstitute in those places, because it doesn't produce the string after the substitution, but rather a fairly complicated set of instructions to produce that string.

A more complicated solution that avoids the need to input spaces between pairs of digits, so it will work even if you forget them.

\documentclass{article}

\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn

\NewDocumentCommand{\phone}{m}
{
\dlichti_phone:n { #1 }
}

\tl_new:N \l_dlichti_phone_href_tl
\tl_new:N \l_dlichti_phone_print_tl

\cs_new_protected:Nn \dlichti_phone:n
{
\tl_set:Nx \l_dlichti_phone_href_tl { #1 }
% remove all spaces
\tl_replace_all:Nnn \l_dlichti_phone_href_tl { ~ } { }
% save a copy
\tl_set_eq:NN \l_dlichti_phone_print_tl \l_dlichti_phone_href_tl
% insert a thin space between any pair of digits
\regex_replace_all:nnN
{ ([0-9][0-9]) } % two digits followed by another digit
{ \1\c{,} } % the same with \, in between
\l_dlichti_phone_print_tl
% remove the trailing \,
\regex_replace_once:nnN { \c{,} \Z } { } \l_dlichti_phone_print_tl
\dlichti_phone_href:VVV
\c_colon_str
\l_dlichti_phone_href_tl
\l_dlichti_phone_print_tl
}
\cs_new_protected:Nn \dlichti_phone_href:nnn
{
\href{tel#1#2}{#3}
}
\cs_generate_variant:Nn \dlichti_phone_href:nnn { VVV }

\ExplSyntaxOff

\begin{document}

\phone{01 23 45 67 89}

\phone{0123456789}

\end{document}