Welcome to plint!
Wait, what is this?
This is a3nm's attempt to make a better world
by eradicating that species of bad French poetry that tries to follow classical
constraints but fails. It checks the validity of a poem with
respect to metric, rhyme and rhyme genre constraints. It uses frhyme for rhymes (itself built on the
Lexique database), haspirater for aspirated 'h'
detection, and a carefully handwritten system for metric and genre. It is
powered by Python and Bottle. You can get the code on the plint repository to run it locally.
Ad: if you like plint, you might enjoy the French rhyme dictionary drime.
How do I use it?
Enter your poem in the text area and select the poem template. If none of the
predefined templates suit you, you can write your
What does plint check?
Here are some simplified explanations. To know all the details, go read the
- Syllable count
- The number of syllables in each verse is usually fixed (12 in
alexandrines, for instance). Syllables are counted in a reading with no
elision of mute e's except at the end of a word and when
the following word starts with a vowel or non-aspirated h (or if it
is the last word). The syllable count is not what you get with a
colloquial everyday reading. Some vowels clusters can count for two
syllables either naturally ("Léon") or through diérèse ("passion");
plint uses a tolerant approximation of allowed diérèses trained on a
corpus of classical texts.
- For classical alexandrines, the 12 syllables are separated in two groups
of 6 with an intermediate cesura (the hémistiche). The cesura must
not split a word and must not end in a weak sound (essentially, a non-elided
- The fact that verses must rhyme is the most well-known poetic constraint.
The rhyming phonemes must include a vowel (eg. "tâte" and "bête" do not rhyme
because their common phoneme suffix is [t] which does not include a vowel
sound). plint enforces rhymes trough a liberal approximation of the
pronunciation of verse endings. Plint merges [ɛ] et [ɛː] ("mettre" and
"maître") and [a] and [ɑ] ("patte" and "pâte") but distinguishes [ɛ̃] and [œ̃]
("brin" and "brun") and [ɔ] and [o] ("cotte" and "côte"). When all classical
rules are enforced, some rhymes such as rime normande and rhymes for
a liaison supposée are accepted though they do not rhyme
- Eye rhyme.
- Classical rules require a minimal degree of rime pour l'œil (end
letter similarity); thus "-é" and "-er" do not rhyme, although common
tolerances exist, such as allowing "-é" and "-ai".
- Rhyme genre.
- In classical verse, rhymes must be made between feminine verse endings, or
masculine verse endings. A verse ending is feminine if it ends with a silent
"e", "es" or "ent", and masculine otherwise. plint enforces this, with a
liberal approximation to try to guess if an ending is indeed silent. Besides,
feminine and masculine rhymes must alternate.
- Ambiguous patterns
- Some patterns such as "-ées" or "-ies", or "-ée" and "-ie" followed by an
aspirated 'h' or a consonant, are forbidden by classical rules. They are
called "ambiguous" because, according to classical prosody rules at the time,
they could be either pronounced or elided, so it was unclear how to count
syllables. In modern French, they are always elided, but classical poetry
still prohibits them. They are
reported by plint.
- Juxtaposition of vowel sounds in two adjacent words with no mute 'e' in
the middle is forbidden and reported. Specifically, it is forbidden to end a
word with a vowel (except mute 'e') and have the next word start with a vowel
or a non-aspirated h. Mute consonants at the end of the word avoid
hiatus, except in the specific case of the word "et" (which is considered to
end by a vowel sound).
- Repeated words
- A word may not rhyme with itself, but may rhyme with a homograph of a
different grammatical nature, so plint will report as error any multiple
occurrences of a known word in a rhyme pattern if the number of occurrences is
more than the number of grammatical natures for the word.
- Illegal characters
- Characters that are not understood by plint, such as arabic numerals, are
reported as errors: on the one hand, they are probably best avoided in
classical poetry; on the second hand plint will probably misinterpret the
verse if it does not understand some of the characters.
- Poem length
- For some poetic forms such as the sonnet, the number of verses is
fixed, so an error is raised if the pattern was not completed to the end or
What isn't checked by plint?
Syllable count is performed by a liberal estimate which may allow some
invalid diérèses and synérèses to make the count match. It is
not checked if hémistiches occur at a sensible grammatical position.
Rhyme is computed by a liberal heuristic, as well as rhyme genre. Rhymes between
words derived from one another, such as justice and injustice,
are usually not allowed,
but this is not checked by plint for lack of adequate data. More importantly,
plint will not check if the words you use exist in French, or are correctly
spelt, and if your poem makes any sense, does not contain spelling mistakes or
has any poetic value; it only enforces formal constraints. For instance,
Tatata tatati tatati tatata is recognized as a perfectly correct
Privacy: Do you keep logs?
Yes, I do, because whenever the program chokes on a poem I need to figure out
what happened, and I need the input poem for that, so I keep a trace of incoming
requests (poem, IP address, etc.). Hence, if you want to run plint on confidential or
personal poems, do not submit them to the online version; instead, retrieve the
source code and run plint locally.
How can I define my own templates?
Each template line will be checked against a non-blank poem line. When the
template is finished, it starts over from the beginning, and the rhyme and rhyme
genre identifiers (see below) are reinitialized unless they start with a '!'.
Each line contains one to three space-separated fields. The fields will be
interpreted in the following order:
- The first field is the metric indication. It is a list of
syllable counts separated by '/'s to indicate hémistiches. For
instance, "6/6" is a classical alexandrine, "12" is an alexandrine without
hémistiche. For technical reasons, the total number of syllables in a
verse is limited to 16.
- The second field is the rhyme identifier. Verses with the
same rhyme identifier must rhyme. You can suffix the pattern with ":" followed
by a rhyme constraint. The rhyme constraint is up to two '|'-separated
values. The first value is either "no" to disable classical constraints and only
enforce phonetic rhyming, or anything else (default) to enable classical
constraints. The second value is a number of required common phonemes (default
- The third field is the rhyme genre. Verses with the same
rhyme genre identifier must have the same rhyme genre. Identifiers with opposite
case (like "ex" and "EX") must represent opposite genres, "m" must represent
masculine, "f" must represent feminine.
Global options can be stated in lines starting with "! ", they are of the
form option:value and separated by spaces, with the following possibilities:
- The value should be a list of X-SAMPA phonemes (with plint's custom
mapping of multi-character to single-character phonemes) to merge (for
instance "oO"). Rhymes will be computed up to these merges.
- The value should be true or false to allow or refuse rimes normandes.
Default is true.
- The value should be true or false to allow or refuse hiatus (in the sense
of classical poetry). Default is false.
- The value should be either "classical" to enforce an approximation of the
rules of classical verse or "permissive" to enforce a more permissive
approximations which will allow mostly all phonetically reasonable diérèses
and synérèses. Default is "classical".
- The value should be true or false to allow or refuse patterns such as
"ées", "ies". Default is false. If you set this, it may be preferable to set
"diaeresis" to "permissive" so that the ambiguous patterns are counted
- If the value is false, the template will not repeat, and going beyond its
end will be an error. Default is true.
- If the value is false, the poem should match the length of the template
(or a multiple thereof is repeat_ok was set), and not completing a template
run will be an error. Default is true.
- Allow liaison supposée for rhymes (default is true).
- Allow liaison supposée for rimes pour l'œil (default is
- Allow tolerances for rimes pour l'œil such as "-é"/"-ai" (default
- Require at least 2 characters in rimes pour l'œil when the sound
rhyme is poor (only one phoneme) and there are no monosyllabic words in the
rhyme (default is true, only applies to classical rhymes). If you want to
disable rimes pour l'œil altogether, see the part about rhyme
- Allow liaison supposée for the rime pour l'œil for
poor_eye_required (default is false).
- Do not require the rhyme of poor_eye_required for successions of two
vocalic sounds (such as Noé/avoué).
Sorry if all of this is a bit obscure. You can have a look to the predefined
templates to understand how this works:
- There is no support for arabic numerals. Always spell out numbers in
- If the verse total is correct but a metric error is reported, check the
hémistiche. Wrong hémistiches (which cut a word or end in a
feminine sound) are reported.
How is pronunciation written?
It is X-SAMPA. Information
about French pronunciation can be found on the French
Wiktionary. Be aware that because of various limitations, the leading
phonemes might be completely wrong. The last few ones should match, however.
Is there an API?
Not yet. If you want to do something creative, grab a copy of the code.
What about the name?
It's "plint" for "poem lint" (like the "lint" tool for
programs), but also because "plint" in French would be read like "plainte",