Expansión macro dentro de \href

Expansión macro dentro de \href

Quiero hacer un atajo para

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

Puedo usar \StrSubstitutedel xstringpaquete como

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

dentro del segundo argumento de href. Pero lo mismo con

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

en el primer argumento no funcionará.

Creo que entiendo que se trata de un problema con el orden de expansión macro. Pero, ¿cómo puedo hacer que LaTeX se expanda primero \StrSubstituteen una cadena que pueda ser analizada \href?

Aquí hay un ejemplo mínimo de lo que realmente quiero lograr:

\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}

Editar: el patrón de pares no es importante, ya que diferentes países tienen diferentes convenciones de formato numérico. Realmente sólo quiero reemplazar/eliminar espacios (y tal vez otras cosas).

Respuesta1

Expandir la sustitución de cadenasprimeroalmacenándolo en un argumento, que luego puede usar conhyperref'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}

Respuesta2

Los xstringcomandos no se pueden expandir, por lo que, en general, no se pueden usar en línea en otros comandos. Puede utilizar un reemplazo expandible simple aquí.

\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}

Respuesta3

No puedes usarlo \StrSubstituteen esos lugares, porque no produce la cadena después de la sustitución, sino más bien un conjunto bastante complicado de instrucciones para producir esa cadena.

Una solución más complicada que evita la necesidad de ingresar espacios entre pares de dígitos, por lo que funcionará incluso si los olvidas.

\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}

ingrese la descripción de la imagen aquí

información relacionada