App-Music-ChordPro
view release on metacpan or search on metacpan
!Highlights
- Configuration files are now [Really Relaxed JSON](https://metacpan.org/pod/JSON::Relaxed#REALLY-RELAXED-EXTENSIONS) files.
These are much easier to write and maintain than JSON.
Don't worry, everything is still backward compatible with the
older JSON and slightly relaxed JSON formats. And ChordPro can
[convert your config files](https://www.chordpro.org/chordpro/using-chordpro/#convert-config) for you.
- Nick Berendsen kindly offered to create a native GUI for macOS.
It looks great and behaves nicely in the way macOS applications should
behave. And it doesn't have the restrictions on opening and saving
of files that the 'classic' GUI suffers from.
Thanks Nick!
- ChordPro bundles free replacement fonts to be used instead of
the corefonts. No configs or settings needed.
!Functionality
- (PDF, page sort) Use sorttitle for page sorting.
- Images: Ignore align with x percentage. Issue warning.
lib/ChordPro/Config/Properties.pm view on Meta::CPAN
Property values can be anything. The value will be I<expanded> before
being assigned to the property unless it is placed between single
quotes C<''>.
Expansion means:
=over
=item *
A tilde C<~> in what looks like a file name will be replaced by the
value of C<${HOME}>.
=item *
If the value contains C<${I<name>}>, I<name> is first looked up in the
current environment. If an environment variable I<name> can be found,
its value is substituted.
If no suitable environment variable exists, I<name> is looked up as a
property and, if it exists and has a non-empty value, this value is
lib/ChordPro/Output/Markdown.pm view on Meta::CPAN
return ( md_textline($cp.$t_line) );
}
my $c_line = "";
foreach ( 0..$#{$elt->{chords}} ) {
$c_line .= chord( $elt->{chords}->[$_] ) . " ";
$t_line .= $phrases[$_];
my $d = length($c_line) - length($t_line);
$t_line .= "-" x $d if $d > 0;
$c_line .= " " x -$d if $d < 0;
} # this looks like setting the chords above the words.
s/\s+$// for ( $t_line, $c_line );
# main problem in markdown - a fixed position is only available in "Code escapes" so weather to set
# a tab or a double backticks (``) - i tend to the tab - so all lines with tabs are "together"
if ($c_line ne ""){ # Block-lines are not replacing initial spaces - as the are "code"
$t_line = $cp.$t_line." ";
$c_line = $cp.$c_line." ";
}
else{
lib/ChordPro/Output/Meta.pm view on Meta::CPAN
method generate_songbook :common ($sb) {
my @res = ( "[" );
for my $song ( @{ $sb->{songs} } ) {
my $m = $song->{meta};
my @r;
my $ll = 0;
for ( qw( songindex title subtitle ) ) {
my $v = flatten($m->{$_});
push( @r, [ qquote($_, 1), qquote( $v, !looks_like_number($v) ) ] );
$ll = max( $ll, length($r[-1][0]) );
}
# The rest.
for ( sort keys %$m ) {
next if /^((sub)?title|songindex)$/; # already done
next if /^(chordpro\..*|bookmark|_.*)/; # internal meta
next if /^(num)?chords$/; # internal meta
next if /^key_(actual|from)/; # transient meta
my $v = flatten($m->{$_});
push( @r, [ qquote($_, 1), qquote( $v, !looks_like_number($v) ) ] );
$ll = max( $ll, length($r[-1][0]) );
}
push( @res, " {" );
for ( @r ) {
push( @res, sprintf( " %-${ll}s : %s,", @$_ ) );
}
$res[-1] =~ s/,$//;
push( @res, " }," );
}
$res[-1] =~ s/,$//;
push( @res, "]" );
\@res;
}
sub looks_like_number($v) {
defined($v) && $v =~ /^[-+]?\d+(?:\.\d*)?$/;
}
sub kv( $k, $v ) {
$v = flatten($v);
qquote($k, 1) . " : " . qquote($v, !looks_like_number($v));
}
sub flatten($v) {
return $v unless is_arrayref($v);
return $v->[0] if @$v == 1;
join( $sep, @$v );
}
1;
lib/ChordPro/Utils.pm view on Meta::CPAN
s/([[:^print:]])/sprintf("\\u%04x", ord($1))/ge;
return $_ unless /[\\\s]/ || $force;
return qq("$_");
}
}
push( @EXPORT, 'qquote' );
# Safely print values.
use Scalar::Util qw(looks_like_number);
# We want overload:
# sub pv( $val )
# sub pv( $label, $val )
sub pv {
my $val = pop;
my $label = pop // "";
my $suppressundef;
if ( $label =~ /\?$/ ) {
$suppressundef++;
$label = $';
}
if ( defined $val ) {
if ( looks_like_number($val) ) {
$val = sprintf("%.3f", $val);
$val =~ s/0+$//;
$val =~ s/\.$//;
}
else {
$val = qquote( $val, 1 );
}
}
else {
return "" if $suppressundef;
lib/ChordPro/lib/JSON/Relaxed.pm view on Meta::CPAN
is equivalent to
foo: {
bar: blech
}
Requires C<combined_keys> or C<prp> option. Overruled by C<strict>.
=head2 Implied outer hash
If the JSON looks like a hash, i.e. a string (key) followed by a
C<:>, the outer C<{> and C<}> are implied.
For example:
foo : bar
is equivalent to:
{ foo : bar }
lib/ChordPro/res/config/chordpro.rjson view on Meta::CPAN
// Force enharmonic when transposing (experimental).
enharmonic-transpose : true
// Transcode chords.
transcode : ""
// Eliminate capo by transposing chords.
decapo : false
// Strictness of parsing chord names.
// Values are `"strict"` (only known chord forms) or `"relaxed"` (anything that looks sane).
chordnames : strict
// Allow parsing of note names in `[]`.
notenames : false
// Always replace chords by their canonical form.
chords-canonical : false
// If `false`, chorus labels are used as tags.
choruslabels : true
lib/ChordPro/res/config/config.schema view on Meta::CPAN
},
"examples": [["guitar"]]
},
"settings": {
"type": "object",
"description": "General settings control global behaviour of the ChordPro program and can be changed by configs and command line.",
"additionalProperties": false,
"properties": {
"chordnames": {
"default": "strict",
"description": "Strictness of parsing chord names.\nValues are `\"strict\"` (only known chord forms) or `\"relaxed\"` (anything that looks sane).",
"enum": ["relaxed", "strict"],
"type": "string"
},
"chords-canonical": {
"default": false,
"description": "Always replace chords by their canonical form.",
"type": "boolean"
},
"chords-under": {
"default": false,
lib/ChordPro/res/pod/Config.pod view on Meta::CPAN
// Force enharmonic when transposing (experimental).
enharmonic-transpose : true
// Transcode chords.
transcode : ""
// Eliminate capo by transposing chords.
decapo : false
// Strictness of parsing chord names.
// Values are `"strict"` (only known chord forms) or `"relaxed"` (anything that looks sane).
chordnames : strict
// Allow parsing of note names in `[]`.
notenames : false
// Always replace chords by their canonical form.
chords-canonical : false
// If `false`, chorus labels are used as tags.
choruslabels : true
t/380_roundtrip.t view on Meta::CPAN
# May be a string containing pretext %s posttext.
# Defaults to "[%s]" if true.
inline-chords = false
# Chords under the lyrics.
chords-under = false
# Transcoding.
transcode = null
# Always decapoize.
decapo = false
# Chords parsing strategy.
# Strict (only known) or relaxed (anything that looks sane).
chordnames = "strict"
# Allow note names in [].
notenames = false
}
# Metadata.
# For these keys you can use {meta key ...} as well as {key ...}.
# If strict is nonzero, only the keys named here are allowed.
# If strict is zero, {meta ...} will accept any key.
# Important: "title" and "subtitle" must always be in this list.
( run in 1.499 second using v1.01-cache-2.11-cpan-39bf76dae61 )