3

With biblatex and Biber, how to create a loop on the years to print bibliography year after year in the following manner:

\section{2016}
    \subsection{Article}
        \printbibliography of all articles published in 2017
    \subsection{inproceedings}
        \printbibliography of all papers in proceedings published in 2017
    \subsection{in Misc}
        \printbibliography of all misc published in 2017

\section{2015}
    etc. for all bib entries and all years.

Here is an example of the desired result: http://malti.fr/index.php/publications which was however obtained using a quite older package (bibunit) with multiple cites, multiple compilations, etc. (no more desired).

Some further enhancements could be:

  • The starting year automatically set up to the older entry year of the bib file,
  • The end year automatically set up to the most recent entry year of the bib file,
  • In case there is no paper published corresponding to a given (sub-)section, then that (sub-)section does not appear, (i.e.) no (sub-)section appears empty.

Printing bibliography between two years was resolved here. Thanks.

EDITED. Here is a MWE borrowed and modified from here to answer @samcarter.

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}

@Article{a,
  date =     2001,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{b,
  date =     2003,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{c,
  date =     2004,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{d,
  date =     2007,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{e,
  date =     2009,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{f,
  date =     2011,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{g,
  date =     2013,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{h,
  date =     2015,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@Article{i,
  date =     2016,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@patent{l,
  year =     2016,
  author =   {Author, Amy},
  title =    {Patent 1},
  number =   4,
  pages =    {100-141}}

@inproceedings{j,
  date =     2016,
  author =   {Author, Amy},
  title =    {Title 1},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}

@patent{o,
  year =     2016,
  author =   {Author, Amy},
  title =    {Patent 1},
  number =   4,
  pages =    {100-141}}

 @patent{m,
  year =     2016,
  author =   {Author, Amy},
  title =    {Patent 2},
  number =   4,
  pages =    {100-141}}

@Article{n,
  date =     2016,
  author =   {Author, Amy},
  title =    {Title},
  journaltitle = {Journal},
  volume =   10,
  number =   4,
  pages =    {100-141}}


\end{filecontents*}

\usepackage[backend=biber,defernumbers=true,sorting=ydnt]{biblatex}
\addbibresource{\jobname.bib}

\DeclareSourcemap{
  \maps[datatype=bibtex]{
      \map[overwrite=true]{
            \step[fieldsource=author,match=Amy,final]
            \step[fieldset=keywords, fieldvalue={,}, append]
            \step[fieldset=keywords, fieldvalue=own, append]
}}}


\defbibcheck{2016}{%There must be a better way to code "different from" 2016
  \ifnumless{\thefield{year}}{2016}
    {\skipentry}
    {\ifnumgreater{\thefield{year}}{2016}
      {\skipentry}
      {}
    }
}

\defbibcheck{2015}{%There must be a better way to code "different from" 2015
  \ifnumless{\thefield{year}}{2015}
    {\skipentry}
    {\ifnumgreater{\thefield{year}}{2015}
      {\skipentry}
      {}
    }
}

\begin{document}
\nocite{*}
\section*{2016}
    \printbibliography[check=2016, keyword=own, resetnumbers=true, type=article, heading=subbibliography, title={Articles}]
    \printbibliography[check=2016, keyword=own, resetnumbers=true, type=inproceedings, heading=subbibliography, title={Inproceedings}]
    \printbibliography[check=2016, keyword=own, resetnumbers=true, type=patent, heading=subbibliography, title={Patent}]
\section*{2015}
    \printbibliography[check=2015, keyword=own, resetnumbers=true, type=article, heading=subbibliography, title={Articles}]
    \printbibliography[check=2015, keyword=own, resetnumbers=true, type=inproceedings, heading=subbibliography, title={Inproceedings}]
    \printbibliography[check=2015, keyword=own, resetnumbers=true, type=patent, heading=subbibliography, title={Patent}]

\end{document}

However, I've got an undesired output with headings Inproceedings and Patent printed with an empty content in year 2015. I'd like not to have any heading if the content is empty.

Back to my request. How to create a loop from 2016 down to 2001 printing the bibliography year after year according to the types (Article, Inproceedings, Patent, Misc, ...)?

Another enhancement would be:

  • to create an inner loop which loops around the different types (Article, Inproceedings, Patent, Misc, ...) for each year.
  • 1
    This sounds all doable with biblatex. Have a look at the filter options of biblatex. It should be fairly easy to just print the entries of a specific year. Can you please give us a minimal working example with bibliography (MWEB) to have something to start with? – user36296 Jan 1 '17 at 15:06
6

Here is a solution (proof of concept) that cycles inside a single \printbibliography.

The solution depends on a specifically created sorting schema (here, we use the fact that article lexicographically precedes inproceedings which in turns proceeds patent). A more robust would define a specified sorting schema (and eventually a Source Map) for an appropriate ordering over the entry types.

Also, for simplicity, the solution assumes that only article, inproceedings and patents entries are presented in the bibliography file (easy to extend with a "Other publications" category).

The first step is to define the sorting order:

\DeclareSortingScheme{rasha}{
  \sort[direction=ascending]{
    \field{year}
    \field{entrytype}
  }
}

Then, we redefine the bibliography environment.

\defbibenvironment{bibliography}
  {\begin{enumerate}}
  {\end{enumerate}}
  {}

The trick here is to remove \item from the last element (the iteration over the bib item). This is delegated to the single entries.

The final step is to redefine the begentry macro (which is executed at the begin on standard bibliography drivers.

\def\mylastentrytype{}

\newcounter{myyear}
\setcounter{myyear}{0}

\renewbibmacro{begentry}{%
\ifnumgreater{\thefield{year}}{\value{myyear}}
  {\section*{\hspace*{-\leftmargin}\printfield{year}}
   \setcounter{myyear}{\thefield{year}}%
   \setcounter{enumi}{0}%
   \xdef\mylastentrytype{}%
   }%
  {}%
  \iffieldequals{entrytype}{\mylastentrytype}
    {}
    { \iffieldequalstr{entrytype}{article}
        {\subsection*{\hspace*{-\leftmargin}Journal Articles}}
        { \iffieldequalstr{entrytype}{inproceedings}
            {\subsection*{\hspace*{-\leftmargin}Conference Papers}
             \setcounter{enumi}{0}%
            }
            {\iffieldequalstr{entrytype}{patent}
                {\subsection*{\hspace*{-\leftmargin}Patents}
                 \setcounter{enumi}{0}  
                }
                {}
            }
        }
      \xdef\mylastentrytype{\thefield{entrytype}}
    }
  \item
}

Given that the sorting schema use year as first parameter, the initial condition checks whether we have an increment in the year, if so it emits a \section command, and the set the counter for the year to the year of the last entry processed.

The second parameter of the sorting schema is the entrytype of the entry. Thus we have to check if the current entry is of the same type of the previous one (stored in \mylastentrytype). If this is not the case, we check if the entry type is one of article, inproceedings or patent. If it is then, we print the corresponding section (reseting the counter for the enumeration)

Finally, we have to instruct to use the sorting schema.

\nocite{*}

\begin{refcontext}[sorting=rasha]
\printbibliography[title={Publication list by year}]
\end{refcontext}

With the bibliography given in the MWE this produce the following output (in a two column format)

enter image description here

EDIT Apparently \sort{\field{entrytype}} is not recognised during the sorting phase. Thus an alternative is to declare a source map to populate the presort field using the \pertype specification, namely:

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \pertype{article}
      \step[fieldset=presort,fieldvalue=article]
    }
    \map{
      \pertype{inproceedings}
      \step[fieldset=presort,fieldvalue=inproceedings]
    }
    \map{
      \pertype{patent}
      \step[fieldset=presort,fieldvalue=patent]
    }
  }
}

and change the sorting template (notice the \DeclareSortingSchema is now deprecated) to

\DeclareSortingTemplate{rasha}{
  \sort[direction=ascending]{
    \field{year}}
  \sort{\field{presort}}
}

The output, with the extended MWE, is:

enter image description here

  • Thanks a lot Guido. Your solution works fine when the bib file contains an ordered bibliography. However, if the bibliography is not ordered, there is a problem because let's say in 2016, we'll find "Journal articles", "conference papers", then "Journal articles" again ... Could you please elaborate a work around regarding this problem. – rasha Dec 19 '17 at 11:37
  • I've modified the MWE to show the problem that appears in 2016 when the bibliography is not ordered. – rasha Dec 19 '17 at 11:55
  • @rasha I guess the only change needed is \DeclareSortingScheme{rasha}{ \sort[direction=ascending]{ \field{year} } \sort{ \field{entrytype} } } (modulo line breaks) – moewe Dec 19 '17 at 14:31
  • @moewe Apparently \sort{\field{entrytype}} has no effect on sorting. According to the documentation it should, but it does not. Is this a bug in biber/biblatex? – Guido Dec 20 '17 at 1:42
  • I reported this to PLK github.com/plk/biber/issues/206 – moewe Dec 20 '17 at 9:51

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.