From 30af34874e19bc96b7cede034088b58044667b67 Mon Sep 17 00:00:00 2001 From: funkpower Date: Sun, 20 Sep 2026 17:15:49 -0400 Subject: [PATCH] citefind: a rule of dashes stands for the author and nothing else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit \_\_\_\_\_. "Die Frage nach der Echtheit von Matth. 16, 17-19." *Theologische Blätter* 20 (1941): 26-30. The dash means the author of the entry above, and an author-date entry may open on one — so the check that decides whether a run of text is the author half of such an entry accepted anything beginning with a rule of dashes. Here that is the whole entry: the title and the journal were read as more of the author, and the title came back as the page range after the year. Only a bare rule counts now. Anything after it belongs to the work. --- crates/citefind/src/parse.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/citefind/src/parse.rs b/crates/citefind/src/parse.rs index a5055c9..83634cd 100644 --- a/crates/citefind/src/parse.rs +++ b/crates/citefind/src/parse.rs @@ -565,7 +565,15 @@ fn author_date(text: &str) -> Option<(usize, usize)> { let head = &text[..span.0]; // A rule of dashes stands in for the author of the entry above, and an // author-date entry may open on one: `—— (1994), Christianizing Homer`. - if head.chars().count() > 120 || !(reads_as_names(head) || repeats_author(head)) { + // Only a bare rule, though: `\_\_\_\_\_. "Die Frage nach der Echtheit." + // *Theologische Blätter* 20 (1941)` opens on one too, and everything + // between it and the year is the title and the journal. + let bare_rule = REPEATED_AUTHOR.find(head).is_some_and(|found| { + head[found.end()..] + .trim_matches(|c: char| ".,; ".contains(c)) + .is_empty() + }); + if head.chars().count() > 120 || !(reads_as_names(head) || bare_rule) { return None; } // Something has to follow the year, or there is no title to find. @@ -1417,6 +1425,22 @@ mod tests { ); } + #[test] + fn a_rule_of_dashes_stands_for_the_author_and_nothing_else() { + // The dash opens the entry, and everything between it and the year + // is the title and the journal — not more of the author. + let found = read( + "\\_\\_\\_\\_\\_. \u{201c}Die Frage nach der Echtheit von Matth. 16, \ + 17-19.\u{201d} *Theologische Blatter* 20 (1941): 26-30.", + ); + assert_eq!( + found.title.as_deref(), + Some("Die Frage nach der Echtheit von Matth. 16, 17-19") + ); + assert_eq!(found.container.as_deref(), Some("Theologische Blatter")); + assert_eq!(found.year, Some(1941)); + } + #[test] fn an_author_date_entry_need_not_bracket_its_year() { let found = read(