4

I'm trying to create subcategories for my bibliography with headings by year (using biblatex). I found I can use defbibcheck to check by year like so:

\defbibcheck{2013}{
  \iffieldint{origyear}
    {\ifnumequal{\thefield{origyear}}{2013}
      {}
      {\skipentry}
    }
    {\iffieldint{2013}
      {\ifnumequal{\thefield{year}}{2013}
       {}
       {\skipentry}
    }
    {\skipentry}
   }
}       

However because there's a lot of years I don't want to have a copy of this for every year. I thought I could use \foreach from the pgffor package like this:

\foreach \year in {2012,2013}{%
 \defbibcheck{\year}{
  \iffieldint{origyear}
    {\ifnumequal{\thefield{origyear}}{\year}
      {}
      {\skipentry}
    }
    {\iffieldint{\year}
      {\ifnumequal{\thefield{year}}{\year}
        {}
        {\skipentry}
      }
      {\skipentry}
    }
}
}   

However, the \prinbibliography[check=2013] results in a Check '2013' not found. Is there another way to do this?

Edit: Minimal not working example below:

\documentclass{article}
\usepackage{filecontents}
\usepackage{pgffor}
\usepackage{biblatex}


\foreach \year in {2012,2013}{%
 \defbibcheck{\year}{
  \iffieldint{origyear}
    {\ifnumequal{\thefield{origyear}}{\year}
      {}
      {\skipentry}
    }
    {\iffieldint{\year}
      {\ifnumequal{\thefield{year}}{\year}
        {}
        {\skipentry}
      }
      {\skipentry}
    }
}
}


\begin{filecontents*}{\jobname.bib}
@inproceedings{Bar2013,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2013}
}
@inproceedings{Bar2012,
    author = {F. Bar},
booktitle = {International Conference on Information},
pages = {3--4},
title = {{Advanced functionality and performance or nothing }},
year = {2012}
}
\end{filecontents*}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography[check=2013]
\end{document} 
  • Please post a Minimal Working (or Non-Working) Example which people can (try to) compile. This will help people to help you and make it more likely you will receive useful answers. – cfr Jan 1 '14 at 4:09
  • Sorry forgot the example. I edited the post now. – cycomanic Jan 1 '14 at 10:49
2

Something like this?

\begin{filecontents*}{\jobname.bib}
@inproceedings{Bar2011,
    author = {F. Bar and B. Foo},
    booktitle = {The conference 2011 on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2011}
}

@inproceedings{Bar2013,
    author = {F. Bar and B. Foo},
    booktitle = {The conference 2013 on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = 2013
}

@inproceedings{Bar2012,
    author = {F. Bar},
booktitle = {International Conference on Information 2012},
pages = {3--4},
title = {{Advanced functionality and performance or nothing }},
year = {2012}
}

@inproceedings{Bar2012b,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2012}
}

@inproceedings{Bar2014,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing 2014},
pages = {1--2},
title = {{A meaningless title}},
year = {2014}
}
\end{filecontents*}

\documentclass{article}
\usepackage{filecontents}
\usepackage{pgffor}
\usepackage{biblatex}

\defbibcheck{ylist}{%
  \iffieldint{year}{%
    \xdef\fldyear{\thefield{year}}\xdef\doskip{1}%
    \foreach \yr in \yrlist{%
      \ifnumequal{\fldyear}{\yr}{\xdef\doskip{0}\breakforeach}{}%
    }%
    \ifnumequal{\doskip}{1}{\skipentry}{}%
  }%
  {\skipentry}%
}

\addbibresource{\jobname.bib}
\begin{document}
\def\yrlist{2012,2013,2011,2010}
Years: \yrlist

\nocite{*}
\printbibliography[check=ylist]
\end{document} 

enter image description here

Edit: MWE for references by year:

\begin{filecontents*}{\jobname.bib}
@inproceedings{Bar2011,
    author = {F. Bar and B. Foo},
    booktitle = {The conference 2011 on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2011}
}

@inproceedings{Bar2013,
    author = {F. Bar and B. Foo},
    booktitle = {The conference 2013 on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = 2013
}

@inproceedings{Bar2012,
    author = {F. Bar},
booktitle = {International Conference on Information 2012},
pages = {3--4},
title = {{Advanced functionality and performance or nothing }},
year = {2012}
}

@inproceedings{Bar2012b,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2012}
}

@inproceedings{Bar2014,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing 2014},
pages = {1--2},
title = {{A meaningless title}},
year = {2014}
}
\end{filecontents*}

\documentclass{article}
\usepackage{filecontents}
\usepackage{pgffor}
\usepackage{biblatex}

\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
%
\def\yrlist{2011,2012,2013}

\foreach \yr in \yrlist{%
  \defbibcheck{ylist}{%
    \iffieldint{year}{%
        \ifnumequal{\thefield{year}}{\yr}{}{\skipentry}%
    }%
    {\skipentry}%
  }%
  \renewcommand{\refname}{REFERENCES: \yr}%
  \printbibliography[check=ylist]
}
\end{document} 

enter image description here

  • As far as I understood the question, it is about being able to split the bibliography by year. Could you specify how that can be achieved? Your code seems to check for a list of years at once, not to define single checks for a each year in that list. – moewe Jan 2 '14 at 6:48
  • @moewe: updated – g.kov Jan 2 '14 at 7:52
  • That's awesome. Any idea why defining the year checks in the loop one-by-one does not work? – moewe Jan 2 '14 at 8:03
  • @moewe: it works with \global\defbibcheck{#1}{ – g.kov Jan 2 '14 at 8:20
  • Sorry for getting back to this so late, was without internet for a couple of days. Do I understand your answer to moewe correctly, that if I would have put \global\defbibcheck{#1}{ in my code it would have worked? – cycomanic Jan 7 '14 at 10:23
2

You could adapt Audrey's answer to a very similar problem (How to split the bibliography alphabetically?).

\makeatletter
\def\ifskipbib{\iftoggle{blx@skipbib}}
\makeatother

\def\yearlist{}
\forcsvlist{\listadd\yearlist}{2010,2011,2012,2013}
\forlistloop{\DeclareBibliographyCategory}{\yearlist}
\renewcommand*{\do}[1]{\defbibheading{#1}{\section*{#1}}}
\dolistloop{\yearlist}
\AtDataInput{\ifskipbib{}{\addtocategory{\thefield{year}}{\thefield{entrykey}}}}

The first block of code makes sure to skip entries that do not appear in the bibliography (you would not want an empty 2010 standing there).

The second block loops through all the years given in the second line and creates a different category for each of those. Then the headings for these sub-bibliographies are defined. Finally, the last line matches the entries to their year category.

\documentclass{article}
\usepackage{biblatex}

\begin{filecontents*}{\jobname.bib}
@inproceedings{Bar2013,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2013}
}
@inproceedings{Bar2012,
    author = {F. Bar},
booktitle = {International Conference on Information},
pages = {3--4},
title = {{Advanced functionality and performance or nothing }},
year = {2012}
}
\end{filecontents*}

\makeatletter
\def\ifskipbib{\iftoggle{blx@skipbib}}
\makeatother

\def\yearlist{}
\forcsvlist{\listadd\yearlist}{2010,2011,2012,2013}
\forlistloop{\DeclareBibliographyCategory}{\yearlist}
\renewcommand*{\do}[1]{\defbibheading{#1}{\section*{#1}}}
\dolistloop{\yearlist}
\AtDataInput{\ifskipbib{}{\addtocategory{\thefield{year}}{\thefield{entrykey}}}}

\addbibresource{\jobname.bib}
\begin{document}
  \nocite{*}
  \printbibheading
  \bibbycategory
\end{document} 

There is also a semi-automatic version of your code.

By defining a new command

\newcommand{\yearcheck}[1]{%
  \defbibcheck{#1}{
    \iffieldint{origyear}
      {\ifnumequal{\thefield{origyear}}{#1}
        {}
        {\skipentry}
      }
      {\iffieldint{year}
        {\ifnumequal{\thefield{year}}{#1}
          {}
          {\skipentry}
        }
        {\skipentry}
      }
   }
}

One can then use that to create year bibchecks via

\yearcheck{2012}
\yearcheck{2013}

Which does not seem to work within a \foeach loop such as \foreach \year in {2012,2013} {\yearcheck{\year}}

Or, much better, via a loop (thanks to @g.kov)

\foreach \year in {2012,2013} {\global\yearcheck{\year}}

Printing the bibliography can be implemented via a loop as well

\foreach \year in {2012,2013} {\printbibliography[check=\year,title={\year}]}

MWE

\documentclass{article}
\usepackage{filecontents}
\usepackage{biblatex}
\usepackage{pgffor}

\newcommand{\yearcheck}[1]{%
  \defbibcheck{#1}{
    \iffieldint{origyear}
      {\ifnumequal{\thefield{origyear}}{#1}
        {}
        {\skipentry}
      }
      {\iffieldint{year}
        {\ifnumequal{\thefield{year}}{#1}
          {}
          {\skipentry}
        }
        {\skipentry}
      }
   }
}

\begin{filecontents*}{\jobname.bib}
@inproceedings{Bar2013,
    author = {F. Bar and B. Foo},
    booktitle = {The conference on nothing},
pages = {1--2},
title = {{A meaningless title}},
year = {2013}
}
@inproceedings{Bar2012,
    author = {F. Bar},
booktitle = {International Conference on Information},
pages = {3--4},
title = {{Advanced functionality and performance or nothing }},
year = {2012}
}
\end{filecontents*}
\addbibresource{\jobname.bib}

\foreach \year in {2012,2013} {\global\yearcheck{\year}}
\begin{document}
  \nocite{*}
  \foreach \year in {2012,2013} {\printbibliography[check=\year,title={\year}]}
\end{document} 
  • Cool thanks for that! I was initially looking at categories, but I'm already using categories and the yearly ordering is in fact a subcategory. – cycomanic Jan 7 '14 at 10:27
  • OK I just realised I have another related question why does \foreach \year in {2012,2013} {\printbibliography[check=\year, title={\year}] work but \foreach \year in {2012,2013} {\pringbibliography[keyword=\year, title={\year}] does not. Looking at the log, \year does not get expanded when I use keyword=\year or category=\year. Why is that? Is there a good reference on how variables get expanded in tex? – cycomanic Jan 7 '14 at 11:34

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.