Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dictionnaire

Deux dictionnaires vers le vietnamien — français et anglais — pour Dictionary.app, et pour le web.

Ils ne demandent rien à personne au moment où on les consulte : pas de modèle de langue, pas de requête réseau, pas de clé d'API. Le contenu est écrit par des humains, compilé une fois, et lu depuis le disque.

Installer

curl -fsSL https://raw.githubusercontent.com/quanghuynt14/dictionnaire/HEAD/scripts/install.sh | sh

Trente-quatre mégaoctets, une dizaine de secondes. Rien à compiler : un bundle .dictionary est un dossier de données, pas un programme — ni Python, ni le DDK, ni Rosetta, ni les 190 Mo de sources, qui ne servent qu'à le fabriquer.

Il reste une chose, à faire une seule fois, et qu'aucun script ne peut faire à votre place : ouvrez Dictionnaire.app > Réglages, cochez « Pháp–Việt » et « Anh–Việt », et remontez-les au-dessus des dictionnaires d'Apple. Rien ne les consultera avant.

Ensuite, ⌃⌘D sur n'importe quel mot, n'importe où dans macOS.

Sans le tube, ou hors ligne

Le même script accepte un dossier d'archives — celles de la dernière version, ou celles que make dist fabrique ici :

sh install.sh                 # les .zip posés à côté
sh install.sh ~/Downloads     # ou dans le dossier indiqué

Posé à côté, il ne cherche que ses archives, par leur nom. Il cherchait n'importe quel *.dictionary.zip, et rangé dans un dossier qui en contenait un autre il installait celui-là en annonçant une réussite. Un dossier passé en argument garde l'ancien comportement : là, c'est un choix explicite.

Il refait les deux gestes qui comptent, et pour lesquels il y a des raisons écrites dans son en-tête : rm -rf avant ditto, sinon macOS garde un index périmé et le dictionnaire disparaît de la fenêtre de consultation ; et un pkill -f sur les services XPC de consultation, que killall ne reconnaît pas. Il enlève aussi la quarantaine d'un fichier téléchargé.

À côté

conjugaison donne la forme — 2 004 verbes, 77 277 formes, une conjugaison inversée. Les deux s'installent côte à côte : allions ouvre sa traduction ici, sa conjugaison là. C'est pourquoi les pages de verbe de ce dictionnaire renvoient à « Conjugaison française » au lieu de recopier quarante-cinq cases.

Ce qu'ils savent faire

Chercher la forme qu'on vient de lire, pas seulement la vedette.

allions   →  aller     imparfait de l'indicatif, 1ʳᵉ pers. plur.
          →  allier    présent de l'indicatif, 1ʳᵉ pers. plur.
prises    →  prendre, pris, prise, priser
went      →  go
saw       →  see

Une forme qui mène à plusieurs mots ouvre une page qui les porte tous : la fenêtre de survol ne rend qu'une entrée par dictionnaire, et n'en montrer qu'un serait une demi-réponse. Chaque mot renvoie à l'article du Wiktionnaire dont il sort, pour vérifier une glose.

État

Phase 0 terminée, sur tout le dump, dans les deux langues.

Pháp–Việt Anh–Việt
vedettes 46 160 119 108
sens 79 607 190 647
— avec exemple traduit 34 % 9 %
exemples 45 995 27 401
formes fléchies 240 788 199 674
pages de forme ambiguë 10 488 23 056
clés 281 174 295 929
bundle 55,6 Mo 53,1 Mo

Les 9 % d'exemples côté anglais sont la faiblesse connue de ce dictionnaire, et elle vient de la source : le Wiktionnaire vietnamien documente bien mieux le français que l'anglais. Rien dans le pipeline ne peut la combler ; seule une autre source le pourrait.

Ce qui reste : make sync, la boucle qui ramène une correction faite sur le site jusque dans les bundles.

Reconstruire depuis les sources

Rien de tout ça n'est nécessaire pour se servir du dictionnaire — seulement pour le refaire, ou pour le modifier.

make fetch                 # les sources, et data/sources.lock qui dit lesquelles
make install               # → Pháp-Việt.dictionary
make install LANG=en       # → Anh-Việt.dictionary
make both                  # les deux
make install TOP=3000      # une coupe, pour essayer

Sur Apple Silicon, les binaires du DDK sont x86_64 : softwareupdate --install-rosetta --agree-to-license.

make check LANG=en    # la clé est-elle dans le XML, et mène-t-elle au bon mot ?
make verify LANG=en   # le bundle installé sait-il y répondre ?  ← celui qui compte

Fabriquer les archives

make dist        # → dist/ : les deux .zip en ASCII, et install.sh
make release     # publie une version datée sur GitHub

Les archives portent un slug ASCII — phap-viet, anh-viet — et non le nom du bundle : GitHub remplace tout caractère non-ASCII du nom d'un fichier de version par un point, et « Pháp-Việt.dictionary.zip » y devient « Phap-Vi.t.dictionary.zip », dont l'URL rend 404. L'installateur lit donc le nom du dictionnaire dans l'archive.

Le site

Le second shell. Le même lexicon-LL.jsonl sort en NDJSON, et c'est practice qui l'ingère avec son pilote et ses identifiants — le dictionnaire décide du contenu, l'application décide de sa base.

make mongo LANG=fr           # → build/mongo-fr.ndjson
cd ../practice && node --env-file .env \
  packages/server/src/scripts/seedLexicon.ts ../dictionnaire/build/mongo-fr.ndjson

Le chargement est idempotent : il remplace une langue au lieu d'y ajouter, et pose les index sans lesquels chaque recherche balaierait 165 000 documents. --keep-ids met à jour au lieu de recharger, ce qui préserve les _id — donc l'historique et les favoris — au prix de la vitesse.

Deux collections. dictionary garde la forme que practice lisait déjà, parce que l'historique et les favoris pointent ses _id : on la remplit, on ne la refait pas. dictionary_forms est nouvelle, et c'est elle qui manquait au site — « allions » n'y donnait rien alors que le bundle le résout depuis Verbiste.

Les sources

Un dictionnaire, ici, c'est du sens et de la morphologie, et les deux ne viennent jamais du même endroit.

Le sens

Source Licence
fr Wiktionnaire vietnamien, section « Tiếng Pháp », extrait par kaikki.org CC BY-SA 4.0
en idem, section « Tiếng Anh » CC BY-SA 4.0

Des vedettes françaises et anglaises glosées en vietnamien, écrites par des humains, déjà en JSON. C'est tout l'intérêt de cette édition-là du Wiktionnaire.

La morphologie

kaikki n'en donne pas : 600 formes fléchies dans le dump français, 8 014 dans l'anglais pour 119 166 vedettes. Chaque langue a donc son module, et c'est le seul endroit où les deux dictionnaires diffèrent vraiment.

Source Ce qu'elle donne
fr Verbiste 146 modèles qui engendrent le paradigme complet de 7 011 verbes
fr Lexique 3.83 les pluriels, les féminins, et la fréquence
en exceptions de WordNet 3.0 5 940 irréguliers, à la main
en des règles pluriels, -s, -ing, -ed, -er, -est
en FrequencyWords la fréquence

Les vedettes que wiktextract ne voit pas

kaikki lit les définitions écrites en syntaxe MediaWiki — les lignes qui commencent par #. Une partie du Wiktionnaire vietnamien ne les écrit pas ainsi. L'import du Free Vietnamese Dictionary Project ({{R:FVDP}}) a posé des <LI class=def> en HTML brut, et d'autres pages mettent la définition sur une ligne indentée après un tiret. wiktextract n'y voit aucune glose et rend un sens vide.

normalize.py écarte une entrée sans glose — à raison. Mais ces pages-là ne sont pas vides : elles sont mal balisées. Mesuré, 197 vedettes françaises (0,43 %) et 75 anglaises (0,06 %), dont « mélancolie », « dictionnaire », « Asie », « français ».

scripts/rescue.py relit leur wikitexte par l'API MediaWiki, quarante titres par requête, et en tire les gloses selon quatre formes rencontrées. 173 des 197 françaises et 17 des 75 anglaises rentrent ainsi.

Ce qui reste dehors le mérite : « cocagne » n'a réellement que des exemples et aucune définition, et la page « appogiature » a été vandalisée — son titre de section est une obscénité vietnamienne, et il n'y a pas de définition dessous.

Une règle en est sortie, et elle vaut au-delà de ce script : une glose fausse est pire qu'une glose absente. Le repli par puces rendait « IMNSHO, IMAO » comme sens de « IMHO » — c'étaient ses synonymes. Les puces ne sont donc lues que dans un bloc dont on sait qu'il porte une définition, alors qu'un #, qui n'est jamais une liste de synonymes, se lit partout.

La même leçon, deux fois

Les deux langues ont d'abord eu une base d'occurrences, et les deux l'ont perdue pour la même raison.

Lexique, français, n'atteste que ce que ses corpus contiennent : 10,1 formes par verbe là où un paradigme en compte ~45, 56 % des verbes sous les dix formes, huit verbes complets sur 6 399. « allions » y figure sous aller et nulle part sous allier. Verbiste, génératif, les a toutes.

UniMorph, anglais, a l'air plus gros — 189 780 formes contre 5 940 — et rate « children », « was », « were », « feet », « geese », en rangeant « ran » sous rin, un verbe dialectal rare. Les listes de WordNet, mille fois plus petites et faites à la main, ont tout bon.

Deux fois la même conclusion : le volume ne dit rien de la justesse, et un dictionnaire qu'on interroge en tapant la forme qu'on vient de lire a besoin de paradigmes engendrés, pas de fréquences observées.

Côté anglais, les règles engendrent, et WordNet tait la règle là où il a rempli la case : sans ça on écrivait « goed » à côté de « went ». Le redoublement de consonne ne s'applique qu'aux monosyllabes — « stop » → « stopped » se décide sur l'accent tonique, que rien ici ne connaît, et « visitted » serait une clé fausse.

base ⊕ edits

Un bundle .dictionary est compilé et en lecture seule : il n'existe pas de mise à jour incrémentale. Toute correction veut dire recompiler. D'où le découpage :

data/sources/     retéléchargeable, jamais dans git, épinglé par sources.lock
data/edits-fr.jsonl  vos corrections, dans git, une ligne par entrée touchée
build/lexicon-LL.jsonl base ⊕ edits — ce que lisent les deux émetteurs

Une retouche est un patch de fusion par id. Une ligne dont l'id n'existe pas crée l'entrée : c'est ainsi que faire est entré. On n'y écrit que le sensfît, ferions, faisions sont arrivées seules, par Lexique.

Les corrections faites depuis le site atterriront dans Mongo, et make sync les rapatriera ici avant de reconstruire. La conséquence à accepter : une correction est immédiate sur le site, et n'arrive dans Dictionary.app qu'au sync suivant. Aucun découpage ne change ça — le bundle est compilé.

Le découpage des entrées

Une entrée par vedette, plusieurs clés par entrée — l'inverse de conjugaison, et pour une raison précise. Conjugaison indexe par forme parce que sa réponse dépend de la forme tapée. Un dictionnaire n'a pas ce problème : « allions » et « irions » veulent tous deux la page d'« aller ». Apple sait faire, et d:title décide de l'étiquette dans la liste de résultats — « allions (aller) ».

Ce que ça coûte : conjugaison produit 580 Mo de XML pour 2 000 verbes, parce que chaque forme réémet le paradigme. Ici, 70 Mo pour 46 000 vedettes.

Sauf pour les formes ambiguës, qui ont leur page

Une exception, et elle vient d'une mesure. La fenêtre de survol — ⌃⌘D, celle qu'on utilise vraiment — ne rend qu'une entrée par dictionnaire. DCSCopyRecordsForSearchString rendait bien les deux enregistrements de « allions » ; DCSCopyTextDefinition, qui est ce que la fenêtre appelle, n'en rendait qu'un — aller, parce qu'il sort le premier du fichier. La liste de Dictionary.app montrait les deux mots. Le survol, jamais.

C'est la limite du découpage par vedette, et c'est exactement celle que conjugaison contourne en découpant par forme : « le haut de la page ne peut pas savoir quelle forme vous avez tapée ». On applique donc ce découpage-là, mais seulement aux 3,7 % de clés qui en ont besoin : une page par forme ambiguë, qui possède la clé seule et rassemble tous les mots qu'elle atteint.

allions          2 mots
  aller          Đi.  « Aller à pied » — đi bộ
  allier         Pha, trộn (để chế hợp kim).  « Allier l'or avec l'argent »

L'analyse de la forme n'y est pas — « imparfait de l'indicatif, première personne du pluriel ». La page répond à « quels mots est-ce que je viens de lire », et deux vedettes y répondent. Quelle case de quel verbe est une autre question, et elle a déjà son dictionnaire sur la même machine.

Même règle sur les entrées ordinaires : les formes fléchies d'un nom ou d'un adjectif se lisent sur une ligne, sans leur analyse, à côté des synonymes et des dérivés — c'est la même sorte de renvoi.

chat
  Danh từ    Mèo
  Danh từ    Trò chuyện, tán gẫu
  Các dạng   chats, chatte, chattes
  Đồng nghĩa tchat
  Cụm từ     à bon chat, bon rat, avoir un chat dans la gorge…  +47

10 355 pages, 5 020 vedettes absorbées, et le corps duplique 9,4 Mo. Les 96,3 % restants ne bougent pas : leur clé reste sur la vedette, leur corps n'est écrit qu'une fois. Depuis, une clé n'appartient qu'à une entrée — c'est ce que make check vérifie, avec la contrepartie qu'aucune vedette ne doit devenir inatteignable.

Les tableaux de conjugaison ne sont pas recopiés. Ils sont déjà installés sur la même machine, dans « Conjugaison française », et la page renvoie à lui.

Ce qui a été repris de conjugaison sans discuter

Ces quatre lignes ont chacune coûté une séance là-bas. Elles sont dans le Makefile avec leur explication :

  • -v 10.11, sinon les macOS récents ne lisent plus le bundle
  • preserve_unused_ref_id_in_reference_index=1, sinon toute recherche ramène la première entrée du fichier
  • rm -rf avant ditto, sinon macOS garde un index périmé et le dictionnaire disparaît de la fenêtre de consultation
  • pkill -f LookupViewService, parce que killall ne reconnaît pas les services XPC et sort sans rien dire

About

Deux dictionnaires vers le vietnamien — français et anglais — compilés depuis le Wiktionnaire vietnamien, pour Dictionary.app et pour le web.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages