mirror of
https://github.com/kennethreitz/rhymepad.org.git
synced 2026-06-11 17:08:33 +00:00
Weak endings rhyme at line ends
Feminine rhymes anchor on the unstressed final syllable: infancy joins see/be/me (Lateralus). End-slant pass tries the bare final vowel as a fallback key, with claiming. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -333,6 +333,16 @@ def multi_keys(word: str) -> tuple[str, ...]:
|
||||
return tuple(dict.fromkeys(out))
|
||||
|
||||
|
||||
def weak_end_key(word: str) -> str | None:
|
||||
"""The bare final vowel, stress be damned — at line ends poets rhyme
|
||||
the weak syllable (infancy / see, eternity / be)."""
|
||||
ph = phones_for(word)
|
||||
if not ph:
|
||||
return None
|
||||
vowels = _all_vowels(ph)
|
||||
return ("v:" + vowels[-1]) if vowels else None
|
||||
|
||||
|
||||
def slant_key(word: str) -> str | None:
|
||||
phones = phones_for(word)
|
||||
if phones:
|
||||
@@ -611,10 +621,23 @@ def analyze(draft: Draft):
|
||||
by_slant = defaultdict(list)
|
||||
for t in tokens:
|
||||
if t["is_end"] and id(t) not in grouped:
|
||||
key = slant_key(t["word"])
|
||||
if key:
|
||||
attach_or_collect(t, key, by_slant, group_by_slant)
|
||||
for (sid, key), toks in by_slant.items():
|
||||
keys = [slant_key(t["word"])]
|
||||
wk = weak_end_key(t["word"])
|
||||
if wk and wk not in keys:
|
||||
keys.append(wk) # feminine endings: infancy rhymes see
|
||||
for key in filter(None, keys):
|
||||
gi = group_by_slant.get((t["sid"], key))
|
||||
if gi is not None:
|
||||
raw_groups[gi]["toks"].append(t)
|
||||
t["slant"] = True
|
||||
grouped.add(id(t))
|
||||
break
|
||||
else:
|
||||
for key in filter(None, keys):
|
||||
by_slant[(t["sid"], key)].append(t)
|
||||
for (sid, key), toks in sorted(by_slant.items(),
|
||||
key=lambda kv: (-len(kv[1]), kv[0][1])):
|
||||
toks = [t for t in toks if id(t) not in grouped]
|
||||
if len(toks) >= 2 and len({t["word"].lower() for t in toks}) >= 2:
|
||||
raw_groups.append({"toks": toks, "slant": True, "key": key})
|
||||
grouped.update(id(t) for t in toks)
|
||||
|
||||
@@ -420,3 +420,13 @@ def test_analyze_rejects_oversized_drafts():
|
||||
from fastapi import HTTPException
|
||||
with _pytest.raises(HTTPException):
|
||||
analyze(Draft(text="a" * 200_000))
|
||||
|
||||
|
||||
def test_weak_ending_rhymes_at_line_end():
|
||||
# Lateralus: stress sits on IN-fancy, but the weak final syllable
|
||||
# carries the rhyme at the line end
|
||||
text = ("All I see\n"
|
||||
"In my infancy\n"
|
||||
"Red and yellow then came to be\n"
|
||||
"Reaching out to me")
|
||||
group_with(text, "see", "infancy", "be", "me")
|
||||
|
||||
Reference in New Issue
Block a user