Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions stackvox/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def strip_emoji(text: str) -> str:
(r"\s*÷\s*", " divided by "),
(r"\s*×\s*", " times "),
(r"\s*=\s*", " equals "),
(r"~\s*(?=\d)", "about "), # ~123 -> "about 123" (else espeak says "tilde 123"); leaves ~/path alone
],
}
DEFAULT_LOCALE = "en-GB"
Expand Down Expand Up @@ -183,6 +184,13 @@ def apply_pronunciations(text: str, mapping: dict[str, str] | None) -> str:
"postgresql": "postgres",
"kubectl": "kube control",
"stackone": "stack one", # org name espeak garbles as "stac kone"
# "dedupe" glued reads as "de-dup" (short u); split + long "dee" gives "dee doop".
# Inflections listed explicitly — apply_pronunciations matches whole words only.
"dedupe": "dee dupe",
"deduped": "dee duped",
"deduping": "dee duping",
"dedupes": "dee dupes",
"dedup": "dee dupe",
}


Expand Down
26 changes: 26 additions & 0 deletions tests/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ def test_math_symbols():
assert expand_units("770 ÷ 2 × 3 = 5").strip() == "770 divided by 2 times 3 equals 5"


def test_tilde_before_number_is_approximately():
assert expand_units("~123") == "about 123"
assert expand_units("~ 50 items") == "about 50 items"


def test_tilde_not_before_number_is_left_alone():
# home dir / approx-equal — not an approximated quantity
assert expand_units("~/projects") == "~/projects"


def test_tilde_approx_end_to_end_with_decimal():
assert normalize_for_speech("took ~1.5 hours", markdown=False) == "took about 1 point 5 hours."


def test_unknown_locale_falls_back_to_en_gb():
assert expand_units("£5", locale="xx-YY") == "5 pounds"

Expand Down Expand Up @@ -306,6 +320,18 @@ def test_dev_terms_leave_correctly_voiced_acronyms_alone():
assert "API" in out


def test_dedupe_respelled_for_speech():
assert normalize_for_speech("dedupe the list", markdown=False) == "dee dupe the list."
# inflections and case
assert "dee duped" in normalize_for_speech("we Deduped it", markdown=False)
assert "dee duping" in normalize_for_speech("deduping now", markdown=False)


def test_dedupe_does_not_touch_other_words():
# whole-word only — must not rewrite the middle of a longer token
assert "dee dupe" not in normalize_for_speech("dedupelicated", markdown=False)


def test_dev_terms_can_be_disabled():
assert normalize_for_speech("Use the CLI.", markdown=False, dev_terms=False) == "Use the CLI."

Expand Down
Loading