0

I'm trying to get agsm.bst to format Harvard-style correctly (or at least the way my university requires me to do it :-) ). I have an @InCollection record like the following:

@incollection{Berndt99,
    author      = {T. J. Berndt},
    title       = {Friendships in adolescence},
    booktitle   = {Making sense of social development},
    editor      = {M. Woodhead and D. Faulkner and K. Littleton},
    year        = 1999,
    publisher   = {London: Routledge in association with the Open University},
}

which needs to be formatted as follows (bbl excerpt):

\harvarditem{Berndt}{1999}{Berndt99}
Berndt, T.~J.  \harvardyearleft 1999\harvardyearright . `Friendships in
  adolescence', in: M.~Woodhead, D.~Faulkner \harvardand\ K.~Littleton (eds)
  {\em Making sense of social development}. London: Routledge in association
  with the Open University.

By default, agsm produces

\harvarditem{Berndt}{1999}{Berndt99}
Berndt, T.~J.  \harvardyearleft 1999\harvardyearright , `Friendships in
  adolescence', in: M.~Woodhead, D.~Faulkner \harvardand\ K.~Littleton (eds)
  {\em Making sense of social development}, London: Routledge in association
  with the Open University.

I have followed the advice in Change separator in Bibtex bibliography from comma to period already, but unfortunately this replaces every separating comma with a period not just the ones I want. In particular, I now also get a period after the chapter title (`Friendships in adolescence') where I need a comma.

If I understand correctly, agsm manages this by tracking output state in an output.state variable. However, I don't understand how it does this and how I might be able to get it to differentiate these two parts of the reference.

Any suggestions?

Many thanks,

Steffen

  • The agsm and dcu bib styles (both part of the harvard package) are known to (designed to!) do some fairly funky stuff with entries with multiple authors; see, e.g., the posting Citation in “dcu” bibliography style sometimes return “et al” other times full author list. Unless your university actively requires you to adhere to agsm's funky settings, you're probably better off creating a new, bespoke bib style from scratch using the makebst utility. makebst will also let you customize which punctuation characters should be used where. – Mico Apr 19 '18 at 19:09
  • Thanks. I have no issue with the handling of multiple authors in agsm, this seems OK for my use case. I'm simply looking for a solution of the problem of period vs comma. Creating a completely fresh style seems a little overkill for this. – Steffen Zschaler Apr 19 '18 at 19:36

1 Answers1

0

Having dug into this a little bit more, I found the solution. It was indeed to do with how output.nonnull manages states. This is fairly confusing in that the state tracking is used to determine what delimiter to place the next time output.nonnull is called.

Here's the original code:

INTEGERS { output.state before.all mid.sentence after.sentence after.block }

FUNCTION {init.state.consts}
{ #0 'before.all :=
  #1 'mid.sentence :=
  #2 'after.sentence :=
  #3 'after.block :=
}

STRINGS { s t f }

FUNCTION {output.nonnull}
{ 's :=
  output.state mid.sentence =
    { ", " * write$ }
    { output.state after.block =
      { add.period$ write$
        newline$
        "\newblock " write$
      }
      { output.state before.all =
          'write$
          { add.period$ " " * write$ }
          if$
      }
      if$
      mid.sentence 'output.state :=
    }
    if$
  s
}

When the year is printed, output.state is still in before.all, meaning it switches to mid.sentence and next time round a comma is appended. However, this same branch is reached for all other parts throughout. I changed this to add a new state after.year, which allowed me to mark that the year had been processed and a period is needed rather than a comma. Note that in the new code below I only need to set this state, but don't need a new if branch for checking it; the default branch already does what we want.

INTEGERS { output.state before.all mid.sentence after.sentence after.block after.year after.collection.title }

FUNCTION {init.state.consts}
{ #0 'before.all :=
  #1 'mid.sentence :=
  #2 'after.sentence :=
  #3 'after.block :=
  #4 'after.year :=
  #5 'after.collection.title :=
}

STRINGS { s t f }

FUNCTION {output.nonnull}
{ 's :=
  output.state mid.sentence =
    { ", " * write$ }
    { output.state before.all =
        {
          write$
          after.year 'output.state :=
        }
        { output.state after.block =
            { 
              add.period$ write$
              newline$
              "\newblock " write$
            }
            { add.period$ " " * write$ }
            if$
            mid.sentence 'output.state :=
        }
        if$
    }
    if$
  s
}

I've also added an after.collection.title state (I could probably have reused after.sentence, but didn't want to mess with that), which I set in the appropriate place in FUNCTION{incollection} to indicate that we have just pushed the collection title onto the stack:

FUNCTION {incollection}
{ output.bibitem
  list.label.output
  " \harvardyearleft " list.year * "\harvardyearright " * output.nonnull
  title.field field.used =
    { skip$ }
    { format.title quote "title" output.check }
    if$
    author "author" item.check
    crossref missing$
      { format.in.ed.booktitle "booktitle" output.check
        after.collection.title 'output.state :=
        ....

This gives me a period after the collection title rather than a comma.