The git repo behind my blog.

lister-des-corrections-en-ligne.html 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="HandheldFriendly" content="True" />
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  8. <meta name="robots" content="index, follow" />
  9. <link href='https://phyks.me/theme/stylesheet/fonts.css' rel='stylesheet' type='text/css'>
  10. <link rel="stylesheet" type="text/css" href="https://phyks.me/theme/stylesheet/style.min.css">
  11. <link rel="stylesheet" type="text/css" href="https://phyks.me/theme/pygments/monokai.min.css">
  12. <link rel="stylesheet" type="text/css" href="https://phyks.me/theme/font-awesome/css/font-awesome.min.css">
  13. <link href="https://phyks.me/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Phyks' blog Atom">
  14. <link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">
  15. <link rel="icon" href="/images/favicon.ico" type="image/x-icon">
  16. <!-- Chrome, Firefox OS and Opera -->
  17. <meta name="theme-color" content="#333">
  18. <!-- Windows Phone -->
  19. <meta name="msapplication-navbutton-color" content="#333">
  20. <!-- iOS Safari -->
  21. <meta name="apple-mobile-web-app-capable" content="yes">
  22. <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  23. <!-- Microsoft EDGE -->
  24. <meta name="msapplication-TileColor" content="#333">
  25. <meta name="author" content="Phyks" />
  26. <meta name="description" content="Il m’arrive souvent de corriger des documents textes et de devoir noter facilement les fautes d’orthographe. Idéalement: Un humain devrait être capable de le lire sans difficultés. Une machine devrait pouvoir le parser facilement pour effectuer la correction elle-même. Le correcteur devrait avoir un minimum de mots à …" />
  27. <meta name="keywords" content="">
  28. <meta property="og:site_name" content="Phyks' blog"/>
  29. <meta property="og:title" content="Lister des corrections en ligne"/>
  30. <meta property="og:description" content="Il m’arrive souvent de corriger des documents textes et de devoir noter facilement les fautes d’orthographe. Idéalement: Un humain devrait être capable de le lire sans difficultés. Une machine devrait pouvoir le parser facilement pour effectuer la correction elle-même. Le correcteur devrait avoir un minimum de mots à …"/>
  31. <meta property="og:locale" content="en_US.UTF-8"/>
  32. <meta property="og:url" content="https://phyks.me/2014/07/lister-des-corrections-en-ligne.html"/>
  33. <meta property="og:type" content="article"/>
  34. <meta property="article:published_time" content="2014-07-24 22:35:00+02:00"/>
  35. <meta property="article:modified_time" content=""/>
  36. <meta property="article:author" content="https://phyks.me/author/phyks.html">
  37. <meta property="article:section" content="Dev"/>
  38. <meta property="og:image" content="/images/profile.png">
  39. <title>Phyks' blog &ndash; Lister des corrections en ligne</title>
  40. </head>
  41. <body>
  42. <aside>
  43. <div>
  44. <a href="https://phyks.me">
  45. <img src="/images/profile.png" alt="Phyks" title="Phyks">
  46. </a>
  47. <h1><a href="https://phyks.me">Phyks</a></h1>
  48. <p>I write about dev, FOSS, DIY and more, in French and English.</p>
  49. <ul class="social">
  50. <li><a class="sc-rss" href="feeds/all.atom.xml" target="_blank"><i class="fa fa-rss"></i></a></li>
  51. <li><a class="sc-envelope-o" href="mailto:phyks+blog@phyks.me" target="_blank"><i class="fa fa-envelope-o"></i></a></li>
  52. <li><a class="sc-github" href="http://github.com/phyks/" target="_blank"><i class="fa fa-github"></i></a></li>
  53. <li><a class="sc-gitlab" href="https://git.phyks.me/phyks" target="_blank"><i class="fa fa-gitlab"></i></a></li>
  54. </ul>
  55. </div>
  56. </aside>
  57. <main>
  58. <nav>
  59. <a href="https://phyks.me">Home</a>
  60. <a href="https://links.phyks.me">Bookmarks</a>
  61. <a href="/pages/hosted-tools.html">Tools</a>
  62. <a href="/archives.html">Archives</a>
  63. <a href="/pages/memo-autohebergement.html">Autohébergement</a>
  64. <a href="https://phyks.me/feeds/all.atom.xml">Atom</a>
  65. </nav>
  66. <article class="single">
  67. <header>
  68. <h1 id="lister-des-corrections-en-ligne">Lister des corrections en&nbsp;ligne</h1>
  69. <p>
  70. Posted on 24 July 2014 in <a href="https://phyks.me/category/dev.html">Dev</a>
  71. &#8226; 4 min read
  72. </p>
  73. </header>
  74. <div>
  75. <p>Il m&#8217;arrive souvent de corriger des documents textes et de devoir noter
  76. facilement les fautes d&#8217;orthographe.&nbsp;Idéalement:</p>
  77. <ul>
  78. <li>Un humain devrait être capable de le lire sans&nbsp;difficultés.</li>
  79. <li>Une machine devrait pouvoir le <em>parser</em> facilement pour effectuer la
  80. correction&nbsp;elle-même.</li>
  81. <li>Le correcteur devrait avoir un minimum de mots à&nbsp;recopier.</li>
  82. </ul>
  83. <p>Une solution est de corriger directement le document, puis de faire un
  84. <em>diff</em>. Ça marche, mais ce n&#8217;est pas des plus pratiques (on n&#8217;a pas
  85. forcément <em>diff</em> partout par exemple, ou encore le texte source n&#8217;est
  86. pas disponible pour du Markdown ou du LaTeX) et c&#8217;est quand même pas le
  87. plus lisible pour le destinataire. Pour résoudre ce problème, on peut
  88. utiliser <a href="http://etherpad.org"><em>etherpad</em></a> (dont une instance est disponible
  89. chez <a href="http://framapad.org/">FramaSoft</a> pour ceux qui ne veulent pas
  90. auto-héberger) par exemple, qui va garder les corrections en couleur et
  91. ce sera donc très&nbsp;lisible.</p>
  92. <p>Ceci dit, j&#8217;utilise une autre solution, qui ne nécessite qu&#8217;un éditeur
  93. de texte brut, et qui, un peu comme Markdown, est facilement lisible par
  94. un humain ou une machine. Je ne suis sûrement pas le seul à l&#8217;utiliser,
  95. et ça n&#8217;a sûrement pas grand chose d&#8217;extraordinaire, mais si jamais ça
  96. peut servir à d&#8217;autres personnes… (au moins à ceux à qui j&#8217;envoie mes
  97. corrections dans ce format&nbsp;^^)</p>
  98. <p>Le plus simple est de partir d&#8217;un exemple. Considérons le texte&nbsp;suivant:</p>
  99. <blockquote>
  100. <p>Cec est un text de démonstratin. Comme vous pouvez aisément le
  101. constater il y a quelques lettres manquntes et quelqueslettres en
  102. troap ou des mauvaises lettres. C&#8217;est donc un bon&nbsp;exiample.</p>
  103. </blockquote>
  104. <p>Évidemment, le texte corrigé&nbsp;est:</p>
  105. <blockquote>
  106. <p>Ceci est un texte de démonstration. Comme vous pouvez le constater
  107. aisément il y a quelques lettres manquantes et quelques lettres en
  108. trop ou des mauvaises lettres. C&#8217;est donc un bon&nbsp;exemple.</p>
  109. </blockquote>
  110. <p>Pour ce texte, ma proposition de correction&nbsp;serait:</p>
  111. <div class="highlight"><pre><span></span>Cec(+i)
  112. text(+e)
  113. démonstrati(+o)n
  114. manqu(+a)ntes
  115. quelques(+ )lettres
  116. tro(-a)p
  117. ex(-ia+e)mple
  118. </pre></div>
  119. <p>Avec cette méthode, la correction est très courte, facilement lisible et
  120. très vite écrite. Détaillons-la un peu&nbsp;plus.</p>
  121. <p>Premier constat: il est très rare d&#8217;avoir des parenthèses au sein d&#8217;un
  122. mot. Et quand il y a des parenthèses, il n&#8217;y a jamais (en français
  123. correctement typographié, sauf erreur de ma part) un + ou un - qui suit
  124. une parenthèse ouvrante. On va donc englober dans des parenthèses nos
  125. corrections, directement au sein du mot. Au sein d&#8217;une parenthèse, on
  126. commencera toujours par le symbole - suivi de la lettre (ou des lettres
  127. consécutives) à retirer, s&#8217;il y a lieu. Puis viendra le symbole + suivi
  128. des lettres à insérer à la place dans le&nbsp;mot.</p>
  129. <p>Quand il manque une lettre dans le mot, elle est dans le champ de vision
  130. au sein de la parenthèse quand on lit le mot, et la lecture du mot est
  131. facilitée, tout en voyant immédiatement qu&#8217;il y a une faute à cet
  132. endroit. Quand il y a une lettre en trop, il suffit de ne pas lire la
  133. parenthèse pour avoir le mot complet bien écrit. Quand il y a eu une
  134. substitution, les lettres à insérer sont après le +, et les lettres à
  135. retirer sont après le -. La lecture d&#8217;un tel <em>diff</em> est donc très&nbsp;facile.</p>
  136. <p>Pour un ordinateur, il est également très facile de lire un tel diff. Le
  137. code serait le&nbsp;suivant:</p>
  138. <ul>
  139. <li>Découper le texte en&nbsp;mots.</li>
  140. <li>Pour chaque mot, regarder s&#8217;il y a un (ou plusieurs) groupe(s) de
  141. parenthèses contenant des + et des -, au format&nbsp;précédent.</li>
  142. <li>Pour chaque mot qui en contient, retirer les caractères suivant le -
  143. et ajouter ceux suivant le&nbsp;+.</li>
  144. </ul>
  145. <p>Une implémentation basique (et mal codée) en Python qui traite un mot
  146. serait&nbsp;:</p>
  147. <div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">inline_diff</span><span class="p">(</span><span class="n">word</span><span class="p">):</span>
  148. <span class="n">index</span> <span class="o">=</span> <span class="n">word</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;(-&#39;</span><span class="p">)</span>
  149. <span class="k">if</span> <span class="n">index</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
  150. <span class="n">index</span> <span class="o">=</span> <span class="n">word</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;(+&#39;</span><span class="p">)</span>
  151. <span class="k">if</span> <span class="n">index</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
  152. <span class="k">return</span> <span class="n">word</span>
  153. <span class="n">index_end</span> <span class="o">=</span> <span class="n">word</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
  154. <span class="k">if</span> <span class="n">index_end</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
  155. <span class="k">return</span> <span class="bp">False</span>
  156. <span class="n">output</span> <span class="o">=</span> <span class="n">word</span><span class="p">[:</span><span class="n">index</span><span class="p">]</span>
  157. <span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;add&#39;</span>
  158. <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">index_end</span><span class="p">):</span>
  159. <span class="k">if</span> <span class="n">word</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;(&#39;</span><span class="p">:</span>
  160. <span class="k">continue</span>
  161. <span class="k">elif</span> <span class="n">word</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;-&#39;</span><span class="p">:</span>
  162. <span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;remove&#39;</span>
  163. <span class="k">elif</span> <span class="n">word</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;+&#39;</span><span class="p">:</span>
  164. <span class="n">action</span> <span class="o">=</span> <span class="s1">&#39;add&#39;</span>
  165. <span class="k">else</span><span class="p">:</span>
  166. <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="s1">&#39;remove&#39;</span><span class="p">:</span>
  167. <span class="k">continue</span>
  168. <span class="k">else</span><span class="p">:</span>
  169. <span class="n">output</span> <span class="o">+=</span> <span class="n">word</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
  170. <span class="n">output</span> <span class="o">+=</span> <span class="n">word</span><span class="p">[</span><span class="n">index_end</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
  171. <span class="k">return</span> <span class="n">inline_diff</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
  172. </pre></div>
  173. <p>Il reste à traiter le cas d&#8217;un diff complet. Plutôt que de fournir le
  174. texte complet, on peut se contenter de fournir une liste des
  175. corrections, comme la liste précédente, par ordre d&#8217;apparition dans le
  176. texte. Avec très peu de précautions nécessaires, une telle liste
  177. pourrait être traitée directement par un ordinateur pour apporter les&nbsp;corrections.</p>
  178. <p><strong>Mise à jour&nbsp;:</strong> Enfin, n&#8217;oublions pas d&#8217;aborder quelques limitations
  179. de ce&nbsp;système:</p>
  180. <ul>
  181. <li>Si le texte possède deux orthographes d&#8217;un mot, il faut prendre des
  182. précautions pour la correction. En particulier, il faut rappeler le
  183. mot à corriger autant de fois qu&#8217;il y a de corrections à faire, et
  184. on ne peut pas faire d&#8217;option <em>greedy</em>. Cependant, ceci devrait déjà
  185. être le cas si vous utilisez la méthode décrite&nbsp;précédemment.</li>
  186. <li>
  187. <p>Dans le cas du texte&nbsp;suivant:</p>
  188. <blockquote>
  189. <p>Il existe des fois où la technique peut être utilisée moyennant
  190. quelques précautions. Dans cet exemple, les technique précédentes
  191. ne fonctionneront pas sans&nbsp;précautions.</p>
  192. </blockquote>
  193. <p>Si on utilise <code>technique(+s)</code>, c&#8217;est la première qui
  194. sera remplacée. Il faut donc étendre cette méthode pour traiter un
  195. contexte suffisant pour effectuer le remplacement sans ambiguïtés.
  196. Le <em>diff</em> adéquat&nbsp;serait:</p>
  197. <p><code>les technique(+s)</code></p>
  198. </li>
  199. <li>
  200. <p>On ne peut pas déplacer de mots facilement avec cette méthode. Plus
  201. exactement, c&#8217;est possible mais n&#8217;est pas optimal. Considérons le
  202. texte&nbsp;suivant:</p>
  203. <blockquote>
  204. <p>Dans ce texte, les sont mots&nbsp;inversés.</p>
  205. </blockquote>
  206. <p>Moyennant une implémentation un peu plus large de l&#8217;algorithme, on
  207. pourrait utiliser la méthode précédente comme ceci, pour corriger
  208. cette&nbsp;phrase:</p>
  209. <p><code>les (-sont) mots (+sont)</code></p>
  210. <p>car rien n&#8217;interdit à un mot d&#8217;être entièrement supprimé ou&nbsp;ajouté.</p>
  211. </li>
  212. </ul>
  213. </div>
  214. <div class="tag-cloud">
  215. <p>
  216. </p>
  217. </div>
  218. </article>
  219. <footer>
  220. <p>
  221. &copy; 2017 - This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>
  222. </p>
  223. <p>Powered by <a href="http://getpelican.com" target="_blank">Pelican</a> - <a href="https://github.com/alexandrevicenzi/flex" target="_blank">Flex</a> theme by <a href="http://alexandrevicenzi.com" target="_blank">Alexandre Vicenzi</a></p><p>
  224. <a rel="license"
  225. href="http://creativecommons.org/licenses/by-nc-sa/4.0/"
  226. target="_blank">
  227. <img alt="Creative Commons License"
  228. title="Creative Commons License"
  229. style="border-width:0"
  230. src="https://phyks.me/theme/img/cc/by-nc-sa.png"
  231. width="80"
  232. height="15"/>
  233. </a>
  234. </p> </footer>
  235. </main>
  236. <script type="application/ld+json">
  237. {
  238. "@context" : "http://schema.org",
  239. "@type" : "Blog",
  240. "name": " Phyks' blog ",
  241. "url" : "https://phyks.me",
  242. "image": "/images/profile.png",
  243. "description": "I write about dev, FOSS, DIY and more, in French and English."
  244. }
  245. </script>
  246. </body>
  247. </html>