mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-22 18:57:14 +00:00
citefind: a name that ends in an initial, and the imprint after it
The stop after `P.` is an initial rather than a sentence stop, so `Hoyt, Edwin P. The Supersalesmen. New York: World Publishing, 1962.` never got cut there. The name came back as `Hoyt, Edwin P. The Supersalesmen` and the next segment along — the imprint — became the work. Both fields wrong from one missing cut. An inverted name whose forenames end in an initial, with two or more words after it, now ends at that initial. Two words, because one is a forename: `Price, M. Philips` and `Drexler, K. Eric` are whole names and must not be cut. And the segment the reader settles on for a title may not be an imprint — which is what the function has said it did since it was written, in a comment above a predicate that never checked. Asked narrowly enough that a title with a colon in it survives. On 199 reference chapters never used for tuning, imprints stored as the work fall from 376 to 55, and the share of rows naming an author rises from 86.1% to 88.1%.
This commit is contained in:
@@ -185,6 +185,7 @@ is enough: a block is a single entry or a list of them, not a mixture.
|
||||
| Commas and a place | `Cheyne, T. K., Founders of Old Testament Criticism, London, 1893.` |
|
||||
| Reading list, unmarked | `Block, N. 1981. Psychologism and behaviorism. Philosophical Review 90:5-43.` |
|
||||
| Editor in the author's place | `Barratt, Alexandra, ed. Women's Writing in Middle English. London: Longman, 1992.` |
|
||||
| A name that ends in an initial | `Hoyt, Edwin P. The Supersalesmen. New York: World Publishing, 1962.` |
|
||||
| A reprint's two years | `Schleiermacher, Friedrich. 1813/1963. "Ueber die verschiedenen Methoden…"` |
|
||||
| Chapter in a book | `Brown, Peter. "Sorcery…" In *Witchcraft Confessions*, ed. Mary Douglas, 17-45. London: Tavistock, 1970.` |
|
||||
|
||||
@@ -223,6 +224,13 @@ topic is not an author and `Buss, 1989` is not a work, so it is flagged
|
||||
**Take a translator's note for a reference.** An em dash and a role at the
|
||||
end — `— Ed.`, `— Tr.` — is how a translator signs a note of their own.
|
||||
|
||||
**Take where a book was published for what it is called.** `Leiden: Brill,
|
||||
2003` and `New York: 1928` are an imprint standing on its own, and a segment
|
||||
that is only an imprint is skipped rather than read as the title. A title
|
||||
with a colon in it is not one: `Russian Popular Culture: Entertainment and
|
||||
Society since 1900` survives, which is why the imprint is asked for narrowly
|
||||
— a place of up to three words, and then a year or a publisher and a year.
|
||||
|
||||
**Take a note's own remark for a work.** `The Commentator seems to have
|
||||
based himself principally on the Bible` and `Dewey remarks that we experience
|
||||
most things as temporal` are what a page of endnotes is mostly made of. A
|
||||
|
||||
@@ -260,6 +260,34 @@ static GLOSS_SIGNATURE: LazyLock<Regex> = LazyLock::new(|| {
|
||||
.expect("a valid pattern")
|
||||
});
|
||||
|
||||
/// `Hoyt, Edwin P. The Supersalesmen.` is one segment, because the stop
|
||||
/// after an initial is not a sentence stop. An inverted name whose forenames
|
||||
/// end in an initial, with more words after it, ends at that initial — what
|
||||
/// follows is the title. Leaving the two joined cost both: the name came
|
||||
/// back with a title stuck to it, and the imprint after it became the work.
|
||||
static NAME_THEN_TITLE: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(r"^([^,]{2,40},(?:\s+[A-Z][A-Za-z.'\-]*)*?\s+[A-Z]\.)\s+([A-Z]\S*(?:\s+\S+)+)$")
|
||||
.expect("a valid pattern")
|
||||
});
|
||||
|
||||
/// A segment that is nothing but where the book was published, which is not
|
||||
/// what it is called. A place of up to three words, a colon, and then either
|
||||
/// a bare year — `New York: 1928` — or a publisher and a year: `Leiden:
|
||||
/// Brill, 2003`. Asked that narrowly because a title may have a colon in it
|
||||
/// too, and `Russian Popular Culture: Entertainment and Society since 1900`
|
||||
/// has to survive it.
|
||||
static IMPRINT_ALONE: LazyLock<Regex> = LazyLock::new(|| {
|
||||
Regex::new(
|
||||
r"(?x)
|
||||
^ [A-Z][A-Za-z.\-']* (?: \ [A-Za-z.\-']+ ){0,2} \s* : \s*
|
||||
(?:
|
||||
(?: 1[5-9]\d\d | 20[0-2]\d ) \.? $
|
||||
| .{0,60} , \s* (?: 1[5-9]\d\d | 20[0-2]\d ) [a-z]? \.? $
|
||||
)",
|
||||
)
|
||||
.expect("a valid pattern")
|
||||
});
|
||||
|
||||
/// A finite verb, which a remark has and the name of a work does not.
|
||||
/// `Quaestiones Parisienses` and `The Lord of the Rings` are noun phrases;
|
||||
/// `The Commentator seems to have based himself on the Bible` is a note
|
||||
@@ -1344,7 +1372,20 @@ fn by_sentence(text: &str) -> (Vec<String>, Option<String>, Option<String>) {
|
||||
Some(found) => &text[..found.start()],
|
||||
None => text,
|
||||
};
|
||||
let segments: Vec<&str> = sentences(text);
|
||||
let mut segments: Vec<String> = sentences(text)
|
||||
.iter()
|
||||
.map(|segment| segment.trim().to_string())
|
||||
.collect();
|
||||
// Put back the cut the stop after an initial did not make.
|
||||
if PAREN_YEAR.find(text).is_none() {
|
||||
if let Some(caught) = segments
|
||||
.first()
|
||||
.and_then(|first| NAME_THEN_TITLE.captures(first))
|
||||
{
|
||||
let parts = [caught[1].to_string(), caught[2].to_string()];
|
||||
segments.splice(0..1, parts);
|
||||
}
|
||||
}
|
||||
let found_authors = match PAREN_YEAR.find(text) {
|
||||
Some(_) => authors(head),
|
||||
None => segments
|
||||
@@ -1371,7 +1412,9 @@ fn by_sentence(text: &str) -> (Vec<String>, Option<String>, Option<String>) {
|
||||
.by_ref()
|
||||
.find(|segment| {
|
||||
let segment = segment.trim();
|
||||
segment.chars().count() >= 4 && !PAREN_YEAR.is_match(segment)
|
||||
segment.chars().count() >= 4
|
||||
&& !PAREN_YEAR.is_match(segment)
|
||||
&& !IMPRINT_ALONE.is_match(segment)
|
||||
})
|
||||
.map(|segment| tidy_title(segment));
|
||||
let container = rest
|
||||
@@ -2228,6 +2271,60 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_name_that_ends_in_an_initial_does_not_run_on_into_the_title() {
|
||||
// The stop after `P.` is an initial, not a sentence stop, so the
|
||||
// entry never got cut there: the name came back with the title on
|
||||
// it and the imprint after it became the work.
|
||||
for (text, name, title) in [
|
||||
(
|
||||
"Hoyt, Edwin P. The Supersalesmen. New York: World Publishing, 1962.",
|
||||
"Hoyt, Edwin P.",
|
||||
"The Supersalesmen",
|
||||
),
|
||||
(
|
||||
"Heckscher, E. The Continental System. Oxford: Clarendon Press, 1922.",
|
||||
"Heckscher, E.",
|
||||
"The Continental System",
|
||||
),
|
||||
] {
|
||||
let read = one(text, None).expect("a record");
|
||||
assert_eq!(read.authors, vec![name.to_string()], "{text}");
|
||||
assert_eq!(read.title.as_deref(), Some(title), "{text}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_initial_before_a_forename_is_still_one_name() {
|
||||
// `M. Philips Price` inverts to `Price, M. Philips`, and cutting at
|
||||
// the initial there would take the forename for a title. One word
|
||||
// after the initial is a name; two are a title.
|
||||
for (text, name) in [
|
||||
(
|
||||
"Price, M. Philips. Dispatches from the Revolution. Durham: Duke, 1997.",
|
||||
"Price, M. Philips",
|
||||
),
|
||||
(
|
||||
"Drexler, K. Eric. Nanosystems, Molecular Machinery. New York: Wiley, 1992.",
|
||||
"Drexler, K. Eric",
|
||||
),
|
||||
] {
|
||||
let read = one(text, None).expect("a record");
|
||||
assert_eq!(read.authors, vec![name.to_string()], "{text}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn where_a_book_was_published_is_not_what_it_is_called() {
|
||||
// An imprint standing alone as a segment is skipped, and the reader
|
||||
// goes on looking. A title with a colon in it is not an imprint.
|
||||
let read = one("Stites, Richard. Russian Popular Culture: Entertainment and Society since 1900. Cambridge, 1992.", None).expect("a record");
|
||||
assert_eq!(
|
||||
read.title.as_deref(),
|
||||
Some("Russian Popular Culture: Entertainment and Society since 1900")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_readers_own_navigation_strip_is_not_a_reference() {
|
||||
for furniture in [
|
||||
|
||||
Reference in New Issue
Block a user