Files
catena/Cargo.toml
T
funkpower ba8ec81735 colophon: the record a book prints in its own front matter
A catalogue's worst records are the ones whose file says nothing true about
itself: a PDF titled `Untitled` by an author called `Oxford`, which is a
publisher, from a filename that was never anything but a filename. What
those books do have is pages. The title page carries the title as the
publisher set it; the copyright page carries the imprint, the year, the
ISBN, and in most English books since the 1970s the cataloguing block, which
is a catalogue record a librarian already made, subject headings and all.

So this reads the pages. Every field names the page it came from, and a book
that printed nothing comes back empty with its fields in `unsettled` rather
than filled with something plausible — an extraction that starts at chapter
one has no front matter in it, and saying so is the answer.

Two pages look like a title page and are not, and both are how a catalogue
comes to name the wrong book. A series advertisement lists other titles in
the shape a title page uses, over as many as four pages with only the first
announcing itself. A translation's cataloguing block prints the original
title in brackets above the real one. Both are found and refused.

Three things the pages give that no file does: the subject headings a
librarian assigned, an ISBN that exists only in print — which turns a book
with no identifier into one `bibfetch` can look up — and a title in the case
the publisher meant, because a half title prints unbroken what the title
page breaks across two lines and sets in capitals.

`--prompt` and `--merge` are citefind's: a question about exactly the fields
the pages left unsettled, composed here and answered wherever the caller
keeps a model, with the advertising taken out of what the model is shown.
A field a model answered is marked `model`, so a record always says which of
it was read and which was inferred.

Measured against 600 books of the home corpus: the cataloguing block
answered for 21% of them and agreed with the catalogue 89% of the time, most
of the residue being the catalogue's error rather than this one's. Title
pages answered for another 41%. The remaining 38% print nothing readable,
and are what the prompt is for.
2026-09-21 09:28:26 -04:00

82 lines
3.3 KiB
TOML

[workspace]
resolver = "3"
members = ["crates/*"]
[workspace.package]
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
license = "MPL-2.0"
repository = "https://git.pumpin.online/funkpower/catena"
[workspace.dependencies]
catena-cli = { path = "crates/catena-cli", version = "0.1.0" }
corpus-core = { path = "crates/corpus-core", version = "0.1.0" }
cuekit = { path = "crates/cuekit", version = "0.1.0" }
textkit = { path = "crates/textkit", version = "0.1.0" }
chunkmd = { path = "crates/chunkmd", version = "0.1.0" }
mdscrub = { path = "crates/mdscrub", version = "0.1.0" }
mdsplit = { path = "crates/mdsplit", version = "0.1.0" }
pdftriage = { path = "crates/pdftriage", version = "0.1.0" }
cuenorm = { path = "crates/cuenorm", version = "0.1.0" }
cueseg = { path = "crates/cueseg", version = "0.1.0" }
rrf = { path = "crates/rrf", version = "0.1.0" }
cuepack = { path = "crates/cuepack", version = "0.1.0" }
bibclean = { path = "crates/bibclean", version = "0.1.0" }
avplan = { path = "crates/avplan", version = "0.1.0" }
pdfgutter = { path = "crates/pdfgutter", version = "0.1.0" }
catena = { path = "crates/bindings", version = "0.1.0" }
seriesof = { path = "crates/seriesof", version = "0.1.0" }
idnorm = { path = "crates/idnorm", version = "0.1.0" }
bibfetch = { path = "crates/bibfetch", version = "0.1.0" }
bookmeta = { path = "crates/bookmeta", version = "0.1.0" }
langid = { path = "crates/langid", version = "0.1.0" }
tocfind = { path = "crates/tocfind", version = "0.1.0" }
booksniff = { path = "crates/booksniff", version = "0.1.0" }
citefind = { path = "crates/citefind", version = "0.1.0" }
colophon = { path = "crates/colophon", version = "0.1.0" }
emb = { path = "crates/emb", version = "0.1.0" }
clap = { version = "4", features = ["derive"] }
clap_mangen = "0.3"
pyo3 = { version = "0.27", features = ["extension-module", "abi3-py39"] }
wasm-bindgen = "0.2"
serde-wasm-bindgen = "0.6"
deunicode = "1"
fancy-regex = "0.16"
# 0.38 is the last release that builds on the pinned toolchain; the ones
# after it need a newer compiler than the rest of this asks for.
lopdf = { version = "0.38", default-features = false }
# Reading one small member out of an EPUB. Default features pull in four
# compression backends; an EPUB is deflate or nothing.
zip = { version = "2", default-features = false, features = ["deflate"] }
regex = "1"
schemars = "1"
serde = { version = "1", features = ["derive"] }
# float_roundtrip: without it a float read back from JSON can be one unit in
# the last place away from the one that was written, which would make a
# record that round-trips through a pipe not the record it started as.
serde_json = { version = "1", features = ["float_roundtrip"] }
thiserror = "2"
unicode-general-category = "1"
unicode-normalization = "0.1"
ureq = { version = "3", features = ["json"] }
tiktoken-rs = "0.12"
[workspace.lints.rust]
unsafe_code = "forbid"
missing_docs = "warn"
[profile.release]
strip = true
lto = true
codegen-units = 1
# The Python extension module, which cannot be stripped the way a binary can.
# Stripping a dylib's symbols leaves one macOS refuses to load at all —
# "mis-aligned LINKEDIT string pool" — and there is nothing to strip for
# anyway, since the interpreter resolves its symbols at load time.
[profile.wheel]
inherits = "release"
strip = false