3

I am trying to do my CV and would like to build bibliography using Biblatex. In the CV, I have different sections to list my published books, and journal articles, while in each section I want to sort all items by year starting from the most recent.

I was able to sort the entries by year descending following the answer of @moewe: https://tex.stackexchange.com/a/434393/173148. However, when printing bibliography by sections, the years of all publication were shown instead of only the years for the current section.

Edit: Also, as this is in the CV, I need to print the bibliography for different types at various places, instead of printing out all of them at once.

example picture

The code I used to produce this result:

\documentclass{article}
\usepackage[style=authoryear,sorting=ydnt]{biblatex}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@book{book1,
  author = {author1},
  date = {1862},
  title = {Book1},
}
@book{book2,
  author = {author1 and author2},
  date = {1831},
  title = {Book2},
}
@article{article1,
  title={title1},
  author={author1 and author2},
  journal={journal1},
  volume={1},
  number={1},
  pages={1},
  year={1841}
}
@article{article2,
  title={title2},
  author={author2},
  journal={journal2},
  volume={2},
  number={2},
  pages={2},
  year={1842}
}
\end{filecontents}

\addbibresource{\jobname.bib}

\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \g__blxbibbyyear_yearlist_seq

\cs_new:Npn \__blxbibbyyear_seq_gput_right_once:Nn #1 #2
  {
    \seq_if_in:NnF #1 {#2}
      { \seq_gput_right:Nn #1 {#2} }
  }

\cs_generate_variant:Nn \__blxbibbyyear_seq_gput_right_once:Nn { NV, Nx }


\prg_new_conditional:Nnn \blx_field_if_undef:n { p, T, F , TF }
  {
    \use:c { iffieldundef } { #1 } { \prg_return_true: } { \prg_return_false: }
  }

% unfortunately, \iffieldint is not expandable, so no p version for us, boo
\prg_new_protected_conditional:Nnn \blx_field_if_int:n { T, F , TF }
  {
    \iffieldint { #1 } { \prg_return_true: } { \prg_return_false: }
  }

\AtDataInput
  {
    \blx_field_if_undef:nF { labeldatesource }
      { 
        \blx_field_if_undef:nTF { \thefield{labeldatesource}year }
          {
            \blx_field_if_undef:nF { \thefield{labeldatesource} }
              {
                \blx_field_if_int:nT { \thefield{labeldatesource} }
                  {
                    \__blxbibbyyear_seq_gput_right_once:Nx \g__blxbibbyyear_yearlist_seq
                      { \thefield{\thefield{labeldatesource}} }
                  }
              }
          }
          {
            \__blxbibbyyear_seq_gput_right_once:Nx \g__blxbibbyyear_yearlist_seq
              { \thefield{\thefield{labeldatesource}year} }
          }
      }
  }

\cs_new:Npn \blxbibbyyear_seq_sort_bydirection:NN #1 #2
  {
    \seq_sort:Nn #2
      {
         \int_compare:nNnTF { ##1 } #1 { ##2 }
          { \sort_return_swapped: }
          { \sort_return_same: }
      }
  }

\cs_new:Nn \blxbibbyyear_seq_sort_descending:N
  {
    \blxbibbyyear_seq_sort_bydirection:NN < #1
  }

\cs_new_nopar:Npn \blxbibbyyear_print_yearbib:nn #1 #2
  {
    \defbibcheck{thisyear}
      {
        \blx_field_if_int:nTF { labelyear }
          {
            \int_compare:nNnF { \thefield{labelyear} } = { #1 }
              { \skipentry }
          }
          { \skipentry }
      }
    \printbibliography[heading=subbibliography, title=#1, check=thisyear, #2]
  }


\DeclareDocumentCommand{\printbibbyyear}{O{}}
  {
    \blxbibbyyear_seq_sort_descending:N \g__blxbibbyyear_yearlist_seq
    \seq_map_inline:Nn \g__blxbibbyyear_yearlist_seq
      { \blxbibbyyear_print_yearbib:nn {##1} {#1} }
  }
\ExplSyntaxOff

\begin{document}
\section{Books}
\nocite{*}
\printbibbyyear[type=book]
\section{Articles}
\nocite{*}
\printbibbyyear[type=article]
\end{document}

1 Answer 1

4

The code needs a few modifications to also split by type. Basically what happens is that instead of one list that collects the years of publications (\g__blxbibbyyear_yearlist_seq) we need one list for each type (g__bblxbibbyyear_yearlist_<type>_seq, and a list of types). The overall idea of the code can remain and most things can just be switched from N/n-type arguments to c.

There are two commands now. \printbibbytypeyear splits the entire bibliography by type and year. \printbibtypebyyear{<type>} splits only the entries of type <type> by year.

\documentclass{article}
\usepackage[style=authoryear,sorting=ydnt]{biblatex}

\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \g__blxbibbyyear_typelist_seq

\cs_new:Npn \__blxbibbyyear_seq_gput_right_once:Nn #1 #2
  {
    \seq_if_in:NnF #1 {#2}
      { \seq_gput_right:Nn #1 {#2} }
  }

\cs_generate_variant:Nn \__blxbibbyyear_seq_gput_right_once:Nn { NV, Nx, cV, cx }


\prg_new_conditional:Npnn \blx_field_if_undef:n #1 { p, T, F , TF }
  {
    \use:c { iffieldundef } { #1 } { \prg_return_true: } { \prg_return_false: }
  }

% unfortunately, \iffieldint is not expandable, so no p version for us, boo
\prg_new_protected_conditional:Npnn \blx_field_if_int:n #1 { T, F , TF }
  {
    \iffieldint { #1 } { \prg_return_true: } { \prg_return_false: }
  }
\prg_new_protected_conditional:Npnn \blx_field_if_eq_str:nn #1 #2 { T, F , TF }
  {
    \iffieldequalstr { #1 } { #2 } { \prg_return_true: } { \prg_return_false: }
  }

\AtDataInput
  {
    \seq_if_exist:cF { g__bblxbibbyyear_yearlist_\thefield{entrytype}_seq }
      {
        \seq_new:c { g__bblxbibbyyear_yearlist_\thefield{entrytype}_seq }
        \__blxbibbyyear_seq_gput_right_once:Nx \g__blxbibbyyear_typelist_seq
          { \thefield{entrytype} }
      }  
    \blx_field_if_undef:nF { labeldatesource }
      { 
        \blx_field_if_undef:nTF { \thefield{labeldatesource}year }
          {
            \blx_field_if_undef:nF { \thefield{labeldatesource} }
              {
                \blx_field_if_int:nT { \thefield{labeldatesource} }
                  {
                    \__blxbibbyyear_seq_gput_right_once:cx
                      { g__bblxbibbyyear_yearlist_\thefield{entrytype}_seq }
                      { \thefield{\thefield{labeldatesource}} }
                  }
              }
          }
          {
            \__blxbibbyyear_seq_gput_right_once:cx
              { g__bblxbibbyyear_yearlist_\thefield{entrytype}_seq }
              { \thefield{\thefield{labeldatesource}year} }
          }
      }
  }

\cs_new:Npn \blxbibbyyear_seq_sort_bydirection:NN #1 #2
  {
    \seq_gsort:Nn #2
      {
         \int_compare:nNnTF { ##1 } #1 { ##2 }
          { \sort_return_swapped: }
          { \sort_return_same: }
      }
  }

\cs_new:Nn \blxbibbyyear_seq_sort_descending:N
  {
    \blxbibbyyear_seq_sort_bydirection:NN < #1
  }

\cs_generate_variant:Nn \blxbibbyyear_seq_sort_descending:N { c }

\cs_new_nopar:Npn \blxbibbyyear_print_yeartypebib:nnn #1 #2 #3 #4
  {
    \defbibcheck{thisyear}
      {
        \blx_field_if_int:nTF { labelyear }
          {
            \int_compare:nNnF { \thefield{labelyear} } = { #2 }
              { \skipentry }
          }
          { \skipentry }
      }
    \printbibliography[heading=subbibliography, title=#3, type=#1, check=thisyear, #4]
  }


\DeclareDocumentCommand{\printbibbytypeyear}{O{}}
  {
    \seq_map_inline:Nn \g__blxbibbyyear_typelist_seq
      { 
        \blxbibbyyear_seq_sort_descending:c { g__bblxbibbyyear_yearlist_##1_seq }
        \seq_map_inline:cn { g__bblxbibbyyear_yearlist_##1_seq }
          {
            \blxbibbyyear_print_yeartypebib:nnn { ##1 } { ####1 } { ##1~from~####1 } { #1 }
          }
      }
  }

\DeclareDocumentCommand{\printbibtypebyyear}{O{}m}
  {
    \blxbibbyyear_seq_sort_descending:c { g__bblxbibbyyear_yearlist_#2_seq }
    \seq_map_inline:cn { g__bblxbibbyyear_yearlist_#2_seq }
      {
        \blxbibbyyear_print_yeartypebib:nnn { #2 } { ##1 } { ##1 } { #1 }
      }
  }
\ExplSyntaxOff


\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{book1,
  author = {author1},
  date = {1862},
  title = {Book1},
}
@book{book2,
  author = {author1 and author2},
  date = {1831},
  title = {Book2},
}
@book{book3,
  author = {author1 and author2},
  date = {1842},
  title = {Book2},
}
@article{article1,
  title={title1},
  author={author1 and author2},
  journal={journal1},
  volume={1},
  number={1},
  pages={1},
  year={1841}
}
@article{article2,
  title={title2},
  author={author2},
  journal={journal2},
  volume={2},
  number={2},
  pages={2},
  year={1842}
}
@article{article3,
  title={title2},
  author={author2},
  journal={journal2},
  volume={2},
  number={2},
  pages={2},
  year={1842}
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}

\printbibtypebyyear{book}

\printbibtypebyyear{article}

\printbibbytypeyear
\end{document}

Separate bibliographies by type and year

5
  • moewe, If I may, isn't this stuff worthy material for biblatex-ext? (with a proper more general interface perhaps). It is certainly regularly demanded around here. And it is nice indeed. biblatex has bibbycategory, it would be natural to extend the principle.
    – gusbrs
    Feb 27, 2019 at 9:47
  • @gusbrs Mhhh, at the moment I can't see a good interface for this. The approach can be generalised to some cases, but at least how it is done at the moment, manual work needs to be involved. It is also worth noting that currently this solution needs to do some sorting, that works reasonably well for integers using expl3, but if we need to sort other stuff, LaTeX is probably not really equipped for that, so we would have to pass that job back to Biber.
    – moewe
    Feb 27, 2019 at 14:49
  • Well, I don't need to tell you to keep in mind, watchful as you are of this kind of stuff. But I do get your point.
    – gusbrs
    Feb 27, 2019 at 15:02
  • Thanks a lot for the answer, it's working great. However, it seems like I cannot pass type as an argument for the \printbibbytypeyear function as the previous version. It would be great if you can help with this since I need to call the function at different places in the document for types of bibliographies. Sorry for the confusion and I will update the question. I am very new to Latex and your help means a lot to me.
    – Xiaoyu Lu
    Feb 28, 2019 at 0:29
  • @XiaoyuLu See the edit, please.
    – moewe
    Feb 28, 2019 at 5:35

You must log in to answer this question.

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