Qu’est-ce que c’est ?
Ce document explique comment le traitement des archives apkg doit fonctionner.
Structure des fichiers .apkg
Les fichiers Anki .apkg sont juste des archives zip contenant les fichiers suivants :
-
collection.anki2
: Une base de données sqlite contenant des cartes, des notes, des modèles de notes, etc… - Des fichiers nommés
1
,2
,3
,4
… : Les images que les cartes utilisent -
media
: Un fichier json contenant les mappings entre les images et leurs noms originaux (ex : le fichier1
est en fait appelélatex-96c15f8a1af25e7a2eec64f7c6fedafe12363352.png
dans les cartes).
La structure de la collection.anki2
C’est la base de données réelle qui contient toutes les notes et autres informations utiles que nous utiliserons pour générer le visualisateur. Il existe un guide très détaillé sur ce que contient exactement la base de données.Dans ce document, nous allons simplement décrire ce que nous devrons extraire de la base de données afin de générer le visualiseur.
Récupérer les notes
Les notes sont stockées dans la table notes
. Les colonnes dont nous avons besoin dans cette table sont :
-
id
: L’identifiant unique de la note -
mid
: L’ID du modèle de cartes (décrit plus loin comment l’obtenir) -
tags
: Les balises associées à la note -
fld
: Les champs de la note. Ce champ doit être introduit dans le modèle de cartes pour générer les cartes. Il contient tous les champs, séparés par le caractère0x1f
(31). L’ordre des champs est exactement celui présenté dans le modèle de la note.
Récupération des modèles de cartes
Pour pouvoir générer les cartes à partir des notes, nous devons récupérer le modèle de cartes. Le modèle nous indique combien de cartes doivent être générées à partir d’une seule note, quel est le HTML entourant la note, comment les champs de notes.fld
doivent être présentés.
Le modèle peut être trouvé dans la colonne models
de la table col
. Notez que la table col
ne contient toujours qu’un seul enregistrement. Le modèle est stocké dans un format JSON ; voici un exemple de ce à quoi ressemble le JSON d’un modèle avec deux modèles:
{ "1471435193999": { "vers": , "name": "Istruzioni Assembly", "tags": , "did": 1493040141981, "usn": 625, "req": ], ] ], "flds": , "sticky": false, "rtl": false, "ord": 0, "font": "Arial", "size": 20 }, { "name": "Descrizione", "media": , "sticky": false, "rtl": false, "ord": 1, "font": "Arial", "size": 20 }, { "name": "Architettura", "media": , "sticky": true, "rtl": false, "ord": 2, "font": "Arial", "size": 20 } ], "sortf": 0, "tmpls": , "mod": 1493150692, "latexPost": "\end{document}", "type": 0, "id": "1471435193999", "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n", "latexPre": "\documentclass{article}\n\special{papersize=3in,5in}\n\usepackage{inputenc}\n\usepackage{amssymb,amsmath}\n\pagestyle{empty}\n\setlength{\parindent}{0in}\n\begin{document}\n" }, "1471435194000": { "vers": , "name": "Base (default)", "tags": , "did": 1492955368330, "usn": 668, "req": ] ], "flds": , "sticky": false, "rtl": false, "ord": 0, "font": "Arial", "size": 20 }, { "name": "Retro", "media": , "sticky": false, "rtl": false, "ord": 1, "font": "Arial", "size": 20 } ], "sortf": 0, "tmpls": , "mod": 1494091839, "latexPost": "\end{document}", "type": 0, "id": 1471435194000, "css": ".card {\n font-family: Arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n\nimg {\n vertical-align: middle;\n padding-bottom: 7px;\n padding-right: 6px;\n padding-left: 6px\n}", "latexPre": "\documentclass{article}\n\special{papersize=3in,5in}\n\usepackage{inputenc}\n\usepackage{amssymb,amsmath}\n\pagestyle{empty}\n\setlength{\parindent}{0in}\n\begin{document}\n" }}
Dans la même URL mentionnée précédemmentil y a une très belle description de ce que fait chaque champ du modèle. Ici seront décrits uniquement ceux dont nous avons besoin pour créer le navigateur de cartes.
Dans la racine de l’objet, il y a une clé "1471435193999"
. Cette clé est l’id de ce modèle.Elle est mentionnée dans la colonne mid
de la table notes
.
Dans cet objet, il y a un tableau avec la clé "flds"
. Ce tableau contient les champs que les cartes spécifient lors de la création des notes. Habituellement, il y a juste les champs « Front » et « Rear », cependant,selon le modèle, il est possible d’avoir plus de champs différents. Comme mentionné précédemment, les notes stockent ces informations dans la colonne notes.fld
; les champs de la colonne sont dans le même ordre que les définitions des champs dans ce tableau.
L’objet "tmpls"
contient les modèles des notes et fournit des informations sur la structure HTML des cartes. Les modèles qui définissent plusieurs modèles génèrent plusieurs cartes, une pour chaque modèle. Cet objet possède deux champs importants :
-
"qfmt"
: Le HTML de l’avant de la carte -
"afmt"
: Le HTML de l’arrière de la carte -
"ord"
: La position du modèle dans le tableau"tmpls"
. Elle est utilisée par la tablecards
pour identifier le modèle qui a généré la carte.
Ces champs peuvent contenir des {{placeholders}}
qui doivent être substitués par les valeurs des champs que les cartes stockent dans notes.fld
. L’association entre la position du champ et le nom du champ est celle des objets dans "flds"
. Notez que "afmt"
peut contenir un espace spécial appelé {{FrontSide}}
; c’est juste un moyen pratique d’afficher le contenu de la carte sans avoir à copier & coller le contenu de "qfmt"
lors de la création de modèles de cartes.
Le dernier champ qui nous intéresse est "css"
; il contient le code CSS qui doit être appliqué à la carte.
Récupérer les informations sur les decks
Les informations sur les decks contenus dans l’archive sont stockées dans la colonne col.decks
au format JSON. Voici un exemple de JSON:
{ "1": { "desc": "", "name": "Predefinito", "extendRev": 50, "usn": 0, "collapsed": false, "newToday": , "timeToday": , "dyn": 0, "extendNew": 10, "conf": 1, "revToday": , "lrnToday": , "id": 1, "mod": 1494099120 }, "1493040141981": { "extendRev": 50, "collapsed": false, "newToday": , "timeToday": , "dyn": 0, "extendNew": 10, "conf": 1, "revToday": , "lrnToday": , "id": 1493040141981, "mod": 1494073733, "name": "Universit\u00e0 - Calcolatori::Assembly", "usn": 661, "browserCollapsed": true, "mid": 1471435194000, "desc": "" }, "1492955368330": { "extendRev": 50, "collapsed": false, "newToday": , "timeToday": , "dyn": 0, "extendNew": 10, "conf": 1, "revToday": , "lrnToday": , "id": 1492955368330, "mod": 1494095504, "name": "Universit\u00e0 - Calcolatori", "usn": 671, "browserCollapsed": true, "mid": 1471435194000, "desc": "" }}
Certains champs à noter:
-
id
: Identifiant unique du pont. L’id est utilisé dans la tablecards
, dans la colonnedid
pour spécifier les associations entre les cartes et les decks (expliqué plus loin). Notez que le deck par défaut a toujours l’id1
. -
name
: Le nom du deck. Dans le cas de decks enfants, le nom sera au format « Nom du deck parent ::Nom du deck enfant »
Récupération des cartes
Les informations sur les cartes sont stockées dans la table cards
. Les colonnes dont nous avons besoin dans cette table sont :
-
id
: identifiant unique de la carte -
nid
: id de la note qui a généré cette carte -
did
: id identifiant du jeu où cette carte est contenue -
ord
: la position du modèle du modèle ; elle correspond au champord
du modèle.
La structure du fichier média
media
est un fichier JSON qui associe les noms de code des images à ses’ noms originaux. Notez que le champ de la carte peut contenir des images, mais les images sont liées avec leur nom complet.Pendant la création du fichier .apkg, anki compresse les noms des images (en fait, il les nomme simplement avec des numéros progressifs), mais les cartes continuent de faire référence au nom d’origine. Le but du fichier media
c’est de nous rendre capable de traduire les noms numériques dans les noms originaux des images.
La structure de media
est assez simple :