plint

French poetry validator
git clone https://a3nm.net/git/plint/
Log | Files | Refs | README

commit e14fca5c1a96cf7a759b1ffb6089fef4bc31a699
parent 9fc43b67568a9e61bdd0044d62eb084dd3665b17
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Wed, 14 Mar 2012 19:41:55 +0100

continue to improve the frontend and help

Diffstat:
plint_web.py | 6+++++-
static/main.css | 16++++++++++++++--
views/about.html | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
views/index.html | 8++++++--
4 files changed, 137 insertions(+), 24 deletions(-)

diff --git a/plint_web.py b/plint_web.py @@ -24,6 +24,10 @@ def get_title(): else: return "plint -- French poetry checker" +@app.route('/static/tpl/<filename>') +def server_static(filename): + return static_file(filename, root="./static/tpl", mimetype="text/plain") + @app.route('/static/<filename>') def server_static(filename): return static_file(filename, root="./static") @@ -61,7 +65,7 @@ def q(): if not re.match("^[a-z]+$", d['template']): return env.get_template('error.html').render(**d) try: - f = open("tpl/" + d['template'] + ".tpl") + f = open("static/tpl/" + d['template'] + ".tpl") except IOError: return env.get_template('error.html').render(**d) templ = template.Template(f) diff --git a/static/main.css b/static/main.css @@ -30,11 +30,19 @@ header { color: #0c0; } +#bigform a { + color: white; +} + #poem { width: 100%; height: 10em; } +#custom_template { + height: 8em; +} + body { margin: 0; padding: 0; @@ -57,12 +65,16 @@ body { overflow: auto; } -dd, #custom_template { +#bigform dd, #custom_template { font-size: 80%; width:80%; margin-bottom: 0.5em; } +dt { + font-weight: bold; +} + #bigform ul { list-style-type: none; padding: 0px; @@ -103,7 +115,7 @@ h2.correct, h2.incorrect { border-left: 6px double #d23d24; } -ol { +#dump { margin: auto; border: 1px solid black; overflow: auto; diff --git a/views/about.html b/views/about.html @@ -2,6 +2,55 @@ {% block body %} {% if lang == 'fr' %} +<h2 id="template">BLAH</h2> +<p> +Écrivez ici le format suivi par votre poème. Chaque ligne du format +correspond à un vers (ie. une ligne non-vide). Une ligne peut indiquer +quatre éléments séparés par une espace : la métrique, l'identifiant de +rime, l'identifiant de genre, et le type de rime. Le premier est +obligatoire, les trois derniers sont facultatifs. +</p> +<p> +La métrique indique le nombre de syllabes du vers, et la position des +hémistiches éventuelles. Il s'agit de totaux de syllabes, séparés par +'/' pour indiquer les hémistiches. Par exemple, "6/6" est un alexandrin +classique, "12" est un alexandrin non nécessairement pourvu de coupure à +l'hémistiche. +</p> +<p> +L'identifiant de rime sert à regrouper les vers qui doivent rimer +ensemble. Les vers ayant le même identifiant doivent rimer. Pour +préciser le type de rime attendue, il est possible de terminer +l'identifiant par ':' suivie d'une liste d'entiers séparée par des '|' +indiquant les types possibles pour cette rime. Une rime est acceptable +si elle remplit l'un des critères. Le premier entier indique le nombre +de phonèmes communs nécessaires (maximum 4, défaut 1), une rime étant +acceptée pour ce critère si et seulement si le plus grand suffixe commun +de la prononciation des vers étiquetés comprend ce nombre de phonèmes, +ainsi qu'un phonème vocalique obligatoirement : ainsi, une valeur de 1, +2 ou 3 nécessite au minimum une rime pauvre, suffisante ou riche +respectivement. Le second entier indique le nombre de caractères communs +nécessaires pour une rime pour l'œil, ou -1 pour interdire (défaut -1). +Le troisième entier indique le nombre de phonèmes nécessaires pour une rime par +assonance, ie. la longueur du suffixe commun en ignorant les phonèmes +consonantiques (maximum 1, défaut -1).</p> +<p> +L'identifiant de genre de rime sert à regrouper les vers qui doivent avoir une +rime de même genre. Les conventions supplémentaires sont que deux identifiants +de casse inversée (tels que "ex" et "EX") ont des genres opposés +obligatoirement, et que "m" et "f" sont obligatoirement masculin et féminin +respectivement.</p> +</p> +<p> +Si des identifiants ne sont pas spécifiés, alors la contrainte correspondante +n'est pas spécifiée. +</p> +<p> +Une fois le format épuisé, il est lu à nouveau à partir du début, jusqu'à la fin +du poème. Les identifiants de rime et de genre sont réinitialisés (ie. peuvent +prendre n'importe quelle valeur), sauf ceux qui commencent par '!'. Il n'est pas +interdit que le poème et le format ne terminent pas simultanément. +</p> TODO TODO {% else %} <p>Welcome to <strong>plint</strong>!</p> @@ -14,13 +63,13 @@ respect to metric, rhyme and rhyme genre constraints. It uses <a href="http://gitorious.org/haspirater">haspirater</a> for aspirated 'h' detection, and a carefully handwritten system for metric and genre. It is powered by <a href="http://python.org">Python</a> and <a - href="http://flask.pocoo.org">Flask</a>. You can get the code on the <a - href="http://gitorious.org/plint">plint gitorious repository</a> to run it -locally.</p> + href="http://bottlepy.org">Bottle</a>. You can get the code on the <a + href="http://cgit.a3nm.net/plint">plint repository</a> to run it locally.</p> <h2 id="help">How do I use it?</h2> -<p>Enter your poem in the text area and select the poem template. Support for -custom poem templates is coming soon!</p> +<p>Enter your poem in the text area and select the poem template. If none of the +predefined templates suit you, you can <a href="#template">write your + own</a>.</p> <h2>What does plint check?</h2> <dl> @@ -29,7 +78,7 @@ custom poem templates is coming soon!</p> <dl> <dt>Syllable count</dt> <dd>The number of syllables in each verse is usually fixed (12 in - alexandrins, for instance). Syllables are counted in a reading with no + alexandrines, for instance). Syllables are counted in a reading with no elision of mute <em>e</em>'s except at the end of a word <em>and</em> when the following word starts with a vowel or non-aspirated <em>h</em> (or if it is the last word). The syllable count is <em>not</em> what you get with a @@ -37,16 +86,17 @@ custom poem templates is coming soon!</p> syllables either naturally ("Léon") or through <em>diérèse</em> ("passion"); plint uses a liberal approximation of allowed <em>diérèses</em>.</dd> <dt>Hemistiche</dt> - <dd>For classical alexandrins, the 12 syllables are separated in two groups - of 6 with an intermediate cesura. The cesura must not split a word and must - not end in a weak sound (essentially, a non-elided feminine ending).</dd> + <dd>For classical alexandrines, the 12 syllables are separated in two groups + of 6 with an intermediate cesura (the <em>hémistiche</em>). The cesura must + not split a word and must not end in a weak sound (essentially, a non-elided + feminine ending).</dd> </dl> <dt>Rhyme.</dt> <dd>The most well-known constraint is that verses must rhyme. The rhyming phonemes must include a vowel (eg. "tâte" and "bête" do not rhyme because - [t] does not include a vowel sound). plint enforces rhymes trough a liberal - approximation of the pronunciation of verse endings; it follows the brin/brun - distinction.</dd> + 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; it follows the brin/brun distinction.</dd> <dt>Rhyme genre.</dt> <dd>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 @@ -58,20 +108,62 @@ custom poem templates is coming soon!</p> <h2>What isn't checked by plint?</h2> <p>Syllable count is performed by a liberal estimate which will allow invalid -<em>diérèses</em> to make the count match. It is not checked if -<em>hémistiches</em> occur at a sensible grammatical position. Rhyme is -computed by a liberal heuristic, as well as rhyme genre. More importantly, +<em>diérèses</em> and <em>synérèses</em> to make the count match. It is not +checked if <em>hémistiches</em> occur at a sensible grammatical position. Rhyme +is computed by a liberal heuristic, as well as rhyme genre. More importantly, plint will not check 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 -classical alexandrin.</p> +instance, <q>Tatata tatati tatati tatata</q> is recognized as a perfectly correct +classical alexandrine.</p> -<h2>Troubleshooting</h2> +<h2 id="template">How can I define my own templates?</h2> + +<p>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:</p> +<ol> +<li>The first field is the <strong>metric indication</strong>. It is a list of +syllable counts separated by '/'s to indicate <em>hémistiches</em>. For +instance, "6/6" is a classical alexandrine, "12" is an alexandrine without +<em>hémistiche</em>.</li> +<li>The second field is the <strong>rhyme identifier</strong>. 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 three '|'-separated +integers. The first integer indicates a required number of common end phonemes +(maximum 4, default 1). The second integer indicates a required number of common +letters (for rhymes <em>pour l'œil</em>) or -1 to disable this constraint +(default: -1). The third integer indicates a required number of common end +vocalic phonemes (for <em>assonances</em>) or -1 to disable this constraint +(maximum 1, default -1). A rhyme is valid if <em>at least one</em> of the +constraints is satisfied.</li> +<li>The third field is the <strong>rhyme genre</strong>. 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.</li> +</ol> + +<p>Sorry if all of this is a bit obscure. You can have a look to the predefined +templates to understand how this works:</p> +<ul> + <li><span class="template"><a + href="static/tpl/classical.tpl">classical</a></span></li> + <li><span class="template"><a + href="static/tpl/sonnet.tpl">sonnet</a></span></li> + <li><span class="template"><a + href="static/tpl/alexandrin.tpl">alexandrin</a></span></li> +</ul> + +<h2>Common issues</h2> <ul> <li>There is no support for arabic numerals. Always spell out numbers in full.</li> <li>There is no support for acronyms or individual letters yet. Indicate the pronunciation, ie. replace "ce S" by "ce èSse".</li> + <li>If the verse total is correct but an error is reported, check the + <em>hémistiche</em>. Wrong <em>hémistiches</em> (which cut a word or end in a + feminine sound) are reported with symbols such as '!', '?' or ':'.</li> </ul> <h2 id="pron">How is pronunciation written?</h2> @@ -82,7 +174,8 @@ about French pronunciation can be found on the <a phonemes might be completely wrong. The last few ones should match, however.</p> <h2>Is there an API?</h2> -<p>Not yet. You can always run the code locally.</p> +<p>Not yet. If you want to do something creative, <a + href="http://cgit.a3nm.net/plint">grab a copy of the code</a>.</p> <h2>What about the name?</h2> diff --git a/views/index.html b/views/index.html @@ -48,8 +48,12 @@ rhyme.</dd> {% endif %} <dt><input type="radio" name="template" value="custom"> - <span class="template">custom</span> TODO help link TODO make this - work</input></dt> + <span class="template">custom</span> + {% if lang == 'fr' %} + (<a href="about#template">plus d'infos</a>) + {%else%} + (<a href="about#template">more info</a>) + {%endif%}</input></dt> <dd> <textarea name="custom_template" id="custom_template" {% if lang == 'fr' %}