9

I am confused as to why the edef below does not get expanded in the link?

The \GetTexFilePath is from Text being output when none should be, which is expandable, and the \GetTexFilePathOld is the older version which is not. Both yield identical results in this case.

I attempted various \expandafter magic but could not figure out the correct combination.

\documentclass{article}

\usepackage{xstring}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn
\NewDocumentCommand{\GetTexFilePath}{m m m}{% Expandable version
    \str_if_eq:xxTF{#1}{SpecialValue}{#1/#2#3}{../#1/#2#3}%
}%
\ExplSyntaxOff

\NewDocumentCommand{\GetTexFilePathOld}{m m m}{%
    \IfStrEq{#1}{SpecialValue}{#1/#2#3}{../#1/#2#3}%
}%


\begin{document}
    \edef\FullExpandedFileName{\GetTexFilePath{foo}{bar}{.tex}}
    \href{run:\FullExpandedFileName}{\GetTexFilePath{foo}{bar}{}}
    %
    \edef\FullExpandedFileName{\GetTexFilePathOld{foo}{bar}{.tex}}
    \href{run:\FullExpandedFileName}{\GetTexFilePathOld{foo}{bar}{}}

    \edef\FullExpandedFileName{\GetTexFilePath{SpecialValue}{bar}{.tex}}
    \href{run:\FullExpandedFileName}{\GetTexFilePath{SpecialValue}{bar}{}}
    %
    \edef\FullExpandedFileName{\GetTexFilePathOld{SpecialValue}{bar}{.tex}}
    \href{run:\FullExpandedFileName}{\GetTexFilePathOld{SpecialValue}{bar}{}}
\end{document} 
Peter Grill
  • 223,288

2 Answers2

5

Commands created with \NewDocumentCommand are robust. You must use \DeclareExpandableDocumentCommand if you want an expandable version (see documentation of xparse). Or you can expand it once with

\expandafter\edef\expandafter\FullExpandedFileName\expandafter{\GetTexFilePath....
Ulrike Fischer
  • 327,261
  • To expand protected commands within an \edef, it is simpler to do \expandafter\empty\yourcommand, so \edef\FullExpandedFileName{\expandafter\empty\GetTeXFilePath...}. – Bruno Le Floch Feb 08 '12 at 23:19
3
\documentclass{article}

\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn
\cs_new:Npn \grill_spval:n #1
  {
   \str_if_eq:nnTF { #1 } { SpecialValue } { #1 } { ../#1 }
  }
\NewDocumentCommand\PathHref{ m m m }
  {
   \exp_args:Nxx \href
     {
      run:\grill_spval:n {#1} / #2 #3
     }
     {
      \grill_spval:n {#1} / #2
     }
  }
\ExplSyntaxOff

Now \PathHref{foo}{bar}{.tex} and \PathHref{SpecialValue}{bar}{.tex} should do what you want.

Notice that \str_if_eq:xxTF is not needed, as long as #1 is a string; of course you might need \str_if_eq:xxTF if the first argument to \PathHref is to be expanded. The needed expansion is that of \grill_spval:n, that should be performed before \href comes into action: we obtain this by \exp_args:Nxx.

egreg
  • 1,121,712