7

Firstly, thank you tex.stackexchange for being the best TeX-Reference on the web. I have been using the archives for months now and could always find answers to my questions.

But now I am stuck:

I'm using biblatex with the authoryear-ibid style. I need some specific changes in my bibliography.

At the moment an @incollection-entry prints like this:

Einstein, Albert (1929). »Using LaTeX«. In: The Latex User's Guide. Edited by Stephen Hawkins. New York: Publisher, p. 15-40. URL: http:\\en.wikipedia.org.

But I also have to reference the @collection which prints like this:

Hawkins, Stephen, ed. (1929). The Latex User's Guide. New York: Publisher. URL: http:\\en.wikipedia.org.

Now the 1st problem: The fact that the publisher, address and URL are printed in the @incollection-entry makes my bibliography artificially and unnecessarily long.

What I want to have instead would be:

Einstein, Albert (1929). »Using LaTeX«. In: The Latex User's Guide. Edited by Stephen Hawkins, p. 15-40.

2nd Problem: when the editor also was an author in the same @collection everything is printed twice, which also makes the bibliography artificially long. At the moment it prints like this

Hawkins, Stephen, ed. (1929a). The Latex User's Guide. New York: Publisher. URL: http:\\en.wikipedia.org.

--- (1929b). »Understanding LaTeX«. In: The Latex User's Guide. Edited by Stephen Hawkins. New York: Publisher, p. 1-15. URL: http:\\en.wikipedia.org.

But what I would prefer is that it prints something like this instead:

Hawkins, Stephen, ed. (1929a). The Latex User's Guide. New York: Publisher. URL: http:\\en.wikipedia.org.

--- (1929b). »Understanding LaTeX«. Edited by same in: The Latex User's Guide, p. 1-15.

(In German it would be:)

Hawkins, Stephens (1929b). »Understanding LaTeX«. In ders.: The Latex User's Guide, S. 1-15.

How can I make that happen?

Thank you very much

EDIT:

Mininmal Working Example (compiled with xelatex & biber)

\documentclass[12pt,a4paper,oneside]{memoir}

\usepackage[ngerman]{babel}
\usepackage[german=guillemets]{csquotes}

\usepackage[%
            style=authoryear-ibid,
            backend=biber,
            backref=true,
            backrefstyle=none,
            doi=false,
            isbn=false,
            maxcitenames=2,
            maxbibnames=2,
            ]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@collection{hawkins.1923,
    editor  = "Hawkins, Stephen",
    title   = "The Latex User's Guide",
    year    = "1923",
    publisher = "Publisher",
    address = "New York",
    url = "en.wikipedia.org",
}
@incollection{hawkins.1923b,
    author = "Hawkins, Stephen",
    title = "Understanding LaTeX",
    crossref = "hawkins.1923",
    pages = "1-15",
}

@incollection{einstein.1923,
    author = "Einstein, Albert",
    title = "Using LaTeX",
    crossref = "hawkins.1923",
    pages = "16-45",
}
\end{filecontents}

\bibliography{\jobname} 

\begin{document}

\nocite{*}

\printbibliography

\end{document}
  • 1
    This seems to be a disadvantage of biblatex in comparison with bibtex. While it is certainly possible to modify things as you wish, there doesn't seem to be any standard option or feature allowing this. (This is one of two features I really feel the lack of with biblatex.) I am currently hoping that your question will show I'm wrong about this but I think you will get redefinitions. That's OK but it would be nice if there were a simple option covering this kind of feature. You should edit your answer to include a Minimum Working Example demonstrating the problem which people can compile. – cfr Feb 12 '14 at 22:33
4

Much of this problem can be solved by altering the inheritance of fields from the cross-referenced @collection entry to its children @incollection entries. Note that the default inheritance (described in the appendix of the biblatex manual) can be changed only with biber.

The rest can be handled by tracking the editor names between bibliography items. Here this is done by re-purposing \indexnames and comparing the hash field.

\documentclass{article}
\usepackage[american]{babel}
%\usepackage[german]{babel}
\usepackage{csquotes}
\usepackage[backend=biber,style=authoryear-ibid]{biblatex}
\usepackage{xpatch}

% just for demo
\ExecuteBibliographyOptions{abbreviate=false}

\NewBibliographyString{same}
\DefineBibliographyStrings{american}{same = {same}}
\DefineBibliographyStrings{german}{same = {ders}}

% @incollection gets editor not publisher, address, url from @collection
\DeclareDataInheritance{collection}{incollection}{
  \inherit{editor}{editor}
  \noinherit{publisher}
  \noinherit{location}
  \noinherit{url}
}

% collect editor name hash
\newcommand*{\editorhash}{}
\newcommand*{\lasteditorhash}{}
\DeclareIndexNameFormat{gethash}{\xappto{\editorhash}{\thefield{hash},}}

% replace recurrent editor list with same string
\AtEveryBibitem{%
  \let\lasteditorhash\editorhash
  \renewcommand*{\editorhash}{}%
  \indexnames[gethash]{editor}%
  \ifdefstrequal{\lasteditorhash}{\editorhash}
    {\xapptobibmacro{byeditor+othersstrg}
       {\setunit{\addspace}\bibstring{same}\clearname{editor}}{}{}}
    {}}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@Collection{hawkins:ed,
  editor       = {Hawkins, Stephen},
  title        = {The Latex User's Guide},
  year         = 1923,
  publisher    = {Publisher},
  url          = {en.wikipedia.org},
  address      = {New York},
}
@InCollection{hawkins,
  author       = {Hawkins, Stephen},
  title        = {Understanding LaTeX},
  pages        = {1-15},
  crossref     = {hawkins:ed},
}
@InCollection{einstein,
  author       = {Einstein, Albert},
  title        = {Using LaTeX},
  pages        = {16-45},
  crossref     = {hawkins:ed},
}
\end{filecontents}
\bibliography{\jobname,biblatex-examples} 

\begin{document}
\nocite{hawkins:ed,hawkins,einstein,nietzsche:ksa,nietzsche:ksa1}
\printbibliography
\end{document}

enter image description here

Note that I didn't bother to reverse the "In..." and "Edited by..." fragments when the editor is recurrent, but you can do so by hooking code into the in: bibliography macro.

  • 1
    That's so much more elegant than my solution above. Nice! – moewe Feb 15 '14 at 7:17
3

Unfortunately, to achieve this there is quite a lot to be done.

This first portion of code makes sure to move the editor before the title for @inbook and @incollection.

\newbibmacro*{ineditor+others}{%
  \ifboolexpr{
    not test {\ifnameundef{editor}}
  }
    {\ifnamesequal{editor}{author}% if author equals editor, print idem
      {\printtext{\bibstring{idem\thefield{gender}}}%
       \setunit{\labelnamepunct}\newblock}%
      {\printnames{editor}}%
     \setunit{\addcomma\space}%
     \usebibmacro{editor+othersstrg}%
     \clearname{editor}}%
    {}}

\newbibmacro*{inauthor/editor+others/translator+others}{%
  \ifboolexpr{
    not test {\ifnameundef{bookauthor}}
  }
    {\usebibmacro{bybookauthor}}
    {\ifboolexpr{
       not test {\ifnameundef{editor}}
     }
       {\usebibmacro{ineditor+others}}
       {%\usebibmacro{translator+others}
       }}}

\xpatchbibdriver{incollection}
  {\usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }
  {\usebibmacro{ineditor+others}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
%       \usebibmacro{byeditor+others}%
  }%
  {\typeout{replaced \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{incollection}}}
  {\typeout{failed to replace \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{incollection}}}%


\xpatchbibdriver{inbook}
  {\usebibmacro{bybookauthor}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }
  {\usebibmacro{inauthor/editor+others/translator+others}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }%
  {}
  {\typeout{failed to replace \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{inbook}}}%

The following shortens the crossref for @in.... entries if the crossref'd entry in the bibliography already.

\newcommand{\shortxref}[1]{%
  \xpatchbibdriver{#1}
    {\usebibmacro{publisher+location+date}%
    }
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\usebibmacro{publisher+location+date}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}%
  \xpatchbibdriver{#1}
    {\iftoggle{bbx:isbn}
      {\printfield{isbn}}
      {}%
    }
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\iftoggle{bbx:isbn}
        {\printfield{isbn}}
        {}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}
  \xpatchbibdriver{#1}
    {\usebibmacro{series+number}}
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\usebibmacro{series+number}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}
}
\shortxref{incollection}
\shortxref{inbook}

I did not get rid of the URL here, but this can be done via

\xpatchbibdriver{#1}
  {\usebibmacro{doi+eprint+url}}
  {\ifentryinbib{\thefield{crossref}}
     {}
     {\usebibmacro{doi+eprint+url}}%
  }%
  {}
  {\typeout{failed to shorten crossref in #1}}

MWE

\documentclass[12pt,a4paper,oneside]{memoir}
\usepackage{xpatch}
\usepackage[ngerman]{babel}
\usepackage[german=guillemets]{csquotes}

\usepackage[%
            style=authoryear-ibid,
            backend=biber,
            backref=true,
            backrefstyle=none,
            doi=false,
            isbn=false,
            maxcitenames=2,
            maxbibnames=2,
            ]{biblatex}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@collection{hawkins.1923,
    editor  = "Hawkins, Stephen",
    title   = "The Latex User's Guide",
    year    = "1923",
    publisher = "Publisher",
    address = "New York",
    url = "en.wikipedia.org",
    series = {A Series},
    number  = {6},
}
@incollection{hawkins.1923b,
    author = "Hawkins, Stephen",
    title = "Understanding LaTeX",
    crossref = "hawkins.1923",
    pages = "1-15",
}

@incollection{einstein.1923,
    author = "Einstein, Albert",
    title = "Using LaTeX",
    crossref = "hawkins.1923",
    pages = "16-45",
}
\end{filecontents*}

\addbibresource{\jobname.bib}

\newbibmacro*{ineditor+others}{%
  \ifboolexpr{
    not test {\ifnameundef{editor}}
  }
    {\ifnamesequal{editor}{author}% if author equals editor, print idem
      {\printtext{\bibstring{idem\thefield{gender}}}%
       \setunit{\labelnamepunct}\newblock}%
      {\printnames{editor}}%
     \setunit{\addcomma\space}%
     \usebibmacro{editor+othersstrg}%
     \clearname{editor}}%
    {}}

\newbibmacro*{inauthor/editor+others/translator+others}{%
  \ifboolexpr{
    not test {\ifnameundef{bookauthor}}
  }
    {\usebibmacro{bybookauthor}}
    {\ifboolexpr{
       not test {\ifnameundef{editor}}
     }
       {\usebibmacro{ineditor+others}}
       {%\usebibmacro{translator+others}
       }}}

\xpatchbibdriver{incollection}
  {\usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }
  {\usebibmacro{ineditor+others}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
%       \usebibmacro{byeditor+others}%
  }%
  {\typeout{replaced \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{incollection}}}
  {\typeout{failed to replace \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{incollection}}}%


\xpatchbibdriver{inbook}
  {\usebibmacro{bybookauthor}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }
  {\usebibmacro{inauthor/editor+others/translator+others}%
   \setunit{\labelnamepunct}\newblock
   \usebibmacro{maintitle+booktitle}%
   \newunit\newblock
   \usebibmacro{byeditor+others}%
  }%
  {}
  {\typeout{failed to replace \usebibmacro{byeditor+others} by \usebibmacro{ineditor+others} in BibliographyDriver{inbook}}}%

\newcommand{\shortxref}[1]{%
  \xpatchbibdriver{#1}
    {\usebibmacro{publisher+location+date}%
    }
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\usebibmacro{publisher+location+date}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}%
  \xpatchbibdriver{#1}
    {\iftoggle{bbx:isbn}
      {\printfield{isbn}}
      {}%
    }
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\iftoggle{bbx:isbn}
        {\printfield{isbn}}
        {}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}
  \xpatchbibdriver{#1}
    {\usebibmacro{series+number}}
    {\ifentryinbib{\thefield{crossref}}
      {}
      {\usebibmacro{series+number}}%
    }%
    {}
    {\typeout{failed to shorten crossref in #1}}
}
\shortxref{incollection}
\shortxref{inbook}

\begin{document}
  \nocite{*}

  \printbibliography
\end{document}

enter image description here

  • Beautiful thank you! I added your alterations via \input{citestyle} in the preamble. And you also have a small mistake in the URL part: you commented out two } – Paul Feb 13 '14 at 8:38
  • 1
    @Paul Thanks for catching that, it should be fixed now. – moewe Feb 13 '14 at 9:05
  • added feature request on GitHub: github.com/plk/biblatex/issues?state=open – Paul Feb 13 '14 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.