1

I have my bib close to the desired format, except I need the first name to be "lastname, firstname" and subsequent names be "firstname lastname". Currently all names are "lastname, firstname".

This is the how the current bib looks:

[1] Van Noorden, Richard, Maher, Brendan, and Nuzzo, Regina. The top 100 papers. Nature, 514(7524):550, 2014. ISSN 0028-0836.

The desired result is:

[1] Van Noorden, Richard, Brendan Maher, and Regina Nuzzo. The top 100 papers. Nature, 514(7524):550, 2014. ISSN 0028-0836.

I am currently using the following commands in my preamble associated with the bib:

\usepackage{cite}
\usepackage[square,numbers,sort&compress]{natbib}
\bibliographystyle{unsrtnat_lastfirst}

Where unsrtnat_lastfirst is an altered version of the unsrtnat style. I modified it to get the last name to be first, but I do not know how to alter the formatting for subsequent authors. The format.names function is as follows:

FUNCTION {format.names}
{ 's :=
  #1 'nameptr :=
  s num.names$ 'numnames :=
  numnames 'namesleft :=
    { namesleft #0 > }
    { s nameptr "{vv~}{ll}{, jj}{, ff}" format.name$ 't :=
      nameptr #1 >
        { namesleft #1 >
            { ", " * t * }
            { numnames #2 >
                { "," * }
                'skip$
              if$
              t "others" =
                { " et~al." * }
                { " and " * t * }
              if$
            }
          if$
        }
        't
      if$
      nameptr #1 + 'nameptr :=
      namesleft #1 - 'namesleft :=
    }
  while$
}

I found this related question to be relevant, but was unable to correctly alter my .bst to match. I would like to continue using my preamble (due to other requirements on formatting) but believe I should be able to modify this .bst to have the desired effect (with some help).

Thanks in advance. Happy to edit for more information if needed.

Mika
  • 13

1 Answers1

0

I don't know much about this stuff, but I found a good reference here, which made things a lot simpler (go upvote this answer). Apparently the language is almost like stack-based assembly, so a lot of things have to be read flipped from what we might be used to. By way of explanation, I'm going to first translate the original format.names to Python; if you compare the two, hopefully the correspondence is clear, but, IMHO, the Python is a lot more readable:

def format_names(s):
    nameptr = 1
    numnames = len(s)
    namesleft = numnames
    while namesleft > 0:
        t = builtin_format_name('{ff~}{vv~}{ll}{, jj}', nameptr, s)
        if nameptr > 1:
            if namesleft > 1:
                result += ', '
                result += t
            else:
                if numnames > 2:
                    result += ','
                else:
                    pass
                if t == 'others':
                    result += ' et~al.'
                else:
                    result += ' and '
                    result += t
        else:
            result = t
        nameptr = nameptr + 1
        namesleft = namesleft - 1
    return result

Per the reference I linked above, BibTeX breaks names into four parts: "first", "von", "last", and "jr.", which explains the format codes ff, vv, ll, and jj. So I agree with your rewrite of the format string. Now if we wanted to patch the Python, we would do something like move this line:

t = builtin_format_name('{ff~}{vv~}{ll}{, jj}', nameptr, s)

into the outer conditional's "then" branch and replace the "else" branch with:

result = builtin_format_name('{vv~}{ll}{, jj}{, ff}', nameptr, s)

If I do that and translate back to the BST language, I get this implementation:

FUNCTION {format.names}
{ 's :=
  #1 'nameptr :=
  s num.names$ 'numnames :=
  numnames 'namesleft :=
    { namesleft #0 > }
    { nameptr #1 >
        { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't :=
          namesleft #1 >
            { ", " * t * }
            { numnames #2 >
                { "," * }
                'skip$
              if$
              t "others" =
                { " et~al." * }
                { " and " * t * }
              if$
            }
          if$
        }
        { s nameptr "{vv~}{ll}{, jj}{, ff}" format.name$ }
      if$
      nameptr #1 + 'nameptr :=
      namesleft #1 - 'namesleft :=
    }
  while$
}

which seems to work as intended. So see if that solves your problem.