71

I am trying to get my list of publications to display in reverse chronological order. I can use \bibliographystyle{unsrt} as a workaround, and just order the entries manually, but I would naturally prefer if BibTeX did that for me.

What tools or approaches can I take to sort the bibliography in reverse chronological order?

1

6 Answers 6

12

You can try https://github.com/plessl/latex-goodies/tree/master/bibstyles/plainyr-rev

Haven't tested it myself. Good luck.

1
43

Here's a solution using biblatex:

\documentclass{article}

\usepackage[sorting=ydnt]{biblatex}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@misc{a01,
  author = {Author, A.},
  year = {2001},
  title = {Alpha},
}
@misc{b03,
  author = {Buthor, B.},
  year = {2003},
  title = {Bravo},
}
@misc{c02,
  author = {Cuthor, C.},
  year = {2002},
  title = {Charlie},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\nocite{*}

\begin{document}

\printbibliography

\end{document}

enter image description here

See sections 3.1.2.1 and 3.5 of the biblatex documentation for details.

1
  • 1
    Unfortunately, this does not take months/day into account. However as mentionned in this github issue, you can either define your sorting method yourself, or use the biblatex-publist style (for CVs). Mar 29, 2019 at 12:22
20

The bibliography style plainyr is a good starting point if you don't want to (or cannot) use biblatex. This style is similar to plain, but sorts the references chronologically by year. To get reverse chronological order, copy plainyr.bst to another file (such as plainrevyr.bst). Edit the new file and replace every occurrence of ITERATE with REVERSE as described in the previous answer.

plainyr.bst is the best starting point because it is the only default style that uses date as the primary sorting field, as described in http://www.ee.ic.ac.uk/hp/staff/dmb/perl/b4w_using.html#Sort

If you attempt to replace ITERATE with REVERSE in any other style you will change the sort order, but not the primary sort field. For example, starting with ieeetr results in a bibliography that is mostly sorted in reverse chronological order...and mostly isn't good enough for your CV!

2
  • Simple yet awesome!
    – Ivan Xiao
    Dec 15, 2011 at 23:35
  • Works pretty well, and is easy to implement. However, there are just a few bibles entries in my bib file for which are not put in the right order. Here is one example (and I don't see, why it would fail to sort that in the correct position): <br/>. @Proceedings{Zachmann-2007-WorkshopTrends, editor = "Gabriel Zachmann", title = "Proc. IEEE VR 2007 Workshop on 'Trends and Issues in Tracking for Virtual Environments'", month = mar, year = 2007, address = "Charlotte, NC, USA", } .
    – Gab
    Nov 8, 2019 at 7:20
12

If you're willing to customise an existing style (any existing style which orders things in ascending date order), then take the corresponding .bst file, head to the bottom, and replace ITERATE {call.type$} with REVERSE {call.type$}.

Details: You can find the existing file with (on unixes) kpsewhich plain.bst (if you want to customize the plain style). Copy that file to, say, myplain.bst, edit it, and then use {myplain} as your bibliographystyle.

Edited to clarify which ITERATE call to change.

2
  • there are many lines with ITERATE like ITERATE {presort} or ITERATE {longest.label.pass} Which one is the good one? Jun 23, 2012 at 19:53
  • Good point. I edited the answer suitably. As Craig Finch's answer points out, to do a complete job would require adjusting the presort function to move the year field.or.null sortify line to the top of the function, but that's getting into more detailed .bst hacking. Jun 23, 2012 at 21:19
6

I did this using the macro file makebst.tex, which takes you through a list of Q&A options, one of which is sort order.

I then copied over relevant chunks of code from the new .bst that macro made to the style file I actually wanted to use. The code copied:

FUNCTION {negate.year}
{ year empty$
    { "99999" }
    { year #1 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$
      year #2 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$ *
      year #3 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$ *
      year #4 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$ *
    }
    if$
}

I've now added month-based sorting (which is kind of ugly because the month three-letter abbreviations need to be parsed into #'s):

FUNCTION {sort.format.month}
{ 't :=
  t #1 #3 substring$ "l" change.case$ "jan" =
    { "01"  }
    { t #1 #3 substring$ "l" change.case$ "feb" =
      { "02"  }
      { t #1 #3 substring$ "l" change.case$ "mar" =
        { "03"  }
        { t #1 #3 substring$ "l" change.case$ "apr" =
          { "04"  }
          { t #1 #3 substring$ "l" change.case$ "may" =
            { "05"  }
            { t #1 #3 substring$ "l" change.case$ "jun" =
              { "06"  }
              { t #1 #3 substring$ "l" change.case$ "jul" =
                { "07"  }
                { t #1 #3 substring$ "l" change.case$ "aug" =
                  { "08"  }
                  { t #1 #3 substring$ "l" change.case$ "sep" =
                    { "09"  }
                    { t #1 #3 substring$ "l" change.case$ "oct" =
                      { "10"  }
                      { t #1 #3 substring$ "l" change.case$ "nov" =
                        { "11"  }
                        { t #1 #3 substring$ "l" change.case$ "dec" =
                          { "12"  }
                          { "00"  } % No match
                        if$
                        }
                      if$
                      }
                    if$
                    }
                  if$
                  }
                if$
                }
              if$
              }
            if$
            }
          if$
          }
        if$
        }
      if$
      }
    if$
    }
  if$
}

FUNCTION {negate.month}
{ month empty$
    { "999" }
    { 
      month sort.format.month #1 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$
      month sort.format.month #2 #1 substring$ chr.to.int$ #105 swap$ - int.to.chr$ *
    }
    if$
}

and bib.sort.order was replaced with:

FUNCTION {bib.sort.order}
{ sort.label
  "    "
  *
  negate.month field.or.null sortify
  swap$
  *
  negate.year field.or.null sortify
  swap$
  *
  "    "
  *
  title field.or.null
  sort.format.title
  *
  #1 entry.max$ substring$
  'sort.key$ :=
}

EDIT: Now sorts by year-then-month. I actually understand what all the code does now, too, which is an improvement.

1
-3

Here's another possibility:

  1. Download and install Java.
  2. Download and install JabRef.
  3. Open a terminal or command window.
  4. Change directory to where JabRef is installed.
  5. Start JabRef: java -jar JabRef-4.3.1.jar
  6. Click File ➡ Open library.
  7. Browse to and select your database (e.g., database.bib).
  8. Click Open.
  9. Click File ➡ Library properties.
  10. Select Save entries ordered as specified.
  11. Set Primary sort criterion to: year
  12. Check Descending.
  13. Set Secondary sort criterion to: author. Properties Dialog
  14. Click OK.
  15. Click File ➡ Save library as.
  16. Provide a new filename (e.g., sorted-database.bib).
  17. Click Save.

The library is saved in the desired order.

From there, you can use the file's pre-sorted order. In ConTeXt this would resemble:

\def\textrm{\rm}

\usebtxdataset[mybiblio][sorted-database.bib]
\definebtxrendering[mybiblio][apa][
  dataset=mybiblio,
  numbering=yes,
  sorttype=index,
]

\starttext
  \startbackmatter
    \startchapter[title=Bibliography]
      \placelistofpublications[mybiblio][method=dataset]
    \stopchapter
  \stopbackmatter
\stoptext
0

You must log in to answer this question.

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