Tuesday, March 24, 2015

Go and unix traditions are a good match

Recently I had start writing a paper on Clive's ZX (more on this soon) and had to add citations in it. I'm writing the paper using wr(1), the Clive text formatter used to write manual pages, papers, and everything.

Because we had the entire set of bibliography entries from Plan 9 and Plan B in troff's refer format, I though wr could be teach to use them.

Being short in time, I added a new Go package to Clive that eats all the entries in the lsub refer bib directory, that have a format like

Article in conference proceedings
%A M. Bishop
%A L. Snyder
%T The Transfer of Information and Authority
in a Protection System
%J Proceedings of the 7th SOSP
%P 45-54
%D 1979


The wr/refs package exploits Go maps, strings, and slices to record a map of words to bib entries, which are also maps from keys (author, title, etc.) to strings. As easy as this:

// A reference maps from the key (eg. 'A') to values (eg. authors)
type Ref {
Keys map[rune][]string
}

// A bib maps from words found in references to references
type Bib {
refs map[string] map[*Ref]bool
all []*Ref
}

Note how easy is in Go to create sets of arbitrary types by using a map of that type to booleans.
Writing the code for these types feels very much like writing lisp.

Citing now in wr is as easy as writing [bib: plan 9 networks] in the source text.
Wr simply takes all  the words in the citation and looks them up in the Go map to locate entries matching all the words. And that's all that has to be done, the result looks like [1] in the text, and the reference is added at the end of the output as shown here.

REFERENCES

1. The organization of networks in Plan 9. D. Presotto, P. Winterbottom. USENIX Association. Proceedings of the Winter 1993 USENIX Conference. 1993.

We can now easily cite in manual pages, web pages, papers in PDF, ...

The UNIX tradition of using simple text files with line oriented format and using Go code to process them is a very powerful combination. I'm still amazed.