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