From fbdf8f6333ff3d0ba99ff27079df7a1b18ca7113 Mon Sep 17 00:00:00 2001 From: funkpower Date: Sun, 20 Sep 2026 14:47:30 -0400 Subject: [PATCH] citefind: the copyright line a digitised book prints on every page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Holquist, Making War, pp. 211-12. 106 Cambridge Histories Online © Cambridge University Press, 2008` is a short note with a page footer glued to it, and the footer was stopping the note from being read at all. One digitised book in the corpus carries that line on every one of its pages. It is cut from wherever the sentence holding the `©` began, because the name of the digitising service in front of it belongs to the footer and not to whatever note the page ended on. And a bracket or a colon belongs to an imprint or a title, never to a name: `Philosophy (Bloomington: Indiana University Press)` was being reported as the author of something. --- crates/citefind/src/parse.rs | 5 +++++ crates/citefind/src/split.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/crates/citefind/src/parse.rs b/crates/citefind/src/parse.rs index c0dc96a..f334f48 100644 --- a/crates/citefind/src/parse.rs +++ b/crates/citefind/src/parse.rs @@ -990,6 +990,11 @@ fn is_name(text: &str) -> bool { if text.chars().any(|c| c.is_ascii_digit()) { return false; } + // A bracket or a colon belongs to an imprint or a title, never to a + // name: `Philosophy (Bloomington: Indiana University Press)` is not one. + if text.contains(['(', ')', ':', '[', ']']) { + return false; + } // An editor's or translator's credit is a role, not a name. if text.to_lowercase().contains("ed.") || text.to_lowercase().contains("trans.") { return false; diff --git a/crates/citefind/src/split.rs b/crates/citefind/src/split.rs index c9b1bde..2ef64c0 100644 --- a/crates/citefind/src/split.rs +++ b/crates/citefind/src/split.rs @@ -92,6 +92,13 @@ static LOCAL_SIGNAL: LazyLock = static GLUED_NUMBER: LazyLock = LazyLock::new(|| Regex::new(r#"^(\d{1,3})(?:\p{Lu}|\*|“|")"#).expect("a valid pattern")); +/// The copyright line a digitised book prints at the foot of every page: +/// `Cambridge Histories Online © Cambridge University Press, 2008`. It is +/// not a reference, and it is glued to the end of whatever note the page +/// ended on. +static COPYRIGHT_FOOTER: LazyLock = + LazyLock::new(|| Regex::new(r"©").expect("a valid pattern")); + /// A bullet or a blockquote marker, which conversion puts in front of a note /// often enough to matter. A leading `*` is left alone: it opens an italic /// title as often as it opens a list. @@ -255,7 +262,7 @@ fn unnumbered(text: &str) -> Vec { /// cut is then made in the original, so that an italic span marking a title /// further along survives. fn strip_marker(raw: &str) -> Entry { - let text = tidy(raw); + let text = cut_footer(&tidy(raw)); let text = BULLET.replace(&text, "").to_string(); let (bare, from) = visible(&text, 160); @@ -294,6 +301,20 @@ fn strip_marker(raw: &str) -> Entry { Entry { text, marker: None } } +/// Cut the copyright line off the end of an entry. +/// +/// It runs from wherever the sentence holding the `©` began, because the +/// words in front of it — the name of the digitising service — belong to it +/// and not to the note the page ended on. +fn cut_footer(text: &str) -> String { + let Some(found) = COPYRIGHT_FOOTER.find(text) else { + return text.to_string(); + }; + let head = &text[..found.start()]; + let cut = head.rfind(". ").map_or(0, |at| at + 1); + text[..cut].trim().to_string() +} + /// The opening of an entry with its tags dropped, and where each character /// that was kept came from in the original. /// @@ -474,6 +495,15 @@ Another Anonymous Work. Cambridge, 2001."; assert_eq!(entry.text, "Smith, John. *A Real Book*. Oxford, 1998."); } + #[test] + fn the_copyright_line_a_digitised_book_prints_is_cut_off() { + let entry = strip_marker( + "Holquist, Making War, pp. 211-12. 106 Cambridge Histories Online \ + © Cambridge University Press, 2008", + ); + assert_eq!(entry.text, "Holquist, Making War, pp. 211-12."); + } + #[test] fn an_entry_with_no_marker_keeps_all_of_itself() { let entry = strip_marker("Smith, John. The Title. Oxford, 1998.");