App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/Output/PDF.pm view on Meta::CPAN
use DDP; p $pagectrl, as => "pagectrl";
}
return $pagectrl;
}
sub pagectrl_msg {
my ( $pagectrl ) = @_;
my $msg = $pagectrl->{dual_pages} ? "dual" : "single";
if ( $pagectrl->{align_tocs} ) {
$msg .= ", align_tocs";
$msg .= "_song" if $pagectrl->{align_tocs} eq "song";
}
if ( $pagectrl->{align_songs} ) {
$msg .= ", align_songs";
$msg .= ", extend" if $pagectrl->{align_songs_extend};
$msg .= ", spread" if $pagectrl->{align_songs_spread};
}
$msg .= ", " . $pagectrl->{sort_songs} if $pagectrl->{sort_songs};
return $msg;
}
sub sort_songbook {
my ( $sb, $pagectrl ) = @_;
return unless my $sorting = $pagectrl->{sort_songs};
foreach my $song ( @{$sb->{songs}} ) {
if (!defined($song->{meta}->{sorttitle})) {
$song->{meta}->{sorttitle} = $song->{meta}->{title};
}
}
my @songlist = @{$sb->{songs}};
my @tbs; # to be sorted
my $desc = 0; # descending
if ( $sorting =~ /^([-+]?)title$/i ) {
$desc = $1 eq "-";
@tbs = map { [ $_->{meta}->{sorttitle}->[0], $_ ] } @songlist;
}
elsif ( $sorting =~ /^([-+]?)subtitle$/i ) {
$desc = $1 eq "-";
@tbs = map { [ $_->{meta}->{subtitle}->[0], $_ ] } @songlist;
}
return unless @tbs;
if ( 1 ) {
my $collator = Unicode::Collate->new;
my ( $aa, $bb ) = $desc ? qw( b a ) : qw( a b );
my $l = "\$$aa"."->[0]";
my $r = "\$$bb"."->[0]";
my $proc = 'sub { my $tbs = shift; ';
$proc .= '[ map { $_->[1] } sort { ';
$proc .= "\$collator->cmp( $l, $r )";
$proc .= ' } @$tbs ] }';
my $sorter = eval $proc;
die("OOPS $proc\n$@") if $@;
$sb->{songs} = $sorter->(\@tbs);
}
else {
my $proc = 'sub { my $tbs = shift; use locale; ';
$proc .= '[ map { $_->[1] } sort { ';
$proc .= $desc ? '$b->[0] cmp $a->[0]' : '$a->[0] cmp $b->[0]';
$proc .= ' } @$tbs ] }';
my $sorter = eval $proc;
die("OOPS $proc\n$@") if $@;
$sb->{songs} = $sorter->(\@tbs);
}
}
sub compact_songbook {
my ( $sb, $pagectrl ) = @_;
return 0 unless $pagectrl->{compact_songs};
my $ps = $config->{pdf};
my $pri = ( __PACKAGE__."::Writer" )->new( $ps, $pdfapi );
# Count pages to properly align multi-page songs without
# needing to turn page.
my $page = $options->{"start-page-number"} ||= 1;
foreach my $song ( @{$sb->{songs}} ) {
if (!defined($song->{meta}->{sorttitle})) {
$song->{meta}->{sorttitle} = $song->{meta}->{title};
}
}
my @songlist = @{$sb->{songs}};
my $filler = 0; # filler for 2page
# Progress indicator
progress( phase => "Counting",
index => 0,
total => scalar(@{$sb->{songs}}) );
my $i = 1;
foreach my $song ( @songlist ) {
return unless progress( msg => $song->{title} );
$i++;
#### HACK ATTACK.
# Assets will be rendered, but then they are part of the temp
# PDF, not the final one.
# We copy the unprocessed assets and restore after the 1st pass.
use Storable qw(dclone);
my $assets;
$assets = dclone( $song->{assets} ) if $song->{assets};
####
$song->{meta}->{pages} =
generate_song( $song,
{ pr => $pri,
startpage => 1,
pagectrl => $pagectrl,
} );
####
$song->{assets} = $assets if $assets;
####
}
my @new;
( run in 0.439 second using v1.01-cache-2.11-cpan-ceb78f64989 )