Metadata-Version: 2.4
Name: rhymepad
Version: 0.1.0
Summary: A scratchpad for poets & rappers — phoneme-aware rhyme-scheme detection.
Author-email: Kenneth Reitz <me@kennethreitz.org>
License-Expression: ISC
Project-URL: Homepage, https://rhymepad.org
Project-URL: Source, https://github.com/kennethreitz/rhymepad.org
Keywords: rhyme,lyrics,poetry,rap,phonetics,cmudict
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Other Audience
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Artistic Software
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.110
Requires-Dist: uvicorn>=0.29
Requires-Dist: pronouncing>=0.2
Requires-Dist: wordfreq>=3.0
Requires-Dist: g2p-en>=2.1.0
Requires-Dist: pillow>=12.2.0
Dynamic: license-file

# RhymePad

A scratchpad for poets & rappers that does **live phonetic rhyme
analysis** of whatever you're writing. Type or paste lyrics into the pad
and the rhyme structure is color-coded as you type — end rhymes,
**internal rhymes**, slant rhymes, multisyllabic and multi-word rhymes —
using the actual *sounds* (CMU Pronouncing Dictionary + a g2p phoneme
fallback), not the spelling.

Yes, it knows **orange** rhymes with **door hinge**.

Live at <https://rhymepad.org>.

## Run

```console
$ uv run uvicorn app:app --reload
```

Then open <http://127.0.0.1:8000>.

## The visual language

- **Color = which sound.** Every rhyme family gets its own hue.
- **Brightness = rhyme strength, per word.** Perfect rhymes blaze, slant
  rhymes sit back, consonance fainter still — and within a family the
  perfect anchors out-glow the loose slant attachments.
- **A faint underline marks the rhyming tail** of a word (under `ight`
  in `tonight`), so you see exactly *where* the rhyme lands.
- **Gray fill = a dead line ending** that rhymes nothing.
- **Dotted gold = a near-miss** — a dead ending that's one phoneme from
  rhyming with another ending (e.g. `hand`/`bond`). A tiny edit locks it.
- **Hover any word** and its whole family brightens across the page.

Toggles for **rhyme · alliteration · rhythm** (syllable-emphasis dots,
"sheet music for your flow"). Hovering a word also names its family in
the readout. Everything you see exports to a pixel-matching **PNG**.

## How rhyme detection works

Every word is mapped to its CMU phonemes (`pronouncing`), with
lyric-friendly fallbacks (`runnin'` → `running`, possessives, made-up
words via `g2p-en`).

- **Perfect rhymes** share everything from the last stressed vowel on
  (`tonight` / `light` / `flight` → `AY T`). Matched *anywhere* in a
  line — that's the internal-rhyme detection.
- **Slant rhymes** share just the vowel run (`hold` / `coal`).
- **Multisyllabic & multi-word mosaics** — `placement of creation`,
  `orange` / `door hinge` — match across word boundaries.
- **Consonance** catches shared vowel+coda endings (`bliss` / `exist`).

The engine is taste-tuned toward *what a listener actually hears*:
rhymes don't cross stanza breaks, vowel families stay local, repeated
refrains are muted, and dialect mergers (NEAR vowel, cot-caught, nasal
and sibilant codas) are folded in. It deliberately rejects naive
vowel-matches — `garbage`/`javascript`, `middle`/`unavoidable`, and
`smell like a` do *not* rhyme, even though a coarser engine would link
them.

`( parentheticals )` are real lyrics; inline `(ad-libs)` rhyme
internally but never claim the line-ending slot. Lines starting with
`#` (your notes) or `[` (section headers) are skipped.

## Using the engine without the web app

The rhyme engine is a framework-free module — no FastAPI, no HTTP:

```python
import rhymes

result = rhymes.analyze_text("an orange door hinge\nporage")
# token spans, rhyme groups (with strength), schemes, meter,
# alliteration, near-misses, unanswered endings

rhymes.lookup_data("light", mode="rhyme")   # ranked rhymes
rhymes.word_data("orange")                  # phonetic anatomy
```

`app.py` is just the FastAPI shell around it.

There's a CLI too:

```console
$ rhymes analyze song.txt     # color-coded rhyme families, in your terminal
$ rhymes density *.txt        # which verse is the most rhyme-dense?
$ rhymes json song.txt        # the full analysis payload
```

(`uv run rhymes …` inside this repo, or `pip install rhymepad` once
it's on PyPI.)

## API

- `POST /api/analyze` `{"text": "..."}` → token spans, rhyme groups
  (with family strength), per-stanza schemes, per-line meter,
  alliteration, near-misses, and unanswered endings
- `GET /api/lookup?word=light&mode=rhyme|near|syn` → frequency-ranked
  rhymes / near rhymes (by syllable count) and WordNet synonyms
- `GET /api/word?word=...` → pronunciation, senses, homophones

Everything is served locally — no external dictionary calls.

## License

ISC. See [LICENSE](LICENSE).
