Files
catena/crates/colophon
funkpower 4ea28c03b6 bibfetch: ask every register that answers about a book, in turn
An ISBN is not a DOI. The body that assigns a DOI is the only one that has
it, so one register is the whole answer. A book's identifier is assigned by
its publisher and recorded by whoever gets round to it, and the record that
comes back is as often as not missing the thing the caller wanted: asked
about 9780199205592, OpenLibrary's edition record names *The First World
War* and the press that printed it, and nobody at all as its author, because
an edition record names its authors by key.

So an ISBN now has a chain rather than a register. The edition record first,
then OpenLibrary's own index — which answers with `author_name` filled in
and costs nothing — and Google Books last, because it answers anonymous
callers only until a daily quota runs out, after which it replies 429 to
everyone behind the same address, as it is doing here today.

The first complete answer wins, an incomplete one is kept in case nothing
better comes, and a register being down is a failure only when every
register is. `source` on the record says which one answered.

colophon comes with it: the imprint reader was taking `Oxford is a
registered trade mark of Oxford University Press` for a publisher and
`Oxford N`, off `Oxford New York`, for a place. A legal notice mentioning a
press is not the press, and a city is the city and not the first letter of
the next one.
2026-09-21 09:28:27 -04:00
..

colophon

The record a book prints in its own front matter.

Part of catena.

What it does

A book states what it is twice before the text starts. The title page carries the title as the publisher set it and the name of whoever wrote it. The copyright page carries the imprint, the year, the ISBN, and — in most English-language books printed since the 1970s — the cataloguing block, which is a catalogue record a librarian made from the manuscript, subject headings and all.

So this reads the pages rather than the file. A PDF whose embedded title is Untitled and whose filename says Oxford opens on The First World War: A Very Short Introduction, by Michael Howard, and that is what comes back.

Every field names the page it was read off. Nothing is inferred: a scan that begins at the preface printed no title page, and the record of that is an empty one with every field listed in unsettled.

When you would use it

  • Cataloguing scans and secondhand files, where the embedded metadata is whatever the last tool to touch the file happened to write.
  • Checking a catalogue against the books themselves. A record that disagrees with the book's own title page is a record worth looking at.
  • Recovering an ISBN that only exists in print, which turns a book with no identifier into one bibfetch can look up.
  • Getting subject headings that nobody had to invent, from the cataloguing block of the books that print one.

Install

cargo install --git https://git.pumpin.online/funkpower/catena colophon

Example

$ colophon first-world-war.md
{"v":1,"path":"first-world-war.md","title":"The First World War","subtitle":"A Very Short Introduction","authors":["Michael Howard"],"editors":[],"isbns":["9780192803535"],"publisher":"Oxford University Press","place":"Oxford","year":2002,"subjects":[],"read_from":{"authors":"title_page","isbns":"copyright_page","publisher":"copyright_page","subtitle":"title_page","title":"title_page","year":"copyright_page"},"unsettled":["subjects"],"pages_read":16}

A library at once, and the books that say nothing about themselves:

colophon library/*.md | jq -r 'select(.title == null) | .path'

An ISBN that only exists in print, looked up:

colophon book.md | jq -r '.isbns[]' | idnorm | bibfetch --polite you@example.org

What it will not read

Two pages in a book's front matter look like a title page and are not, and both of them are how a catalogue ends up naming the wrong book. They are found and refused.

The series advertisement lists other titles in the same series in the same shape a title page uses — a work in capitals, a person beside it — sometimes for four pages, with only the first saying what it is. The uniform title in a translation's cataloguing block is the original title, printed in brackets above the real one as a filing heading.

Asking a model about the rest

Roughly a third of books print nothing this can read: an extraction that starts at chapter one has no front matter in it at all. --prompt writes a question about exactly the fields left unsettled, and --merge folds the answer back in.

colophon --prompt book.md | ollama run qwen3:8b > reply.json
colophon --merge reply.json book.md

Nothing is sent from here: the question goes to stdout, and the model is yours. What a model answers is marked model in read_from, so a record always says which of its fields were read off a page and which were answered.

The pages the question shows have had the advertising taken out of them first. Handing a model a series list is how a book becomes catalogued as whichever of two hundred other titles the model's eye fell on.

Where this stops

It reports what the book printed, not what is true. THE HUMAN CONDITION is reported in the capitals it was set in, and straightening that is bibclean's job. What a file's own metadata claims is bookmeta's. What a register says about the ISBN is bibfetch's. Which series a book belongs to is seriesof's.

Options

Option Effect
--pages <COUNT> How many pages in from the front to read. Default 16
--prompt Write the question to put to a model about what the pages left unsettled
--merge <FILE> Fill in from a model's reply and write the completed record
--quiet Say nothing; the exit code is the answer
--man Write this page as a manual page, in roff

Exit codes

Code Meaning
0 The book printed something about itself
1 It printed nothing this could read
65 The input was not readable as text
74 The file could not be read