diff --git a/app.py b/app.py index 554f1ed..0b9f17b 100644 --- a/app.py +++ b/app.py @@ -344,6 +344,8 @@ def _final_coda_tag(pl: list[str]) -> str: if p[-1].isdigit(): last = i coda = "".join(_coda_class(DIGITS.sub("", p)) for p in pl[last + 1:]) + if coda.endswith("S"): + coda = coda[:-1] # trailing plural/3rd-person sibilant is transparent return coda or "." @@ -398,6 +400,10 @@ def weak_end_key(word: str) -> str | None: for i in range(len(pl) - 1, -1, -1): if pl[i][-1].isdigit(): syl = [DIGITS.sub("", p) for p in pl[i:]] + if syl[0] in REDUCED: + return None # a bare schwa tail (-le, -able) rhymes + # everything; weak endings need a full final vowel + # (infancy/see on IY, not middle/unavoidable on AH-L) out = [syl[0]] + [_coda_class(c) for c in syl[1:]] return "w:" + " ".join(out) return None diff --git a/tests/test_rhymes.py b/tests/test_rhymes.py index 9f0b51d..4d4399f 100644 --- a/tests/test_rhymes.py +++ b/tests/test_rhymes.py @@ -714,3 +714,12 @@ def test_garbage_javascript_dont_attach(): bg[t["g"]].add(res["lines"][t["l"]][t["s"]:t["e"]].lower()) dfam = next(s for s in bg.values() if "dollar" in s) assert "garbage" not in dfam and "javascript" not in dfam + + +def test_weak_ending_needs_a_full_vowel(): + # middle and unavoidable share only a schwa+L tail — too weak to rhyme + text = ("Wednesday has given up and admitted it's the middle\n" + "slightly apologetic and entirely unavoidable") + assert "middle" not in highlighted(text) + # but a full-vowel feminine ending still pairs (infancy/see on IY) + group_with("all I can see\nin my infancy", "see", "infancy")