Read the a of a.m. and attached am as the letter name A (#2832)

Read the a of a.m. and attached am as the letter name A
This commit is contained in:
skylar taylor-barrick
2026-10-22 17:44:05 -06:00
committed by GitHub
2 changed files with 14 additions and 2 deletions
+4 -2
View File
@@ -431,6 +431,8 @@ fn parse_time(rest: &str) -> Option<(Vec<Token>, usize)> {
for (lit, letter_pair) in [("am", ['a', 'm']), ("pm", ['p', 'm'])] {
if after.get(..2).is_some_and(|s| s.eq_ignore_ascii_case(lit)) {
for letter in letter_pair {
// Uppercase "A" so it is read as a letter name, not the article.
let letter = if letter == 'a' { 'A' } else { letter };
tokens.push(Token::Word(letter.into()));
}
used += 2;
@@ -962,7 +964,7 @@ fn parse_wordish(rest: &str, _lang: Lang) -> Option<(Vec<Token>, usize)> {
if word.len() == 1 && matches!(lower.as_str(), "a" | "p") && peek(rest, used) == Some('.') && matches!(peek(rest, used + 1), Some('m') | Some('M')) {
let after_m = used + 2;
if peek(rest, after_m).is_none_or(|c| !c.is_alphanumeric()) {
let mut tokens = vec![Token::Word(word.to_ascii_lowercase())];
let mut tokens = vec![Token::Word(if lower == "a" { "A".into() } else { lower.clone() })];
tokens.push(Token::Word("m".into()));
let consumed = if peek(rest, after_m) == Some('.') { after_m + 1 } else { after_m };
return Some((tokens, consumed));
@@ -1363,7 +1365,7 @@ mod tests {
assert_eq!(words("23:59", Lang::EnUs), "twenty-three fifty-nine");
assert_eq!(words("3:30pm", Lang::EnUs), "three thirty p m");
assert_eq!(words("3:30 p.m.", Lang::EnUs), "three thirty p m");
assert_eq!(words("9:00 a.m.", Lang::EnUs), "nine zero a m");
assert_eq!(words("9:00 a.m.", Lang::EnUs), "nine zero A m");
}
#[test]
+10
View File
@@ -1335,6 +1335,16 @@ PERCENT P ER0 S EH1 N T
}
}
#[test]
fn am_reads_the_letter_name_not_the_article() {
for text in ["At 9:00 a.m.", "At 9:00am"] {
let chunks = phonemize(text, Lang::EnUs, &test_lex(), &Overrides::default()).unwrap();
let joined = format!("{chunks:?}");
assert!(joined.contains("ˈA"), "{text}: {joined}");
assert!(!joined.contains('ə'), "{text}: {joined}");
}
}
#[test]
fn every_output_char_is_in_symbols() {
let inputs = [