Parentheticals rhyme internally but never claim the line ending

(justify greed) now lights up with need/breed as internal rhyme; the
ending slot stays with the last word outside parens, so (yeah) tails
still can't set the scheme. The old all-or-nothing exclusion is gone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 12:57:49 -04:00
parent ff7a6b5790
commit 5e7845f0bb
2 changed files with 21 additions and 5 deletions
+8 -5
View File
@@ -487,8 +487,9 @@ def analyze(draft: Draft):
for i, line in enumerate(lines):
if sids[i] is None:
continue
# ad-libs — anything in (parens) mid-line — are delivery, not
# text: they don't rhyme and can't claim the line-ending slot
# parentheticals can rhyme internally, but the line-ending slot
# belongs to the last word OUTSIDE parens — "(yeah)" tails and
# backing vocals never set the scheme
adlib, depth, astart = [], 0, None
for j, ch in enumerate(line):
if ch == "(":
@@ -501,12 +502,14 @@ def analyze(draft: Draft):
adlib.append((astart, j + 1))
if depth:
adlib.append((astart, len(line)))
matches = [m for m in WORD_RE.finditer(line)
all_matches = list(WORD_RE.finditer(line))
outside = [m for m in all_matches
if not any(s <= m.start() < e for s, e in adlib)]
for j, m in enumerate(matches):
last_out = outside[-1] if outside else None
for m in all_matches:
tokens.append({
"line": i, "start": m.start(), "end": m.end(),
"word": m.group(0), "is_end": j == len(matches) - 1,
"word": m.group(0), "is_end": m is last_out,
"sid": sids[i], "gid": None, "slant": False,
})
+13
View File
@@ -617,3 +617,16 @@ def test_repetition_alone_does_not_color():
def test_repetition_colors_once_a_differing_word_joins():
text = "it was Tammy\npure whammy\nstill Tammy"
group_with(text, "tammy", "whammy")
def test_paren_words_highlight_but_never_end():
# (justify greed) rhymes internally with need/breed, but the line's
# ending slot belongs to "tragedies", outside the parens
text = ("How can we still succeed taking what we don't need?\n"
"Telling lies, alibis, selling all the hate that we breed,\n"
"Super-size our tragedies (you can't define me, or justify greed),")
group_with(text, "need", "breed", "greed", "succeed")
res = analyze(Draft(text=text))
ends = {res["lines"][t["l"]][t["s"]:t["e"]].lower()
for t in res["tokens"] if t["end"] and not t["ph"]}
assert "greed" not in ends