slavetto / anki-cards-web-browser

Cos’è questo?

Questo documento spiega come dovrebbe funzionare l’elaborazione degli archivi apkg.

Struttura dei file .apkg

I file Anki .apkg sono solo archivi zip contenenti i seguenti file:

  • collection.anki2: Un database sqlite contenente carte, note, modelli di note, ecc…
  • File chiamati 1,2,3,4…: Le immagini che le schede utilizzano
  • media: Un file json contenente le mappature tra le immagini e i loro nomi originali (es: il file 1 si chiama in realtà latex-96c15f8a1af25e7a2eec64f7c6fedafe12363352.png nelle carte).

La struttura della collezione.anki2

Questo è il vero e proprio database che contiene tutte le note e altre informazioni utili che useremo per generare il visualizzatore. C’è una guida molto dettagliata su cosa contiene esattamente il database. In questo documento descriveremo solo ciò di cui avremo bisogno per estrarre dal database per generare il visualizzatore.

Recuperare le note

Le note sono memorizzate nella tabella notes. Le colonne di cui abbiamo bisogno da quella tabella sono:

  • id: L’identificatore unico della nota
  • mid: L’ID del modello delle carte (descritto più avanti come ottenerlo)
  • tags: I tag associati alla nota
  • fld: I campi della nota. Questo deve essere inserito nel modello delle carte per generare le carte e contiene tutti i campi, separati dal carattere 0x1f (31). L’ordine dei campi è esattamente quello presentato nel modello della nota.

Recuperare i modelli di carte

Per poter generare le carte dalle note, dobbiamo recuperare il modello di carte. Il modello ci dice quante carte devono essere generate da una singola nota, qual è l’HTML che circonda la nota, come devono essere presentati i campi di notes.fld.

Il modello può essere trovato nella colonna models della tabella col. Si noti che la tabella col contiene sempre un solo record. Il modello è memorizzato in un formato JSON; questo è un esempio di come appare il JSON di un modello con due modelli:

{ "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" }}

Nello stesso URL menzionato prima c’è una descrizione molto bella di cosa fa ogni campo del modello. Qui saranno descritti solo quelli di cui abbiamo bisogno per creare il browser delle carte.

Nella radice dell’oggetto, c’è una chiave "1471435193999". Questa chiave è l’id di quel modello, che è menzionato nella colonna mid della tabella notes.

All’interno di quell’oggetto c’è un array con chiave "flds". Questo array contiene i campi che le schede specificano quando si creano le note. Di solito ci sono solo i campi “Front” e “Rear”, tuttavia, a seconda del modello, è possibile avere più campi diversi. Come detto prima, le note conservano queste informazioni nella colonna notes.fld; i campi della colonna sono nello stesso ordine delle definizioni dei campi in questo array.

L’oggetto "tmpls" contiene i modelli delle note e fornisce informazioni sulla struttura HTML delle carte. I modelli che definiscono più modelli generano più schede, una per ogni modello. Questo oggetto ha due campi importanti:

  • "qfmt": L’HTML del fronte della carta
  • "afmt": L’HTML del retro della carta
  • "ord": La posizione del modello nell’array "tmpls". Questo è usato dalla tabella cards per identificare il modello che ha generato la carta.

Questi campi possono contenere {{placeholders}} che devono essere sostituiti con i valori dei campi che le carte memorizzano in notes.fld. L’associazione tra posizione del campo e nome del campo è quella degli oggetti in "flds". Si noti che "afmt" può contenere uno speciale segnaposto chiamato {{FrontSide}}; questo è solo un modo pratico di mostrare il contenuto della scheda senza dover copiare & incollare il contenuto di "qfmt" durante la creazione di modelli di schede.

L’ultimo campo di nostro interesse è "css"; contiene il codice CSS che deve essere applicato alla carta.

Recupero delle informazioni sul mazzo

Le informazioni sui mazzi contenute nell’archivio sono memorizzate nella colonna col.decks in formato JSON. Ecco un esempio 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": "" }}

Alcuni campi da notare:

  • id: Id unico del mazzo. L’id è usato nella tabella cards, nella colonna did per specificare le associazioni tra carte e mazzi (spiegato più avanti). Si noti che il mazzo di default ha sempre l’id 1.
  • name: Il nome del mazzo. In caso di mazzi figli, il nome sarà nel formato “Parent deck name::Child deck name”

Fetching cards

Le informazioni sulle carte sono memorizzate nella tabella cards. Le colonne che ci servono da questa tabella sono:

  • id: identificatore unico della carta
  • nid: id della nota che ha generato questa carta
  • did: identificatore id del mazzo dove questa carta è contenuta
  • ord: la posizione del modello del modello; corrisponde al campo ord del modello.

La struttura del file media

media è un file JSON che associa i nomi in codice delle immagini ai loro nomi originali. Durante la creazione del file .apkg anki comprime i nomi delle immagini (in realtà li rinomina solo con numeri progressivi), tuttavia le schede continuano a fare riferimento al nome originale. Lo scopo del file media è quello di renderci capaci di tradurre i nomi numerici nei nomi originali delle immagini.

La struttura di media è abbastanza semplice:

Lascia un commento