App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/Song.pm view on Meta::CPAN
if $config->{debug}->{images};
}
}
# Move to assets.
$self->{assets}->{$id} =
{ type => "image",
subtype => "delegate",
delegate => "Grille",
handler => "grille2xo",
opts => $opts,
line => $grille[0]{line},
data => \@grille,
context => $in_context,
};
if ( $def ) {
my $label = delete $a->{label};
do_warn("Label \"$label\" ignored on non-displaying $in_context section\n")
if $label;
}
else {
my $label = delete $opts->{label};
$self->add( type => "set",
name => "label",
value => $label )
if $label && $label ne "";
$self->add( type => "image",
opts => $opts,
id => $id );
if ( $opts->{label} ) {
push( @labels, $opts->{label} )
unless $in_context eq "chorus"
&& !$config->{settings}->{choruslabels};
}
}
}
}
else {
$self->add( type => "set",
name => "context",
value => $def_context );
}
$in_context = $def_context;
undef $memchords;
return 1;
}
# Metadata extensions (legacy). Should use meta instead.
# Only accept the list from config.
if ( any { $_ eq $dir } @{ $config->{metadata}->{keys} } ) {
return $self->dir_meta( "meta", "$dir $arg" );
}
# Formatting. {chordsize XX} and such.
if ( $dir =~ m/ ^( $propitems_re )
( font | size | colou?r )
$/x ) {
my $item = $1;
my $prop = $2;
$self->propset( $item, $prop, $arg );
# Derived props.
$self->propset( "chorus", $prop, $arg ) if $item eq "text";
# ::dump( { %propstack, line => $diag->{line} } );
return 1;
}
# More private hacks.
if ( !$options->{reference} && $d =~ /^([-+])([-\w.]+)$/i ) {
if ( $2 eq "dumpmeta" ) {
warn(::dump($self->{meta}));
}
$self->add( type => "set",
name => $2,
value => $1 eq "+" ? 1 : 0,
);
return 1;
}
if ( !$options->{reference} && $dir =~ /^\+([-\w.]+(?:\.[<>])?)$/ ) {
$self->add( type => "set",
name => $1,
value => $arg,
);
$config->unlock;
prpadd2cfg( $config, $1 => $arg );
$config->lock;
upd_config();
return 1;
}
# Warn about unknowns, unless they are x_... form.
do_warn("Unknown directive: $d\n")
if $config->{settings}->{strict} && $d !~ /^x_/;
return;
}
sub dir_chorus {
my ( $self, $dir, $arg ) = @_;
if ( $in_context ) {
do_warn("{chorus} encountered while in $in_context context -- ignored\n");
return 1;
}
# Clone the chorus so we can modify the label, if required.
my $chorus = @chorus ? dclone(\@chorus) : [];
if ( @$chorus && $arg && $arg ne "" ) {
my $kv = parse_kv( $arg, "label" );
my $label = $kv->{label};
if ( $chorus->[0]->{type} eq "set" && $chorus->[0]->{name} eq "label" ) {
$chorus->[0]->{value} = $label;
}
elsif ( defined $label ) {
unshift( @$chorus,
{ type => "set",
name => "label",
value => $label,
context => "chorus",
lib/ChordPro/Song.pm view on Meta::CPAN
my $info_s = $xpk->transpose( transpose_sound() );
$self->{chordsinfo}->{$info_p->name} //= $info_p;
$self->{chordsinfo}->{$info_s->name} //= $info_s;
$m->{key_print} = [ $info_p->keyname ];
$m->{key_sound} = [ $info_s->keyname ];
$xpose->set_key($info_p);
transpose_debug( "xp($arg)", $m );
}
else {
warn("WHOAH! Key \"$key\" not found in chordsinfo");
}
}
}
$self->add( %a, value => $xpose )
if $no_transpose;
return 1;
}
#### End of directive handlers ####
sub transpose_sound {
my ( $only_print ) = @_;
my $xp =
# Use current.
$xpose
# Apply capo.
+ ( $only_print ? 0 : $capo//0 )
# Apply global (cli, config) transpose.
+ $config->{settings}->{transpose};
warn( "XPOSE: ",
"base = ", $xpose->_data_printer, " ",
($only_print || !$capo) ? "" : "capo = $capo ",
"outer = ", $config->{settings}->{transpose}->_data_printer, " ",
$only_print ? "print = " : "sound = ", $xp->_data_printer,
"\n") if $config->{debug}->{xpose};
return $xp;
}
sub transpose_print {
transpose_sound(1);
}
sub transpose_debug {
return unless $config->{debug}->{xpose};
my ( $tag, $m ) = @_;
my $xp = transpose_print();
warn( "XPOSE: $tag, ",
"key = ", $m->{key}->[-1], ", ",
"print = ", $m->{key_print}->[0], ", ",
"sound = ", $m->{key_sound}->[0],
" [ ", join( " ", $config->{settings}->{transpose},
$xpose, $capo//0,
$xp->key ? "\@" . $xp->key->keyname : () ),
" ]\n" );
}
sub propset {
my ( $self, $item, $prop, $value ) = @_;
$prop = "color" if $prop eq "colour";
my $name = "$item-$prop";
$propstack{$name} //= [];
if ( $value eq "" ) {
my @toadd;
# Pop current value from stack.
if ( @{ $propstack{$name} } ) {
my $old = pop( @{ $propstack{$name} } );
# A trailing number after a font directive means there
# was also a size saved. Pop it.
if ( $prop eq "font" && $old =~ /\s(\d+(?:\.\d+)?)$/ ) {
pop( @{ $propstack{"$item-size"} } );
# Resetting the size must follow the font reset.
push( @toadd, type => "control",
name => "$item-size",
value =>
@{ $propstack{"$item-size"} }
? $propstack{"$item-size"}->[-1]
: undef );
}
}
else {
do_warn("No saved value for property $item$prop\n" )
}
# Use new current value, if any.
if ( @{ $propstack{$name} } ) {
$value = $propstack{$name}->[-1]
}
else {
$value = undef;
}
$self->add( type => "control",
name => $name,
value => $value );
$self->add( @toadd ) if @toadd;
return 1;
}
if ( $prop eq "size" ) {
unless ( $value =~ /^\d+(?:\.\d+)?\%?$/ ) {
do_warn("Illegal value \"$value\" for $item$prop\n");
return 1;
}
}
if ( $prop eq "color" ) {
my $v;
unless ( $v = get_color($value) ) {
do_warn("Illegal value \"$value\" for $item$prop\n");
return 1;
}
$value = $v;
}
$value = $prop eq "font" ? $value : lc($value);
$self->add( type => "control",
name => $name,
value => $value );
push( @{ $propstack{$name} }, $value );
( run in 0.527 second using v1.01-cache-2.11-cpan-71847e10f99 )