Anki-Import
view release on metacpan or search on metacpan
lib/Anki/Import.pm view on Meta::CPAN
# the meat of the matter
# TODO: break up into shorter functions for readability
sub process_note {
my $note = shift; logd($note, 'note_2b_processed');
my @fields = ();
my $new_autotags = 0; # flag raised if autotag line found
# loop over note fields
foreach my $field (@$note) {
my $ws_mode = 0; # tracks if we are preserving whitespace
my $field_out = '';
# loop over lines in field and process accordingly
my @lines = (''); # can't take a reference to nothing
foreach my $line (@$field) {
my $last_line = \$lines[-1]; # just to make it easier to type
# detect autotags
logd($line);
if ($line =~ /^\+\s*$/ && !$ws_mode) {
push @autotags, split (/\s+/, $$last_line);
$new_autotags = 1;
}
if ($line =~ /^\^\s*$/ && !$ws_mode) {
@autotags = split (/\s+/, $$last_line);
$new_autotags = 1;
next;
}
# blanks lines not in non-whitespace mode
if ($line =~ /^`\s*$/ && !$ws_mode) {
if ($$last_line && $$last_line !~ /^<br>+$/) {
$$last_line .= '<br><br>';
}
next;
}
# enter whitespace mode and adding appropriate HTML
if ($line =~ /^`{3,3}$/ && !$ws_mode) {
$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
Anki::Import - Anki note generation made easy.
=head1 VERSION
version 0.030
=head1 OVERVIEW
Efficiently generate formatted Anki notes with your
text editor for easy import into Anki.
=head1 SYNOPSIS
# Step 1: Create the source file
# Step 2: Run the anki_import command
supplied by this module...
# ...from the command line
anki_import path/to/source_file.txt
# or
# ...from within a perl script
use Anki::Import;
anki_import('path/to/source_file.txt');
# Step 3: Import the resultant files into Anki
=head1 DESCRIPTION
Inputting notes into Anki can be a tedious chore. C<Anki::Import> lets you
you generate Anki notes with your favorite text editor (e.g. vim, BBEdit, Atom,
etc.) so you can enter formatted notes into Anki's database more efficiently.
At a minimum, you should have basic familiarity with using your computer's
command line terminal to make use of this program.
=head2 Steps for creating, processing and imorting new notes
=head3 Step 1: Generate the notes with your text editor
( run in 0.741 second using v1.01-cache-2.11-cpan-39bf76dae61 )