mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-23 11:17:13 +00:00
colophon: file a book's printed subjects onto a shelf someone has
A cataloguing block states subjects in Library of Congress form, which is precise, deep and no use for browsing. Real blocks from this library read 'Political science – Early works to 1800' and 'English literature—Middle English, 1100–1500—History and criticism'. Nobody has a shelf called that. --shelf takes the closed list the library is actually browsed by and files the printed headings onto it, longest term first so a period of thought does not collapse into its parent. Matching is on whole words after folding punctuation away, because a cataloguing block separates with em dashes, en dashes, full stops and plain hyphens, often three in one heading, and OCR turns any of those into any other. What matches nothing comes back under unshelved rather than being dropped: a subject silently discarded is indistinguishable from a book that printed none, and the difference is the whole value of reading the block.
This commit is contained in:
@@ -38,6 +38,7 @@ pub mod cip;
|
||||
pub mod imprint;
|
||||
pub mod page;
|
||||
pub mod prompt;
|
||||
pub mod shelf;
|
||||
pub mod title;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
@@ -109,8 +110,18 @@ pub struct Printed {
|
||||
pub place: Option<String>,
|
||||
/// The year of publication, preferring first publication.
|
||||
pub year: Option<u16>,
|
||||
/// The subject headings the cataloguing block filed it under.
|
||||
/// The subject headings the cataloguing block filed it under, as printed.
|
||||
pub subjects: Vec<String>,
|
||||
/// Those headings filed onto a caller's own shelf, when one was given.
|
||||
///
|
||||
/// Empty without `--shelf`, and empty too when the book's subjects match
|
||||
/// nothing on it — which is an answer, and the reason `unshelved` exists.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub shelved: Vec<String>,
|
||||
/// Printed headings that matched nothing on the shelf, kept verbatim so a
|
||||
/// subject is never silently dropped.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub unshelved: Vec<String>,
|
||||
/// Which page each field was read off.
|
||||
pub read_from: BTreeMap<String, Source>,
|
||||
/// The fields a catalogue wants that this book did not print.
|
||||
@@ -197,6 +208,24 @@ fn squash(s: &str) -> String {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Read a book's front matter, and file its subjects onto a shelf.
|
||||
///
|
||||
/// `budget` is how many pages in to read; [`PAGES`] is the sensible default.
|
||||
/// Passing a [`Shelf`](shelf::Shelf) fills `shelved` and `unshelved`; without
|
||||
/// one, `subjects` is still read and both stay empty.
|
||||
pub fn read_onto(text: &str, budget: usize, shelf: Option<&shelf::Shelf>) -> Printed {
|
||||
let mut out = read(text, budget);
|
||||
if let Some(shelf) = shelf.filter(|s| !s.is_empty()) {
|
||||
let filed = shelf.file(&out.subjects);
|
||||
if !filed.on.is_empty() {
|
||||
out.note("shelved", Source::Cip);
|
||||
}
|
||||
out.shelved = filed.on;
|
||||
out.unshelved = filed.unfiled;
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Read a book's front matter.
|
||||
///
|
||||
/// `budget` is how many pages in to read; [`PAGES`] is the sensible default.
|
||||
@@ -214,6 +243,8 @@ pub fn read(text: &str, budget: usize) -> Printed {
|
||||
place: None,
|
||||
year: None,
|
||||
subjects: Vec::new(),
|
||||
shelved: Vec::new(),
|
||||
unshelved: Vec::new(),
|
||||
read_from: BTreeMap::new(),
|
||||
unsettled: Vec::new(),
|
||||
pages_read: pages.len(),
|
||||
|
||||
Reference in New Issue
Block a user