From 56ec754c5fe4d88ca1f3bf46684cbbb74b3cf3cb Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 7 Jun 2026 05:16:39 -0400 Subject: [PATCH] Rapper-native: ad-lib awareness and a bar counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline (parentheticals) are delivery, not text — they no longer rhyme or steal the line-ending slot ("...bunch (yeah)" rhymes on bunch). The readout leads with "bar 3/16" for the caret's place in its verse. Co-Authored-By: Claude Opus 4.8 (1M context) --- app.py | 17 ++++++++++++++++- static/index.html | 4 ++++ tests/test_rhymes.py | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index 0291c18..42808ea 100644 --- a/app.py +++ b/app.py @@ -476,7 +476,22 @@ def analyze(draft: Draft): for i, line in enumerate(lines): if sids[i] is None: continue - matches = list(WORD_RE.finditer(line)) + # ad-libs — anything in (parens) mid-line — are delivery, not + # text: they don't rhyme and can't claim the line-ending slot + adlib, depth, astart = [], 0, None + for j, ch in enumerate(line): + if ch == "(": + if depth == 0: + astart = j + depth += 1 + elif ch == ")" and depth: + depth -= 1 + if depth == 0: + adlib.append((astart, j + 1)) + if depth: + adlib.append((astart, len(line))) + matches = [m for m in WORD_RE.finditer(line) + if not any(s <= m.start() < e for s, e in adlib)] for j, m in enumerate(matches): tokens.append({ "line": i, "start": m.start(), "end": m.end(), diff --git a/static/index.html b/static/index.html index b26d01c..fa42568 100644 --- a/static/index.html +++ b/static/index.html @@ -602,6 +602,10 @@ function buildReadout(){ parts.push(p); } const st = caretStanza(); + if(st){ + const bi = st.lines.indexOf(ln); + if(bi >= 0) parts.unshift(`bar ${bi + 1}/${st.lines.length}`); + } if(st && st.scheme){ const sch = st.scheme.toUpperCase(); const shown = sch.slice(0, 16).split('').join(' ') + (sch.length > 16 ? ' …' : ''); diff --git a/tests/test_rhymes.py b/tests/test_rhymes.py index 18d5db1..1949e56 100644 --- a/tests/test_rhymes.py +++ b/tests/test_rhymes.py @@ -533,3 +533,12 @@ def test_word_inside_grouped_phrase_still_rhymes(): "wastin' all this time with style") group_with(text, "mind", "time") group_with(text, "while", "style") + + +def test_inline_adlibs_excluded(): + # (yeah) is delivery, not text — bunch keeps the line-ending slot + text = ("Six-foot, seven-foot, eight-foot bunch (yeah)\n" + "I roll with the gang, throw a punch (what)") + assert scheme(text) == "aa" + assert "yeah" not in highlighted(text) + group_with(text, "bunch", "punch")