Crate genanki_rs
source ·Expand description
A crate for easily generating flashcard decks for the popular open source flashcard platform Anki. It is based on the code of genanki, a python library.
Getting Started
To use genanki-rs, add the following to your Cargo.toml
genanki-rs = "0.4"
Minimal Example
The following example creates a simple deck, containing 2 question-answer flashcards:
use genanki_rs::{basic_model, Deck, Error, Note};
fn main() -> Result<(), Error> {
let mut deck = Deck::new(1234, "Example Deck", "Example Deck containing 2 Flashcards");
deck.add_note(Note::new(basic_model(), vec!["What is the capital of France?", "Paris"])?);
deck.add_note(Note::new(basic_model(), vec!["What is the capital of Germany?", "Berlin"])?);
deck.write_to_file("output.apkg")?;
Ok(())
}
Concepts
Notes
The basic unit in Anki is the Note
, which contains a fact to memorize. Note
s correspond to one or more Card
s.
Here’s how you create a Note
:
use genanki_rs::{Note, Error};
fn main() -> Result<(), Error> {
// let my_model = ...
let my_note = Note::new(my_model, vec!["Capital of Argentina", "Buenos Aires"])?;
Ok(())
}
You pass in a Model
, discussed below, and a set of fields
(encoded as HTML).
Models
A Model
defines the fields and cards for a type of Note
. For example:
use genanki_rs::{Field, Model, Template, Error};
fn main() -> Result<(), Error> {
let my_model = Model::new(
1607392319,
"Simple Model",
vec![Field::new("Question"), Field::new("Answer")],
vec![Template::new("Card 1")
.qfmt("{{Question}}")
.afmt(r#"{{FrontSide}}<hr id="answer">{{Answer}}"#)],
);
// let my_note = ...
Ok(())
}
This note-type has two fields and one card. The card displays the
Question
field on the front and the Question
and Answer
fields on the
back, separated by a <hr>
. You can also pass custom css
by calling
Model::css
to supply custom CSS.
let custom_css = ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n}\n";
let my_model_with_css = Model::new(
1607392319,
"Simple Model",
vec![Field::new("Question"), Field::new("Answer")],
vec![Template::new("Card 1")
.qfmt("{{Question}}")
.afmt(r#"{{FrontSide}}<hr id="answer">{{Answer}}"#)])
.css(custom_css);
You need to pass a model id
and a model name
so that Anki can keep track of your model. It’s important that you use a unique model id
for each Model
you define.
Generating a Deck/Package
To import your notes into Anki, you need to add them to a Deck
:
use genanki_rs::{Deck, Error};
fn main() -> Result<(), Error> {
let my_note = make_note();
let mut my_deck = Deck::new(
2059400110,
"Country Capitals",
"Deck for studying country capitals",
);
my_deck.add_note(my_note);
Ok(())
}
Once again, you need a unique deck id
, a deck name
and a deck description
.
Then, create a Package
for your Deck
and write it to a file:
my_deck.write_to_file("output.apkg")?;
You can then load output.apkg
into Anki using File -> Import…
Media Files
To add sounds or images, create a Package
and pass the decks
and media_files
you want to include:
use genanki_rs::{Deck, Error, Package};
fn main() -> Result<(), Error> {
// ...
// my_deck.add(my_note)
let mut my_package = Package::new(vec![my_deck], vec!["sound.mp3", "images/image.jpg"])?;
my_package.write_to_file("output.apkg")?;
Ok(())
}
media_files
should have the path (relative or absolute) to each file. To use them in notes, first add a field to your model, and reference that field in your template:
let my_model = Model::new(
1607392319,
"Simple Model",
vec![
Field::new("Question"),
Field::new("Answer"),
Field::new("MyMedia"), // ADD THIS
],
vec![Template::new("Card 1")
.qfmt("{{Question}}{{Question}}<br>{{MyMedia}}") // AND THIS
.afmt(r#"{{FrontSide}}<hr id="answer">{{Answer}}"#)],
);
Then, set the MyMedia
field on your Note
to [sound:sound.mp3]
for audio and <img src="image.jpg">
for images (e.g):
let my_note = Note::new(my_model.clone(), vec!["Capital of Argentina", "Buenos Aires", "[sound:sound.mp3]"])?;
// or
let my_note = Note::new(my_model.clone(), vec!["Capital of Argentina", "Buenos Aires", r#"<img src="image.jpg">"#])?;
You cannot put <img src="{MyMedia}">
in the template and image.jpg
in the field. See these sections in the Anki manual for more information: Importing Media and Media & LaTeX.
You should only put the filename (aka basename) and not the full path in the field; <img src="images/image.jpg">
will not work. Media files should have unique filenames.
sort_field
Anki has a value for each Note
called the sort_field
. Anki uses this
value to sort the cards in the Browse interface. Anki also is happier if
you avoid having two notes with the same sort_field
, although this isn’t
strictly necessary. By default, the sort_field
is the first field, but
you can change it by calling Note::sort_field
.
You can also call Model::sort_field_index
, passing the
sort_field_index
to change the sort field. 0
means the first field in
the Note, 1
means the second, etc.
Structs
- A flashcard deck which can be written into an .apkg file.
- Field to be fed into a
Model
. Model
to determine the structure of aNote
- Note (Flashcard) to be added to a
Deck
Package
to packDeck
s andmedia_files
and write them to a.apkg
file- Template to be fed into a
Model
. A Template represents the structure ofNotes
(Flashcards) in the deck and can be created using the builder pattern.
Enums
FrontBack
orCloze
to determine the type of a Model.
Functions
- Returns a basic Front/Back, Back/Front
Model
. - Returns a basic Front/Back
Model
. - Returns a basic Front/Back, Optional Back/Front
Model
. - Returns a basic
Model
for cards where you can type in the answer. - Returns a basic
Model
for cards with clozes.