Sort thebibliography (LaTeX) alphabetically using Vim

If you write a paper in LaTeX and choose not to use a *.bib file and BibTeX, but in stead simply use thebibliography to manage your citations, the citations will appear in the order that you entered them in thebibliography. There is no automatic way to have the references appear in alphabetical order. But with some (not so simple) Vim commands, the entries can be sorted quickly.

Imagine we have the following entries in thebibliography.

bibitem{ref1}
Carlton N
(2013)
Some Interesting Title
Journal of Something
12:34-45.

bibitem{paper3}
Aaron T
(2013)
Another Interesting Title
Journal of Something Else
23:56-67.

The problem is that we have to sort blocks of code according to the second line of each block. The following worked for me:

First add a ‘unique’ character to the beginning of each non-empty line (here I assumed you copied the references you want to sort to a seperate buffer).

:%s/v^./#&/
#bibitem{ref1}
#Carlton N
#(2013)
#Some Interesting Title
#Journal of Something
#12:34-45.

#bibitem{paper3}
#Aaron T
#(2013)
#Another Interesting Title
#Journal of Something Else
#23:56-67.

Second, restructure the bibitems, so that you have a single bibitem per line. Before executing this statement, make sure you have an empty line as the last line of your document.

:g/^./ .,/^$/-1 join
#bibitem{ref1} #Carlton N #(2013) #Some Interesting Title #Journal of Something #12:34-45.

#bibitem{paper3} #Aaron T #(2013) #Another Interesting Title #Journal of Something Else #23:56-67.

Third, sort every line in the document. The difficulty here is that we want to sort on the autor names. This can be done by defining the right ‘offset’ that should be used for the sorting. The code below tells Vim to sort based on the string that follows the first pound sign after the text “bibitem” (also note the use of “zs”):

:%sort /\bibitem[^#]*#zs/ 
#bibitem{paper3} #Aaron T #(2013) #Another Interesting Title #Journal of Something Else #23:56-67.
#bibitem{ref1} #Carlton N #(2013) #Some Interesting Title #Journal of Something #12:34-45.

Finally, the remaining problem is to put the bibitems back in the original structure. This is easily done by replacing each pound sign with a “newline”:

:%s/#/r/g 
bibitem{paper3} 
Aaron T 
(2013) 
Another Interesting Title 
Journal of Something Else 
23:56-67.

bibitem{ref1} 
Carlton N 
(2013) 
Some Interesting Title 
Journal of Something 
12:34-45.

Done!

Vim: Capitalize every first character of every word in a sentence

Today I got a request from a publisher to make all my references ‘title style’, meaning that all principal words in the title of the articles should be upper case. With the powerful editor Vim, this boring task can be easily automated. Below you can find a way to accomplish this using regular expressions. In order to make the final code easier to digest, I provide a step-by-step guide.


Basic vim find and replace:

:s/foo/bar/g


To avoid that the above statement would also change ‘foobar’ into ‘barbar’:

:s/<foo>/bar/g

< :: beginning of word
>
:: end of word


or, equivalent (with v you can avoid escaping special characters all the time):

:s/v<foo>/bar/g


Capitalize the first letter of the first word of a line:

:s/v^a/u&/g

^      :: beginning of line
a
   :: any alphabetic character
u
   :: make next character uppercase
&
    :: matched pattern


Capitalize every first letter of every word of a line:

:s/v<a/u&/g


Capitalize the first letter of any word of a line that appears in list (‘in’,’ik’):

:s/v<(in>|ik>)/u&/g

(in>|ik>) :: matches only words that end on ‘in’ or ‘ik’


Capitalize the first letter of any word of a line that does not appear in list (‘in’,’ik’):

:s/v<(in>|ik>)@!a/u&/g

(in>|ik>)@!    :: machtes only words that do not end on ‘in’ or ‘ik’
<(in>|ik>)@!a
:: matches first character of any word that is not in the list (‘in’,’ik’):


Capitalize every first letter of every word of a line, but not the words in the list (‘in’,’ik’) except if (‘in’,’ik’) is first word of line:

:s/v^a|<(in>|ik>)@!a/u&/g


Capitalize every first letter of every word of a line, but not the words in the list (‘in’,’ik’) except if (‘in’,’ik’) is first word of line or if (‘in’,’ik’) is the first word following a colon:

:s/v^a|:sa|<(in>|ik>)@!a/U&/g

:sa :: patter is ‘colon followed by a space followed by any alphabetical character’
U          :: since the character to capitalize appears at the end, uppercase entire match


The expression that I used to capitalize the titles of the journal articles in my bibliography is:

:s/v^a|:sa|<%(in>|the>|at>|with>|a>|and>|for>|of>|on>|from>|by>)@!a/U&/g