----
title: BST module – implementing the BibTeX .bst language
SPDX-FileCopyrightText: 2024 Norman Gray <https://nxg.me.uk>
SPDX-License-Identifier: BSD-2-Clause


This module implements the BibTeX Style Language, as described in the
`btxhak` document in the [BibTeX package at
CTAN](https://ctan.org/pkg/bibtex).

The key function here is the
[`process-bibs/bst`](#fn-process-bibs/bst) function, which is suitable
as an argument to `call-with-aux-file` from the `aux` module.

Extensions
----------

Beastie supports a couple of minor enhancements to the `.bst`
language, in the form of additional built-in functions.

  * `show.stack$$` : The BibTeX `stack$` function displays the stack
    _and_ clears it.  This actually _isn't_ terribly helpful for
    debugging.  The function `show.stack$$` displays the stack in the
    same way, but leaves it unchanged.

  * `printf$$` : this pops a string format, and then pops as many
    further objects as there are `~a` or `~s` format specifiers in the
    string.  It then formats and outputs the format string and
    arguments, replacing the format specifiers, from first to last, by
    the items popped from the stack, in the _reverse_ order they were popped
    (that is, from left to right, in the usual way of laying out a `.bst` file).
    The format `~a` prints the item in a readable way, whereas `~s`
    does so in a possibly variant way which makes it clearer what type
    the object is.  The format string may also include `~~` or `~%` to
    append a tilde or newline respectively.

  * `printf.push$$` and `printf.pop$$` : by default, `printf$$` sends
    its output to the same destination as `write$`, but this can be
    adjusted.  The `printf.push$$` function pops one argument from the
    `.bst` stack, and leaves none behind.  The `printf.pop$$` function
    pops nothing from the `.bst` stack, and pushes one item.

    If `printf.push$$` is given a string argument, then it
    names a file which will be created, and which will receive the
    material written by `write$`, `newline$` and `printf$$`, until a
    matching appearance of `printf.pop$$`.  That matching call will
    return the output to what it was before, and leave the name of the
    file on the stack.

    The function `printf.push$$` can also be given a numeric argument.
    If this is `#1` or `#2`, then beastie redirects output to stdout
    or the current error-port respectively, and `printf.pop$$` will
    leave an indicative string on the stack.  If the argument is `#0`,
    however, then output will be directed to a string, which is what
    will be left on the stack by `printf.pop$$`.

For example:

    function {try.printing}
    {
      "Hello from try.printing" write$ newline$ %chatter as normal

      "test.txt" printf.push$$      % redirect to file "test.txt"
      "Going to a file" write$ newline$
      #1 #2 "string" "string" "sending 1=~s and 2=~s and string=~a/~s via printf~%" printf$$
      printf.pop$$                  % leaves the filename on the stack
      "file was: " swap$ * write$ newline$ % ...printed

      #0 printf.push$$              % write to a string
      "Going to a file" write$ newline$
      printf.pop$$                  % leaves the string on the stack
      "string was: " swap$ * write$ newline$ % ...displayed
    }
