OK
AJAX error!

Les forumsGrammalecteUtilisation de Grammalecte dans une application

Utilisation de Grammalecte dans une application

Bonsoir à toutes et à tous !

J'espère que ma demande est possible ici et que mon sujet est à sa place.

J'utilise dicollecte et grammalecte depuis un moment (avec LibreOffice) et j'en suis très content !
J'ai un projet d'éditeur de texte dans lequel je voudrais intégrer la correction orthographique en utilisant le dictionnaire dicollecte. Toutefois, je ne sais pas exactement comment l'utiliser. Je programme en C++, l'interface graphique sera gérée via la bibliothèque Qt.

Quelqu'un saurait-il m'expliquer quels fichiers sont à télécharger et comment les utiliser ?
Merci d'avance pour toute l'aide que vous pourriez m'apporter.
le 21 septembre 2012 à 21:17
Dicollecte utilise un dictionnaire Hunspell (fichiers *.aff et *.dic). Tu peux utiliser l'API C de Hunspell :
linux.die.net…

Ou tu peux utiliser l’API d’Enchant qui permet aussi de lire le format Hunspell parmi d'autres formats :
www.abisource.com…

Pour la grammaire avec Grammalecte, je ne sais pas. J’aimerais moi-même écrire un plugin Vim pour Grammalecte (comme je l’ai fait pour LanguageTool). Mais on ne peut pas utiliser Grammalecte en ligne de commande je crois. Je ne sais pas si on peut utiliser Grammalecte en dehors de LibreOffice.
le 21 septembre 2012 à 23:12
Bonjour,

Le problème vient du fait que Grammalecte a un besoin impérieux de Hunspell pour fonctionner, pour l’instant. D’où sa dépendance à LibO/AOO qui fournissent l’interface pour communiquer avec.
Je me suis un peu essayé à faire fonctionner Hunspell directement avec Python. C’est possible, puisque Hunspell possède une API pour le C. J’y suis parvenu sous Linux, mais impossible de charger les dicos sous Windows. Je n’ai pas eu le temps de creuser ce problème.

L’autre solution, c’est l’automate à états finis (c’est un algo qui permet de faire un correcteur orthographique capable aussi de fournir les données morphologiques des mots ; c’est ainsi que fonctionne LT, avec le module appelé fsa). J’ai commencé à en écrire un pour Lightproof/Grammalecte, afin de pouvoir utiliser les lexiques de LangageTool. Je n’y avais pas songé, mais ça permettra aussi à Grammalecte de fonctionner de manière autonome.

En fait, mon automate fonctionne déjà (j’ai beaucoup repris de cette page : stevehanov.ca…), mais il me reste à tout transcrire en format binaire compressé, afin de réduire drastiquement le coût mémoire, qui est pour l’instant assez important. Comme c’est un domaine que je connais très mal, ça va me prendre du temps.

Il s’appelle comment, ce nouvel éditeur de texte ? Pour ma part, j’utilise PsPad, qui reste mon préféré malgré ses imperfections.

Notez que si le dictionnaire est sous licence MPL 2, Hunspell sous licence LGPL (sourceforge.net…), et Grammalecte sous GPL 3.
le 22 septembre 2012 à 00:20
Merci pour les pistes !

Je vais me renseigner sur la librairie Hunspell. Fonctionne-t-elle uniquement sous Linux ou est-elle exploitable sous windows ?

Si c'est bien de "mon" éditeur que vous parlez, je travaille en fait sur une application d'aide à l'écriture de roman avec de nombreuses fonctionnalités dont la principale est tout de même la rédaction de texte et sa correction ;)
Je n'ai pas encore pensé au nom...
le 22 septembre 2012 à 16:21
Hunspell peut être compilé pour Windows, Linux et probablement pour Mac.
Vous pouvez trouver la librairie Hunspell compilée sur le site de LT :
languagetool.svn.sourceforge.net…
le 22 septembre 2012 à 18:02
Bon bon bon...

J'ai bien trouvé cette page (sourceforge.net…), mais j'avoue ne pas trop savoir comment m'en sortir... Je vais tourner vers mes forums de programmation.

En tous cas, merci pour les pistes ! Et ces très bons dictionnaires !
le 23 septembre 2012 à 20:55
Admin a écrit :

Le problème vient du fait que Grammalecte a un besoin impérieux de Hunspell pour fonctionner, pour l’instant. D’où sa dépendance à LibO/AOO qui fournissent l’interface pour communiquer avec.


Je viens de faire un recherche avec Google et je vois "pyhunspell" : code.google.com…

Peut-être utile ?
le 24 septembre 2012 à 10:38
Pas vraiment... Les sources sont, dans ce cas, en Python, et je ne connais absolument pas ce langage.
Mais je vais chercher, il existe des sources en c/c++.
le 25 septembre 2012 à 12:50

dominiko :
Je viens de faire un recherche avec Google et je vois "pyhunspell" : code.google.com…


En fait, c’est, je crois, un binding C pour Python. C’est utile sur Linux, et peut-être avec cygwin.
Mais j’arrive déjà à interroger Hunspell sur Linux sans ça et je ne veux pas de cygwin sous Windows. :)
le 27 septembre 2012 à 10:56
Comment interroges-tu Hunspell en C ?
le 03 octobre 2012 à 20:14
Aucune idée. Je n’ai plus programmé en C depuis mes études, il y a bien des années. Je ne fais plus guère que du Python, du PHP, et un peu de JavaScript. Je dois dire que les langages de bas niveau ne me manquent pas du tout, même si j’estime qu’il est indispensable de les avoir étudiés. :)
Tout ce que je sais, c’est qu’on peut appeler en Python les fonctions C décrites dans le fichier hunspell.h. Après…
le 04 octobre 2012 à 12:38

Comment interroges-tu Hunspell en C ?



Voir la doc linux.die.net… dans un de mes commentaire précédent.

Sous Ubuntu (et Debian), tu peux installer la librairie avec :

$ sudo apt-get install libhunspell-dev libhunspell-1.3-0

Voici un exemple très simple :

$ cat hunspell-ex.cpp
#include «hunspell/hunspell.h»
#include «cstdio»

int main()
{
const char* word_ok = "voiture";
const char* word_notok = "voitture";

// Dictionnaire disponible ici:
// www.dicollecte.org…
Hunhandle* dic = Hunspell_create("fr-classique+reforme1990.aff", "fr-classique+reforme1990.dic");

printf("%s found: %d\n", word_ok, Hunspell_spell(dic, word_ok));
printf("%s found: %d\n\n", word_notok, Hunspell_spell(dic, word_notok));
printf("encoding: %s\n\n", Hunspell_get_dic_encoding(dic));

char **slist;
int list_size = Hunspell_suggest(dic, &slist, word_notok);
printf("suggestion count: %d\n", list_size);
for (int i = 0; i < list_size; i++)
{
printf("suggestion #%d: %s\n", i, slist[i]);
}

Hunspell_destroy(dic);
return 0;
}


$ g++ -Wall hunspell-ex.cpp -lhunspell
$ ./a.out
voiture found: 1
voitture found: 0

encoding: UTF-8

suggestion count: 1
suggestion #0: voiture
le 04 octobre 2012 à 17:04
Merci, je teste ça de ce pas !

Juste une question, quand j'installe la librairie via apt-get, où va-t-elle se placer ?
le 04 octobre 2012 à 21:07

Juste une question, quand j'installe la librairie via apt-get, où va-t-elle se placer ?


Là où il faut :-) Typiquement dans /usr/lib/... pour la librarie et /usr/include/... pour les fichiers header.

Ces commandes indiquent où les fichiers des packages sont installés sous Ubuntu :

$ dpkg -L libhunspell-1.3-0
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0.0.0
/usr/share
/usr/share/doc
/usr/share/doc/libhunspell-1.3-0
/usr/share/doc/libhunspell-1.3-0/copyright
/usr/share/doc/libhunspell-1.3-0/changelog.Debian.gz
/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so.0

$ dpkg -L libhunspell-dev
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libhunspell-1.3.a
/usr/lib/x86_64-linux-gnu/libparsers.a
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/hunspell.pc
/usr/include
/usr/include/hunspell
/usr/include/hunspell/affentry.hxx
/usr/include/hunspell/htypes.hxx
/usr/include/hunspell/affixmgr.hxx
/usr/include/hunspell/csutil.hxx
/usr/include/hunspell/hunspell.hxx
/usr/include/hunspell/atypes.hxx
/usr/include/hunspell/dictmgr.hxx
/usr/include/hunspell/hunspell.h
/usr/include/hunspell/suggestmgr.hxx
/usr/include/hunspell/baseaffix.hxx
/usr/include/hunspell/hashmgr.hxx
/usr/include/hunspell/langnum.hxx
/usr/include/hunspell/phonet.hxx
/usr/include/hunspell/filemgr.hxx
/usr/include/hunspell/hunzip.hxx
/usr/include/hunspell/w_char.hxx
/usr/include/hunspell/replist.hxx
/usr/include/hunspell/hunvisapi.h
/usr/share
/usr/share/man
/usr/share/man/man3
/usr/share/man/man3/hunspell.3.gz
/usr/share/man/man4
/usr/share/man/man4/hunspell.4.gz
/usr/share/man/hu
/usr/share/man/hu/man4
/usr/share/man/hu/man4/hunspell.4.gz
/usr/share/doc
/usr/share/doc/libhunspell-dev
/usr/share/doc/libhunspell-dev/NEWS.gz
/usr/share/doc/libhunspell-dev/README.gz
/usr/share/doc/libhunspell-dev/TODO
/usr/share/doc/libhunspell-dev/copyright
/usr/share/doc/libhunspell-dev/examples
/usr/share/doc/libhunspell-dev/examples/example.cxx
/usr/lib/x86_64-linux-gnu/libhunspell-1.3.so
/usr/lib/x86_64-linux-gnu/libhunspell.a
/usr/lib/x86_64-linux-gnu/libhunspell.so
/usr/share/doc/libhunspell-dev/changelog.Debian.gz

Si en revanche tu compiles la librairie toi-même, il ne faut jamais installer dans ces répertoires mais plutôt dans /usr/local/... (/usr/local/lib/..., /usr/local/include/...)

PS: dans mon commentaire ci-dessus, l'indentation en C est perdue dans et les includes entre les signes "plus petit que" et "plus grand que" sont perdus. Il serait bien d'avoir l'équivalent du tag HTML pre (pre-formated text = verbatim en LaTeX) pour mettre des source codes tels quels.
le 05 octobre 2012 à 10:20
Justement, quel sont les include à mettre ?
Pour ceux qui connaissent, je travaille avec la libraire Qt et son IDE.

Je peux lister l'ensemble des fichier d'entête (disponibles dans /usr/include/husnpell) mais ça me lance toujours des erreurs de non définition de Hunhandle...
J'ai essayé de préciser que j'incluais la librairie disponible /usr/lib/libhunspell-1.3 mais rien n'y fait...
le 05 octobre 2012 à 12:55
Au temps pour moi !
J'avais juste mal noté le nom du fichier de bibliothèque dans mon projet.
le 05 octobre 2012 à 13:47

J’ai commencé à en écrire un pour Lightproof/Grammalecte, afin de pouvoir utiliser les lexiques de LangageTool. Je n’y avais pas songé, mais ça permettra aussi à Grammalecte de fonctionner de manière autonome.


J’ai hâte d'essayer ça :-) Je trouve LibreOffice si lourd…
le 06 octobre 2012 à 21:40
Maintenant que j'ai les bases pour la correction orthographique, quelqu'un pourrait-il m'aider pour utiliser grammalecte ?
le 07 octobre 2012 à 14:55

Maintenant que j'ai les bases pour la correction orthographique, quelqu'un pourrait-il m'aider pour utiliser grammalecte ?


Pour Grammalecte, je ne sais pas, mais pour LanguageTool (www.languagetool.org…), il y a plusieurs solutions :
* utliser LanguageTool en ligne de commande avec l'option --api. LanguageTool produit sur stdout les erreurs trouvées en xml. C'est comme cela que fonctionne mon plugin LanguageTool pour l'éditeur de texte Vim.
* ou utiliser LanguageTool en mode serveur. Tu peux alors envoyer le texte à contrôler à un serveur HTTP (qui peut être local ou une autre machine sur Internet) avec la méthode GET ou POST en utilisant ce genre d'URL : localhost…
* ou utiliser l'API Java de LanguageTool (mais pas pratique si tu programmes en C++).
le 07 octobre 2012 à 17:38
@myrddin772 : Pour l’instant, rien d’utilisable hormis ce que vous pouvez déjà télécharger.

J’ai hâte d'essayer ça :-) Je trouve LibreOffice si lourd…


Il va falloir être patient. J’avais commencé ça en mai, j’y ai passé une semaine ou deux, puis j’ai manqué de temps pour approfondir la question.

Au début, j’avais regardé comment ça fonctionnait pour LT, qui utilise le fsa de Daciuk :
www.eti.pg.gda.pl…
Mais je dois dire que le code m’a paru abscons. Et la version Java (qu’on trouve en ligne je ne sais plus où) ne m’a pas paru plus claire.

Finalement, constatant que les lexiques de LT étaient implémentés de manière différente, j’ai poussé un soupir et j’ai décidé de partir dans la logique inverse, de reconstruire les lexiques décompressés de LT dans un format binaire que je pourrai comprendre. :)

Donc, j’ai déjà bâti un fsa/fst en Python capable de lire n’importe quel lexique LT décompressé et de fournir le lemme et la morphologie de chaque mot. Le problème, c’est que ça bouffe beaucoup de mémoire et qu’il faut donc compresser tout ça en un dictionnaire compressé indexable, afin d’être léger, rapide et de ne pas avoir à rebâtir le graphe des données à chaque chargement (ça prend beaucoup de temps et les lexiques décompressés de LT prennent une place énorme sur le disque dur)…

J’ai téléchargé plein de documents sur le net sur ces sujets. Recherchez : compressed data structure, fsa (finite state automaton), fst (finite state transducer), succint indexable dictionary ou indexable dictionary structure ou similaire… Vous trouverez des tas de papiers (universitaires) sur ces sujets. Personnellement, je n’ai pas encore trouvé le temps de lire tout ça.

Le plus utile pour mettre le pied à l’étrier, c’est ce blog : stevehanov.ca…
le 07 octobre 2012 à 17:44
À mon avis, un "bitstream" avec codes Huffman pour encoder les caractères + codes Huffman pour encoder le nombre d'enfants à chaque nœud doit être compact. On peut aussi utiliser plusieurs codes Huffman en utilisant le contexte. Exemple de contexte : si le caractère précédent est un "q", il est très probable que la lettre suivante est un "u". Un seul bit peut alors suffire pour encoder le "u" avec un code Huffman spécialisé en fonction du caractère précédent. Le décodeur ne devrait pas avoir à décoder beaucoup de bits puisque pour décoder un mot, il ne doit décoder que la branche de ce mot en partant de la racine. Le mot peut alors être stocké dans un cache, si on le rencontre à nouveau, ce qui doit arriver souvent pour les mots fréquents comme "le", "la", etc. Pour la morphologie, un code Huffman pour encoder l'index vers un dictionnaire de tous le codes de morphologie doit faire l'affaire. Ça me donne envie d'essayer mais je n'ai pas beaucoup de temps.
le 07 octobre 2012 à 18:04
J'ai un peu de mal à suivre l'histoire de "bitstream"... Dommage qu'en ce moment je n'ai pas beaucoup de temps à consacrer à ça parce que ça à l'air vraiment intéressant...
le 10 octobre 2012 à 15:53
J’essaie de faire fonctionner Hunspell avec Python. J’y parviens en partie, mais quelques fonctions résistent encore. Il ne faut plus grand-chose pour que Grammalecte comme serveur puisse exister.

Mais j’ai beau essayer, ça coince. Si quelqu’un s’y connaît en C et en Python, il pourra sûrement débloquer la situation. J’essaie d’utiliser la fonction analyze de Hunspell.

/* analyze(result, word) - morphological analysis of the word */
LIBHUNSPELL_DLL_EXPORTED int Hunspell_analyze (Hunhandle *pHunspell, char*** slst, const char * word);



Le problème, c’est que le résultat de cette fonction (en sus de l’entier retourné) est écrit en mémoire à l’endroit pointé par slst (ça devrait être une liste de pointeurs vers des chaînes) qui est passé en paramètre. Il faut que je parvienne à récupérer le résultat écrit à cet emplacement. Si quelqu’un sait comment faire… merci à lui, parce que je sèche sur la manière d’y parvenir, malgré mes efforts. Et là, j’en ai juste marre d’être bloqué par ça. :(

La doc concernant la manière d’utiliser les librairies en C est ici : docs.python.org…

J’ai aussi préparé une petite archive :
www.dicollecte.org…

Le dossier lib contient les librairies Hunspell en DLL.
Le dossier dict contient le dictionnaire.
Le dossier doc contient, pour information, le fichier .h du code de Hunspell et aussi, pour exemple, le code en Java qui permet d’utiliser la librairie Hunspell (voir la fonction suggest vers la fin du fichier qui parvient à récupérer le résultat envoyé par Hunspell, de la même paramètre que celle requise pour la fonction analyze).

Edit : ah oui, j’oubliais de dire que je ne parviens à lire les dictionnaires que sur Linux. Sur Windows, je n’ai pas encore trouvé pourquoi ce point coince.
le 24 octobre 2012 à 17:42
Si mes souvenirs sont bons :

char*** slst

peut représenter un tableau de tableaux de tableaux de char...

En d'autres termes : un tableau à deux dimensions de chaînes de caractères... pour accéder à une liste en particulier, tu dois adresser via :

slst[a][b] /* ici tu "reçois" un char* */

le 28 octobre 2012 à 13:08
Finalement, j’ai abandonné l’idée d’utiliser Hunspell pour l’instant et je travaille à nouveau sur l’automate à états finis. Comme ça je ne suis pas dépendant d’un module tiers.
Et ça avance, ça avance. :)
Lire www.dicollecte.org…

Edit : pour utiliser Hunspell via Python, Ragd a trouvé la solution : www.dicollecte.org…

def analyze (self, s):
....l = POINTER(None)()
....n = self.libHunspell.Hunspell_analyze(self.oDict, pointer(l), s)
....l = cast(l, POINTER(c_char_p * n))
....print n, l
....for i in range(n) :
........print l[0][i]

le 27 novembre 2012 à 12:45

Notification par e-mail    0