tags:

views:

30

answers:

1

Hi,

my question is regarding the way a bibtex-style field is defined in a bst file. I would like to have the following example below explained piece by piece, to understand what each piece is doing. I would like to be in a position to make changes to that example myself.

FUNCTION {format.eprint}
{ eprint duplicate$ empty$
    'skip$
    { "\eprint"
      archive empty$
        'skip$
        { "[" * archive * "]" * }
      if$
      "{" * swap$ * "}" *
    }
  if$
}
+1  A: 

The BibTeX language is a bit complex: for a full reference take a look at Tame the BeaST. The key things to remember are that it is a stack language and that it uses a postfix approach. Almost all of the built-in functions also remove their input from the stack.

Taking it piece by piece, the first line starts with FUNCTION, which means it will define a new function (format.eprint) that can be used elsewhere in the .bst file. Importantly, this new function can only be used below here: the order of functions in the .bst file is important. The braces are used to show different arguments: FUNCTION needs two, the name of the function and the code that implements it.

In the code itself, eprint will be a field. Using the name of a field adds the value of the field to the stack (for the current record). We then have duplicate$, which duplicates the top item on the stack. This is a BibTeX build-in instruction, shown by the terminal $. So the stack will now contain two copies of the value of eprint.

The next instruction is empty$. This will test if the top item of the stack is empty and deletes it, hence the need for the duplicate$. The result of the test is either 1 or 0, which is left on the stack. So the top item on the stack is now either 1 or 0, and the next item is the value of eprint.

Next you have an if$ statement, which is in postfix and so has the two branches before the if$. As the language is postfix, what happens is that the if$ will select the true branch if the top item on the stack is 1 and the false branch otherwise. That also removes the top item from the stack. (If you want the real detail, the two branches are actually placed on the stack, and the if$ statement then removes the appropriate one and leaves the rest of the material to be executed.)

The first (true) branch reads 'skip$, which is a 'do nothing' instruction. The braces around a single instruction can be missed out if you include the leading '. An alternative which is (slightly) easier to read for new users would be

FUNCTION {format.eprint}
{ eprint duplicate$ empty$
    { }
    { "\eprint"
      archive empty$
        { }
        { "[" * archive * "]" * }
      if$
      "{" * swap$ * "}" *
    }
  if$
}

i.e. simply using an empty set of braces for the 'do nothing' (true) branch. So the aim here is to do nothing if the eprint field was empty.

The false branch starts "\eprint", which will place the literal \eprint onto the top of the stack. The next part them places the archive field onto the stack and does another test for an empty field. If the archive field is available, the code

"[" * archive * "]" * 

will place [ onto the stack then join it to the top item on the stack (which was \eprint): this joining operation is what * does. The value of the archive field is then added to the stack and joined on, followed by another ]. So the top of the stack will contain

\eprint[<archive>]

(where <archive> is the value of the archive field) if there is anything given for archive, and still just \eprint otherwise.

Finally, there is some more string-building to do. We have

"{" * swap$ * "}" *

which first places { onto the stack. This is joined onto the top item (\eprint or \eprint[<archive>]) to give \eprint{. The swap$ function swaps the top two items on the stack, so the top item is name <eprint> (the value of the eprint field). There is a joint to make

\eprint{<eprint>

followed by a final addition of } to the end.

The result is that the stack will gain one item on the top. If eprint is empty there will be an empty item on the top of the stack, otherwise it will read

    \eprint{<eprint>}
Joseph Wright