The implementation of the .bst language
This module implements the BibTeX Style Language, as described in the btxhak document in the BibTeX package at CTAN.
The key function here is the process-bibs/bst function, which is suitable as an argument to call-with-aux-file from the aux module.
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
}Index:
(en-dashify s) : Replace '-' or '--' or Unicode en-dash in the string with en-dash '–'. BibTeX permits "1+" to indicate a start-of-range, so that has to turn into a dash. If the argument is not a string, evaluates to #f
(lowercase-string/bst us) : Lowercase a ustring, returning a copy. The function mutates characters using uchar-downcase, similarly to uppercase-string/bst.
See also titlecase-string/bst.
parse-bst-file : [filename] -> list? : Parse a .bst file, returning a 'compiled' version of it. This is not of much general use, since the only thing which can use the result is internal functions in this module, but it may be of interest.
If the filename is absent or #f, then parse from stdin.
I have vague plans to create a decompiler, to turn the output of this into a .bst file, so that it would be possible to edit the result here and create a modified or derivative .bst file without insane pattern-matching.
(parse-bst-string input) : as with parse-bst-file, but parsing from a string argument (mostly for testing)
process-bibs/bst : (or (listof symbol) 'all) (listof string?) string? -> unspecified : In (process-bibs/bst citation-list bibdata-files bibstyle-file), the citation-list is a list of string citations, or the symbol 'all.
bibdata-files is a list of .bib files to be searched. Each of these is looked up in the usual TeX search path, both without then with a .bib file extension.
bibstyle-file is the .bst file to be used. This, also, is looked up both without and with the .bst file extension.
(string->page-range str) : Break a string page-range into the quoted page numbers.
If the argument is not a string, or if there are no digits present, return #f.
Argument strings such as "x1-2" or "1-2-3" are invalid as a page range and will produce #f.
(titlecase-string/bst us) : return a copy of the ustring us, converted to titlecase. This version is intended to be compatible with the definition of titlecasing for BibTeX .bst files, the documentation for which describes a slightly idiosyncratic definition of ‘titlecase’. The key peculiarities are:
btxhak.pdf document says: ‘If the first literal is the string ‘t’, it converts to lower case all letters except the very first character in the string, which it leaves alone, and except the first character following any colon and then nonnull white space, which it also leaves alone.’That is, for titlecase, the function will not uppercase anything, since the BibTeX specification implies that entries are created in uppercase or titlecase, so that titlecasing consists only of lowercasing selected letters.
For consistency, if the argument is #f, then this returns #f, and if the function is passed a string?, then (for convenience/consistency) it will be converted to a ustring? before being processed.
(uppercase-string/bst us) : Uppercase a ustring, returning a copy. The function will mutate characters, using uchar-upcase at brace level 0 only, passing unchanged any characters enclosed within braces.
This version is intended to be compatible with the .bst definition of uppercasing. See also titlecase-string/bst.
A still-rudimentary prettyprinter for a bstscm program (really for internal use only at present)