55

I've started writing my thesis using LaTeX (as recommended by the school) and as a complete novice at it, I've been stuck trying to figure out how to change the citation by order of appearance.

I'm using the natbib package and a custom bibliography style that I found on the net, with my referencing going by the author-year (John et al., 2005) style as opposed to numeric [1,3]. I have done some searching but most of my results come up with people using the numeric system and being a complete beginner at this, I have yet to tinker around with something that works.

The citation I have currently looks like this: (Frank et al., 2005; John et al., 2002; Matthew, 2008)

I would like to sort it by year or turn off sorting so it will show up in the order I type it in the document.

E.g.: (John et al., 2002; Frank et al., 2005; Matthew, 2008)

The citing and bibliography itself are perfect, I'm only concerned with the citation order being unsorted (or sorted by appearance in the document), as currently it is sorting everything alphabetically by name. So my question is, how would one achieve sorting the references in the citation by appearance (or turning off alphabetical sorting) using natbib and a customized bibliostyle? And if that is not possible, could someone point me in the right direction on obtaining a similar effect?

Thank you in advance for your time and help.

5 Answers 5

37

The unsrtnat style orders the bibliography by citation order. Similar to the example from LaTeX/BibTex not arranging citations by order of appearance:

enter image description here

\documentclass{article}
\usepackage[semicolon]{natbib}

\begin{filecontents}{\jobname.bib}
@book{foo,
 author = {Foo},
 year = {2002},
 title = {Title of Foo},
}
@book{bar,
 author = {Bar},
 year = {2005},
 title = {Title of Bar},
}
@book{baz,
 author = {Baz},
 year = {2008},
 title = {Title of Baz},
}
\end{filecontents}

\begin{document}
\section{The Beginning}
First we cite \citep{foo}.
Now we cite \citep{bar}.
Then we cite \citep{baz}.
Finally, we cite \citep{foo,bar,baz}.

\bibliographystyle{unsrtnat}
\bibliography{\jobname}
\end{document}
5
  • 1
    I understand that unsrtnat style can do this for me, but is there a way to edit the style itself? The customized style I'm currently using does everything but the ordering perfectly.
    – James
    Jul 2, 2012 at 1:19
  • 5
    I'm not that good with editing .bst files manually, so my advice would be to either contact the author of your .bst file and get a modified version, or to make a new .bst using latex makebst, following the prompts, and then running tex on the created .dbj file to create the .bst. Examples given in A BibTeX Guide via Examples, section 4. Jul 2, 2012 at 13:43
  • does this still work? I am using in Overleaf and it spits out an error.
    – David
    Nov 2, 2021 at 21:48
  • This exact example in my answer? That works in Overleaf as of today, and produces the same output shown in the screenshot. Nov 4, 2021 at 19:21
  • If this doesn't work, try deleting the .bbl files, then rerun the latex compilation Feb 2, 2023 at 11:07
24

There are two ways to proceed. Regardless of which way you choose, make sure you re-run BibTeX using the new BST so that the BBL is properly updated.

1.) The Easy Way (in general)


The simplest way to accomplish what you want is to re-generate the bst using makebst. That is, from the command line, execute:

latex makebst

The resulting script will custom-build a docstrip bst driver for you. You can select all of the formatting options you like, including the sort order (if any) of the entries. Once you are finished, you will get a "dbj" file that you can use to generate your bst. For example, if the result is "mycustom.dbj", then you execute:

latex mycustom.dbj

and you will generate a "mycustom.bst". Moreover, this BST file will be natbib compatible.

2.) The Hard Way (for a general BST)


Alternatively, you can edit the bst file yourself and hack in an explicit sort order based on appearance in the manuscript. This is not difficult to do so long as you are comfortable with a postfix (think "reverse Polish notation") syntax. For example, if I open up the "abbrvnat.bst" file, I see that there is a block...

FUNCTION {presort}
{ calc.label
  label sortify
  "    "
  *
  type$ "book" =
  type$ "inbook" =
  or
    'author.editor.sort
    { type$ "proceedings" =
        'editor.organization.sort
        { type$ "manual" =
            'author.organization.sort
            'author.sort
          if$
        }
      if$
    }
  if$
  "    "
  *
  year field.or.null sortify
  *
  "    "
  *
  cite$
  *
  #1 entry.max$ substring$
  'sort.label :=
  sort.label *
  #1 entry.max$ substring$
  'sort.key$ :=
}

This is the function that sets up the order of the entries. Within the function, you have to read the code in reverse. The first important block to note starts with type$ "book" = and ends in if$. The line type$ "book" = tests if the type$ is equal to "book". The following line similarly tests if the type is inbook. The following "or" then takes the disjunction of those two, and the result is the test for the if$ at the end. The line following the or is the first branch of the if$ and the curly-braced block following that line is the else branch of the if$. The pattern continues inside the block. Basically, this section of code decides which field to sort by initially. The lines following this large section of code concatenate (* in this language) those primary sort keys with secondary sort keys, like the year. This concatenation continues until eventually the sort.key$ is assigned. So it is our job to re-write this code to set the sort.key$ based on the order of appearance in the manuscript. So, borrowing from unsrtnat.bst, we replace that block of code with the following:

INTEGERS { seq.num }

FUNCTION {init.seq}
{ #0 'seq.num :=}

EXECUTE {init.seq}
FUNCTION {int.to.fix}
{ "000000000" swap$ int.to.str$ *
  #-1 #10 substring$
}

FUNCTION {presort}
{ calc.label
  label sortify
  "    "
  *
  seq.num #1 + 'seq.num :=
  seq.num int.to.fix
  'sort.label :=
  sort.label *
  #1 entry.max$ substring$
  'sort.key$ :=
}

The result is that the sort key is consistent with the order the entries show up in the manuscript.


But, again, the best way to craft your own custom BST's is almost always to use latex makebst, which allows you to set custom sort order. Plus, the resulting BST file is natbib compatible.

5

i have run into the same issue and the solution was soo simple even if it took me weeks to figure out! try using

\bibliographystyle{unsrtnat}

as a style, yes as simple as that! this will provide you ordering of citations by the order of appearance and not by alphabetic order of the author names.

3

I have started using LaTeX shortly I noticed the same problem in document I was writing. I found simple solution, which is good if you do not have many citations like that to correct. You can make brackets by yourself and cited separately inside (and without brackets), in my case I replaced:

\citep{b1971, a1973}

by:

(\citealp{b1971}; \citealp{a1973})

It is very easy solution but it might bring some problems if one wants to change format of citation (ex. type of bracket).

1

I use natbib along with a .bst file that is specific for a journal. I needed to list my papers in the order that they appear in my document. It turned out that the following simple solution worked for me:

I opened the .bst file and commented out the lines that had only the command SORT. I saved the file with a new name and used that as my style file. Now, the papers are not sorted and they are listed in the order of their appearance.

You must log in to answer this question.

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