mirror of
https://github.com/kennethreitz/rhymepad.org.git
synced 2026-06-11 17:08:33 +00:00
Fuse rhyme groups that share a vowel family
Perfect subgroups (shoulder/older/colder, coaster/roaster/toaster) no longer split colors with the slant family around them (soldier/ holster): groups with the same multisyllabic vowel projection merge, perfect members keep strong styling, slant members keep their marks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -547,6 +547,31 @@ def analyze(draft: Draft):
|
||||
raw_groups[gi]["toks"].append(p)
|
||||
grouped.add(id(p))
|
||||
|
||||
# fuse groups that carry the same vowel family — a perfect subgroup
|
||||
# (shoulder/older/colder) shouldn't split colors with the slant family
|
||||
# it lives inside (soldier/holster/coaster). Perfect members keep the
|
||||
# strong styling; the slant side keeps per-token slant marks.
|
||||
by_family: dict[str, dict] = {}
|
||||
fused: list[dict] = []
|
||||
for g in raw_groups:
|
||||
mk = founding_projections(g["key"]).get("multi")
|
||||
tgt = by_family.get(mk) if mk else None
|
||||
if tgt is None:
|
||||
if mk:
|
||||
by_family[mk] = g
|
||||
fused.append(g)
|
||||
continue
|
||||
if g["slant"]:
|
||||
for t in g["toks"]:
|
||||
t["slant"] = True
|
||||
elif tgt["slant"]:
|
||||
for t in tgt["toks"]:
|
||||
t["slant"] = True
|
||||
tgt["slant"] = False
|
||||
tgt["key"] = g["key"]
|
||||
tgt["toks"].extend(g["toks"])
|
||||
raw_groups = fused
|
||||
|
||||
# stable colors: order groups by first appearance
|
||||
raw_groups.sort(key=lambda g: min((t["line"], t["start"]) for t in g["toks"]))
|
||||
groups_out = []
|
||||
|
||||
@@ -281,3 +281,19 @@ def test_annotation_lines_ignored():
|
||||
(st,) = res["stanzas"]
|
||||
assert st["lines"] == [1, 2, 5, 6]
|
||||
assert st["scheme"] == "aabb"
|
||||
|
||||
|
||||
def test_perfect_subgroup_fuses_with_slant_family():
|
||||
# shoulder/older/colder (perfect, OW L D ER) live inside the bigger
|
||||
# OW-schwa family — one color for the whole column
|
||||
text = ("Skunk, bug, soldier\n"
|
||||
"Tongue, shrub, shoulder\n"
|
||||
"One month older\n"
|
||||
"Sponge, mob, colder\n"
|
||||
"Nun, rug, holster\n"
|
||||
"Lug nut, coaster\n"
|
||||
"Lung, jug, roaster\n"
|
||||
"Young Thug poster\n"
|
||||
"Unplugged toaster")
|
||||
group_with(text, "soldier", "shoulder", "older", "colder", "holster",
|
||||
"coaster", "roaster", "poster", "toaster")
|
||||
|
||||
Reference in New Issue
Block a user