line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#! perl |
2
|
|
|
|
|
|
|
|
3
|
79
|
|
|
79
|
|
6267
|
use v5.26; |
|
79
|
|
|
|
|
315
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package ChordPro; |
6
|
|
|
|
|
|
|
|
7
|
79
|
|
|
79
|
|
1014
|
use App::Packager; |
|
79
|
|
|
|
|
2735
|
|
|
79
|
|
|
|
|
476
|
|
8
|
|
|
|
|
|
|
|
9
|
79
|
|
|
79
|
|
40247
|
use ChordPro::Utils; |
|
79
|
|
|
|
|
208
|
|
|
79
|
|
|
|
|
7800
|
|
10
|
79
|
|
|
79
|
|
38489
|
use ChordPro::Chords; |
|
79
|
|
|
|
|
320
|
|
|
79
|
|
|
|
|
3549
|
|
11
|
79
|
|
|
79
|
|
41819
|
use ChordPro::Output::Common; |
|
79
|
|
|
|
|
238
|
|
|
79
|
|
|
|
|
5085
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# Single line for stupid tools. |
14
|
79
|
|
|
79
|
|
33527
|
use ChordPro::Version; our $VERSION = $ChordPro::Version::VERSION; |
|
79
|
|
|
|
|
359
|
|
|
79
|
|
|
|
|
4352
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
ChordPro - A lyrics and chords formatting program |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
perl -MChordpro -e run -- [ options ] [ file ... ] |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
When the associated B program has been installed correctly: |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
chordpro [ options ] [ file ... ] |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 DESCRIPTION |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
B will read one or more text files containing the lyrics of |
31
|
|
|
|
|
|
|
one or many songs plus chord information. B will then |
32
|
|
|
|
|
|
|
generate a photo-ready, professional looking, impress-your-friends |
33
|
|
|
|
|
|
|
sheet-music suitable for printing on your nearest printer. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Typical ChordPro input: |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
{title: Swing Low Sweet Chariot} |
38
|
|
|
|
|
|
|
{subtitle: Traditional} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
{start_of_chorus} |
41
|
|
|
|
|
|
|
Swing [D]low, sweet [G]chari[D]ot, |
42
|
|
|
|
|
|
|
Comin’ for to carry me [A7]home. |
43
|
|
|
|
|
|
|
Swing [D7]low, sweet [G]chari[D]ot, |
44
|
|
|
|
|
|
|
Comin’ for to [A7]carry me [D]home. |
45
|
|
|
|
|
|
|
{end_of_chorus} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# Verse |
48
|
|
|
|
|
|
|
I [D]looked over Jordan, and [G]what did I [D]see, |
49
|
|
|
|
|
|
|
Comin’ for to carry me [A7]home. |
50
|
|
|
|
|
|
|
A [D]band of angels [G]comin’ after [D]me, |
51
|
|
|
|
|
|
|
Comin’ for to [A7]carry me [D]home. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
{c: Chorus} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
B is a rewrite of the Chordii program. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
For more information about the ChordPro file format, see |
58
|
|
|
|
|
|
|
L. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=cut |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
################ Common stuff ################ |
63
|
|
|
|
|
|
|
|
64
|
79
|
|
|
79
|
|
506
|
use strict; |
|
79
|
|
|
|
|
173
|
|
|
79
|
|
|
|
|
1876
|
|
65
|
79
|
|
|
79
|
|
395
|
use warnings; |
|
79
|
|
|
|
|
156
|
|
|
79
|
|
|
|
|
1903
|
|
66
|
79
|
|
|
79
|
|
429
|
use Carp; |
|
79
|
|
|
|
|
160
|
|
|
79
|
|
|
|
|
3970
|
|
67
|
79
|
|
|
79
|
|
488
|
use Text::ParseWords (); |
|
79
|
|
|
|
|
187
|
|
|
79
|
|
|
|
|
63249
|
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
################ The Process ################ |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
package main; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
our $options; |
74
|
|
|
|
|
|
|
our $config; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
package ChordPro; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub ::run { |
79
|
91
|
|
|
91
|
|
342278
|
binmode(STDERR, ':utf8'); |
80
|
91
|
|
|
|
|
338
|
binmode(STDOUT, ':utf8'); |
81
|
91
|
|
|
|
|
499
|
$options = app_setup( "ChordPro", $VERSION ); |
82
|
91
|
50
|
|
|
|
424
|
$options->{trace} = 1 if $options->{debug}; |
83
|
91
|
50
|
|
|
|
349
|
$options->{verbose} = 1 if $options->{trace}; |
84
|
91
|
50
|
|
|
|
338
|
$options->{verbose} = 9 if $options->{debug}; |
85
|
91
|
|
|
|
|
329
|
main(); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub main { |
89
|
91
|
|
|
91
|
0
|
282
|
my ($opts) = @_; |
90
|
91
|
50
|
|
|
|
278
|
$options = { %$options, %$opts } if $opts; |
91
|
91
|
50
|
|
|
|
393
|
warn("ChordPro invoked: @{$options->{_argv}}\n") if $options->{debug}; |
|
0
|
|
|
|
|
0
|
|
92
|
91
|
|
|
|
|
354
|
chordpro(); |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub chordpro { |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Establish backend. |
99
|
91
|
|
|
91
|
0
|
295
|
my $of = $options->{output}; |
100
|
|
|
|
|
|
|
|
101
|
91
|
50
|
33
|
|
|
614
|
if ( defined($of) && $of ne "" ) { |
|
|
0
|
|
|
|
|
|
102
|
91
|
100
|
|
|
|
2059
|
if ( $of =~ /\.pdf$/i ) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
103
|
8
|
|
50
|
|
|
73
|
$options->{generate} ||= "PDF"; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
elsif ( $of =~ /\.ly$/i ) { |
106
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "LilyPond"; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
elsif ( $of =~ /\.(tex|ltx)$/i ) { |
109
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "LaTeX"; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
elsif ( $of =~ /\.cho$/i ) { |
112
|
6
|
|
50
|
|
|
38
|
$options->{generate} ||= "ChordPro"; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
elsif ( $of =~ /\.msp$/i ) { |
115
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "ChordPro"; |
116
|
0
|
|
|
|
|
0
|
$options->{'backend-option'}->{variant} = "msp"; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
elsif ( $of =~ /\.(crd|txt)$/i ) { |
119
|
9
|
|
50
|
|
|
67
|
$options->{generate} ||= "Text"; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
elsif ( $of =~ /\.html?$/i ) { |
122
|
3
|
|
50
|
|
|
22
|
$options->{generate} ||= "HTML"; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
elsif ( $of =~ /\.mma?$/i ) { |
125
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "MMA"; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
elsif ( $of =~ /\.(md|markdown)$/i ) { |
128
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "Markdown"; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
elsif ( $of =~ /\.(debug)$/i ) { |
131
|
0
|
|
0
|
|
|
0
|
$options->{generate} ||= "Debug"; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
elsif ( -t STDOUT ) { |
135
|
|
|
|
|
|
|
# No output, and stdout is terminal. |
136
|
|
|
|
|
|
|
# Derive output name from input name. |
137
|
0
|
0
|
0
|
|
|
0
|
if ( @ARGV > 1 || ( $options->{'dump-chords'} && !@ARGV ) ) { |
|
|
|
0
|
|
|
|
|
138
|
|
|
|
|
|
|
# No default if more than one input document. |
139
|
0
|
|
|
|
|
0
|
die("Please use \"--output\" to specify the output file name\n"); |
140
|
|
|
|
|
|
|
} |
141
|
0
|
|
|
|
|
0
|
my $f = $ARGV[0]; |
142
|
0
|
|
|
|
|
0
|
$f =~ s/\.\w+$/.pdf/; |
143
|
0
|
0
|
|
|
|
0
|
$f .= ".pdf" if $f eq $ARGV[0]; |
144
|
0
|
|
|
|
|
0
|
$options->{output} = $f; |
145
|
0
|
0
|
|
|
|
0
|
warn("Writing output to $f\n") if $options->{verbose}; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
else { |
148
|
|
|
|
|
|
|
# Write output to stdout. |
149
|
0
|
|
|
|
|
0
|
$options->{output} = "-"; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
91
|
|
50
|
|
|
517
|
$options->{generate} ||= "PDF"; |
153
|
91
|
|
|
|
|
372
|
my $pkg = "ChordPro::Output::".$options->{generate}; |
154
|
91
|
|
|
|
|
10643
|
eval "require $pkg;"; |
155
|
91
|
50
|
|
|
|
609
|
die("No backend for ", $options->{generate}, "\n$@") if $@; |
156
|
91
|
|
|
|
|
379
|
$options->{backend} = $pkg; |
157
|
91
|
50
|
33
|
|
|
622
|
$pkg->version if $options->{verbose} && $pkg->can("version"); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# One configurator to bind them all. |
160
|
79
|
|
|
79
|
|
1763
|
use ChordPro::Config; |
|
79
|
|
|
|
|
193
|
|
|
79
|
|
|
|
|
4503
|
|
161
|
91
|
|
|
|
|
579
|
$config = ChordPro::Config::configurator({}); |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
# Parse the input(s). |
164
|
79
|
|
|
79
|
|
34990
|
use ChordPro::Songbook; |
|
79
|
|
|
|
|
299
|
|
|
79
|
|
|
|
|
82409
|
|
165
|
91
|
|
|
|
|
1328
|
my $s = ChordPro::Songbook->new; |
166
|
91
|
|
|
|
|
228
|
my $res; |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
# Shortcut a2crd conversion. |
169
|
91
|
100
|
|
|
|
495
|
if ( $options->{a2crd} ) { |
170
|
19
|
|
|
|
|
250
|
require ChordPro::A2Crd; |
171
|
19
|
|
|
|
|
129
|
$res = ChordPro::A2Crd::a2crd(); |
172
|
19
|
|
|
|
|
92
|
push( @$res, '' ); |
173
|
19
|
|
|
|
|
211
|
goto WRITE_OUTPUT; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# Check for metadata in filelist. Actually, this works on the |
177
|
|
|
|
|
|
|
# command line as well, but don't tell anybody. |
178
|
72
|
|
|
|
|
322
|
foreach my $file ( @ARGV ) { |
179
|
72
|
|
|
|
|
140
|
my $opts; |
180
|
72
|
50
|
|
|
|
423
|
if ( $file =~ /(^|\s)--(?:meta|config|define)\b/ ) { |
181
|
|
|
|
|
|
|
# Break into words. |
182
|
0
|
|
|
|
|
0
|
my @w = Text::ParseWords::shellwords($file); |
183
|
0
|
|
|
|
|
0
|
my %meta; |
184
|
|
|
|
|
|
|
my %defs; |
185
|
0
|
|
|
|
|
0
|
my @cfg; |
186
|
0
|
0
|
0
|
|
|
0
|
die("Error in filelist: $file\n") |
187
|
|
|
|
|
|
|
unless Getopt::Long::GetOptionsFromArray |
188
|
|
|
|
|
|
|
( \@w, 'config=s@' => \@cfg, 'meta=s%' => \%meta, |
189
|
|
|
|
|
|
|
'define=s%' => \%defs, |
190
|
|
|
|
|
|
|
) |
191
|
|
|
|
|
|
|
&& @w == 1; |
192
|
0
|
|
|
|
|
0
|
$file = $w[0]; |
193
|
0
|
|
|
|
|
0
|
$opts = { meta => { map { $_, [ $meta{$_} ] } keys %meta }, |
|
0
|
|
|
|
|
0
|
|
194
|
|
|
|
|
|
|
defs => \%defs }; |
195
|
0
|
0
|
|
|
|
0
|
if ( @cfg ) { |
196
|
0
|
|
|
|
|
0
|
$opts->{meta}->{__config} = \@cfg; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
} |
199
|
72
|
|
|
|
|
492
|
$s->parse_file( $file, $opts ); |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
72
|
50
|
|
|
|
387
|
if ( $options->{'dump-chords'} ) { |
203
|
0
|
|
|
|
|
0
|
my $d = ChordPro::Song->new; |
204
|
0
|
|
|
|
|
0
|
$d->{title} = "ChordPro $VERSION Built-in Chords"; |
205
|
0
|
|
|
|
|
0
|
$d->{subtitle} = [ "https://www.chordpro.org" ]; |
206
|
0
|
|
|
|
|
0
|
my @body; |
207
|
|
|
|
|
|
|
my @chords; |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
my $prev = ""; |
210
|
0
|
|
|
|
|
0
|
foreach my $c ( @{ ChordPro::Chords::chordnames() } ) { |
|
0
|
|
|
|
|
0
|
|
211
|
0
|
0
|
|
|
|
0
|
next if $c =~ /^n\.?c\.?$/i; |
212
|
0
|
0
|
0
|
|
|
0
|
if ( $c =~ /^(.[b#]?)/ and $1 ne $prev ) { |
213
|
0
|
|
|
|
|
0
|
$prev = $1; |
214
|
0
|
0
|
|
|
|
0
|
push( @body, { type => "diagrams", |
215
|
|
|
|
|
|
|
context => "", |
216
|
|
|
|
|
|
|
origin => "__CLI__", |
217
|
|
|
|
|
|
|
chords => [ @chords ] |
218
|
|
|
|
|
|
|
} ) if @chords; |
219
|
0
|
|
|
|
|
0
|
@chords = (); |
220
|
|
|
|
|
|
|
} |
221
|
0
|
|
|
|
|
0
|
push( @chords, $c ); |
222
|
0
|
|
|
|
|
0
|
$d->{chordsinfo}->{$c} = ChordPro::Chords::known_chord($c); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
0
|
0
|
|
|
|
0
|
push( @body, { type => "diagrams", |
226
|
|
|
|
|
|
|
context => "", |
227
|
|
|
|
|
|
|
origin => "__CLI__", |
228
|
|
|
|
|
|
|
chords => [ @chords ] |
229
|
|
|
|
|
|
|
} ) if @chords; |
230
|
|
|
|
|
|
|
|
231
|
0
|
|
|
|
|
0
|
$d->{body} = \@body; |
232
|
0
|
0
|
0
|
|
|
0
|
if ( @{ $s->{songs} } == 1 |
|
0
|
|
|
|
|
0
|
|
233
|
|
|
|
|
|
|
&& !exists $s->{songs}->[0]->{body} ) { |
234
|
0
|
|
|
|
|
0
|
$s->{songs} = [ $d ]; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
0
|
|
|
|
|
0
|
push( @{ $s->{songs} }, $d ); |
|
0
|
|
|
|
|
0
|
|
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Try interpolations. |
242
|
72
|
50
|
|
|
|
283
|
if ( $of ) { |
243
|
72
|
|
|
|
|
345
|
my $f = fmt_subst( $s->{songs}->[0], $of ); |
244
|
72
|
50
|
|
|
|
6701
|
if ( $f ne $of ) { |
245
|
|
|
|
|
|
|
# Replace most non-alpha by underscore (but keep the extension). |
246
|
0
|
|
|
|
|
0
|
$f =~ s;(?!\.\w+$)[^\w/-];_;g; |
247
|
0
|
0
|
|
|
|
0
|
warn("Writing output to $f\n") if $options->{verbose}; |
248
|
0
|
|
|
|
|
0
|
$options->{output} = $f; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# Call backend to produce output. |
253
|
72
|
|
|
|
|
920
|
$res = $pkg->generate_songbook($s); |
254
|
72
|
100
|
|
|
|
3500
|
return $res if $options->{output} eq '*'; |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
WRITE_OUTPUT: |
257
|
|
|
|
|
|
|
# Some backends write output themselves, others return an |
258
|
|
|
|
|
|
|
# array of lines to be written. |
259
|
79
|
100
|
66
|
|
|
693
|
if ( $res && @$res > 0 ) { |
260
|
71
|
50
|
33
|
|
|
430
|
if ( $of && $of ne "-" ) { |
261
|
71
|
|
|
|
|
10684
|
open( my $fd, '>', $of ); |
262
|
71
|
|
|
|
|
1038
|
binmode( $fd, ":utf8" ); |
263
|
71
|
100
|
|
|
|
447
|
push( @$res, '' ) unless $res->[-1] eq ''; |
264
|
71
|
|
|
|
|
167
|
print { $fd } ( join( "\n", @$res ) ); |
|
71
|
|
|
|
|
2800
|
|
265
|
71
|
|
|
|
|
22003
|
close($fd); |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
else { |
268
|
0
|
|
|
|
|
0
|
binmode( STDOUT, ":utf8" ); |
269
|
0
|
0
|
|
|
|
0
|
push( @$res, '' ) unless $res->[-1] eq ''; |
270
|
0
|
|
|
|
|
0
|
print( join( "\n", @$res ) ); |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
# Don't close STDOUT! |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub ::dump { |
277
|
79
|
|
|
79
|
|
55426
|
use Data::Dumper qw(); |
|
79
|
|
|
|
|
541972
|
|
|
79
|
|
|
|
|
16215
|
|
278
|
0
|
|
|
0
|
|
0
|
local $Data::Dumper::Sortkeys = 1; |
279
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Indent = 1; |
280
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Quotekeys = 0; |
281
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Deparse = 1; |
282
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Terse = 1; |
283
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Trailingcomma = 1; |
284
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Useperl = 1; |
285
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Useqq = 0; # I want unicode visible |
286
|
|
|
|
|
|
|
|
287
|
0
|
|
|
|
|
0
|
my $s = Data::Dumper::Dumper @_; |
288
|
0
|
0
|
|
|
|
0
|
defined wantarray or warn $s; |
289
|
0
|
|
|
|
|
0
|
return $s; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
################ Options and Configuration ################ |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 COMMAND LINE OPTIONS |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=over 4 |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item B<--about> (short: B<-A>) |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Prints version information about the ChordPro program. No other |
301
|
|
|
|
|
|
|
processing will be done. |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=item B<--back-matter=>I |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Appends the contents of the named PDF document to the output. This can |
306
|
|
|
|
|
|
|
be used to produce documents with back matter pages. |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=item B<--config=>I (shorter: B<--cfg>) |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
A JSON file that defines the behaviour of the program and the layout |
311
|
|
|
|
|
|
|
of the output. See L for details. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
This option may be specified more than once. Each additional config |
314
|
|
|
|
|
|
|
file overrides the corresponding definitions that are currently |
315
|
|
|
|
|
|
|
active. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=item B<--cover=>I |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
See B<--front-matter>. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=item B<--csv> |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
When generating PDF output, also write a CSV file with titles and page |
324
|
|
|
|
|
|
|
numbers. Some tools, e.g., MobileSheets, can use the CSV to process |
325
|
|
|
|
|
|
|
the PDF as a collection of independent songs. |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
The CSV has the same name as the PDF, with extension C<.pdf> replaced |
328
|
|
|
|
|
|
|
by C<.csv>. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=item B<--decapo> |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Eliminate capo settings by transposing the song. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item B<--diagrams=>I |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Prints diagrams of chords used in a song. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
I can be C to print all chords used, C to only print |
339
|
|
|
|
|
|
|
the user-defined chords, and C to suppress printing of chord |
340
|
|
|
|
|
|
|
diagrams. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=item B<--encoding=>I |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
Specify the encoding for input files. Default is UTF-8. |
345
|
|
|
|
|
|
|
ISO-8859.1 (Latin-1) encoding is automatically sensed. |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item B<--filelist=>I |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
Read the names of the files to be processed from the named file. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
This option may be specified multiple times. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
Song file names listed on the command line are processed I the |
354
|
|
|
|
|
|
|
files from the filelist arguments. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=item B<--front-matter=>I B<--cover=>I |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
Prepends the contents of the named PDF document to the output. This can |
359
|
|
|
|
|
|
|
be used to produce documents with front matter (cover) pages. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=item B<--lyrics-only> (short: B<-l>) |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Only prints lyrics. All chords are suppressed. |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Useful to make prints for singers and other musicians that do not |
366
|
|
|
|
|
|
|
require chords. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=item B<--no-csv> |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Suppresses generating the CSV file. See B<--toc>. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=item B<--no-strict> |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Enables liberal interpretation of the input with regard to the |
375
|
|
|
|
|
|
|
ChordPro standard. Most notably, unknown directives will not |
376
|
|
|
|
|
|
|
not flagged as warnings but silently ignored. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
This makes it more convenient to process ChordPro files have custom |
379
|
|
|
|
|
|
|
directives. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=item B<--no-toc> |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Suppresses the table of contents. See B<--toc>. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=item B<--output=>I (short: B<-o>) |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
Designates the name of the output file where the results are written |
388
|
|
|
|
|
|
|
to. |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
The filename extension determines the type of the output. It should |
391
|
|
|
|
|
|
|
correspond to one of the backends that are currently supported: |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=over 6 |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=item pdf |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Portable document format (PDF). |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=item txt |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
A textual representation of the input, mostly for visual inspection. |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=item cho |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
A functional equivalent version of the ChordPro input. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=back |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item B<--start-page-number=>I (short: B<-p>) |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Sets the starting page number for the output. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=item B<--strict> |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
Requires the input to be strictly compliant to the ChordPro standard. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
This is enabled by default. See also B<--nostrict>. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=item B<--toc> (short: B<-i>) |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
Includes a table of contents. |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
By default a table of contents is included in the PDF output when |
424
|
|
|
|
|
|
|
it contains more than one song. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=item B<--transpose=>I (short: -x) |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Transposes all songs by I semi-tones. Note that I may be |
429
|
|
|
|
|
|
|
specified as B<+>I to transpose upward, using sharps, or as |
430
|
|
|
|
|
|
|
B<->I to transpose downward, using flats. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=item B<--version> (short: B<-V>) |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
Prints the program version and exits. |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
=back |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head2 Chordii compatibility options |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
The following Chordii command line options are recognized. Note that |
441
|
|
|
|
|
|
|
not all of them actually do something. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
Options marked with * are better specified in the config file. |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
B Chordii used the term _grid_ for chord diagrams. It |
446
|
|
|
|
|
|
|
should not be confused with ChordPro grids. |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=over 4 |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=item B<--text-font=>I (short: B<-T>) * |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
Sets the font used to print lyrics and comments. |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
I can be either a full path name to a TrueType font file, or the |
455
|
|
|
|
|
|
|
name of one of the standard fonts. See section L for more |
456
|
|
|
|
|
|
|
details. |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=item B<--text-size=>I (short: B<-t>) * |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Sets the font size for lyrics and comments. |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=item B<--chord-font=>I (short: B<-C>) * |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Sets the font used to print the chord names. |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
I can be either a full path name to a TrueType font file, or the |
467
|
|
|
|
|
|
|
name of one of the standard fonts. See section L for more |
468
|
|
|
|
|
|
|
details. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=item B<--chord-size=>I (short: B<-c>) * |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
Sets the font size for the chord names. |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=item B<--chord-grid-size=>I (short: B<-s>) * |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
Sets the total width of a chord diagram. |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=item B<--chord-grids> |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
Prints chord diagrams of all chords used in a song. |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=item B<--no-chord-grids> (short: B<-G>) * |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Disables printing of chord diagrams of the chords used in a song. |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
=item B<--easy-chord-grids> |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Not supported. |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item B<--no-easy-chord-grids> (short: B<-g>) |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Not supported. |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=item B<--chord-grids-sorted> (short: B<-S>) * |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Prints chord diagrams of the chords used in a song, ordered by key and |
497
|
|
|
|
|
|
|
type. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=item B<--no-chord-grids-sorted> * |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Prints chord diagrams in the order they appear in the song. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=item B<--user-chord-grids> * |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
Prints chord diagrams of all user defined chords used in a song. |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=item B<--even-pages-number-left> (short B<-L>) |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Prints even/odd pages with pages numbers left on even pages. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=item B<--odd-pages-number-left> |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Prints even/odd pages with pages numbers left on odd pages. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=item B<--page-size=>I (short: B<-P>) * |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
Specifies the page size for the PDF output, e.g. C (default), C. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=item B<--single-space> (short B<-a>)) * |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
When a lyrics line has no chords associated, suppresses the vertical |
522
|
|
|
|
|
|
|
space normally occupied by the chords. |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=item B<--vertical-space=>I (short: B<-w>) * |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
Adds some extra vertical space between the lines. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=item B<--2-up> (short: B<-2>) |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Not supported. |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=item B<--4-up> (short: B<-4>) |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
Not supported. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=item B<--page-number-logical> (short: B<-n>) |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
Not supported. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=item B<--dump-chords> (short: B<-D>) |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
Dumps a list of built-in chords in a form dependent of the backend used. |
543
|
|
|
|
|
|
|
The PDF backend will produce neat pages of chord diagrams. |
544
|
|
|
|
|
|
|
The ChordPro backend will produce a list of C directives. |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=item B<--dump-chords-text> (short: B<-d>) |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Dumps a list of built-in chords in the form of C directives, |
549
|
|
|
|
|
|
|
and exits. |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=back |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=head2 Configuration options |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
See L for details about the configuration |
556
|
|
|
|
|
|
|
files. |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
Note that missing default configuration files are silently ignored. |
559
|
|
|
|
|
|
|
Also, B will never create nor write configuration files. |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=over |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
=item B<--nosongconfig> |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
Don't use song specific config files, even if they exist. |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=item B<--sysconfig=>I |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Designates a system specific config file. |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
The default system config file depends on the operating system and user |
572
|
|
|
|
|
|
|
environment. A common value is C on Linux systems. |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
This is the place where the system manager can put settings like the |
575
|
|
|
|
|
|
|
paper size, assuming that all printers use the same size. |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
=item B<--nosysconfig> |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
Don't use the system specific config file, even if it exists. |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
=item B<--userconfig=>I |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
Designates the config file for the user. |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
The default user config file depends on the operating system and user |
586
|
|
|
|
|
|
|
environment. Common values are C<$HOME/.config/chordpro/chordpro.json> |
587
|
|
|
|
|
|
|
and C<$HOME/.chordpro/chordpro.json>, where C<$HOME> indicates the |
588
|
|
|
|
|
|
|
user home directory. |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
Here you can put settings for your preferred fonts and other layout |
591
|
|
|
|
|
|
|
parameters that you want to apply to all B runs. |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=item B<--nouserconfig> |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
Don't use the user specific config file, even if it exists. |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=item B<--config=>I (shorter: B<--cfg>) |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
Designates the config file specific for this run. |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
Default is a file named C in the current directory. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
Here you can put settings that apply to the files in this |
604
|
|
|
|
|
|
|
directory only. |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
You can specify multiple config files. The settings are accumulated. |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=item B<--noconfig> |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
Don't use the specific config file, even if it exists. |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=item B<--define=>I-
|
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
Sets a configuration item. I- must be in the format of
|
615
|
|
|
|
|
|
|
colon-separated configuration keys, an equal sign, and the value. For |
616
|
|
|
|
|
|
|
example, the equivalent of B<--diagrams=none> is |
617
|
|
|
|
|
|
|
B<--define=diagrams:show=0>. |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
B<--define> may be used multiple times to set multiple items. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
=item B<--no-default-configs> (short: B<-X>) |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
Do not use any config files except the ones mentioned explicitly on |
624
|
|
|
|
|
|
|
the command line. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
This guarantees that the program is running with the default |
627
|
|
|
|
|
|
|
configuration. |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=item B<--print-default-config> |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Prints the default configuration to standard output, and exits. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
The default configuration is commented to explain its contents. |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=item B<--print-final-config> |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
Prints the final configuration (after processing all system, user and |
638
|
|
|
|
|
|
|
other config files) to standard output, and exits. |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
The final configuration is not commented. Sorry. |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
=back |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head2 Miscellaneous options |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
=over |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
=item B<--help> (short: -h) |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Prints a help message. No other output is produced. |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
=item B<--manual> |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
Prints the manual page. No other output is produced. |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=item B<--ident> |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
Shows the program name and version. |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
=item B<--verbose> |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Provides more verbose information of what is going on. |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=back |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=cut |
667
|
|
|
|
|
|
|
|
668
|
79
|
|
|
79
|
|
63818
|
use Getopt::Long 2.13 qw( :config no_ignorecase ); |
|
79
|
|
|
|
|
1097680
|
|
|
79
|
|
|
|
|
2317
|
|
669
|
79
|
|
|
79
|
|
16582
|
use File::Spec; |
|
79
|
|
|
|
|
240
|
|
|
79
|
|
|
|
|
2468
|
|
670
|
79
|
|
|
79
|
|
489
|
use File::LoadLines; |
|
79
|
|
|
|
|
199
|
|
|
79
|
|
|
|
|
155700
|
|
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
# Package name. |
673
|
|
|
|
|
|
|
my $my_package; |
674
|
|
|
|
|
|
|
# Program name and version. |
675
|
|
|
|
|
|
|
my ($my_name, $my_version); |
676
|
|
|
|
|
|
|
my %configs; |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
sub app_setup { |
679
|
91
|
|
|
91
|
0
|
400
|
my ($appname, $appversion, %args) = @_; |
680
|
91
|
|
|
|
|
248
|
my $help = 0; # handled locally |
681
|
91
|
|
|
|
|
209
|
my $manual = 0; # handled locally |
682
|
91
|
|
|
|
|
208
|
my $ident = 0; # handled locally |
683
|
91
|
|
|
|
|
192
|
my $about = 0; # handled locally |
684
|
91
|
|
|
|
|
181
|
my $version = 0; # handled locally |
685
|
91
|
|
|
|
|
185
|
my $defcfg = 0; # handled locally |
686
|
91
|
|
|
|
|
186
|
my $fincfg = 0; # handled locally |
687
|
91
|
|
|
|
|
190
|
my $deltacfg = 0; # handled locally |
688
|
91
|
|
|
|
|
201
|
my $dump_chords = 0; # handled locally |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
# Package name. |
691
|
91
|
|
|
|
|
312
|
$my_package = $args{package}; |
692
|
|
|
|
|
|
|
# Program name and version. |
693
|
91
|
50
|
|
|
|
357
|
if ( defined $appname ) { |
694
|
91
|
|
|
|
|
331
|
($my_name, $my_version) = ($appname, $appversion); |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
else { |
697
|
0
|
|
|
|
|
0
|
($my_name, $my_version) = qw( MyProg 0.01 ); |
698
|
|
|
|
|
|
|
} |
699
|
|
|
|
|
|
|
|
700
|
91
|
|
|
|
|
305
|
my $app_lc = lc($my_name); |
701
|
91
|
50
|
|
|
|
432
|
if ( $app_lc eq "a2crd" ) { |
702
|
0
|
|
|
|
|
0
|
$app_lc = "chordpro"; |
703
|
0
|
|
|
|
|
0
|
unshift( @ARGV, "--a2crd" ); |
704
|
|
|
|
|
|
|
} |
705
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
# Config files. |
707
|
91
|
50
|
|
|
|
1925
|
if ( -d "/etc" ) { # some *ux |
708
|
|
|
|
|
|
|
$configs{sysconfig} = |
709
|
91
|
|
|
|
|
2426
|
File::Spec->catfile( "/", "etc", "$app_lc.json" ); |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
|
712
|
91
|
50
|
33
|
|
|
2408
|
if ( $ENV{XDG_CONFIG_HOME} && -d $ENV{XDG_CONFIG_HOME} ) { |
|
|
50
|
33
|
|
|
|
|
713
|
|
|
|
|
|
|
$configs{userconfig} = |
714
|
0
|
|
|
|
|
0
|
File::Spec->catfile( $ENV{XDG_CONFIG_HOME}, $app_lc, "$app_lc.json" ); |
715
|
0
|
|
0
|
|
|
0
|
$ENV{CHORDPRO_LIB} ||= File::Spec->catfile( $ENV{XDG_CONFIG_HOME}, $app_lc); |
716
|
|
|
|
|
|
|
} |
717
|
|
|
|
|
|
|
elsif ( $ENV{HOME} && -d $ENV{HOME} ) { |
718
|
91
|
|
|
|
|
1252
|
my $dir = File::Spec->catfile( $ENV{HOME}, ".config" ); |
719
|
91
|
50
|
|
|
|
1151
|
if ( -d $dir ) { |
720
|
|
|
|
|
|
|
$configs{userconfig} = |
721
|
0
|
|
|
|
|
0
|
File::Spec->catfile( $dir, $app_lc, "$app_lc.json" ); |
722
|
0
|
|
0
|
|
|
0
|
$ENV{CHORDPRO_LIB} ||= File::Spec->catfile( $dir, $app_lc ); |
723
|
|
|
|
|
|
|
} |
724
|
|
|
|
|
|
|
else { |
725
|
91
|
|
|
|
|
1148
|
$dir = File::Spec->catfile( $ENV{HOME}, ".$app_lc" ); |
726
|
|
|
|
|
|
|
$configs{userconfig} = |
727
|
91
|
|
|
|
|
967
|
File::Spec->catfile( $dir, "$app_lc.json" ); |
728
|
91
|
|
66
|
|
|
767
|
$ENV{CHORDPRO_LIB} ||= $dir; |
729
|
|
|
|
|
|
|
} |
730
|
|
|
|
|
|
|
} |
731
|
|
|
|
|
|
|
|
732
|
91
|
50
|
|
|
|
1202
|
if ( -s ".$app_lc.json" ) { |
733
|
0
|
|
|
|
|
0
|
$configs{config} = ".$app_lc.json"; |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
else { |
736
|
91
|
|
|
|
|
553
|
$configs{config} = "$app_lc.json"; |
737
|
|
|
|
|
|
|
} |
738
|
|
|
|
|
|
|
|
739
|
91
|
|
|
|
|
1644
|
my $options = |
740
|
|
|
|
|
|
|
{ |
741
|
|
|
|
|
|
|
verbose => 0, # verbose processing |
742
|
|
|
|
|
|
|
encoding => "", # input encoding, default UTF-8 |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
### ADDITIONAL CLI OPTIONS ### |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
'vertical-space' => 0, # extra vertical space between lines |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
### NON-CLI OPTIONS ### |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
'chords-column' => 0, # chords in a separate column |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
# Development options (not shown with -help). |
753
|
|
|
|
|
|
|
debug => 0, # debugging |
754
|
|
|
|
|
|
|
trace => 0, # trace (show process) |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# Service. |
757
|
|
|
|
|
|
|
_package => $my_package, |
758
|
|
|
|
|
|
|
_name => $my_name, |
759
|
|
|
|
|
|
|
_version => $my_version, |
760
|
|
|
|
|
|
|
_stdin => \*STDIN, |
761
|
|
|
|
|
|
|
_stdout => \*STDOUT, |
762
|
|
|
|
|
|
|
_stderr => \*STDERR, |
763
|
|
|
|
|
|
|
_argv => [ @ARGV ], |
764
|
|
|
|
|
|
|
}; |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
# Colled command line options in a hash, for they will be needed |
767
|
|
|
|
|
|
|
# later. |
768
|
91
|
|
|
|
|
292
|
my $clo = {}; |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
# When running in reference mode, we carefully defeat everything |
771
|
|
|
|
|
|
|
# the user could change to the built-in default config. |
772
|
91
|
|
|
|
|
234
|
my $reference = 0; |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
# Sorry, layout is a bit ugly... |
775
|
|
|
|
|
|
|
my $ok = |
776
|
|
|
|
|
|
|
GetOptions |
777
|
|
|
|
|
|
|
($clo, |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
### Options ### |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
"a2crd!", # perform ascii to cho |
782
|
|
|
|
|
|
|
"crd", # input is ascii, not cho |
783
|
|
|
|
|
|
|
"output|o=s", # Saves the output to FILE |
784
|
|
|
|
|
|
|
"generate=s", |
785
|
|
|
|
|
|
|
"backend-option|bo=s\%", |
786
|
|
|
|
|
|
|
"diagrams=s", # Prints chord diagrams |
787
|
|
|
|
|
|
|
"encoding=s", |
788
|
|
|
|
|
|
|
"csv!", # Generates contents CSV |
789
|
|
|
|
|
|
|
"front-matter|cover=s", # Front matter page(s) |
790
|
|
|
|
|
|
|
"back-matter=s", # Back matter page(s) |
791
|
|
|
|
|
|
|
"filelist=s@", # List of input files |
792
|
|
|
|
|
|
|
"meta=s\%", # Command line meta data |
793
|
|
|
|
|
|
|
"decapo", # remove capo |
794
|
|
|
|
|
|
|
"fragment|F", # partial (incomplete) song |
795
|
|
|
|
|
|
|
"strict!", # strict conformance |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
### Standard Chordii Options ### |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
"about|A" => \$about, # About... |
800
|
|
|
|
|
|
|
"chord-font|C=s", # Sets chord font |
801
|
|
|
|
|
|
|
"chord-grid-size|s=f", # Sets chord diagram size [30] |
802
|
|
|
|
|
|
|
"chord-grids-sorted|S!", # Prints chord diagrams ordered |
803
|
|
|
|
|
|
|
"chord-size|c=i", # Sets chord size [9] |
804
|
|
|
|
|
|
|
"dump-chords|D", # Dumps chords definitions (PostScript) |
805
|
|
|
|
|
|
|
"dump-chords-text|d" => \$dump_chords, # Dumps chords definitions (Text) |
806
|
0
|
|
|
0
|
|
0
|
"dump-chords-json" => sub { $dump_chords = 2}, # Dumps instrument defs (json). |
807
|
|
|
|
|
|
|
"even-pages-number-left|L", # Even pages numbers on left |
808
|
|
|
|
|
|
|
"odd-pages-number-left", # Odd pages numbers on left |
809
|
|
|
|
|
|
|
"lyrics-only|l", # Only prints lyrics |
810
|
0
|
|
|
0
|
|
0
|
"G" => sub { $clo->{'chord-grids'} = 0 }, |
811
|
|
|
|
|
|
|
"chord-grids!", # En[dis]ables printing of chord diagrams |
812
|
|
|
|
|
|
|
"easy-chord-grids|g!", # Do[esn't] print diagrams for built-in "easy" chords. Ignored. |
813
|
|
|
|
|
|
|
"page-number-logical|n", # Numbers logical pages, not physical |
814
|
|
|
|
|
|
|
"page-size|P=s", # Specifies page size [letter, a4 (default)] |
815
|
|
|
|
|
|
|
"single-space|a!", # Automatic single space lines without chords |
816
|
|
|
|
|
|
|
"start-page-number|p=i", # Starting page number [1] |
817
|
|
|
|
|
|
|
"text-size|t=i", # Sets text size [12] |
818
|
|
|
|
|
|
|
"text-font|T=s", # Sets text font |
819
|
0
|
|
|
0
|
|
0
|
"i" => sub { $clo->{toc} = 1 }, |
820
|
|
|
|
|
|
|
"toc!", # Generates a table of contents |
821
|
|
|
|
|
|
|
"transpose|x=i", # Transposes by N semi-tones |
822
|
|
|
|
|
|
|
"transcode|xc=s", # Transcodes to another notation |
823
|
|
|
|
|
|
|
"user-chord-grids!", # Do[esn't] print diagrams for user defined chords. |
824
|
|
|
|
|
|
|
"version|V" => \$version, # Prints version and exits |
825
|
|
|
|
|
|
|
"vertical-space|w=f", # Extra vertical space between lines |
826
|
|
|
|
|
|
|
"2-up|2", # 2 pages per sheet |
827
|
|
|
|
|
|
|
"4-up|4", # 4 pages per sheet |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
### Configuration handling ### |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
'config|cfg=s@', |
832
|
|
|
|
|
|
|
'noconfig|no-config', |
833
|
|
|
|
|
|
|
'sysconfig=s', |
834
|
|
|
|
|
|
|
'nosysconfig|no-sysconfig', |
835
|
|
|
|
|
|
|
'nolegacyconfig|no-legacyconfig', # legacy |
836
|
|
|
|
|
|
|
'userconfig=s', |
837
|
|
|
|
|
|
|
'nosongconfig|no-songconfig', |
838
|
|
|
|
|
|
|
'nouserconfig|no-userconfig', |
839
|
|
|
|
|
|
|
'nodefaultconfigs|no-default-configs|X', |
840
|
|
|
|
|
|
|
'define=s%', |
841
|
|
|
|
|
|
|
'print-default-config' => \$defcfg, |
842
|
|
|
|
|
|
|
'print-final-config' => \$fincfg, |
843
|
|
|
|
|
|
|
'print-delta-config' => \$deltacfg, |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
# This aborts option scanning. |
846
|
0
|
|
|
0
|
|
0
|
'reference|R' => sub { $reference++; die("!FINISH!"); }, |
|
0
|
|
|
|
|
0
|
|
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
### Standard options ### |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
'ident' => \$ident, |
851
|
|
|
|
|
|
|
'help|h|?' => \$help, |
852
|
0
|
|
|
0
|
|
0
|
'help-config' => sub { $manual = 2 }, |
853
|
91
|
|
|
|
|
2448
|
'manual' => \$manual, |
854
|
|
|
|
|
|
|
'verbose|v+', |
855
|
|
|
|
|
|
|
'trace', |
856
|
|
|
|
|
|
|
'debug+', |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
); |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
# If --reference was encountered, retry with a very restricted set |
861
|
|
|
|
|
|
|
# of options. |
862
|
91
|
50
|
|
|
|
436153
|
if ( $reference ) { |
863
|
0
|
|
|
|
|
0
|
@ARGV = @{ $options->{_argv} }; |
|
0
|
|
|
|
|
0
|
|
864
|
0
|
|
|
|
|
0
|
warn("Running in reference mode.\n"); |
865
|
0
|
|
|
|
|
0
|
$ok = |
866
|
|
|
|
|
|
|
GetOptions |
867
|
|
|
|
|
|
|
($clo, |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
### Options for reference run ### |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
"output|o=s", # Saves the output to FILE |
872
|
|
|
|
|
|
|
"strict!", # strict conformance |
873
|
|
|
|
|
|
|
"about|A" => \$about, # About... |
874
|
|
|
|
|
|
|
"version|V" => \$version, # Prints version and exits |
875
|
|
|
|
|
|
|
'reference|R', |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
### Standard options ### |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
'ident' => \$ident, |
880
|
|
|
|
|
|
|
'help|h|?' => \$help, |
881
|
|
|
|
|
|
|
'verbose|v+', |
882
|
|
|
|
|
|
|
'trace', |
883
|
|
|
|
|
|
|
'debug+', |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
); |
886
|
0
|
|
|
|
|
0
|
$clo->{nodefaultconfigs} = 1; |
887
|
0
|
|
|
|
|
0
|
$clo->{nosongconfig} = 1; |
888
|
0
|
|
|
|
|
0
|
$::options->{reference} = 1; |
889
|
|
|
|
|
|
|
} |
890
|
|
|
|
|
|
|
|
891
|
91
|
|
33
|
|
|
819
|
$clo->{trace} ||= $clo->{debug}; |
892
|
91
|
|
33
|
|
|
589
|
$clo->{verbose} ||= $clo->{trace}; |
893
|
|
|
|
|
|
|
|
894
|
91
|
50
|
|
|
|
324
|
unless ( $ok ) { |
895
|
|
|
|
|
|
|
# GNU convention: message to STDERR upon failure. |
896
|
0
|
|
|
|
|
0
|
app_usage(\*STDERR, 2); |
897
|
|
|
|
|
|
|
} |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
my $pod2usage = sub { |
900
|
|
|
|
|
|
|
# Load Pod::Usage only if needed. |
901
|
0
|
|
|
0
|
|
0
|
require Pod::Usage; |
902
|
0
|
|
|
|
|
0
|
Pod::Usage->import; |
903
|
0
|
0
|
|
|
|
0
|
my $f = $manual == 2 ? "pod/Config.pod" : "pod/ChordPro.pod"; |
904
|
0
|
|
|
|
|
0
|
unshift( @_, -input => getresource($f) ); |
905
|
0
|
|
|
|
|
0
|
&pod2usage; |
906
|
91
|
|
|
|
|
648
|
}; |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
# GNU convention: message to STDOUT upon request. |
909
|
91
|
50
|
33
|
|
|
1148
|
app_ident(\*STDOUT) if $ident || $clo->{verbose} || $help || $manual; |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
910
|
91
|
50
|
33
|
|
|
573
|
if ( $manual or $help ) { |
911
|
0
|
0
|
|
|
|
0
|
app_usage(\*STDOUT, 0) if $help; |
912
|
0
|
0
|
|
|
|
0
|
$pod2usage->(VERBOSE => 2) if $manual; |
913
|
|
|
|
|
|
|
} |
914
|
91
|
50
|
|
|
|
336
|
app_ident(\*STDOUT, 0) if $version; |
915
|
91
|
50
|
|
|
|
321
|
app_about(\*STDOUT, 0) if $about; |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
# If the user specified a config, it must exist. |
918
|
|
|
|
|
|
|
# Otherwise, set to a default. |
919
|
91
|
|
|
|
|
360
|
for my $config ( qw(sysconfig userconfig) ) { |
920
|
182
|
|
|
|
|
543
|
for ( $clo->{$config} ) { |
921
|
182
|
50
|
|
|
|
526
|
if ( defined($_) ) { |
922
|
0
|
0
|
|
|
|
0
|
die("$_: $!\n") unless -r $_; |
923
|
0
|
|
|
|
|
0
|
next; |
924
|
|
|
|
|
|
|
} |
925
|
|
|
|
|
|
|
# Use default. |
926
|
182
|
50
|
|
|
|
608
|
next if $clo->{nodefaultconfigs}; |
927
|
0
|
0
|
|
|
|
0
|
next unless $configs{$config}; |
928
|
0
|
|
|
|
|
0
|
$_ = $configs{$config}; |
929
|
0
|
0
|
|
|
|
0
|
undef($_) unless -r $_; |
930
|
|
|
|
|
|
|
} |
931
|
|
|
|
|
|
|
} |
932
|
91
|
|
|
|
|
362
|
for my $config ( qw(config) ) { |
933
|
91
|
|
|
|
|
349
|
for ( $clo->{$config} ) { |
934
|
91
|
50
|
|
|
|
352
|
if ( defined($_) ) { |
935
|
0
|
|
|
|
|
0
|
foreach my $c ( @$_ ) { |
936
|
|
|
|
|
|
|
# Check for resource names. |
937
|
0
|
0
|
|
|
|
0
|
if ( $c !~ m;[/.]; ) { |
938
|
0
|
|
|
|
|
0
|
$c = ::rsc_or_file( $c, "config" ); |
939
|
|
|
|
|
|
|
} |
940
|
0
|
0
|
|
|
|
0
|
die("$c: $!\n") unless -r $c; |
941
|
|
|
|
|
|
|
} |
942
|
0
|
|
|
|
|
0
|
next; |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
# Use default. |
945
|
91
|
50
|
|
|
|
445
|
next if $clo->{nodefaultconfigs}; |
946
|
0
|
0
|
|
|
|
0
|
next unless $configs{$config}; |
947
|
0
|
|
|
|
|
0
|
$_ = [ $configs{$config} ]; |
948
|
0
|
0
|
|
|
|
0
|
undef($_) unless -r -f $_->[0]; |
949
|
|
|
|
|
|
|
} |
950
|
|
|
|
|
|
|
} |
951
|
|
|
|
|
|
|
# If no config was specified, and no default is available, force no. |
952
|
91
|
|
|
|
|
300
|
for my $config ( qw(sysconfig userconfig config ) ) { |
953
|
273
|
50
|
|
|
|
1106
|
$clo->{"no$config"} = 1 unless $clo->{$config}; |
954
|
|
|
|
|
|
|
} |
955
|
91
|
|
33
|
|
|
708
|
$clo->{nosongconfig} ||= $clo->{nodefaultconfigs}; |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
# Decode command line strings. |
958
|
|
|
|
|
|
|
# File names are dealt with elsewhere. |
959
|
91
|
|
|
|
|
284
|
for ( qw(transcode) ) { |
960
|
91
|
50
|
|
|
|
396
|
next unless defined $clo->{$_}; |
961
|
0
|
|
|
|
|
0
|
$clo->{$_} = decode_utf8($clo->{$_}); |
962
|
|
|
|
|
|
|
} |
963
|
|
|
|
|
|
|
####TODO: Should decode all, and remove filename exception. |
964
|
91
|
|
|
|
|
231
|
for ( keys %{ $clo->{define} } ) { |
|
91
|
|
|
|
|
505
|
|
965
|
10
|
|
|
|
|
246
|
$clo->{define}->{$_} = decode_utf8($clo->{define}->{$_}); |
966
|
|
|
|
|
|
|
} |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
# Plug in command-line options. |
969
|
91
|
|
|
|
|
847
|
@{$options}{keys %$clo} = values %$clo; |
|
91
|
|
|
|
|
650
|
|
970
|
91
|
|
|
|
|
1292
|
$::options = $options; |
971
|
|
|
|
|
|
|
# warn(::dump($options), "\n") if $options->{debug}; |
972
|
|
|
|
|
|
|
|
973
|
91
|
50
|
33
|
|
|
913
|
if ( $defcfg || $fincfg || $deltacfg ) { |
|
|
|
33
|
|
|
|
|
974
|
0
|
0
|
|
|
|
0
|
print ChordPro::Config::config_default() |
975
|
|
|
|
|
|
|
if $defcfg; |
976
|
0
|
0
|
0
|
|
|
0
|
print ChordPro::Config::config_final($deltacfg) |
977
|
|
|
|
|
|
|
if $fincfg || $deltacfg; |
978
|
0
|
|
|
|
|
0
|
exit 0; |
979
|
|
|
|
|
|
|
} |
980
|
|
|
|
|
|
|
|
981
|
91
|
50
|
|
|
|
383
|
if ( $dump_chords ) { |
982
|
0
|
|
|
|
|
0
|
$::config = ChordPro::Config::configurator($options); |
983
|
0
|
|
|
|
|
0
|
require ChordPro::Chords; |
984
|
0
|
|
|
|
|
0
|
ChordPro::Chords::dump_chords($dump_chords); |
985
|
0
|
|
|
|
|
0
|
exit 0; |
986
|
|
|
|
|
|
|
} |
987
|
|
|
|
|
|
|
|
988
|
91
|
50
|
|
|
|
391
|
if ( $clo->{filelist} ) { |
989
|
0
|
|
|
|
|
0
|
my @files; |
990
|
0
|
|
|
|
|
0
|
foreach ( @{ $clo->{filelist} } ) { |
|
0
|
|
|
|
|
0
|
|
991
|
0
|
|
|
|
|
0
|
my $list = loadlines( $_, $clo ); |
992
|
0
|
|
|
|
|
0
|
foreach ( @$list ) { |
993
|
0
|
0
|
|
|
|
0
|
next unless /\S/; |
994
|
0
|
0
|
|
|
|
0
|
next if /^#/; |
995
|
0
|
|
|
|
|
0
|
s/[\r\n]+$//; |
996
|
0
|
|
|
|
|
0
|
push( @files, encode_utf8($_) ); |
997
|
|
|
|
|
|
|
} |
998
|
|
|
|
|
|
|
} |
999
|
0
|
0
|
|
|
|
0
|
if ( @files ) { |
1000
|
0
|
0
|
|
|
|
0
|
if ( $files[0] =~ /\.pdf$/i ) { |
1001
|
0
|
|
0
|
|
|
0
|
$options->{'front-matter'} //= $files[0]; |
1002
|
0
|
|
|
|
|
0
|
shift(@files); |
1003
|
|
|
|
|
|
|
} |
1004
|
0
|
0
|
|
|
|
0
|
if ( $files[-1] =~ /\.pdf$/i ) { |
1005
|
0
|
|
0
|
|
|
0
|
$options->{'back-matter'} //= $files[-1]; |
1006
|
0
|
|
|
|
|
0
|
pop(@files); |
1007
|
|
|
|
|
|
|
} |
1008
|
|
|
|
|
|
|
} |
1009
|
0
|
0
|
|
|
|
0
|
unshift( @ARGV, @files ) if @files; |
1010
|
|
|
|
|
|
|
} |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
# At this point, there should be filename argument(s) |
1013
|
|
|
|
|
|
|
# unless we're embedded or just dumping chords. |
1014
|
|
|
|
|
|
|
app_usage(\*STDERR, 1) |
1015
|
91
|
50
|
33
|
|
|
746
|
unless $::__EMBEDDED__ || $clo->{'dump-chords'} || @ARGV; |
|
|
|
33
|
|
|
|
|
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
# Return result. |
1018
|
91
|
|
|
|
|
924
|
$options; |
1019
|
|
|
|
|
|
|
} |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
sub app_ident { |
1022
|
0
|
|
|
0
|
0
|
0
|
my ($fh, $exit) = @_; |
1023
|
0
|
|
|
|
|
0
|
print {$fh} ("This is ", ::runtimeinfo("short"), "\n"); |
|
0
|
|
|
|
|
0
|
|
1024
|
0
|
0
|
|
|
|
0
|
exit $exit if defined $exit; |
1025
|
|
|
|
|
|
|
} |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
sub app_about { |
1028
|
0
|
|
|
0
|
0
|
0
|
my ($fh, $exit) = @_; |
1029
|
0
|
|
|
|
|
0
|
print ${fh} <
|
1030
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
ChordPro: A lyrics and chords formatting program. |
1032
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
ChordPro will read a text file containing the lyrics of one or many |
1034
|
|
|
|
|
|
|
songs plus chord information. ChordPro will then generate a |
1035
|
|
|
|
|
|
|
photo-ready, professional looking, impress-your-friends sheet-music |
1036
|
|
|
|
|
|
|
suitable for printing on your nearest printer. |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
To learn more about ChordPro, look for the man page or do |
1039
|
|
|
|
|
|
|
"chordpro --help" for the list of options. |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
For more information, see https://www.chordpro.org . |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
Run-time information: |
1044
|
0
|
|
|
|
|
0
|
@{[::runtimeinfo()]} |
1045
|
|
|
|
|
|
|
EndOfAbout |
1046
|
0
|
0
|
|
|
|
0
|
exit $exit if defined $exit; |
1047
|
|
|
|
|
|
|
} |
1048
|
|
|
|
|
|
|
|
1049
|
79
|
|
|
79
|
|
859
|
use Cwd qw(realpath); |
|
79
|
|
|
|
|
244
|
|
|
79
|
|
|
|
|
47211
|
|
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
sub ::runtimeinfo { |
1052
|
8
|
|
|
8
|
|
33
|
my $short = shift; |
1053
|
|
|
|
|
|
|
|
1054
|
8
|
|
|
|
|
26
|
my $fmt = " %-22.22s %s\n"; |
1055
|
8
|
50
|
|
|
|
48
|
my $fmtv = defined($Wx::VERSION) ? " %s version %s\n" : $fmt; |
1056
|
8
|
50
|
|
|
|
40
|
my $fmtvv = defined($Wx::VERSION) ? " %s %s\n" : $fmt; |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
# Sometimes version numbers are localized... |
1059
|
8
|
|
|
8
|
|
81
|
my $dd = sub { my $v = $_[0]; $v =~ s/,/./g; $v }; |
|
8
|
|
|
|
|
38
|
|
|
8
|
|
|
|
|
32
|
|
|
8
|
|
|
|
|
65
|
|
1060
|
|
|
|
|
|
|
|
1061
|
8
|
|
|
|
|
43
|
my $msg = sprintf( $fmtv, "ChordPro core", $dd->($VERSION) ); |
1062
|
8
|
50
|
|
|
|
45
|
$msg =~ s/core/reference/ if $::options->{reference}; |
1063
|
8
|
50
|
|
|
|
44
|
if ( $VERSION =~ /_/ ) { |
1064
|
0
|
|
|
|
|
0
|
$msg =~ s/\n$/ (Unsupported development snapshot)\n/; |
1065
|
|
|
|
|
|
|
} |
1066
|
|
|
|
|
|
|
|
1067
|
8
|
50
|
|
|
|
32
|
if ( $short ) { |
1068
|
8
|
|
|
|
|
56
|
$msg =~ s/^\s+//; |
1069
|
8
|
|
|
|
|
63
|
$msg =~ s/\s+/ /g; |
1070
|
8
|
|
|
|
|
34
|
$msg =~ s/\s*\n//; |
1071
|
8
|
|
|
|
|
59
|
return $msg; |
1072
|
|
|
|
|
|
|
} |
1073
|
|
|
|
|
|
|
|
1074
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "Perl", $^V ); |
1075
|
0
|
|
|
|
|
0
|
$msg =~ s/\n$/ ($^X)\n/; |
1076
|
0
|
0
|
|
|
|
0
|
if ( $App::Packager::PACKAGED ) { |
1077
|
0
|
|
|
|
|
0
|
my $p = App::Packager::Packager(); |
1078
|
0
|
0
|
|
|
|
0
|
$p .= " Packager" unless $p =~ /packager/i; |
1079
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, $p, $dd->(App::Packager::Version()) ); |
1080
|
|
|
|
|
|
|
} |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
# Determine resource path. |
1083
|
0
|
|
|
|
|
0
|
my @p; |
1084
|
0
|
0
|
|
|
|
0
|
if ( $ENV{CHORDPRO_LIB} ) { |
1085
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtvv, "CHORDPRO_LIB", $ENV{CHORDPRO_LIB} ); |
1086
|
0
|
|
|
|
|
0
|
@p = splitpath($ENV{CHORDPRO_LIB}); |
1087
|
|
|
|
|
|
|
} |
1088
|
0
|
|
|
|
|
0
|
push( @p, realpath( App::Packager::GetResourcePath() ) ); |
1089
|
0
|
|
|
|
|
0
|
my $tag = "Resource path"; |
1090
|
0
|
|
|
|
|
0
|
for ( @p ) { |
1091
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtvv, $tag, $_ ); |
1092
|
0
|
|
|
|
|
0
|
$tag = ""; |
1093
|
|
|
|
|
|
|
} |
1094
|
|
|
|
|
|
|
|
1095
|
0
|
|
|
|
|
0
|
$msg .= "\nModules and libraries:\n"; |
1096
|
0
|
0
|
|
|
|
0
|
if ( defined $Wx::VERSION ) { |
1097
|
79
|
|
|
79
|
|
717
|
no strict 'subs'; |
|
79
|
|
|
|
|
234
|
|
|
79
|
|
|
|
|
60787
|
|
1098
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "wxPerl", $dd->($Wx::VERSION) ); |
1099
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "wxWidgets", $dd->(Wx::wxVERSION) ); |
1100
|
|
|
|
|
|
|
} |
1101
|
|
|
|
|
|
|
|
1102
|
0
|
|
|
0
|
|
0
|
local $SIG{__WARN__} = sub {}; |
1103
|
0
|
|
|
0
|
|
0
|
local $SIG{__DIE__} = sub {}; |
1104
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "Storable", $dd->($Storable::VERSION) ); |
1105
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "Object::Pad", $dd->($Object::Pad::VERSION) ); |
1106
|
0
|
|
|
|
|
0
|
eval { require Text::Layout; |
|
0
|
|
|
|
|
0
|
|
1107
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "Text::Layout", $dd->($Text::Layout::VERSION) ); |
1108
|
|
|
|
|
|
|
}; |
1109
|
0
|
|
|
|
|
0
|
eval { require HarfBuzz::Shaper; |
|
0
|
|
|
|
|
0
|
|
1110
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "HarfBuzz::Shaper", $dd->($HarfBuzz::Shaper::VERSION) ); |
1111
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "HarfBuzz library", $dd->(HarfBuzz::Shaper::hb_version_string()) ); |
1112
|
|
|
|
|
|
|
}; |
1113
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "File::LoadLines", $dd->($File::LoadLines::VERSION) ); |
1114
|
0
|
|
|
|
|
0
|
eval { require PDF::Builder; |
1115
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "PDF::Builder", $dd->($PDF::Builder::VERSION) ); |
1116
|
|
|
|
|
|
|
} |
1117
|
|
|
|
|
|
|
or |
1118
|
0
|
0
|
|
|
|
0
|
eval { require PDF::API2; |
|
0
|
|
|
|
|
0
|
|
1119
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "PDF::API2", $dd->($PDF::API2::VERSION) ); |
1120
|
|
|
|
|
|
|
}; |
1121
|
0
|
|
|
|
|
0
|
eval { require Font::TTF; |
|
0
|
|
|
|
|
0
|
|
1122
|
0
|
|
|
|
|
0
|
$msg .= sprintf( $fmtv, "Font::TTF", $dd->($Font::TTF::VERSION) ); |
1123
|
|
|
|
|
|
|
}; |
1124
|
0
|
|
|
|
|
0
|
eval { require Image::Magick; |
|
0
|
|
|
|
|
0
|
|
1125
|
0
|
|
0
|
|
|
0
|
$msg .= sprintf( $fmtv, "Image::Magick", |
1126
|
|
|
|
|
|
|
$dd->( $Image::Magick::VERSION || |
1127
|
|
|
|
|
|
|
$Image::Magick::Q16::VERSION || |
1128
|
|
|
|
|
|
|
$Image::Magick::Q8::VERSION || "6.x?" ) ); |
1129
|
|
|
|
|
|
|
}; |
1130
|
0
|
|
|
|
|
0
|
return $msg; |
1131
|
|
|
|
|
|
|
} |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
sub splitpath { |
1134
|
150
|
|
|
150
|
0
|
544
|
my ( $path ) = @_; |
1135
|
150
|
50
|
|
|
|
562
|
return () unless $path; |
1136
|
150
|
50
|
|
|
|
1154
|
if ( $^O =~ /Win/ ) { |
1137
|
0
|
|
|
|
|
0
|
return split( /;/, $path ); |
1138
|
|
|
|
|
|
|
} |
1139
|
150
|
|
|
|
|
1085
|
return split( /;/, $path ); |
1140
|
|
|
|
|
|
|
} |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
sub app_usage { |
1143
|
0
|
|
|
0
|
0
|
0
|
my ($fh, $exit) = @_; |
1144
|
0
|
|
|
|
|
0
|
my %cfg; |
1145
|
0
|
|
|
|
|
0
|
for ( qw( config userconfig sysconfig) ) { |
1146
|
0
|
|
0
|
|
|
0
|
$cfg{$_} = $configs{$_} || "no default"; |
1147
|
|
|
|
|
|
|
} |
1148
|
0
|
|
|
|
|
0
|
print ${fh} <
|
1149
|
|
|
|
|
|
|
Usage: $0 [ options ] [ file ... ] |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
Options: |
1152
|
|
|
|
|
|
|
--a2crd Perform text to ChordPro conversion only |
1153
|
|
|
|
|
|
|
--noa2crd Do not auto-sense text to ChordPro conversion |
1154
|
|
|
|
|
|
|
--about -A About ChordPro... |
1155
|
|
|
|
|
|
|
--back-matter=FILE Add back matter pages from PDF document |
1156
|
|
|
|
|
|
|
--config=JSON --cfg Config definitions (multiple) |
1157
|
|
|
|
|
|
|
--cover=FILE Add cover pages from PDF document |
1158
|
|
|
|
|
|
|
--crd Input is text, not ChordPro |
1159
|
|
|
|
|
|
|
--csv (with PDF) Also generate CSV |
1160
|
|
|
|
|
|
|
--decapo Eliminate capo settings |
1161
|
|
|
|
|
|
|
--diagrams=WHICH Prints chord diagrams |
1162
|
|
|
|
|
|
|
--encoding=ENC Encoding for input files (UTF-8) |
1163
|
|
|
|
|
|
|
--filelist=FILE Reads song file names from FILE |
1164
|
|
|
|
|
|
|
--fragment -F Partial (incomplete) song |
1165
|
|
|
|
|
|
|
--front-matter=FILE Add cover pages from PDF document |
1166
|
|
|
|
|
|
|
--lyrics-only -l Only prints lyrics |
1167
|
|
|
|
|
|
|
--meta KEY=VALUE Add meta data |
1168
|
|
|
|
|
|
|
--output=FILE -o Saves the output to FILE |
1169
|
|
|
|
|
|
|
--[no]strict Strict conformance |
1170
|
|
|
|
|
|
|
--start-page-number=N -p Starting page number [1] |
1171
|
|
|
|
|
|
|
--toc --notoc -i Generates/suppresses a table of contents |
1172
|
|
|
|
|
|
|
--transcode=SYS -xc Transcodes to notation system |
1173
|
|
|
|
|
|
|
--transpose=N -x Transposes by N semi-tones |
1174
|
|
|
|
|
|
|
--version -V Prints version and exits |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
Chordii compatibility. |
1177
|
|
|
|
|
|
|
Options marked with * are better specified in the config file. |
1178
|
|
|
|
|
|
|
Options marked with - are ignored. |
1179
|
|
|
|
|
|
|
--chord-font=FONT -C *Sets chord font |
1180
|
|
|
|
|
|
|
--chord-grid-size=N -s *Sets chord diagram size [30] |
1181
|
|
|
|
|
|
|
--chord-grids-sorted -S *Prints chord diagrams ordered by key |
1182
|
|
|
|
|
|
|
--chord-size=N -c *Sets chord size [9] |
1183
|
|
|
|
|
|
|
--dump-chords -D Dumps chords definitions (PostScript) |
1184
|
|
|
|
|
|
|
--dump-chords-text -d Dumps chords definitions (Text) |
1185
|
|
|
|
|
|
|
--even-pages-number-left -L *Even pages numbers on left |
1186
|
|
|
|
|
|
|
--odd-pages-number-left *Odd pages numbers on left |
1187
|
|
|
|
|
|
|
--no-chord-grids -G *Disables printing of chord diagrams |
1188
|
|
|
|
|
|
|
--no-easy-chord-grids -g Not supported |
1189
|
|
|
|
|
|
|
--page-number-logical -n -Numbers logical pages, not physical |
1190
|
|
|
|
|
|
|
--page-size=FMT -P *Specifies page size [letter, a4 (default)] |
1191
|
|
|
|
|
|
|
--single-space -a *Automatic single space lines without chords |
1192
|
|
|
|
|
|
|
--text-size=N -t *Sets text size [12] |
1193
|
|
|
|
|
|
|
--text-font=FONT -T *Sets text font |
1194
|
|
|
|
|
|
|
--user-chord-grids *Prints the user defined chords in the song |
1195
|
|
|
|
|
|
|
--vertical-space=N -w *Extra vertical space between lines |
1196
|
|
|
|
|
|
|
--2-up -2 Not supported |
1197
|
|
|
|
|
|
|
--4-up -4 Not supported |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
Configuration options: |
1200
|
|
|
|
|
|
|
--config=CFG Project specific config file ($cfg{config}) |
1201
|
|
|
|
|
|
|
--define=XXX=YYY Sets config item XXX to value YYY |
1202
|
|
|
|
|
|
|
--noconfig Don't use a project specific config file |
1203
|
|
|
|
|
|
|
--nodefaultconfigs -X Don't use any default config files |
1204
|
|
|
|
|
|
|
--nosongconfig Don't use song specific configs |
1205
|
|
|
|
|
|
|
--nosysconfig Don't use a system specific config file |
1206
|
|
|
|
|
|
|
--nouserconfig Don't use a user specific config file |
1207
|
|
|
|
|
|
|
--print-default-config Prints the default config and exits |
1208
|
|
|
|
|
|
|
--print-delta-config Prints the diffs for the resultant config and exits |
1209
|
|
|
|
|
|
|
--print-final-config Prints the resultant config and exits |
1210
|
|
|
|
|
|
|
--reference -R Reference mode (no configs etc.) |
1211
|
|
|
|
|
|
|
--sysconfig=CFG System specific config file ($cfg{sysconfig}) |
1212
|
|
|
|
|
|
|
--userconfig=CFG User specific config file ($cfg{userconfig}) |
1213
|
|
|
|
|
|
|
Missing default configuration files are silently ignored. |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
Miscellaneous options: |
1216
|
|
|
|
|
|
|
--help -h This message |
1217
|
|
|
|
|
|
|
--help-config Help for ChordPro configuration |
1218
|
|
|
|
|
|
|
--ident Show identification |
1219
|
|
|
|
|
|
|
--manual The full manual. |
1220
|
|
|
|
|
|
|
--verbose Verbose information. Repeat for more. |
1221
|
|
|
|
|
|
|
EndOfUsage |
1222
|
0
|
0
|
|
|
|
0
|
exit $exit if defined $exit; |
1223
|
|
|
|
|
|
|
} |
1224
|
|
|
|
|
|
|
|
1225
|
|
|
|
|
|
|
################ Resources ################ |
1226
|
|
|
|
|
|
|
|
1227
|
79
|
|
|
79
|
|
764
|
use Encode qw(decode decode_utf8 encode_utf8); |
|
79
|
|
|
|
|
232
|
|
|
79
|
|
|
|
|
33342
|
|
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
sub ::rsc_or_file { |
1230
|
161
|
|
|
161
|
|
691
|
my ( $c, $cfg ) = @_; |
1231
|
161
|
|
|
|
|
428
|
my $f = $c; |
1232
|
161
|
100
|
|
|
|
745
|
$cfg .= "/" if $cfg; |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
# Check for resource names. |
1235
|
161
|
100
|
|
|
|
933
|
if ( $f !~ m;[/.]; ) { |
1236
|
119
|
50
|
|
|
|
769
|
if ( $c =~ /^(.+):(.*)/ ) { |
1237
|
0
|
|
|
|
|
0
|
$f = $cfg . lc($1) . "/" . lc($2) . ".json"; |
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
else { |
1240
|
119
|
|
|
|
|
650
|
$f = $cfg . lc($c) . ".json"; |
1241
|
|
|
|
|
|
|
} |
1242
|
|
|
|
|
|
|
} |
1243
|
161
|
100
|
|
|
|
1005
|
if ( $ENV{CHORDPRO_LIB} ) { |
1244
|
150
|
|
|
|
|
879
|
my @libs = splitpath($ENV{CHORDPRO_LIB}); |
1245
|
150
|
|
|
|
|
559
|
foreach my $lib ( @libs ) { |
1246
|
150
|
|
|
|
|
929
|
$lib = expand_tilde($lib); |
1247
|
150
|
50
|
|
|
|
792
|
warn("RSC1: $lib/$f\n") if $options->{debug}; |
1248
|
150
|
50
|
|
|
|
4311
|
return $lib . "/" . $f if -r $lib . "/" . $f; |
1249
|
|
|
|
|
|
|
} |
1250
|
|
|
|
|
|
|
} |
1251
|
|
|
|
|
|
|
|
1252
|
161
|
50
|
|
|
|
955
|
warn("RSC3: $f\n") if $options->{debug}; |
1253
|
161
|
|
|
|
|
1251
|
my $t = getresource($f); |
1254
|
161
|
50
|
|
|
|
39057
|
return defined($t) ? $t : $c; |
1255
|
|
|
|
|
|
|
} |
1256
|
|
|
|
|
|
|
|
1257
|
79
|
|
|
79
|
|
39003
|
use lib ( grep { defined } getresource("CPAN") ); |
|
79
|
|
|
|
|
57131
|
|
|
79
|
|
|
|
|
868
|
|
|
0
|
|
|
|
|
0
|
|
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
=head1 FONTS |
1260
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
There are two ways to specify fonts: with a font filename, and a |
1262
|
|
|
|
|
|
|
built-in font name. |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
A font filename must be either and absolute filename, or a relative |
1265
|
|
|
|
|
|
|
filename which is interpreted relative to the I, which |
1266
|
|
|
|
|
|
|
consists of configuration setting C, the C resource |
1267
|
|
|
|
|
|
|
dir, and the contents of environment variable C. In any case, |
1268
|
|
|
|
|
|
|
the filename should point to a valid TrueType (C<.ttf>) or OpenType |
1269
|
|
|
|
|
|
|
(C<.otf>) font. |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
If it is not a filename, it must be the name one of the built-in fonts. |
1272
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
Built-in 'Adobe Core Fonts': |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
Courier Symbol |
1276
|
|
|
|
|
|
|
Courier-Bold Times-Bold |
1277
|
|
|
|
|
|
|
Courier-BoldOblique Times-BoldItalic |
1278
|
|
|
|
|
|
|
Courier-Oblique Times-Italic |
1279
|
|
|
|
|
|
|
Helvetica Times-Roman |
1280
|
|
|
|
|
|
|
Helvetica-Bold ZapfDingbats |
1281
|
|
|
|
|
|
|
Helvetica-BoldOblique |
1282
|
|
|
|
|
|
|
Helvetica-Oblique |
1283
|
|
|
|
|
|
|
|
1284
|
|
|
|
|
|
|
Built-in 'Windows Fonts': |
1285
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
Georgia Webdings |
1287
|
|
|
|
|
|
|
Georgia,Bold Wingdings |
1288
|
|
|
|
|
|
|
Georgia,BoldItalic |
1289
|
|
|
|
|
|
|
Georgia,Italic |
1290
|
|
|
|
|
|
|
Verdana |
1291
|
|
|
|
|
|
|
Verdana,Bold |
1292
|
|
|
|
|
|
|
Verdana,BoldItalic |
1293
|
|
|
|
|
|
|
Verdana,Italic |
1294
|
|
|
|
|
|
|
|
1295
|
|
|
|
|
|
|
=head1 MOTIVATION |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
Why a rewrite of Chordii? |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
Chordii is the de facto reference implementation of the ChordPro file |
1300
|
|
|
|
|
|
|
format standard. It implements ChordPro version 4. |
1301
|
|
|
|
|
|
|
|
1302
|
|
|
|
|
|
|
ChordPro version 5 adds a number of new features, and this was pushing |
1303
|
|
|
|
|
|
|
the limits of the very old program. Unicode support would have been |
1304
|
|
|
|
|
|
|
very hard to add, and the whole program centered around PostScript |
1305
|
|
|
|
|
|
|
generation, while nowadays PDF would be a much better alternative. |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
So I decided to create a new reference implementation from the ground |
1308
|
|
|
|
|
|
|
up. I chose a programming language that is flexible and very good at |
1309
|
|
|
|
|
|
|
handling Unicode data. And that is fun to program in. |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
=head1 CURRENT STATUS |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
This program implements ChordPro version 5. It |
1314
|
|
|
|
|
|
|
supports most of the features of Chordii, and a lot more: |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
* Native PDF generation |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
* Unicode support (all input is UTF8) |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
* User defined chords and tuning, not limited to 6 strings. |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
* Support for Nashville Numbering and Roman Numbering. |
1323
|
|
|
|
|
|
|
|
1324
|
|
|
|
|
|
|
* Support for external TrueType and OpenType fonts |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
* Font kerning (with external TrueType fonts) |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
* Fully customizable layout, fonts and sizes |
1329
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
* Customizable backends for PDF, ChordPro, LilyPond*, LaTeX* and HTML*. |
1331
|
|
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
(* = under development) |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
=head1 AUTHOR |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
Johan Vromans C<< >> |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
=head1 SUPPORT |
1339
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
ChordPro (the program) development is hosted on GitHub, repository |
1341
|
|
|
|
|
|
|
L. |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
Please report any bugs or feature requests to the GitHub issue tracker, |
1344
|
|
|
|
|
|
|
L. |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
A user community discussing ChordPro can be found at |
1347
|
|
|
|
|
|
|
L. |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
=head1 LICENSE |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
Copyright (C) 2010,2018 Johan Vromans, |
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
1354
|
|
|
|
|
|
|
under the same terms as Perl itself. |
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
=cut |
1357
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
1; |