30

I am using biblatex (with biber) and I am currently writing a book class document. I will have a long bibliography at the end of the document.

Inside this bibliography I would like to have alphabetical sections (A, B, C, ...). The purpose is to help someone who is looking for a reference; he can visualize that he is inside G section (for example). This is the kind of layout that dictionaries have.

Here is an visual attempt to show what I want to achieve:

**A** (Big "A" with a size of a section)

Author1 , ...
  --, ...
  --, ...
Author2, ...
.
.
.

**B** (Big "B")

Bauthor1, ...
  --, ...
Bauthor2, ...
  --, ...
.
. 
.

Of course, I can add keywords to my .bib file and say to BibLaTeX to print all references with keywords "A" inside a section "A". But it sounds stupid to add keywords just for alphabetical section sorting.

Here is a MWE:

\documentclass[12pt,twoside,a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx} 
\usepackage{lmodern}
\usepackage{xspace}
\usepackage[style=authoryear-comp,hyperref,backend=biber,isbn=false,doi=false,url=false]{biblatex}
\bibliography{bib}
\title{}
\usepackage[francais]{babel}
\usepackage{csquotes}
\usepackage[colorlinks]{hyperref}

\begin{document}

\nocite* 
\printbibliography
\end{document}

.bib file:

@InBook{arwez_title_2000,
  author =   {Paul Arwez},
  title =    {Title},
  chapter =      {Chapter},
  publisher =    {Publisher},
  year =     2000}

@Book{arwez_book_2013,
  author =   {Paul Arwez},
  title =    {Book},
  publisher =    {Publisher},
  year =     2013}

@Book{barwez_book_2013,
  author =   {Paul Barwez},
  title =    {Book},
  publisher =    {Publisher},
  year =     2013}

@Book{carwez_book_2013,
  author =   {Paul Carwez},
  title =    {Book},
  publisher =    {Publisher},
  year =     2013}

@Article{carwez_artic_1873,
  author =   {Paul Carwez},
  title =    {Article},
  journal =      {Journal},
  year =     1876}

.bbl file:

% $ biblatex auxiliary file $
% $ biblatex bbl format version 2.2 $
% Do not modify the above lines!
%
% This is an auxiliary file used by the 'biblatex' package.
% This file may safely be deleted. It will be recreated by
% biber as required.
%
\begingroup
\makeatletter
\@ifundefined{[email protected]}
  {\@latex@error
     {Missing 'biblatex' package}
     {The bibliography requires the 'biblatex' package.}
      \aftergroup\endinput}
  {}
\endgroup


\refsection{0}
  \sortlist{entry}{nyt}
    \entry{arwez_title_2000}{inbook}{}
      \name{labelname}{1}{}{%
        {{uniquename=0,hash=378583d49d9a8ada29208d6cb5267d5f}{Arwez}{A\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \name{author}{1}{}{%
        {{uniquename=0,hash=378583d49d9a8ada29208d6cb5267d5f}{Arwez}{A\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \list{publisher}{1}{%
        {Publisher}%
      }
      \strng{namehash}{378583d49d9a8ada29208d6cb5267d5f}
      \strng{fullhash}{378583d49d9a8ada29208d6cb5267d5f}
      \field{sortinit}{A}
      \field{labelyear}{2000}
      \field{labeltitle}{Title}
      \field{chapter}{Chapter}
      \field{title}{Title}
      \field{year}{2000}
    \endentry
    \entry{arwez_book_2013}{book}{}
      \name{labelname}{1}{}{%
        {{uniquename=0,hash=378583d49d9a8ada29208d6cb5267d5f}{Arwez}{A\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \name{author}{1}{}{%
        {{uniquename=0,hash=378583d49d9a8ada29208d6cb5267d5f}{Arwez}{A\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \list{publisher}{1}{%
        {Publisher}%
      }
      \strng{namehash}{378583d49d9a8ada29208d6cb5267d5f}
      \strng{fullhash}{378583d49d9a8ada29208d6cb5267d5f}
      \field{sortinit}{A}
      \field{labelyear}{2013}
      \field{labeltitle}{Book}
      \field{title}{Book}
      \field{year}{2013}
    \endentry
    \entry{barwez_book_2013}{book}{}
      \name{labelname}{1}{}{%
        {{uniquename=0,hash=d0455efa6586ff2338c954fc0860f0d2}{Barwez}{B\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \name{author}{1}{}{%
        {{uniquename=0,hash=d0455efa6586ff2338c954fc0860f0d2}{Barwez}{B\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \list{publisher}{1}{%
        {Publisher}%
      }
      \strng{namehash}{d0455efa6586ff2338c954fc0860f0d2}
      \strng{fullhash}{d0455efa6586ff2338c954fc0860f0d2}
      \field{sortinit}{B}
      \field{labelyear}{2013}
      \field{labeltitle}{Book}
      \field{title}{Book}
      \field{year}{2013}
    \endentry
    \entry{carwez_artic_1873}{article}{}
      \name{labelname}{1}{}{%
        {{uniquename=0,hash=baa123e8e737243bb6575c9b2955a321}{Carwez}{C\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \name{author}{1}{}{%
        {{uniquename=0,hash=baa123e8e737243bb6575c9b2955a321}{Carwez}{C\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \strng{namehash}{baa123e8e737243bb6575c9b2955a321}
      \strng{fullhash}{baa123e8e737243bb6575c9b2955a321}
      \field{sortinit}{C}
      \field{labelyear}{1876}
      \field{labeltitle}{Article}
      \field{journaltitle}{Journal}
      \field{title}{Article}
      \field{year}{1876}
    \endentry
    \entry{carwez_book_2013}{book}{}
      \name{labelname}{1}{}{%
        {{uniquename=0,hash=baa123e8e737243bb6575c9b2955a321}{Carwez}{C\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \name{author}{1}{}{%
        {{uniquename=0,hash=baa123e8e737243bb6575c9b2955a321}{Carwez}{C\bibinitperiod}{Paul}{P\bibinitperiod}{}{}{}{}}%
      }
      \list{publisher}{1}{%
        {Publisher}%
      }
      \strng{namehash}{baa123e8e737243bb6575c9b2955a321}
      \strng{fullhash}{baa123e8e737243bb6575c9b2955a321}
      \field{sortinit}{C}
      \field{labelyear}{2013}
      \field{labeltitle}{Book}
      \field{title}{Book}
      \field{year}{2013}
    \endentry
  \endsortlist
\endrefsection
\endinput
8
  • Do you use the alpha style bib keys like [Aut05]? Then it should be quite doable with bibtex.
    – yo'
    Dec 15, 2013 at 15:24
  • I am using authoryear-comp style. And my bib keys are defined by zotero and look like author_title_year? But perhaps what works for alpha styles work also for authoryear ones. I just have no idea how to do it even with alpha style.
    – ppr
    Dec 15, 2013 at 15:30
  • Could you please add a short typical .bbl file? (That's the file produced by bibtex.) Having that, I will quite surely manage to make a solution ;)
    – yo'
    Dec 15, 2013 at 15:40
  • @tohecz I updated my question with a MWE and a .bbl file.
    – ppr
    Dec 15, 2013 at 15:56
  • Oh you use biblatex, please specify such important thing very clearly in the question next time. I don't know whether my solution works with biblatex, and I have little experience with it to be able to modify it accordingly.
    – yo'
    Dec 15, 2013 at 16:01

6 Answers 6

31

You can create a category for each letter in the alphabet and, with \AtDataInput, add entries to each category on the basis of the sortinit field.

\documentclass{book}
\usepackage[style=alphabetic]{biblatex}

\addbibresource{biblatex-examples.bib}
\nocite{angenendt,bertram,doody,gillies}

% user-level test for skipbib enabled (e.g. related entry matuz:doody)
\makeatletter
\def\ifskipbib{\iftoggle{blx@skipbib}}
\makeatother

\def\initlist{}
\forcsvlist{\listadd\initlist}{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}
\forlistloop{\DeclareBibliographyCategory}{\initlist}
\renewcommand*{\do}[1]{\defbibheading{#1}{\section*{#1}}}
\dolistloop{\initlist}
\AtDataInput{\ifskipbib{}{\addtocategory{\thefield{sortinit}}{\thefield{entrykey}}}}

\begin{document}
\printbibheading
\bibbycategory
\end{document}

enter image description here

Note that we need to access some internals to avoid entries that are skipped in the bibliography. I keep forgetting to make these toggle values available to the user, but we'll get around to it soon.

9
  • Very nice solution which works well.
    – ppr
    Dec 15, 2013 at 22:37
  • 3
    I suggest a little modification. If you use the entry vangennep, you will get a small v. So you can use something like this: \AtDataInput{% \ifskipbib{} {% \edef\@tempa{\thefield{sortinit}}% \uppercase\expandafter{\expandafter\def\expandafter\@tempb\expandafter{\@tempa}}% \addtocategory{\@tempb}{\thefield{entrykey}} }% } Dec 16, 2013 at 8:58
  • 1
    @MarcoDaniel Thanks for catching that. The backend should generate an uppercase letter for the sortinit field, so this is a biber bug. It is already fixed in the dev release.
    – Audrey
    Dec 16, 2013 at 16:39
  • Is there a way to make this work for author names whose first letter is an accented character? I get ! Package biblatex Error: Category '\IeC {\r A}' not declared. when I use the entry author = {\r{A}gren, J. Arvid}.
    – sudosensei
    Feb 24, 2014 at 19:58
  • 1
    @sudosensei You need to use the bibencoding setting if you want to mix your tex and bib encodings. Refer to "specifying encodings" in the manual.
    – Audrey
    Mar 5, 2014 at 20:15
13

Here a hack of the internal bibitem:

\documentclass[]{scrartcl}

\usepackage[style=alphabetic]{biblatex}
\makeatletter
\def\blx@head@tempa{0}
\def\blx@bibitem#1{%
  \blx@ifdata{#1}
    {\begingroup
     \blx@getdata{#1}%
     \blx@imc@iffieldequals{sortinit}\blx@head@tempa{}{\item[]\textbf{\thefield{sortinit}}}%
       \global\let\blx@head@tempa\abx@field@sortinit%
     \blx@bibcheck
       \global\let\blx@noitem\@empty
     \iftoggle{blx@skipentry}{}{%
       \blx@setoptions@type\abx@field@entrytype
       \blx@setoptions@entry
       \blx@thelabelnumber
       \blx@addprefixnumber
       \addtocounter{instcount}\@ne
       \csuse{blx@item@\blx@theenv}\relax
       \blx@initsep
       \blx@namesep
       \csuse{blx@hook@bibitem}%
       \blx@execute
       \blx@initunit
       \blx@anchor
       \blx@beglangbib
       \bibsentence
       \blx@pagetracker
       \blx@driver\abx@field@entrytype
       \blx@postpunct
       \blx@endlangbib}%
     \endgroup}
    {}}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}

enter image description here

6
  • seeing the code, I start to understand why it's (almost) impossible to make biblatex do what you want;) However, this seems to be the only working solution, so +1
    – yo'
    Dec 15, 2013 at 16:41
  • This solution does not work for me. I obtain double letters (AA, BB, CC, ...) before every references.
    – ppr
    Dec 15, 2013 at 16:43
  • 1
    I get errors with it... BTW you forgot \addbibresource{biblatex-examples.bib} Dec 15, 2013 at 16:48
  • @ppr: Did you try the example. I forgot a important line (see comment above) Dec 15, 2013 at 17:22
  • I pasted the code inside \makeatletter and \makeatother to my .tex file (so the missing line is not the problem). I was unable to compile without errors and the result is not correct (double AA, BB). I can upload my file in the chat if you want?
    – ppr
    Dec 15, 2013 at 17:47
12

Although the marking of alphabetical sections with "heading letters" is sometimes used for indexes, I have never encountered such letters in bibliographies. I suggest to only add extra spacing between alphabetical sections; with biblatex, this can be done by simply setting the \bibinitsep length to a positive value.

\documentclass{book}

\usepackage[style=authoryear]{biblatex}

\setlength{\bibinitsep}{\baselineskip}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@misc{A01,
  author = {Author, A.},
  year = {2001},
  title = {Alpha},
}
@misc{A02,
  author = {Author, A.},
  year = {2002},
  title = {And now for something completely different},
}
@misc{B02,
  author = {Buthor, B.},
  year = {2002},
  title = {Bravo},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\nocite{*}

\begin{document}

\printbibliography

\end{document}

enter image description here

1
  • It is a good workaround and it works well. I will wait if there is another answer with sections (A, B, C) and, if not, accept this one.
    – ppr
    Dec 15, 2013 at 16:18
11

As biblatex is able to insert a space (\bibinitsep) between this entries, it should also be possible to enter text at this places. The main problem is that we are in a list and so getting the correct spacing and identation is a bit problematic:

\documentclass[12pt,twoside,a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{xspace}
\usepackage[style=authoryear-comp,hyperref,backend=biber,isbn=false,doi=false,url=false]{biblatex}
\addbibresource{bib.bib}
\title{}
\usepackage[francais]{babel}
\usepackage{csquotes}
\usepackage[colorlinks]{hyperref}

\makeatletter

\newcommand\bibsection{\@startsection {section}{1}{-\leftmargin}%
                                   {-3.5ex \@plus -1ex \@minus -.2ex}%
                                   {2.3ex \@plus.2ex}%
                                   {\normalfont\Large\bfseries}}

\bibinitsep=1pt %to trigger blx@initsep
\def\blx@initsep{%
  \blx@imc@iffieldundef{sortinit}
    {}
    {\ifnum\c@instcount>\@ne
       \blx@imc@iffieldequals{sortinit}\blx@previnit
         {}
         {\bibsection*{\printfield{sortinit}}\item}%instead of \addvspace
     \fi
     \global\let\blx@previnit\abx@field@sortinit}}
\makeatother
\begin{document}

\nocite*
\printbibliography
\end{document}
6

Disclaimer: This is a work-around, not a solution.

You could use biblatex's ability to filter bibliographic entries according to the keywords field to do this. All you need to do is add keywords = {<letter>} to every bibliographic entry, and \printbibliography[keyword=<letter>] will do the rest for you:

Output

I had to use my bibliography because yours wouldn't display correctly (not sure why). Also, \bibliography{<file>} is deprecated now, so I replaced it with \addbibresource{<file>.ext}. See the example below.

\documentclass[12pt,twoside,a4paper]{book}
\begin{filecontents}{bib.bib}
@Article{a:agrawal:2001:01,
  title         = {Phenotypic Plasticity in the Interactions and Evolution of Species},
  author        = {Agrawal, Anurag A.},
  journal       = {Science},
  year          = {2001},
  month         = oct,
  volume        = {294},
  number        = {5541},
  pages         = {321--326},
  doi           = {10.1126/science.1060701},
  url           = {http://dx.doi.org/10.1126/science.1060701},
  keywords      = {A},
}

@Article{a:auld:2010:01,
  title         = {Re-evaluating the Costs and Limits of Adaptive Phenotypic Plasticity},
  author        = {Auld, Josh R. and Agrawal, Anurag A. and Relyea, Rick A.},
  journal       = {Proceedings of the Royal Society B: Biological Sciences},
  year          = {2010},
  month         = feb,
  volume        = {277},
  number        = {1681},
  pages         = {503--511},
  doi           = {10.1098/rspb.2009.1355},
  url           = {http://dx.doi.org/10.1098/rspb.2009.1355},
  keywords      = {A},
}

@Article{a:brown:2013:01,
  title         = {What Evolvability Really Is},
  author        = {Brown, Rachael L.},
  journal       = {The British Journal for the Philosophy of Science},
  year          = {2013},
  month         = aug,
  doi           = {10.1093/bjps/axt014},
  url           = {http://dx.doi.org/10.1093/bjps/axt014},
  keywords      = {B},
}

@Article{a:clune:2013:01,
  title         = {The Evolutionary Origins of Modularity},
  author        = {Clune, Jeff and Mouret, Jean-Baptiste and Lipson, Hod},
  journal       = {Proceedings of the Royal Society B: Biological Sciences},
  year          = {2013},
  month         = mar,
  volume        = {280},
  number        = {1755},
  doi           = {10.1098/rspb.2012.2863},
  url           = {http://dx.doi.org/10.1098/rspb.2012.2863},
  keywords      = {C},
}

@Article{a:dias:2013:01,
  title         = {Parental Olfactory Experience Influences Behavior and Neural Structure in Subsequent Generations},
  author        = {Dias, Brian G. and Ressler, Kerry J.},
  journal       = {Nature Neuroscience},
  publisher     = {Nature Publishing Group},
  year          = {2013},
  month         = dec,
  volume        = {},
  number        = {},
  pages         = {1546--1726},
  doi           = {10.1038/nn.3594},
  url           = {http://dx.doi.org/10.1038/nn.3594},
  keywords      = {D},
}
\end{filecontents}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{xspace}
\usepackage[style=authoryear-comp,hyperref,backend=biber,isbn=false,doi=false,url=false]{biblatex}
\addbibresource{bib.bib}
\title{}
\usepackage[francais]{babel}
\usepackage{csquotes}
\usepackage[colorlinks]{hyperref}

\begin{document}

\nocite{*}
% \printbibliography
\printbibliography[keyword=A,title={A},heading=subbibliography]
\printbibliography[keyword=B,title={B},heading=subbibliography]
\printbibliography[keyword=C,title={C},heading=subbibliography]
\printbibliography[keyword=D,title={D},heading=subbibliography]
\end{document}
7
  • 2
    Also, using biblatex and biber, if you always could be sure that the first character of the author field was the same as the letter that entry needed to be under, you could automatically add the keyword field using \DeclareSourcemap.
    – PLK
    Dec 15, 2013 at 18:56
  • @PLK: Nice idea. Dec 15, 2013 at 18:59
  • 1
    @sudosensei: You can use a loop to simplify it: \makeatletter \count@=0 \loop\ifnum\count@<26 \advance\count@\@ne \DeclareBibliographyCategory{\@Alph\count@} \repeat \makeatletter \AtEveryCitekey{\addtocategory{\thefield{sortinit}}{\thefield{entrykey}}}\addbibresource{biblatex-examples.bib} and \makeatletter \count@=0 \loop\ifnum\count@<26 \advance\count@\@ne \begingroup\edef\x{\endgroup\noexpand\printbibliography[category=\@Alph\count@,title={\@Alph\count@},heading=subbibliography]}\x \repeat \makeatletter Dec 15, 2013 at 19:00
  • @PLK: I tried: \DeclareSourcemap{ \maps[datatype = bibtex]{ \map[overwrite=true]{ \step[fieldsource = sortinit ] \step[fieldset = keywords , origfieldval ,append] } } } But it doesn't work? Do I miss something? Dec 15, 2013 at 19:16
  • 1
    @MarcoDaniel - sortinit isn't a .bib field and sourcemapping works at the .bib level. You'd have to do a regexp match and extract the first character of the author (assuming it was Last, First) and put that in keywords - there are examples in the biber manual.
    – PLK
    Dec 17, 2013 at 20:34
5

I give a bibtex solution, in case someone looks for it.

Well, you should be able to use the following. The idea is that we (1) assume the optional argument is always given, and (2) assume that the first token/letter of the optional argument is the right thing.

File test.tex:

\documentclass{article}

\begin{document}

\makeatletter
\let\x@bibitem\bibitem% store original \bibitem
\def\x@getfirst#1#2\endgetfirst{#1}% macro that returns the first letter/token of its argument
\def\x@bibalph{}% previous first letter, initiated to nothing
\def\bibitem[#1]{% new bibitem
  \edef\x@bibalphtest{\x@getfirst#1\endgetfirst}% get the new first letter
  \ifx\x@bibalphtest\x@bibalph\else % if the first letter changed
    \let\x@bibalph\x@bibalphtest% update
    \subsection*{\x@bibalph}% and make the \subsection
  \fi
  \x@bibitem[#1]% start the \bibitem itself
}
\makeatother

\bibliographystyle{amsalpha}
\bibliography{test}

\end{document}

File test.bbl:

\begin{thebibliography}{ABC06}

\bibitem[Aut00]{author_00}
Author, 2000.

\bibitem[ABC06]{author_buthor_cuthor_2005}
Author, Buthor, Cuthor, 2005.

\bibitem[But02]{buthor_2002}
Buthor, 2002.

\end{thebibliography}
3
  • 2
    Does not work with biblatex.
    – ppr
    Dec 15, 2013 at 16:36
  • Two questions. First, how might this code be adjusted to make it disregard capitalization? E.g., Dutch surnames freqently start with de or De (de Vries, De Jong) or with van or Van (van Gogh, Van der Laan, etc). It would be great if the code didn't treat "van Gogh" and "van der Laan" as starting with different letters of the alphabet. Secondly, how might the code be adjusted to treat "accented" characters to be the same as non-accented characters. E.g., how to make the code think that {\v C}erne starts with a C? (After all, that's what BibTeX does.) Thanks.
    – Mico
    Mar 1, 2018 at 22:11
  • Just in case what may have prompted these questions, please see the recent query How to group the bibliography alphabetically, if some surnames start with “accented” characters. If you feel inclined to provide a new answer to that query, that would be fabulous.
    – Mico
    Mar 1, 2018 at 22:15

You must log in to answer this question.

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