Sébastien Wallachia330 downloadsSyllable, meter and rhyme analysis for English poetry (CMUdict-based, with optional Datamuse online lookups).
An Obsidian plugin for writing and revising English poetry: syllable and meter analysis, rhyme search, synonyms and antonyms, definitions, thematic vocabulary, an experimental sound-pattern analyzer, and a quick-reference guide — all in a tabbed sidebar panel.
Sibling project to the French plugin "Carnet du Poète," built independently for English rather than as a translation or extension of it.
Paste a poem and get, per line: a syllable count, meter (iambic / trochaic / anapestic / dactylic, named "pentameter," "tetrameter," etc.), and a rhyme scheme with colored badges. Analysis updates live as you type.
Syllable and stress data comes primarily from CMUdict (see below), with:
-'d elision (e.g. "plann'd" → "planned").Hover any line to see a per-word breakdown, including which source (CMUdict / override / heuristic / Datamuse) each word's syllable count came from.
Flip the card ("🔄 Sonorities" button, top-left) to switch to the sound-pattern panel described below.
Above the draft, the action bar offers Export (copies the analysis as a
Markdown table), Copy, Active note (loads the selection in the open
note, else its first ```poem block, else the whole note, with
frontmatter and Markdown syntax stripped) and Clear. Each line shows its
rhyme letter, its meter spelled out ("iambic trimeter") and its syllable
count. Stanzas are separated by blank lines: below the lines, one row per
stanza gives its rhyme scheme and names the common ones (couplets AABB, cross
rhyme ABAB, enclosed rhyme ABBA). Continuous rhymes across stanzas (on by
default) carries the letters on from one stanza to the next; off, each stanza
restarts at A.
The Form menu (Syllables tab) checks the poem against a fixed form —
Shakespearean, Petrarchan or Spenserian sonnet, villanelle, limerick, haiku,
heroic couplets, blank verse, terza rima, ballad stanza — with a checklist
above the analysis: ✓ rule met, ✗ rule broken, ⚠ point to check (things the
engine can only estimate: stress-based meter, a syllable count one off, a
rhyme only on the last unstressed syllable, refrains with changed wording).
Line numbers in the checklist open the Rhymes tab on that line's last word.
A form: property in a note (e.g. form: villanelle) sets the menu when the
note is loaded with Active note.
Search CMUdict for perfect rhymes (matching stressed vowel and everything after it) and near/slant rhymes (consonance or assonance), grouped by syllable count. Near rhymes are always shown in a separate section unless "Strict rhyme mode" is on in Settings. Filter by starting letter, syllable count or part of speech (noun, verb, adjective, adverb — needs Datamuse, since CMUdict has no part of speech; words whose part of speech is unknown are always kept). An optional Datamuse online lookup (off by default) adds any extra matches; a link opens the word's RhymeZone page in your browser for RhymeZone's own advanced filters.
The results say what kind of rhyme the word takes — masculine (one syllable from the stressed vowel: night), feminine (two: dancing) or triple (three: tenderly) — and keep apart identical rhymes, which also repeat the sound before the stressed vowel (night / knight, light / delight): unlike the French rime riche, English verse usually treats them as weak. Near rhymes are split into assonance (same stressed vowel: lake / fate) and consonance (same final consonants: shape / keep). In the Syllables tab, hovering a rhyme letter gives the rhyme's length, a red "identical" badge marks an identical rhyme, and the Form checklist flags them as a point to check.
Look up a word against your personal dictionary, with an optional Datamuse online lookup (off by default) shown as clickable chips — click one to save it. You can also add entries by hand. Saved entries can be removed with the × button.
On-demand lookup (nothing is fetched until you search), with two sources switched by pills, like the French plugin's dictionaries: the Free Dictionary API (dictionaryapi.dev, built on Wiktionary — pronunciation, definitions with examples, synonyms/antonyms per part of speech), tried first, and the English Wiktionary page itself (etymology and definitions), used automatically when the first has no entry. An "Open on Wiktionary ↗" link is always available.
Type a common word (forest, sea, night, love, time, fire, weather, silence…) to get rarer, more literary vocabulary on the same theme, each with a short gloss. Ten hand-written themes are built in, and a published base adds about 950 more, one per category of Roget's Thesaurus (1911), each word with a short WordNet definition (downloaded once, like CMUdict — see Data sources). An optional Datamuse "means like" online lookup (off by default) adds loosely related words.
Draw a random rare/literary word — about 6,300 from the published base
(rare words of Roget's Thesaurus with WordNet definitions, some tagged
archaic) plus the built-in and personal ones (about half are not in CMUdict: their syllables are estimated). Words tagged vulgar or sexual are left out of draws by default — remove those tags from "Exclude tags" to bring them in; the choice is remembered — with a gloss and quick links to look it up in Definitions or
search it in Rhymes.
Every word — built-in or from your personal dictionary — can also carry your own custom tags on top of its theme, be marked ♥ liked, or 🚫 excluded from future draws. Tagging or excluding a built-in word never touches its definition; it's tracked separately. Filter the draw pool by included tags (switch between matching any or all of several at once), excluded tags, a "liked only" quick filter, or a "review excluded" mode to revisit what you've set aside — with a live count of how many words match the current filters.
Every tab follows the same layout as the French sibling plugin, Carnet du Poète: framed filter boxes, a "complete online" box whose ticked sources are remembered, and results in collapsible blocks, one per source (personal or built-in data first, then each online source). Online word lists can be clicked to leave a word out before saving them to your personal dictionary. In Synonyms, Datamuse results carry a relevance (Datamuse's score rescaled to 0-100 against the best match): a threshold (All / 30% / 60% / 85%) hides the weaker ones, and strong matches (70+) are shown in bold. In Inspiration, the Datamuse block also gives collocations — adjectives often used with the word, nouns it often qualifies, and words often found near it. In Inspiration, clicking words builds a selection (kept across searches) that can be added to a personal theme or as rare words.
Lists the words in your personal dictionary that have no note yet —
rareWords and the words of your own vocabularyThemes — each with an
inline field to add a short definition, saved straight to the dictionary
file. Built-in themes always carry a note, so they never show up here.
Select a single word in the editor and right-click: Rhymes for "…" and Inspiration around "…" open the matching results in a pop-up, without leaving your note. Pop-ups use local data only (CMUdict and the vocabulary themes); no online lookup is made from them.
A static reference: meter and foot names, perfect vs. slant rhyme, classic poem forms (Shakespearean and Petrarchan sonnets, blank verse, villanelle, limerick), and a short note on poetic elision.
A flip side of the Syllables tab's card: four sound patterns across the whole poem, not just line endings.
Three grouping levels — exact ARPAbet sounds, simplified families, extended families with a voiced/voiceless split — each sound shown with a frequency ratio ("×N.N") comparing how often it occurs in this poem against its normal frequency in English, computed live from the loaded CMUdict index (no external citation needed for this — unlike the French sibling plugin, which has to lean on an older published study for lack of a better source).
Why "experimental": newer and less battle-tested than the rest of this plugin. Detection relies entirely on CMUdict's phoneme data — a word missing from CMUdict is skipped for Sonorities rather than guessed at from spelling, since English spelling-to-sound is too irregular to approximate safely the way this plugin's heuristic fallback does for basic syllable counts. Highlighting also colors the whole word rather than a precise letter range: CMUdict gives a word's phoneme identity, not a mapping back to letter positions, so there's no reliable way to know which letters correspond to a given sound the way the French plugin's orthographic scan can.
main.js, manifest.json, and styles.css into a new folder at
<vault>/.obsidian/plugins/poetry-notebook/.CMUdict gives accurate syllable counts, stress, meter and rhyme detection,
and is required for Sonorities. It installs itself: when no
cmudict.dict is found in the vault, the plugin downloads a compressed copy
(about 1 MB) attached to its own GitHub release, checks it, and saves it as
<vault>/.obsidian/plugins/poetry-notebook/cmudict.dict. This happens once,
in the background; until then (or offline) syllable counts use an
approximate heuristic, and the download is retried at the next start.
The same goes for the base vocabulary (poetry-notebook-base.json.gz,
about 0.6 MB: Inspiration themes and Random words), downloaded into the
plugin folder on first start and again only when a new version of it is
published.
Network use: these downloads, and the online lookups you tick yourself (Datamuse, Free Dictionary API, Wiktionary), are the only requests the plugin makes. Nothing about your notes is sent anywhere.
You can still provide the file yourself (e.g. offline): download
cmudict.dict from https://github.com/cmusphinx/cmudict and place it at any
of these places (checked in this order):
<vault>/.obsidian/plugins/poetry-notebook/cmudict.dict<vault>/.obsidian/cmudict.dict<vault>/cmudict.dict (vault root)then click Settings → Poet's Notebook → "Reload CMUdict".
CMUdict is public domain / unrestricted for research and commercial use.
The Synonyms tab writes to poets-notebook-dictionary.json automatically,
but you can also create or edit this file by hand — for bulk-importing
vocabulary, or adding entries no online lookup surfaces.
Where it's stored: same search order as cmudict.dict above. If no file
is found anywhere in the vault, the first save creates one at the vault
root. Override the path in Settings → Poet's Notebook → "Custom personal
dictionary path," and re-scan at any time with "Reload personal dictionary."
Format:
{
"synonyms": {
"happy": ["joyful", "glad", "content", "cheerful"]
},
"antonyms": {
"happy": ["sad", "miserable"]
},
"vocabularyThemes": [
{
"theme": "Mountains",
"triggers": ["mountain", "mountains", "peak"],
"words": [
{ "word": "crag", "note": "a steep, rugged rock or cliff" },
{ "word": "escarpment", "note": "a long, steep slope at the edge of a plateau" }
]
}
],
"rareWords": [
{ "word": "petrichor", "note": "the smell of rain on dry earth" }
],
"wordMeta": {
"petrichor": { "tags": ["favorite-sound"], "liked": true, "excluded": false }
}
}
All five top-level keys are optional and can be combined in the same file:
synonyms / antonyms — each key is a word (matched case-insensitively),
each value an array of related words. Read and written by the Synonyms tab.vocabularyThemes — extends the Inspiration tab. triggers are the
everyday words that surface the theme (matched case-insensitively, with
simple plural stripping). Also feeds the Random tab's word pool.rareWords — standalone words for the Random tab's pool without building
a full theme around them (shown with theme "Personal dictionary").wordMeta — per-word tags/liked/excluded state for the Random tab,
applying to built-in words too. Written automatically by the Random tab's
controls; editing it by hand is possible but not required for normal use.A word cannot be saved as its own synonym or antonym through the UI.
-'d → -ed pattern (e.g.
"plann'd," "belov'd"); other archaic contractions (o'er, 'twas, e'er) are
not yet normalized.vocabularyThemes as needed.The source lives in src/ as numbered files (engine, data, one file per
tab, settings, plugin), assembled into main.js by plain concatenation:
node build.js
Tests (no dependencies, run against the built main.js and the repository's
cmudict.dict):
node test/run.js
They cover syllables and meter, rhymes, whole-poem analysis, note import,
fixed forms, sonorities, the parsing of online sources (with canned
responses), personal-dictionary writes, and a smoke test that builds every
tab. A GitHub workflow runs them on every push to dev or main, and the
release workflow runs them again before publishing.
Edit the files in src/, never main.js directly. styles.css stays at
the repository root; its first section is generated from Carnet du Poète's
stylesheet with the cp- prefix renamed pn- (the command is in the file's
header), so both plugins share one look without their classes colliding. A GitHub workflow (.github/workflows/release.yml)
publishes a release automatically when a push to main carries a
manifest.json version that has no tag yet, using that version's entry
in the changelog below as release notes.
form: note
property sets it. Rhymes: part-of-speech filter (via Datamuse). Small
spacing fix under the online-sources row.!important (more specific selectors instead) and no more :has() (toggle
pills get an is-checked class from the code instead). Same look. README:
install folder corrected to .obsidian/plugins/poetry-notebook/ (the
plugin id).src/
and assembled by node build.js; automatic GitHub release on push to main.rel_ant plus a personal-dictionary
antonyms key), alongside Synonyms.