slavetto / anki-cards-web-browser

¿Qué es esto?

Este documento explica cómo debe funcionar el procesamiento de los archivos apkg.

Estructura de los archivos .apkg

Los archivos .apkg de Anki no son más que archivos zip que contienen los siguientes ficheros:

  • collection.anki2: Una base de datos sqlite que contiene tarjetas, notas, modelos de notas, etc…
  • Los archivos llamados 1,2,3,4…: Las imágenes que utilizan las tarjetas
  • media: Un archivo json que contiene los mapeos entre las imágenes y sus nombres originales (por ejemplo: el archivo 1 se llama en realidad latex-96c15f8a1af25e7a2eec64f7c6fedafe12363352.png en las tarjetas).

La estructura de la colección.anki2

Esta es la base de datos real que contiene todas las notas y otra información útil que usaremos para generar el visor. Hay una guía muy detallada sobre lo que contiene exactamente la base de datos.En este documento nos limitaremos a describir lo que necesitaremos extraer de la base de datos para generar el visor.

Obtención de notas

Las notas se almacenan en la tabla notes. Las columnas que necesitamos de esa tabla son:

  • id: El identificador único de la nota
  • mid: El ID del modelo de tarjetas (se describe más adelante cómo obtenerlo)
  • tags: Las etiquetas asociadas a la nota
  • fld: Los campos de la nota. Contiene todos los campos, separados por el carácter 0x1f (31). El orden de los campos es exactamente el que se presenta en el modelo de la nota.

Obtención de modelos de tarjetas

Para poder generar las tarjetas a partir de las notas, necesitamos obtener el modelo de tarjetas. El modelo nos indica cuántas tarjetas deben generarse a partir de una sola nota, cuál es el HTML que rodea a la nota y cómo deben presentarse los campos de notes.fld.

El modelo se encuentra en la columna models de la tabla col. Tenga en cuenta que la tabla col siempre contiene un solo registro. El modelo se almacena en formato JSON; este es un ejemplo de cómo se ve el JSON de un modelo con dos modelos:

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

En la misma URL mencionada anteriormentehay una descripción muy bonita de lo que hace cada campo del modelo. Aquí se describirán sólo los que necesitamos para crear el navegador de tarjetas.

En la raíz del objeto, hay una clave "1471435193999". Esa clave es el id de ese modelo, que se menciona en la columna mid de la tabla notes.

Dentro de ese objeto hay un array con clave "flds". Este array contiene los campos que las tarjetas especifican al crear las notas. Normalmente sólo hay campos «Front» y «Rear», sin embargo, dependiendo del modelo, es posible tener más campos diferentes. Como se mencionó anteriormente, las notas almacenan esta información en la columna notes.fld; los campos de la columna están en el mismo orden de las definiciones de los campos en esta matriz.

El objeto "tmpls" contiene plantillas de las notas y proporciona información sobre la estructura HTML de las tarjetas. Los modelos que definen varias plantillas generan varias tarjetas, una por cada plantilla. Este objeto tiene dos campos importantes:

  • "qfmt": El HTML del anverso de la tarjeta
  • "afmt": El HTML del reverso de la tarjeta
  • "ord": La posición de la plantilla en el array "tmpls". La tabla cards la utiliza para identificar la plantilla que ha generado la tarjeta.

Estos campos pueden contener {{placeholders}} que deben ser sustituidos por los valores de los campos que las tarjetas almacenan en notes.fld. La asociación entre la posición del campo y el nombre del campo es la de los objetos en "flds". Tenga en cuenta que "afmt" puede contener un marcador de posición especial llamado {{FrontSide}}; esto es sólo una forma práctica de mostrar el contenido de la tarjeta sin tener que copiar & pegar el contenido de "qfmt" al crear modelos de tarjetas.

El último campo que nos interesa es "css"; contiene el código CSS que hay que aplicar a la tarjeta.

Obtención de la información de las barajas

La información sobre las barajas contenidas en el archivo se almacena en la columna col.decks en formatoJSON. A continuación se muestra un ejemplo 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": "" }}

Algunos campos que deben tenerse en cuenta:

  • id: Id. único de la baraja. El id se utiliza en la tabla cards, en la columna did para especificar las asociaciones entre cartas y barajas (se explica más adelante). Tenga en cuenta que el mazo por defecto tiene siempre el id 1.
  • name: El nombre del mazo. En el caso de los mazos hijos, el nombre tendrá el formato «Nombre del mazo padre::Nombre del mazo hijo»

Obtención de cartas

La información sobre las cartas se almacena en la tabla cards. Las columnas que necesitamos de esa tabla son:

  • id: identificador único de la carta
  • nid: id de la nota que generó esta carta
  • did: id identificador del mazo donde está contenida esta carta
  • ord: la posición de la plantilla del modelo; coincide con el campo ord de la plantilla.

La estructura del archivo multimedia

media es un archivo JSON que asocia los nombres en clave de las imágenes a sus nombres originales. Durante la creación del archivo .apkg, anki comprime los nombres de las imágenes (en realidad sólo las nombra con números progresivos), pero las tarjetas siguen haciendo referencia al nombre original. El propósito del archivo media es hacernos capaces de traducir los nombres numéricos en los nombres originales de las imágenes.

La estructura de media es bastante sencilla:

Deja un comentario