use strict;
use warnings;
use Spreadsheet::ParseExcel;
use LaTeX::Encode;
use Template;
use Data::Printer;
my %fieldmap = (
spellname => 'name',
name => 'name',
level => 'level',
school => 'scuola',
comp => 'components',
ct => 'tempo',
range => 'range',
target => 'target',
duration => 'durata',
st => 'st',
sr => 'sr',
description => 'descrizione',
special => 'specialcomp',
page => 'ref',
notes => 'note',
);
my ($input_filename,$output_filename)=@ARGV;
die "$0 \$input \$output\n"
unless $input_filename && $output_filename;
my $parser = Spreadsheet::ParseExcel->new();
my $wb = $parser->parse($input_filename)
or die $parser->error;
sheet_2_latex(
sheet_name => 'Incantesimi',
output_filename => "${output_filename}.incantesimi.tex",
);
sheet_2_latex(
sheet_name => 'Domini',
sheet_idx => 1,
output_filename => "${output_filename}.domini.tex",
skip_col => 1,
);
{
my $template;
sub template {
$template //= do {local $/;<DATA>};
return $template;
}
}
sub sheet_2_latex {
my %opts = (
sheet_idx => 0,
fieldmap => \%fieldmap,
@_,
);
my $spells = parse_table(
$wb->worksheet($opts{sheet_name})
// $wb->worksheet($opts{sheet_idx}),
$opts{skip_col},
);
munge($spells);
my $template = Template->new();
$template->process(
\template(),
{
spells => $spells,
fieldmap => $opts{fieldmap},
lt => \&latexise,
},
$opts{output_filename},
)
or die $template->error;
}
sub parse_table {
my ($ws,$skip_col) = @_;
$skip_col //= 0;
my ($min_col,$max_col) = $ws->col_range();
my ($min_row,$max_row) = $ws->row_range();
my @headings = map { eval { $ws->get_cell($min_row,$_)->value } }
$min_col .. $max_col;
for my $h (@headings) {
$h =~ s{^spell\W}{}i;
$h =~ s{\W.*$}{};
$h = lc($h);
}
my @ret = ();
for my $row ((1+$min_row) .. $max_row) {
next unless eval { $ws->get_cell($row,$min_col+$skip_col)->value };
my %record;
keys @headings;
while (my ($idx,$heading) = each @headings) {
next unless $heading;
$record{$heading} =
eval { $ws->get_cell($row,$idx+$min_col)->value } // '';
}
push @ret,\%record;
}
return \@ret;
}
sub munge {
my ($spells) = @_;
for my $spell (@$spells) {
if ($spell->{page} =~ m{^\d+$}) {
$spell->{page} = 'PHB'.$spell->{page};
}
}
return;
}
sub latexise {
my ($str) = @_;
$str = latex_encode($str);
$str =~ s{(?<!\\)\. }{.\\ }g;
return $str;
}
__DATA__
\input{incantesimi.cmd}
\usepackage{textcomp}
\begin{document}
%
\begin{tikzpicture}
\matrix {
[% FOREACH spell IN spells %]
\incantesimo{type=spell,
[%- FOREACH field IN fieldmap; IF spell.item(field.key) != '' %]
[% field.value %]={[% lt(spell.item(field.key)) %]},
[%- END; END %]
} [% IF (loop.count() % 6) %]& [% ELSE %] \\ [% END -%]
[% IF (loop.count() % 18) == 0 %]};
\end{tikzpicture}
\pagebreak
\begin{tikzpicture}
\matrix {
[% END; END;
rest_in_row = spells.size % 6;
FOREACH skip IN [ 1 .. rest_in_row ]; ' & '; END; ' \\\\ '
%]};
\end{tikzpicture}
\vspace{-10pt}
\end{document}