mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-22 18:57:14 +00:00
0.2.2 — a subtitle begins with a capital
title_case counted small words from the start of the whole string, so every subtitle that opened with one was set in lower case: 'Aesthetic in Kant: a Critique', 'Born Fighting: the Scots-Irish'. A colon starts a title of its own and the first word of one is capitalised however small it is. Found by book-pipeline, which had been proposing a title page's capitals verbatim into a catalogue and needed this to stop.
This commit is contained in:
@@ -67,7 +67,19 @@ pub fn title_case(title: &str) -> String {
|
||||
.to_lowercase()
|
||||
.trim_end_matches(['.', ',', ':', ';', '!', '?', ')', ']', '"', '\''])
|
||||
.to_string();
|
||||
if SMALL_WORDS.binary_search(&core.as_str()).is_ok() && at > 0 && at < last {
|
||||
// A small word stays small in the middle of a title, but not
|
||||
// where a title actually starts. A colon starts a subtitle, and
|
||||
// "Aesthetic in Kant: a Critique" is the giveaway that the rule
|
||||
// was only ever counting from the beginning of the whole string.
|
||||
let opens_a_subtitle = at > 0
|
||||
&& words[at - 1]
|
||||
.trim_end_matches(['"', '\'', ')', ']'])
|
||||
.ends_with([':', ';', '?', '!', '.']);
|
||||
if SMALL_WORDS.binary_search(&core.as_str()).is_ok()
|
||||
&& at > 0
|
||||
&& at < last
|
||||
&& !opens_a_subtitle
|
||||
{
|
||||
return word.to_lowercase();
|
||||
}
|
||||
let lowered = word.to_lowercase();
|
||||
@@ -218,3 +230,35 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod subtitle_case_tests {
|
||||
use super::title_case;
|
||||
|
||||
#[test]
|
||||
fn a_subtitle_starts_with_a_capital() {
|
||||
// The rule counted small words from the start of the string, so every
|
||||
// subtitle beginning "A", "The" or "Of" was set lower case.
|
||||
assert_eq!(
|
||||
title_case("AESTHETIC IN KANT: A CRITIQUE"),
|
||||
"Aesthetic in Kant: A Critique"
|
||||
);
|
||||
assert_eq!(
|
||||
title_case("BORN FIGHTING: THE SCOTS-IRISH"),
|
||||
"Born Fighting: The Scots-Irish"
|
||||
);
|
||||
assert_eq!(
|
||||
title_case("A HISTORY: AN INTRODUCTION TO IT"),
|
||||
"A History: An Introduction to It"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_small_word_in_the_middle_is_still_small() {
|
||||
assert_eq!(
|
||||
title_case("THE RISE AND FALL OF THE THIRD REICH"),
|
||||
"The Rise and Fall of the Third Reich"
|
||||
);
|
||||
assert_eq!(title_case("WAR OF THE WORLDS"), "War of the Worlds");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +260,14 @@ mod tests {
|
||||
#[test]
|
||||
fn an_underscored_title_is_cleaned_before_it_is_cased() {
|
||||
let cleaned = clean(&book("THE FALL_ AND THE RISE_txt", "Arendt, Hannah"));
|
||||
// "And" is capitalised because the colon starts a subtitle, and the
|
||||
// first word of one is capitalised however small it is. This asserted
|
||||
// "and" until the rule was found to be counting small words from the
|
||||
// start of the whole string, which set every subtitle opening "A",
|
||||
// "The" or "An" in lower case.
|
||||
assert_eq!(
|
||||
cleaned.book.title.as_deref(),
|
||||
Some("The Fall: and the Rise")
|
||||
Some("The Fall: And the Rise")
|
||||
);
|
||||
assert_eq!(cleaned.changes.len(), 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user