App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/Song.pm view on Meta::CPAN
ChordPro::Chords::set_parser($target);
my $p = ChordPro::Chords::get_parser;
$xcmov = $p->movable;
if ( $target ne $p->{system} ) {
::dump(ChordPro::Chords::Parser->parsers);
warn("OOPS parser mixup, $target <> ",
ChordPro::Chords::get_parser->{system})
}
ChordPro::Chords::set_parser($self->{system});
}
else {
$target = $self->{system};
}
upd_config();
$self->{source} = { file => $diag->{file}, line => 1 + $$linecnt };
$self->{system} = $target // $config->{notes}->{system};
$self->{config} = $config;
$self->{meta} = $meta if $meta;
$self->{chordsinfo} = {};
$target //= $self->{system};
# Preprocessor.
my $prep = make_preprocessor( $config->{parser}->{preprocess} );
# Pre-fill meta data, if any. TODO? ALREADY DONE?
if ( $options->{meta} ) {
while ( my ($k, $v ) = each( %{ $options->{meta} } ) ) {
$self->{meta}->{$k} = [ $v ];
}
}
$self->{meta}->{"chordpro.songsource"} = $diag->{file}
unless $::running_under_test;
# Build regexp to split out chords.
if ( $config->{settings}->{memorize} ) {
$re_chords = qr/(\[.*?\]|\^)/;
}
else {
$re_chords = qr/(\[.*?\])/;
}
my $skipcnt = 0;
while ( @$lines ) {
if ( $skipcnt ) {
$skipcnt--;
}
else {
$diag->{line} = ++$$linecnt;
}
$_ = shift(@$lines);
while ( /\\\Z/ && @$lines ) {
chop;
my $cont = shift(@$lines);
$$linecnt++;
$cont =~ s/^\s+//;
$_ .= $cont;
}
# Uncomment this to allow \uDXXX\uDYYY (surrogate) escapes.
s/ \\u(d[89ab][[:xdigit:]]{2})\\u(d[cdef][[:xdigit:]]{2})
/ pack('U*', 0x10000 + (hex($1) - 0xD800) * 0x400 + (hex($2) - 0xDC00) )
/igex;
# Uncomment this to allow \uXXXX escapes.
s/\\u([0-9a-f]{4})/chr(hex("0x$1"))/ige;
# Uncomment this to allow \u{XX...} escapes.
s/\\u\{([0-9a-f]+)\}/chr(hex("0x$1"))/ige;
$diag->{orig} = $_;
# Get rid of TABs.
s/\t/ /g;
if ( $config->{debug}->{echo} ) {
warn(sprintf("==[%3d]=> %s\n", $diag->{line}, $diag->{orig} ) );
}
for my $pp ( "all", "env-$in_context" ) {
next if $pp eq "env-$in_context"
&& /^\s*\{(\w+)\}\s*$/
&& $self->parse_directive($1)->{name} eq "end_of_$in_context";
if ( $prep->{$pp} ) {
$config->{debug}->{pp} && warn("PRE: ", $_, "\n");
$prep->{$pp}->($_);
$config->{debug}->{pp} && warn("POST: ", $_, "\n");
if ( /\n/ ) {
my @a = split( /\n/, $_ );
$_ = shift(@a);
unshift( @$lines, @a );
$skipcnt += @a;
}
}
}
if ( $skip_context ) {
if ( /^\s*\{(\w+)\}\s*$/ ) {
my $dir = $self->parse_directive($1);
if ( $dir->{name} eq "end_of_$in_context" ) {
$in_context = $def_context;
$skip_context = 0;
}
}
next;
}
if ( /^\s*\{((?:new_song|ns)\b.*)\}\s*$/ ) {
if ( $self->{body} ) {
unshift( @$lines, $_ );
$$linecnt--;
last;
}
my $dir = $self->parse_directive($1);
next unless my $kv = parse_kv($dir->{arg}//"");
if ( defined $kv->{toc} ) {
$self->{meta}->{_TOC} = [ $kv->{toc} ];
}
if ( $kv->{forceifempty} ) {
push( @{ $self->{body} },
{ type => "set",
name => "forceifempty",
value => $kv->{forceifempty} } );
}
next;
}
if ( /^#/ ) {
( run in 0.562 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )