mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-23 03:07:13 +00:00
citefind: a stray closing quote, and a note that only thanks people
Ranked what still had no work across 145,987 entries from the 30 most-cited
books, and the largest single class was this rule's own doing. A conversion
that loses an opening quotation mark leaves its partner at the end:
McClelland, J.L, D.E. Rumelhart, & G.E. Hinton 1986. The appeal of
parallel distributed processing". In Parallel Distributed Processing…
That was being refused as a title the cut had landed inside. One quotation
mark at the very end is a stray; one in the middle still means the opening is
on the page before, and is still refused.
A note that opens by thanking people cites nothing, however many names it
carries — and among endnotes it carries a great many. `Spade 1975 and 1980.`
is one short cite naming two years.
This commit is contained in:
@@ -189,6 +189,7 @@ static SHORT_CITE: LazyLock<Regex> = LazyLock::new(|| {
|
|||||||
r"(?ix) ^ (?:(?:see|cf\.?|and)\s+)?
|
r"(?ix) ^ (?:(?:see|cf\.?|and)\s+)?
|
||||||
\p{Lu}[\p{L}'’\-]{1,24}(?:\s+(?:and|&)\s+\p{Lu}[\p{L}'’\-]{1,24})?
|
\p{Lu}[\p{L}'’\-]{1,24}(?:\s+(?:and|&)\s+\p{Lu}[\p{L}'’\-]{1,24})?
|
||||||
\s+ (?:1[4-9]|20)\d{2} [a-z]?
|
\s+ (?:1[4-9]|20)\d{2} [a-z]?
|
||||||
|
(?: \s*(?:,|\s+and)\s* (?:1[4-9]|20)\d{2}[a-z]? )*
|
||||||
(?: \s* ,\s* (?:pp?\.\s*)? \d{1,4}(?:[-–]\d{1,4})? )?
|
(?: \s* ,\s* (?:pp?\.\s*)? \d{1,4}(?:[-–]\d{1,4})? )?
|
||||||
\.? $",
|
\.? $",
|
||||||
)
|
)
|
||||||
@@ -221,6 +222,15 @@ static SERIES_CITE: LazyLock<Regex> = LazyLock::new(|| {
|
|||||||
.expect("a valid pattern")
|
.expect("a valid pattern")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// What a note that thanks people opens with. These sit among the endnotes,
|
||||||
|
/// name a dozen people, and cite nothing.
|
||||||
|
static ACKNOWLEDGEMENT: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
|
Regex::new(
|
||||||
|
r"(?i)^(?:(?:my\s+|with\s+)?thanks\b|i\s+(?:am\s+(?:grateful|indebted)|thank|should\s+like\s+to\s+thank|owe)|this\s+(?:paper|chapter|essay|paper)\s+(?:was|is|grew)|an\s+earlier\s+version|parts?\s+of\s+this)",
|
||||||
|
)
|
||||||
|
.expect("a valid pattern")
|
||||||
|
});
|
||||||
|
|
||||||
/// A page reference or a bracketed imprint: what a citation has and a remark
|
/// A page reference or a bracketed imprint: what a citation has and a remark
|
||||||
/// about the argument does not.
|
/// about the argument does not.
|
||||||
static CITATION_ANCHOR: LazyLock<Regex> = LazyLock::new(|| {
|
static CITATION_ANCHOR: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
@@ -341,7 +351,11 @@ pub fn one(text: &str, marker: Option<&str>) -> Option<Reference> {
|
|||||||
if !CITATION_SIGNAL.is_match(text) {
|
if !CITATION_SIGNAL.is_match(text) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if is_scripture(text) || BIOGRAPHY.is_match(text) || PRINT_FURNITURE.is_match(text) {
|
if is_scripture(text)
|
||||||
|
|| BIOGRAPHY.is_match(text)
|
||||||
|
|| PRINT_FURNITURE.is_match(text)
|
||||||
|
|| ACKNOWLEDGEMENT.is_match(text)
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// A short cite points at a full entry elsewhere, the way `ibid.` points
|
// A short cite points at a full entry elsewhere, the way `ibid.` points
|
||||||
@@ -845,6 +859,13 @@ fn tidy_title(raw: &str) -> String {
|
|||||||
// A trailing backslash is a line break conversion left behind, not part
|
// A trailing backslash is a line break conversion left behind, not part
|
||||||
// of anything.
|
// of anything.
|
||||||
let text = text.trim_end_matches('\\');
|
let text = text.trim_end_matches('\\');
|
||||||
|
// A conversion that lost an opening quotation mark leaves its partner at
|
||||||
|
// the end. That is a stray, not evidence the cut went wrong — which is
|
||||||
|
// what one in the middle of a run means.
|
||||||
|
let text = match text.matches('"').count() == 1 && text.ends_with('"') {
|
||||||
|
true => text.trim_end_matches('"'),
|
||||||
|
false => text,
|
||||||
|
};
|
||||||
// The quotation marks a style puts round a title are the style's, not the
|
// The quotation marks a style puts round a title are the style's, not the
|
||||||
// title's, and only the outermost pair is trimmed.
|
// title's, and only the outermost pair is trimmed.
|
||||||
let text =
|
let text =
|
||||||
@@ -1559,6 +1580,40 @@ mod tests {
|
|||||||
assert_eq!(real.title.as_deref(), Some("The Conscious Mind"));
|
assert_eq!(real.title.as_deref(), Some("The Conscious Mind"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_stray_quotation_mark_at_the_end_is_not_a_cut_title() {
|
||||||
|
// Conversion lost the opening mark and left its partner behind.
|
||||||
|
let found = read(
|
||||||
|
"McClelland, J.L, D.E. Rumelhart, & G.E. Hinton 1986. The appeal \
|
||||||
|
of parallel distributed processing\". In Parallel Distributed \
|
||||||
|
Processing, MIT Press.",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
found.title.as_deref(),
|
||||||
|
Some("The appeal of parallel distributed processing")
|
||||||
|
);
|
||||||
|
// One in the middle still means the opening is on the page before.
|
||||||
|
let cut = read(
|
||||||
|
"Mediterraneans.\" In Rethinking the Mediterranean, ed. William V. \
|
||||||
|
Harris, 64-93. Oxford: Oxford University Press, 2005.",
|
||||||
|
);
|
||||||
|
assert_eq!(cut.title, None, "{cut:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_note_that_thanks_people_cites_nothing() {
|
||||||
|
for note in [
|
||||||
|
"Thanks to Ned Block, Frank Jackson, David Kaplan and David Lewis \
|
||||||
|
for discussion of these matters over many years.",
|
||||||
|
"I am grateful to the seminar at Leiden for pressing me on this, \
|
||||||
|
and to two anonymous readers for the Press.",
|
||||||
|
"An earlier version of this chapter was given at the 1998 meeting \
|
||||||
|
of the Society, and I thank those present.",
|
||||||
|
] {
|
||||||
|
assert!(one(note, None).is_none(), "{note}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_short_cite_names_a_work_it_does_not_name() {
|
fn a_short_cite_names_a_work_it_does_not_name() {
|
||||||
// `Spade 1980` points at the full entry elsewhere in the same
|
// `Spade 1980` points at the full entry elsewhere in the same
|
||||||
@@ -1574,6 +1629,11 @@ mod tests {
|
|||||||
let several = read("Trentman 1970; Spade 1980.");
|
let several = read("Trentman 1970; Spade 1980.");
|
||||||
assert!(several.continuation);
|
assert!(several.continuation);
|
||||||
assert_eq!(several.authors, ["Trentman", "Spade"]);
|
assert_eq!(several.authors, ["Trentman", "Spade"]);
|
||||||
|
|
||||||
|
// One name, two years: `Spade 1975 and 1980.`
|
||||||
|
let years = read("Spade 1975 and 1980.");
|
||||||
|
assert!(years.continuation);
|
||||||
|
assert_eq!(years.authors, ["Spade"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user