Anki-Import
view release on metacpan or search on metacpan
lib/Anki/Import.pm view on Meta::CPAN
$ws_mode = 1;
# add a couple of blank lines to previous line
if ($$last_line) {
$$last_line .= '<br><br>';
}
$$last_line .= '<div style="text-align: left; font-family: courier; white-space: pre;">';
next;
}
# exit whitespace mode, close out HTML, add blank lines
if ($line =~ /^`{3,3}$/ && $ws_mode) {
$ws_mode = 0;
$$last_line .= "</div><br><br>";
next;
}
# handle lines differently based on if we are preserving whitespace
if ($ws_mode) {
# escape characters in preserved text
if ($line =~ /^`\s*$/) {
$$last_line .= '<br>';
next;
}
$line =~ s/(?<!\\)`/\\`/g;
$line =~ s/(?<!\\)\*/\\*/g;
$line =~ s/(?<!\\)%/\\%/g;
$$last_line .= $line . "<br>";
} else {
push @lines, $line;
}
}
logf('A set of backticks (```) is unmatched or you failed to backtick a'
. ' blank line inside of a backtick set. Please correct the source'
. ' file and try again. Run "perldoc Anki::Import" for more help.') if $ws_mode;
logd($field_out, 'field_out');
shift @lines if !$lines[0];
my $field = join ' ', @lines;
# clean up dangling breaks
$field =~ s/<br><\/div>/<\/div>/g;
# handle formatting codes in text, preserve escaped characters
# preserve angle brackets between backticks
my $parts = [ split /[^\\]`|^`/, $field, -1];
my $count = 0;
foreach my $part (@$parts) {
$count++;
next if ($count % 2); # only substitute on odd number array items
$part =~ s/</</g;
}
$field = join '`', @$parts;
# backticked characters
$field =~ s/(?<!\\)`(.*?)`/<span style="font-family: courier; weight: bold;">$1<\/span>/gm;
$field =~ s/\\`/`/g;
# bold
$field =~ s/(?<!\\)\*(.*?)\*/<span style="weight: bold;">$1<\/span>/gm;
$field =~ s/\\\*/*/g;
# unordered lists
$field =~ s'(?<!\\)%(.*?)%'"<ul><li>" . join ("</li><li>", (split (/,\s*/, $1))) . "</li><\/ul>"'gme;
$field =~ s/\\%/%/g;
$field =~ s/(<br>)+$//;
push @fields, $field;
}
# generate tag field
if (@autotags && !$new_autotags) {
# get tags from tag field
my @note_tags = split (/\s+/, $fields[-1]); logd(\@note_tags, 'raw_note_tags');
my @new_tags = ();
# add tags from tag field
foreach my $note_tag (@note_tags) {
my $in_autotags = grep { $_ eq $note_tag } @autotags;
push @new_tags, $note_tag unless $in_autotags;
}
# add autotags
foreach my $autotag (@autotags) {
my $discard_autotag = grep { $_ eq $autotag } @note_tags;
push @new_tags, $autotag if !$discard_autotag;
}
# add combined tags as a field
logd(\@new_tags, 'new_tags');
my $new_tags = join (' ', @new_tags);
$fields[-1] = $new_tags;
}
$new_autotags = 0;
my $out = join ("\t", @fields);
# create cloze fields
my $cloze_count = 1;
# TODO: should probably handle escaped braces just in case
while ($out =~ /\{\{\{(.*?)}}}/) {
$out =~ s/\{\{\{(.*?)}}}/{{c${cloze_count}::$1}}/s;
$cloze_count++;
}
logd($out, 'out');
$out .= "\n";
}
1; # Magic true value
# ABSTRACT: Anki note generation made easy.
__END__
=pod
=head1 NAME
lib/Anki/Import.pm view on Meta::CPAN
=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.
Monday. # Question 1, Field 2
# Add two or more blank lines between
questions
How many days of the week are there? # Question 2, Field 1
Our caldendar # Question 2, Field 2
has seven days # Answers can run
in a week # across one or more lines but
# will be imported as a single
# line into Anki.
# less_basic # New note type called "less_basic"
# with 3 fields
What is the third day of week? # Question 3, Field 1
Wednesday # Question 3, Field 2
Wed. # Question 3, Field 3
your_tags go_here # We set up automated tags on this note
^ # with the '^' symbol on a line by itself
# immediately after out tag list.
# These tags will be applied to this and
# all future notes unless overridden.
Put {{{another question}}} here. # Surround text with 3 braces for a cloze
Here is an field that has
` # Insert a blank line into a field
a blank line in it. # with a single backtick character
# surrounded by lines with text.
go_here # We set autotags in the last note and
# they will carry forward to this note
# except for the exclusions we place
# here. This note will *not* be tagged
# with 'go_here' but it will still be
# tagged under 'your_tags'.
What does this code do? # Another less_basic question
``` # Preserve whitespace in a field with 3
This_is_some_code { # backticks on a single line.
` # You must still backtick blank lines
print 'Whitespace will be # when preserving whitespace, however.
preserved';
` # Another blank line.
}
``` # End whitespace preservation
This is %comma,delimted,text% # Bullet lists with %item1,item2,item3%
' # The tags field is left blank. But all
# the auto tags will still be applied.
Another question # Field 1
` # Field 2 is blank.
This is *in bold* # Field 3 has bold words, followed by a
` # blank line, followed by
%an,unordered,list% # an ordered list.
new_tags more_new_tags # This and future notes will use these
^ # newer automated tags.
#basic # switch back to a 'basic' note type
Last question
Last anser
add_this_tag_to_autotags # We add a new_tag to our autotag list
+ # with the '+' sign by itself on a new
# line.
=head3 Getting the most from C<Anki::Import>
By itself, C<Anki::Import> will make it easier for you to format and
input your notes especially if you do a lot of basic HTML formatting. However,
the huge productivity gains of C<Anki::Import> can only be unlocked by getting
proficient wih your text editor of choice.
For example, you can generate templates for each of the note types you use to
make data entry exceptionally painless. And with a text editor like vim, you
can automate the generation of the formatting codes used by C<Anki::Import>
and make Anki note creation joyful, or at least much less tedious.
Teaching you how to use and optimize your text editor for C<Anki::Import> is
well beyond the scope of this document. But if you take the time now and do the
up front work of learning your text editor and tweaking it for use with
C<Anki::Import>, you will save a lot of time in the long run.
In the future, vim configurations and plugins for use with C<Anki::Import>
may be released as they are developed to help you get going faster with vim.
Unfortunately, other text editors cannot be supported as there are far too many
and far too little time to get familiar with all their features.
=head1 USAGE
C<anki_import> can be run from the command line or from within another perl
script. It behaves the same way in both environments.
=head2 Command line usage
The C<Anki::Import> module installs the C<anki_import> command line command
for generating import files which is used as follow:
anki_import source_file [parent_dir] [--verbosity_level]
B<Example:> anki_import pop_quiz.txt /home/me --verbose
C<anki_import> processes the C<source_file> and generates files to be imported into
Anki, one file for each note type. These files are placed in a directory called
C<anki_import_files>. This directory is placed in the current working directory
by default.
Note that previously generated files already located in the C<anki_import_files>
directory the command is outputting to will will be overwritten without warning.
Add a unique (C<parent_dir> path to help prevent this.
( run in 0.436 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )