I want to create my own bibliography style!

You’re in luck! Code for creating new bibliographic style files (BSTs) should be included in your (La)TeX distribution.

Simply run latex makebst or tex makebst, which starts a (somewhat lengthy) series of questions. Go with the default values for the master file and language definition file (merlin.mbs), pick the name for your about-to-be-created BST, and then answer the questions about the various style options. (Section 9 of Patrick W. Daly’s documentation contains an overview of the options with more detailed descriptions.) The questions look like this:

STYLE OF CITATIONS:
(*) Numerical as in standard LaTeX
(a) Author-year with some non-standard interface
(b) Alpha style, Jon90 or JWB90 for single or multiple authors
(o) Alpha style, Jon90 even for multiple authors
(f) Alpha style, Jones90 (full name of first author)
(c) Cite key (special for listing contents of bib file)
  Select:
\ans=

(In this case, hit enter for a numeral citation style (the default value marked with *) or enter one of the letters corresponding to the choices first.)

This creates a ‘docstrip batch job’ file (yourfilename.dbj) that summarizes your choices and how they should be applied to the original merlin.mbs file (which contains code for all options) to just retrieve the code relevant to your choices.

At the very end, answer y to Shall I now run this batch job?. (If you went with the default ‘no,’ you can do so manually: latex yourfilename.dbj or tex yourfilename.dbj.)

Add your beautiful new BST file to your project folder and include it in your code via \bibliographystyle{yourfilename}.

Help, I picked a wrong option but don't want to repeat the full questionnaire!

Just continue the script (and decline running the batch job at the end), then open yourfilename.dbj and find the section for the option you want to change. Then simply comment out the previously chosen option and remove the % from the beginning of the line corresponding to your new choice. The merlin.mbs documentation comes in handy for finding specific settings and understanding the options.

Say I initially chose to start all bibliography entries with author (or editor) names:

%ADJACENT REFERENCES WITH REPEATED NAMES:
    %: (def) Author/editor names always present
% nmdash,%: Repeated author/editor names replaced by dash
% nmdash,nmd-2,%: Repeated author/editor names replaced by 2 dashes
% nmdash,nmd-3,%: Repeated author/editor names replaced by 3 dashes

I can change this to the following so triple hyphens will be used in lieu of repeated names if the same author groups wrote multiple publications:

%ADJACENT REFERENCES WITH REPEATED NAMES:
%   %: (def) Author/editor names always present
% nmdash,%: Repeated author/editor names replaced by dash
% nmdash,nmd-2,%: Repeated author/editor names replaced by 2 dashes
nmdash,nmd-3,%: Repeated author/editor names replaced by 3 dashes

(Re-commenting out the default option as I did here isn’t actually necessary.) If some questions are missing from your DBJ file because getting to them would have required making different choices while running makebst, you can find their original definitions in merlin.mbs.

When you’re done editing the DBJ file, run latex yourfilename.dbj or tex yourfilename.dbj again to produce a BST file.

I know what (non-default) options I want, but I don't want to go through the entire makebst dialogue

Easy. The following is a DBJ file with all comments and extraneous line breaks removed. Just add the option codes you want to line 11 and change the BST file name in line 12.

1
2
3
4
5
6
7
8
9
10
11
12
13
\input docstrip
\preamble
----------------------------------------
***  ***
\endpreamble
\postamble
End of customized bst file
\endpostamble
\keepsilent
\askforoverwritefalse
\def\MBopts{\from{merlin.mbs}{comma,separated,list,of,non-default,options,}}
\generate{\file{yourfilename.bst}{\MBopts}}
\endbatchfile

I want to directly edit a .bst file – how does the syntax work?

In short, BST files use a stack-based language wherein arguments are added onto a stack. When the parser comes across a function, it pops the relevant number of arguments from the stack, applies the function to them, and adds the result to the stack. (For more detailed explanations on this kind of programming works, search for postfix language or Reverse Polish Notation.) For an introduction with proper examples, a list of available functions (mostly various string operations) and information on the general structure of BST files, I recommend reading chapter 4 of Nicolas Markey’s Taming the BeaST.

An example: say, you went for the nmdash and nmd-3 options because you want repeating author (or editor) names to be replaced with dashes in the bibliography, and you want to find out how that code works so you can alter it. Here’s the relevant block of code (you can find this in your BST file by searching merlin.mbs for ‘nmd-3’ and then locating the relevant lines in your file):

STRINGS {oldname}

FUNCTION {name.or.dash}
{ 's :=
   oldname empty$
     { s 'oldname := s }
     { s oldname =
         { "---{}---{}---" }
         { s 'oldname := s }
       if$
     }
   if$
}

This tells us:

  • oldname is a string variable
  • name.or.dash is a function that will…
    • 's := Assign whatever is currently on top of the stack to the variable s. (This will be the already formatted author/editor names that were put on the stack just before the name.or.dash function was called – not pictured here.) The ' is there to denote that we’re working with the variable s rather than its value here.
    • oldname empty$ {[then-code]} {[else-code]} if$ Check if the oldname string is empty. If it is, the code in the first pair of curly braces gets executed, if not, the code in the second pair.
    • The then-code: s 'oldname := s Assign the value of s to the variable oldname (s 'oldname :=) and then put s back on the stack (s).
    • The else-code contains a new if-then-else statement: s oldname = {...} {...} if$ If s equals oldname (if we have the same author group as for the last entry), "---{}---{}---" add three em-dashes to the stack, else s 'oldname := s assign s to the variable oldname and add s to the stack.

So even if the notation style might be unfamiliar, what’s actually happening here is really quite simple. If the current author group is the same as the previous one, replace the author names with three dashes. If they’re different (or if there is no previous author group), keep the author names. Either way, update the ‘previous author group’ information for the next time this function is called.

Applying minor edits is very easy then. So if you’d prefer to have one long dash instead of three shorter ones, you just need to change the line with the dashes to { "---\kern-1pt---\kern-1pt---" }.