3

I have run into what looks like a macro expansion issue. Consider the following example:

\documentclass{article}
\usepackage{hyperref}
\usepackage{biblatex}

\begin{filecontents}{expprob.bib}
@online{example,
  shorthand    = {foo-bar},
  url          = {http://example.com}
}
\end{filecontents}

\bibliography{expprob}

\newcommand{\demofield}[2]{foo-#1}
\newcommand{\demourl}[1]{\url{http://example.com/link/\demofield{#1}{shorthand}}}

\newcommand{\biburl}[1]{\url{http://example.com/link/\citefield{#1}{shorthand}}}

\begin{document}

\textbf{without biblatex}

expected: \url{http://example.com/link/foo-bar}

actual: \demourl{bar}

\textbf{with biblatex}

ze field: \citefield{example}{shorthand}

expected: \url{http://example.com/link/foo-bar}

actual: \biburl{example}

\end{document}

The commands \demourl and \biburl are quite similar, they just use different macros to determine a part of the URL. Processing this file (e. g. with latexmk) yields the following result:

problem

As you can see, the \citefield command works correctly and retrieves the contents of the shorthand attribute. The problem is that the macro is not expanded within \url, while the apparently similar \demofield is expanded correctly. I don't understand this - what is happening here, and how do I get the system to expand \citefield as well?

2
  • 2
    The difference seems to be that \citefield is a \protected command, so it doesn't get expanded in an \edef.
    – egreg
    Jul 12, 2014 at 10:56
  • 2
    And, from what I see using \tracingmacros=1, \citefield has better be a \protected command. ;-)
    – egreg
    Jul 12, 2014 at 11:11

1 Answer 1

1

After reading a bit about the pains involved in forcing *TeX to expand protected commands, I've changed my approach and used the BiBTeX facilities. The following code contains three command sets - one to print out the raw URL, one to format and link the URL using \url and one to create a \href hyperlink with some arbitrary text.

\documentclass{article}
\usepackage{hyperref}
\usepackage{biblatex}

% These are the parts used to print a raw URL without any formatting.
\DeclareFieldFormat{rawurl}{http://example.com/link/#1}
\DeclareCiteCommand{\rawurlcite}{}{\printfield[rawurl]{shorthand}}{}{}

% These are the parts used to print a hyperlinked URL.
\DeclareFieldFormat{linkurl}{\url{http://example.com/link/#1}}
\DeclareCiteCommand{\linkurlcite}{}{\printfield[linkurl]{shorthand}}{}{}

% This provides a \hrefcite{key}{text} command
\makeatletter
\DeclareCiteCommand{\@saveurlcite}{}{\savefield{shorthand}{\@savedshorthand}}{}{}
\newcommand{\hrefcite}[2]{%
\@saveurlcite{#1}%
\edef\@savedurl{http://example.com/link/\@savedshorthand}%
\href{\@savedurl}{#2}%
\let\@savedurl\empty%
\let\@savedshorthand\empty}

\begin{filecontents}{expprob.bib}
@online{example,
  shorthand    = {foo-bar},
  url          = {http://example.com}
}
\end{filecontents}

\bibliography{expprob}

\newcommand{\demofield}[2]{foo-#1}
\newcommand{\demourl}[1]{\url{http://example.com/link/\demofield{#1}{shorthand}}}

\newcommand{\biburl}[1]{\expandafter\url{\qlcite{#1}}}

\begin{document}

\textbf{without biblatex}

expected: \url{http://example.com/link/foo-bar}

actual: \demourl{bar}

\textbf{with biblatex}

ze field: \citefield{example}{shorthand}

rawurlcite: \rawurlcite{example}

linkurlcite: \linkurlcite{example}

a hyperlink: \hrefcite{example}{example text}

\end{document}
1
  • 1
    I could have answered telling you to load the usebib package, then to say \newbibfield{shorthand} and \bibinput{expprob}, so \newcommand{\biburl}[1]{\url{http://example.com/link/\usebibentry{#1}{shorthand}}}. Of course yours is a better and more robust method.
    – egreg
    Jul 12, 2014 at 15:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .