65

This is a follow up question to biblatex: Make title hyperlink to doi url (if available). My reference database contains some DOI codes, but mainly normal URLs and some ISBN/ISSN codes. What I would like to achieve is extending the code from Herbert and hyperlink the title of the entry with the following priority: 1. DOI, 2. URL, 3. ISBN/ISSN. What I mean is, if both DOI and URL is available, use DOI. If URL and ISBN is available use URL. If only ISBN is available use that.

There are two further isses:

  • The URL field might contain several URLs, which are just seperated by a white space. In that case just the first URL should be used.
  • Herbert's code just extends to articles. I would like to extend this to all entry types.

The code from Herbert to Hyperlink the Title with DOIs is:

\newbibmacro{string+doi}[1]{%
  \iffieldundef{doi}{#1}{\href{http://dx.doi.org/\thefield{doi}}{#1}}}
\DeclareFieldFormat{title}{\usebibmacro{string+doi}{\mkbibemph{#1}}}
\DeclareFieldFormat[article]{title}{\usebibmacro{string+doi}{\mkbibquote{#1}}}

This far surpasses my skill, so it would be great if someone could give me some guidance how to achieve that.

3 Answers 3

53

One possibility is to extend Herbert's bibmacro to several nested conditions. (The following example contains only placeholder links for the ISBN/ISSN fields because I don't know how this links must be formatted.)

With regard to your further issues:

  • I'm not sure if the url field allows to specify several URLs separated by white spaces; if it does, I don't know how to retain only the first URL.

  • Herbert's code actually first covers all entry types, then specifies a special title format (quotes instead of emphasis) for articles.


\documentclass{article}

\usepackage[doi=false,url=false,isbn=false]{biblatex}

\usepackage[colorlinks]{hyperref}

\newbibmacro{string+doiurlisbn}[1]{%
  \iffieldundef{doi}{%
    \iffieldundef{url}{%
      \iffieldundef{isbn}{%
        \iffieldundef{issn}{%
          #1%
        }{%
          \href{http://books.google.com/books?vid=ISSN\thefield{issn}}{#1}%
        }%
      }{%
        \href{http://books.google.com/books?vid=ISBN\thefield{isbn}}{#1}%
      }%
    }{%
      \href{\thefield{url}}{#1}%
    }%
  }{%
    \href{http://dx.doi.org/\thefield{doi}}{#1}%
  }%
}

\DeclareFieldFormat{title}{\usebibmacro{string+doiurlisbn}{\mkbibemph{#1}}}
\DeclareFieldFormat[article,incollection]{title}%
    {\usebibmacro{string+doiurlisbn}{\mkbibquote{#1}}}

\begin{filecontents}{\jobname.bib}
@article{A01,
  author = {Author, A.},
  year = {2001},
  title = {Alpha},
  doi = {doi},
  url = {url},
  issn = {isbn-issn},
}
@book{B02,
  author = {Buthor, B.},
  year = {2002},
  title = {Bravo},
  url = {http://tex.stackexchange.com/},
  isbn = {isbn-issn},
}
@incollection{C03,
  author = {Cuthor, C.},
  year = {2003},
  title = {Charlie},
  isbn = {9780521867016},
}
@misc{D04,
  author = {Duthor, D.},
  year = {2004},
  title = {Delta},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\nocite{*}

\begin{document}

\printbibliography

\end{document}

enter image description here

6
  • Regarding my second point, I can obviously solve the problem by adding \DeclareFieldFormat[incollection]{title}, but why is that not automatically done by the "all entry type" option?
    – Jörg
    Commented Mar 18, 2012 at 10:53
  • @Jörg You could use the starred version \DeclareFieldFormat* to clear type-specific formats. But IMO it's more consistent to format @incollection titles like @article titles. I've edited my example accordingly.
    – lockstep
    Commented Mar 18, 2012 at 11:20
  • 1
    It would also be good to extend this for eprints
    – mu7z
    Commented Jul 25, 2016 at 23:18
  • What is \thefield?
    – Paul Wintz
    Commented Oct 30, 2022 at 23:04
  • If the links aren't appearing in the PDF, check that you are not compiling the document in draft mode.
    – Paul Wintz
    Commented Oct 30, 2022 at 23:11
25

Another approach is to define a new format that adds links. This can be used in any bibliography macro that applies the title format. In standard styles there are only two of these macros: title and periodical. You can revert to the original style with \DeclareFieldAlias{<new format name>}{default}.

The url field is intended to hold only one URL, so we need to devise a way to access the first URL. One option is to have biber to drop the extra URLs by adapting this previous answer. The code below demonstrates an alternative that accesses bibliographic data like the internal biblatex formatting commands.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{csquotes}
\usepackage[american]{babel}
\usepackage[style=verbose,url=false,doi=false,isbn=false]{biblatex}
\usepackage[colorlinks]{hyperref}

% Define new format that applies a hypertext reference
\DeclareFieldFormat{linked}{%
  \ifboolexpr{ test {\ifhyperref} and not test {\ifentrytype{online}} }
    {\iffieldundef{doi}
       {\iffieldundef{url}
          {\iffieldundef{isbn}
             {\iffieldundef{issn}
                {#1}
                {\href{\worldcatsearch\thefield{issn}}{#1}}}
             {\href{\worldcatsearch\thefield{isbn}}{#1}}}
          {\href{\thefieldfirstword{url}}{#1}}}
       {\href{http://dx.doi.org/\thefield{doi}}{#1}}}
    {#1}}

% URL prefix for WorldCat query
\def\worldcatsearch{http://www.worldcat.org/search?qt=worldcat_org_all&q=}

% Define new command that returns the first word of a given field
\makeatletter
\def\thefieldfirstword#1{%
  \expandafter\expandafter
  \expandafter\firstword
  \expandafter\expandafter
  \expandafter{\csname abx@field@#1\endcsname}}
\def\firstword#1{\firstword@i#1 \@nil}
\def\firstword@i#1 #2\@nil{#1}
\makeatother

% Redefine url format to print only first URL, omit URL prefix
\DeclareFieldFormat{url}{\url{\firstword{#1}}}

\renewbibmacro*{title}{% Based on generic definition from biblatex.def
  \ifboolexpr{ test {\iffieldundef{title}} and test {\iffieldundef{subtitle}} }
    {}
    {\printtext[title]{\printtext[linked]{%
       \printfield[titlecase]{title}%
       \setunit{\subtitlepunct}%
       \printfield[titlecase]{subtitle}}}%
     \newunit}%
  \printfield{titleaddon}}

\renewbibmacro*{periodical}{% Based on generic definition from biblatex.def
  \iffieldundef{title}
    {}
    {\printtext[title]{\printtext[linked]{%
       \printfield[titlecase]{title}%
       \setunit{\subtitlepunct}%
       \printfield[titlecase]{subtitle}}}}}

\begin{filecontents}{\jobname.bib}
@Online{ctanmirror,
  label = {CTAN},
  title = {CTAN Mirror},
  date = {2006},
  url = {http://mirror.ctan.org http://www.ctan.org},
  urldate = {2006-10-01}}
@Periodical{jcg,
  title = {Computers and Graphics},
  issuetitle = {Semantic {3D} Media and Content},
  volume = {35},
  number = {4},
  year = {2011},
  issn = {0097-8493}}
@Manual{cmso,
  label = {CMS Online},
  title = {The Chicago Manual of Style Online},
  edition = {16},
  publisher = {University of Chicago},
  date = {2010},
  url = {http://www.chicagomanualofstyle.org http://www.chicagomanualofstyle.org/16/contents.html},
  isbn = {0-226-10403-6}}
@Article{sarfraz,
  author = {M. Sarfraz and M. F. A. Razzak},
  title = {An algorithm for automatic capturing of the font outlines},
  journal = {Computers and Graphics},
  volume = {26},
  number = {5},
  pages = {795--804},
  year = {2002},
  issn = {0097-8493},
  doi = {10.1016/S0097-8493(02)00134-6}}
\end{filecontents}

% Don't link titles in citations
\AtEveryCite{\DeclareFieldAlias{linked}{default}}

\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}
\begin{document}
\null\vfill
Filler text.\footcite{gonzalez,companion,cmso}
Filler text.\footcite{sarfraz,ctan,ctanmirror,jcg}
\printbibliography
\end{document}

enter image description here

Instead of redefining bibliography macros, the new format can be applied in the title format definition.

\DeclareFieldFormat{title}{\printtext[linked]{\mkbibemph{#1}}}
\DeclareFieldFormat
  [article,inbook,incollection,inproceedings,patent,thesis,unpublished]
  {title}{\mkbibquote{\printtext[linked]{#1}\isdot}}
\DeclareFieldFormat[suppbook,suppcollection,suppperiodical]{title}
  {\printtext[linked]{#1}}
1

This is in addition to the previous answers. When LuaLaTeX is used it's easy to extract the first URL or ISBN number by calling a lua function. I put a lua script in the_first_word.lua file that returns the first word of a string if the string is a list of ISBNs separated by comma-space

-- find the first comma or space
-- return the string before first comma or space if found,
-- otherwise return entire string
function the_first_word( s )
   i = string.find( s, ",? " )
   if i == nil then return s end
   return string.sub( s, 0, i - 1 )
end

Then the LaTeX code to invoke the script along with wrapping the title field in the href macros is like this

\directlua{dofile("the_first_word.lua")}
\newcommand*{\thefirstword}[1]{%
  \directlua{tex.sprint(the_first_word("\luatexluaescapestring{#1}"))}}

\newbibmacro{linktitle}[1]{%
  \iffieldundef{doi}{%
    \iffieldundef{url}{%
      \iffieldundef{isbn}{%
        \iffieldundef{issn}{%
          #1%
        }{\href{http://books.google.com/books?vid=ISSN\thefield{issn}}{#1}}%
      }{\href{http://books.google.com/books?vid=ISBN\thefirstword{\thefield{isbn}}}{#1}}%
    }{\href{\thefirstword{\thefield{url}}}{#1}}%
  }{\href{http://dx.doi.org/\thefield{doi}}{#1}}%
}

You must log in to answer this question.

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