Anki-Import
view release on metacpan or search on metacpan
lib/Anki/Import.pm view on Meta::CPAN
opt vverbose => (
isa => 'Bool',
alias => 'V',
comment => 'verbose information plus debug info'
);
# start here
sub anki_import {
my $args = optargs( @_ );
my $file = $args->{file};
if (!$file) {
logf('Aborting: No file passed to Anki::Import.');
}
# set parent directory
my $pd = $args->{parent_dir};
# set log level as appropriate
if ($args->{verbose}) {
set_log_level('info');
} elsif ($args->{vverbose}) {
set_log_level('debug');
} else {
set_log_level('error');
}
logi('Log level set');
# get and load the source file
logi('Loading file');
my $path = File::Spec->catfile($file); logd($path);
if (! -e $path) {
logf("Aborting: Source file named '$path' does not exist.");
};
open (my $handle, "<:encoding(UTF-8)", $path) or logf("Could not open $path");;
chomp(@lines = <$handle>);
close $handle;
logi('Source file loaded.');
# pad data with a blank line to make it easier to process
push @lines, '';
# do the stuff we came here for
validate_src_file(); logd(\@notes);
generate_importable_files($pd);
# print a success message
unless ($args->{'quiet'}) {
set_log_level('info');
logi("Success! Your import files are in the $pd"
. '/anki_import_files directory');
}
# fin
}
# functions for first pass parsing of source data
sub validate_src_file {
logi('Validating source file');
# throw error if file is empty
logf('Source data file is empty.') if !$lines[0];
# outer loop for parsing notes
my %fields; # keeps track of number of fields for each type of note
while (next_line()) {
# ignore blank lines
next if ($cline =~ /^$|^\s+$/);
if ($cline =~ /^#\s*(\S+)/) {
$ntype = $1;
logi("Found note type");
logd($ntype);
next;
}
logi('Processing new note');
# get the note
my $note = slurp_note();
logd($note);
logi('Checking number of note fields');
# validaate that notes of the same type have the same number of fields
if (my $number_of_fields = $fields{$ntype}) {
if (scalar (@$note) != $number_of_fields) {
my $field_count = scalar(@$note);
logf("A(n) $ntype note ending on line $line_count"
. " has $field_count fields, a different amount than previous '$ntype' note types."
. " Notes of the same note type must have the same number of fields. One common reason"
. " for this error is that you did not indicate that you wanted to leave a field blank. To leave a field blank,"
. " place a single '`' (backtick) on the line by itself in the source file. You may also"
. " have failed to separate notes with two or more blank lines."
. " Check your source file to ensure it is properly formatted.\n\n\tRefer to the"
. " Anki::Import documentation for more help with formatting your source file."
);
}
} else {
$fields{$ntype} = scalar @$note;
}
logi('Storing note');
push @notes, {ntype => $ntype, note => $note};
}
}
sub slurp_note {
my @current_field;
my @note;
push @current_field, $cline;
# loop over lines in the note
while (next_line()) {
logd($cline, 'cline');
if ($cline =~ /^$|^\s+$/) {
my @all_fields = @current_field;
push (@note, \@all_fields) if @current_field;
@current_field = ();
if ($lline =~ /^$|^\s+$/) {
last;
lib/Anki/Import.pm view on Meta::CPAN
Next, check Anki's settings to be sure you are importing notes into the proper
fields, deck and note type. Also ensure you have the "Allow HTML in fields"
option enabled and that you have "Fields separated by: Tab" selected.
Click "Import" and repeat for each note type you are importing.
Consult L<Anki's documentation|https://apps.ankiweb.net/docs/manual.html#importing>
for more details on importing and managing your notes.
=head2 General description of the source file
The source file contains one or more Anki notes. To make importing easier,
each source file should contain notes that will be imported into the same Anki
deck.
=head3 Creating notes and fields in the source file
Each note in the source file contains fields which should correspond to your
existing note types in Anki. Individual notes in the source file are delineated
by two or more blank lines. Fields are separated by a single blank line. Fields
for each note should be in the same order as your Anki note types to make
importing more automatic. All fields must have content or left intentionally
blank.
To create an intionally blank field, add a single '`' (backtick) character on a
line by itself with blank lines before and after the line with the single
backtick.
See the L</Source file example> for more help.
=head3 Source file requirements and limitations
=head4 Use UTF-8 encoding
The source file should be a plain text file with UTF-8 encoding. UTF-8
is likely the default encoding method for your editor but check your editor's
settings and documentation for further details.
=head4 Avoid tabs
Since tab characters are used by Anki to split your fields, you should
avoid relying on tab characters in your source file. Any tabs found in your
source file will get converted to four spaces.
=head3 Assigning notes to note types
You can indicate which note type a note belongs to by preceding notes with a
C<#note_type> comment at the beginning of a line. You can choose any note type
name you wish but it is recommended that you use note type names similar to
those that exist in your Anki database to make importing the notes easier.
Note type comments not only assign a note type to the next note, but any
notes therafter until a new note type comment is encountered (see the example
in the next section). So note type comments actually delineate a note type
section. If no note types are indicated in your source file, the
"Basic" note type is used.
Note types are used to help C<Anki::Import> ensure other notes of the same type
have the same number of fields. If the notes assigned to a particular note type
do not all have the same number of fields, an error is thrown so be sure each
note has the correct number of fields.
Note: note type sections can be split across the file (i.e. you do not have to
group the notes of a particular note type together).
=head3 Tagging notes
Place your space seprated lit of tags in the last field. As long as there is
one more field in the source files that fields in the note you are importing
to, Anki will generate tags from the last field.
You can automate tag generation by placing a single '^' (caret) character
on a line by itself immediately after your list of tags. These tags will now
be used for all later notes in the file until they are overridden by a new list
of automated tags. Also any new tags you place at the end of a note will be
added to the list of tags that are automatically generated.
To reset the automated list of tags, place a single '^' (caret) character
in place of the field where your tags will go.
To suppress the application of an automated tag from the list of automated tags
for a particular note, include that tag in the tag field and it will not be
tagged with that term for that one note.
To add a new tag to the already existing set of tags, enter the tags on
a line followed by a new line with a single '+' sign on it by itself.
Note: If you use tags on any of your notes in a parcitular note type, you must
use tags on all of your notes or indicate that the tag field should be left
blank with a '`' (backtick) character on a line by itself.
=head3 Applying text formatting to your notes
Learning how to format the source file is key to getting Anki to import your
notes properly and getting the most out of C<Anki::Import>.
Following a few simple rules, you can assign notes to a note type, preserve
whitespace in fields, create bold text, create blank lines in your fields,
add tags, create cloze deletions, indicate which fields are blank and
generate simple lists. Study the example below for details.
Note: Lines containing only whitespace characters are treated as blank lines.
=head4 Example source file
Below is an example of how to format a source data file. Note that the column on
the right containing comments for this example are not permitted in an actual
source data file.
# Basic # We start a note section here. Any
# notes below here to the next
# note type comment are assigned to
# the 'Basic' note type
# You can have blank lines between the
# note type comment and the next
# question.
What is the first day of the week? # Question 1, Field 1
# Blank line here indicates a new field.
( run in 0.951 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )