No description
Find a file
mog fea7fbf915 Unfold a kanji's story and components on the vocabulary cards
Tapping a kanji of the keywords row opens its story and components, the
<details> of the kanji cards, so it works on the phone apps too. Words
and users are left out to keep notes small. keywords now stores the
fallback font too, shared with note-type, for the rare components.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:39:45 +02:00
src/lkdlt Unfold a kanji's story and components on the vocabulary cards 2026-10-22 11:39:45 +02:00
tests Unfold a kanji's story and components on the vocabulary cards 2026-10-22 11:39:45 +02:00
.copier-answers.yml Update template to 0.1.6 2026-10-15 21:41:58 +02:00
.gitignore Integrate lkdlt's existing code into the template 2026-10-15 08:30:59 +02:00
.python-version Update template to 0.1.6 2026-10-15 21:41:58 +02:00
dodo.py Create a skeleton from template via Copier 2026-10-15 08:30:59 +02:00
LICENSE Create a skeleton from template via Copier 2026-10-15 08:30:59 +02:00
main-list.txt Fix 2142 2023-03-28 10:32:05 +08:00
pyproject.toml Cut drawn shapes out of real kanji; merge review entries 2026-10-19 10:37:19 +02:00
README.md Unfold a kanji's story and components on the vocabulary cards 2026-10-22 11:39:45 +02:00
uv.lock Cut drawn shapes out of real kanji; merge review entries 2026-10-19 10:37:19 +02:00

lkdlt

Construit le deck Anki de kanji (Les kanji dans la tête, l'édition française de RTK) à partir de nihongo/kanjis.yaml et nihongo/primitives.yaml. Les commandes se lancent depuis ce dépôt.

Commandes principales

Anki ouvert

Commande Rôle
uv run lkdlt deck Met les cartes à jour depuis kanjis.yaml : mots-clefs, histoires, composants, mots. Ajoute une carte par composant nommé qui n'est pas un kanji (étiquette composante, sans numéro). Ne touche jamais une histoire modifiée dans Anki, et tague histoire::à-relire les histoires à relire.
uv run lkdlt note-type Met à jour le modèle de carte et ses polices (Klee One, police de secours des composants rares). À lancer après un changement de modèle ou de forme dessinée.
uv run lkdlt keywords Écrit les mots-clefs des kanji de chaque mot dans le champ « Mots-clefs » du deck de vocabulaire (Kaishi), affiché au verso, et passe son texte japonais en Klee One. Les mots-clefs des kanji encore nouveaux dans 漢字 sont grisés. Toucher un kanji déplie son histoire et ses composants, comme sur sa carte (sans script : marche aussi sur téléphone). À relancer après avoir étudié ou changé des mots-clefs ou des composants.
uv run lkdlt pull-stories --apply Rapatrie dans kanjis.yaml les histoires écrites ou modifiées dans Anki, et retire leur tag histoire::à-relire. Sans --apply, liste seulement.
uv run lkdlt leeches Liste les sangsues : cartes ratées 4 fois, celles sans histoire en premier.
uv run lkdlt story-stats Compare le taux d'oubli des kanji avec et sans histoire, par tranche du livre.

Anki fermé

Commande Rôle
uv run lkdlt reorder --apply Remet les nouvelles cartes dans l'ordre d'étude. Les cartes déjà étudiées ne bougent pas.

Sans Anki

Commande Rôle
uv run lkdlt check-names Vérifie les invariants des noms ; tout doit être à 0.
uv run lkdlt check-stories Compare ce que citent les histoires avec les composants affichés.
uv run lkdlt check-rtk Compare les composants des cartes aux éléments que cite le livre de Heisig (l'epub anglais). Ne liste que les différences nouvelles ; --accept les accepte, --all les montre toutes.
uv run lkdlt apply-review FICHIER --apply Applique une revue de noms (voir plus bas). Sans --apply, montre les changements.

Routines

Après avoir modifié kanjis.yaml ou primitives.yaml

  1. uv run lkdlt check-names : tout à 0. Si une décomposition a changé, uv run lkdlt check-rtk : relire les différences nouvelles, puis --accept.
  2. Anki ouvert : uv run lkdlt deck, plus uv run lkdlt note-type si une forme dessinée a changé.
  3. Anki fermé : uv run lkdlt reorder --apply, si une décomposition a changé.
  4. Commiter nihongo.

Pendant les révisions

  • Une carte devient sangsue (étiquette leech) : écrire son histoire d'une ligne dans le champ « Histoire ».
  • Une histoire taguée histoire::à-relire : la corriger dans Anki si besoin.
  • De temps en temps : uv run lkdlt pull-stories --apply, puis commiter nihongo.

Les histoires et les sangsues

On n'écrit une histoire que lorsqu'une carte résiste. Le deck 漢字 a son propre groupe d'options (« 漢字 ») : FSRS avec une rétention de 0,85, 20 nouvelles cartes par jour, et une carte est étiquetée leech au 4e échec, sans être suspendue.

  • Écrire dans Anki : le champ « Histoire » accepte du texte brut. *composant* et #mot-clef# sont facultatifs, car le mot-clef est mis en valeur tout seul.
  • deck ne l'écrase pas : lkdlt garde la dernière histoire qu'il a écrite dans chaque note (~/.local/share/lkdlt/stories.json). Une note qui en diffère a été modifiée dans Anki ; deck la laisse telle quelle et la signale.
  • pull-stories la convertit en balisage, l'écrit dans kanjis.yaml et retire la marque « à relire ». Le deck suivant la réécrit dans Anki avec la mise en forme habituelle.
  • Bilan vers le 19 novembre 2026 :
    • story-stats indique si les kanji sans histoire s'oublient nettement plus ;
    • dans Anki, Options du groupe « 漢字 » → FSRS → Optimiser : les paramètres par défaut cèdent la place à ceux tirés des révisions (il en faut un bon millier). Recommencer tous les mois ou deux.

Fichiers

kanjis.yaml

Un kanji par entrée, dans l'ordre du livre :

- index: 25
  kanji: 昌
  keyword: prospère
  original_keyword: …   # mot-clef du livre, s'il a été changé
  sens: …               # le sens, quand le mot-clef ne le dit pas (champ « Sens »)
  story_review: true    # histoire à relire (tag histoire::à-relire)
  story: "Deux *soleils* dans le ciel, c'est #prospère#."

Dans les histoires, *nom* cite un composant et #mot-clef# le mot-clef ; l'histoire est toujours la dernière clef.

primitives.yaml

Le nom des composants qui ne sont pas des kanji, et les corrections des décompositions d'AnimCJK :

Clef Exemple Sens
(nom seul) 氵: éclaboussures le nom affiché
nom {nom: Tintin} le nom affiché, avec d'autres clefs
positions {gauche: tertre, droite: bourg} un nom par position (gauche, droite, haut, bas, milieu, enveloppe, contenu, superposé)
variantes {variantes: [pinacle]} formes citées par les histoires, jamais affichées
forme_de {forme_de: 幺} mêmes traits qu'un autre élément : même nom
petite_forme_de {nom: Tintin, petite_forme_de: 人} forme réduite, nom lié mais distinct
entier {entier: true} jamais décomposé sur les cartes
décomposition {décomposition: ⿰糹彖} remplace la description IDS d'AnimCJK
en_composant {en_composant: 日} lu comme un autre caractère dans les composés (曰 → 日)
dessin, cadre voir ci-dessous forme sans caractère Unicode

Une forme qu'aucun caractère Unicode n'encode (Dark Vador, complexe souterrain, ensilage, tubes) reçoit un caractère d'usage privé (U+E000…) et un dessin. La police de secours en tire le glyphe, sous l'une de ces formes :

  • dessin: ⿱十罒 : une description IDS, mise en page régulièrement ;
  • dessin: [[十, .15, .5, .85, .95], …] : des caractères, chacun dans sa case (gauche, bas, droite, haut, en fractions du cadratin) ;
  • dessin: {extrait: 聴, garde: [[.45, .465, 1, 1]]} : la partie d'un vrai kanji comprise dans ces cases, avec ses épaisseurs de trait. C'est la méthode qui donne le meilleur résultat.

similar.yaml

Les kanji faciles à confondre, un groupe par ligne :

- 右石   # droite, pierre

Au verso de chaque carte du groupe, « À ne pas confondre » montre les autres avec leur mot-clef. Un caractère peut appartenir à plusieurs groupes, et un composant nommé peut aussi faire partie d'un groupe. Après une modification : check-names (catégorie similaire), puis deck, Anki ouvert.

revue-noms.yaml et apply-review

Le journal des décisions sur les noms, par sections. Pour appliquer de nouvelles décisions, on les écrit dans un fichier au même format, puis on lance uv run lkdlt apply-review FICHIER. Une entrée complète la primitive existante ; une clef mise à null est retirée. Pour les histoires qui citent un ancien nom :

  • remplace: [ancien] réécrit la citation ;
  • relire: [ancien] la réécrit et marque l'histoire à relire ;
  • invalide: [ancien] supprime l'histoire.

Invariants (check-names)

  1. Un nom par élément, ou un par position, et seul le bon s'affiche.
  2. Le nom d'un kanji en composant est son mot-clef.
  3. Deux éléments ne partagent jamais un nom. Les noms proches, eux, se relisent à la main.
  4. Une carte n'affiche que des kanji ou des composants nommés (sans-nom), y compris dans les composants dépliés.
  5. Un kanji s'étudie après les kanji qui le composent. L'ordre d'étude suit celui du livre, mais chaque kanji est avancé juste avant le premier qui l'utilise ; seuls les cycles sont signalés.
  6. Un composant s'étudie avant le premier kanji qui l'utilise. Chaque composant nommé qui n'est pas un kanji a sa carte (comme les cadres de primitives de Heisig), placée juste avant son premier utilisateur. Les noms selon la position (八 en bas : pattes) s'affichent au verso, dans « En composant ».

Configuration

~/.config/lkdlt/config.yml, à ouvrir avec uv run lkdlt edit-config :

  • paths : kanji (le kanjis.yaml), animcjk, kanjidic, jmdict, jpdb, collection (la collection Anki, pour reorder), fallback_fonts (Klee One d'abord, dont on découpe les composants qui lui manquent avec dessin: {extrait, garde}, puis Jigmo pour le reste) et rtk_epub (le livre de Heisig, pour check-rtk) ;
  • kanji : deck, modèle et noms des champs (positions : le champ des noms selon la position ; similar : celui des kanji à ne pas confondre, puis note-type) ;
  • words : les sources des mots affichés sur les cartes ;
  • keywords : les modèles de vocabulaire qui affichent les mots-clefs (model_name, word le champ du mot, after le champ après lequel les afficher).

Autres commandes

  • primitives : propose des noms de composants d'après les histoires.
  • regularities : liste les composants nommés différemment selon leur position.
  • rename : renomme un élément (mot-clef, primitive, histoires).
  • index et stats : listes des kanji et des mots-clefs.
  • triage, examples, vocab, cjve, jmdict : outils du deck de vocabulaire.

Développement

uv run pytest
uv run ruff check && uv run ruff format --check
uv run ty check