Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 446 lines (392 sloc) 17.269 kb
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
1 use v6;
2 use ABC::Header;
3 use ABC::Tune;
4 use ABC::Grammar;
5 use ABC::Actions;
d6fa923 @colomon Clean up.
authored
6 use ABC::Duration; #OK
0d17ae0 @colomon Rename Duration.Str to Duration.duration-to-str (so it can be easily …
authored
7 use ABC::Note;
bfee93a @colomon Support for multi-measure rests.
authored
8 use ABC::LongRest;
d39bfc4 @colomon Move some stuff to ABC::Utils, pitch-to-ordinal and ordinal-to-pitch …
authored
9 use ABC::Utils;
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
10
6aeb675 @colomon Add crude paper size control.
authored
11 my $paper-size = "letter"; # or switch to "a4" for European paper
12
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
13 my %accidental-map = ( '' => "",
14 '=' => "",
15 '^' => "is",
16 '^^' => "isis",
17 '_' => "es",
18 '__' => "eses" );
19
6c5a781 @colomon Add support for 3/4 time, octave modifiers.
authored
20 my %octave-map = ( -1 => "",
21 0 => "'",
22 1 => "''",
23 2 => "'''" );
28c4076 @colomon Segnos and codas and D.C.s, oh my!
authored
24
25 my %unrecognized_gracings;
26
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
27 class Context {
c68369e @colomon Tweaks to get inline fields working better, plus more tests for them.
authored
28 has $.key-name;
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
29 has %.key;
e57f6a8 @colomon Add support for meters other than 4/4.
authored
30 has $.meter;
56c09ce @colomon Support length field and proper final bar line.
authored
31 has $.length;
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
32
56c09ce @colomon Support length field and proper final bar line.
authored
33 method new($key-name, $meter, $length) {
34 self.bless(*, :$key-name,
35 :key(key_signature($key-name)),
36 :$meter,
28d8d1a @colomon Use classic trick sorear++ reminded me of to figure out if an int is …
authored
37 :$length);
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
38 }
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
39
40 method get-Lilypond-pitch(ABC::Note $abc-pitch) {
41 my $real-accidental = $abc-pitch.accidental || ($.key{$abc-pitch.basenote.uc} // "");
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
42
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
43 my $octave = +($abc-pitch.basenote ~~ 'a'..'z');
44 given $abc-pitch.octave {
e301f63 @colomon Eliminate a boatload of "Uninitialized value used as string" warnings…
authored
45 when !*.defined { } # skip if no additional octave info
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
46 when /\,/ { $octave -= $abc-pitch.octave.chars }
47 when /\'/ { $octave += $abc-pitch.octave.chars }
6c5a781 @colomon Add support for 3/4 time, octave modifiers.
authored
48 }
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
49
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
50 $abc-pitch.basenote.lc ~ %accidental-map{$real-accidental} ~ %octave-map{$octave};
945131a @colomon Get the key signature correct (at least for simple key signatures) bu…
authored
51 }
f9cdf54 @colomon Refactor in preparation for handling base note lengths other than 1/8.
authored
52
53 method get-Lilypond-duration(ABC::Duration $abc-duration) {
694c7c1 @colomon Replace hardcoded (and limited) note length hash tables with a genera…
authored
54 my $ticks = $abc-duration.ticks.Rat * $.length;
55 my $dots = "";
56 given $ticks.numerator {
57 when 3 { $dots = "."; $ticks *= 2/3; }
58 when 7 { $dots = ".."; $ticks *= 4/7; }
59 }
28d8d1a @colomon Use classic trick sorear++ reminded me of to figure out if an int is …
authored
60 die "Don't know how to handle duration { $abc-duration.ticks }" unless is-a-power-of-two($ticks);
694c7c1 @colomon Replace hardcoded (and limited) note length hash tables with a genera…
authored
61 die "Don't know how to handle duration { $abc-duration.ticks }" if $ticks > 4;
62 if $ticks == 4 {
63 "\\longa" ~ $dots;
64 } elsif $ticks == 2 {
65 "\\breve" ~ $dots;
66 } else {
67 $ticks.denominator ~ $dots;
68 }
f9cdf54 @colomon Refactor in preparation for handling base note lengths other than 1/8.
authored
69 }
e57f6a8 @colomon Add support for meters other than 4/4.
authored
70
138f1a9 @colomon Replace write-meter and write-key with meter-to-string and key-to-str…
authored
71 method meter-to-string() {
69d70e7 @colomon Support for cut time, dotted sixteenths and thirty-second notes, and …
authored
72 given $.meter {
73 when "C" { "\\time 4/4" }
74 when "C|" { "\\time 2/2" }
75 "\\time $.meter ";
76 }
e57f6a8 @colomon Add support for meters other than 4/4.
authored
77 }
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
78
56c09ce @colomon Support length field and proper final bar line.
authored
79 method ticks-in-measure() {
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
80 given $.meter {
664f368 @colomon Remove uses of eval to convert rational strings to Rats; using defaul…
authored
81 when "C" | "C|" { 1 / $.length; }
82 $.meter / $.length;
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
83 }
84 }
bfee93a @colomon Support for multi-measure rests.
authored
85
86 method get-Lilypond-measure-length() {
87 given $.meter {
69d70e7 @colomon Support for cut time, dotted sixteenths and thirty-second notes, and …
authored
88 when "C" | "C|" | "4/4" { "1" }
bfee93a @colomon Support for multi-measure rests.
authored
89 when "3/4" | 6/8 { "2." }
90 when "2/4" { "2" }
91 }
92 }
b561dfc @colomon Refactor key signature handling a bit.
authored
93
138f1a9 @colomon Replace write-meter and write-key with meter-to-string and key-to-str…
authored
94 method key-to-string() {
b561dfc @colomon Refactor key signature handling a bit.
authored
95 my $sf = %.key.map({ "{.key}{.value}" }).sort.Str.lc;
96 my $major-key-name;
97 given $sf {
98 when "" { $major-key-name = "c"; }
99 when "f^" { $major-key-name = "g"; }
100 when "c^ f^" { $major-key-name = "d"; }
101 when "c^ f^ g^" { $major-key-name = "a"; }
102 when "c^ d^ f^ g^" { $major-key-name = "e"; }
103 when "a^ c^ d^ f^ g^" { $major-key-name = "b"; }
104 when "a^ c^ d^ e^ f^ g^" { $major-key-name = "fis"; }
105 when "a^ b^ c^ d^ e^ f^ g^" { $major-key-name = "cis"; }
106 when "b_" { $major-key-name = "f"; }
107 when "b_ e_" { $major-key-name = "bes"; }
108 when "a_ b_ e_" { $major-key-name = "ees"; }
109 when "a_ b_ d_ e_" { $major-key-name = "aes"; }
110 when "a_ b_ d_ e_ g_" { $major-key-name = "des"; }
111 when "a_ b_ c_ d_ e_ g_" { $major-key-name = "ges"; }
112 when "a_ b_ c_ d_ e_ f_ g_" { $major-key-name = "ces"; }
113 }
138f1a9 @colomon Replace write-meter and write-key with meter-to-string and key-to-str…
authored
114 "\\key $major-key-name \\major\n";
b561dfc @colomon Refactor key signature handling a bit.
authored
115 }
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
116 }
117
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
118 sub HeaderToLilypond(ABC::Header $header, $out) {
119 $out.say: "\\header \{";
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
120
69d70e7 @colomon Support for cut time, dotted sixteenths and thirty-second notes, and …
authored
121 my $title = $header.get-first-value("T");
122 $title .=subst('"', "'", :g);
123 $out.say: " piece = \" $title \"";
70e5a12 @colomon Add "Tali Foster's" to r-star.abc file so we can easily test multiple…
authored
124 my @composers = $header.get("C")>>.value;
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
125 $out.say: " composer = \"{ @composers[0] }\"" if ?@composers;
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
126
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
127 $out.say: "}";
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
128 }
129
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
130 class TuneConvertor {
131 has $.context;
7f72e30 @colomon Very weak implementation of tuple that works for the common triplet c…
authored
132
56c09ce @colomon Support length field and proper final bar line.
authored
133 method new($key, $meter, $length) {
134 self.bless(*, :context(Context.new($key, $meter, $length)));
0d17ae0 @colomon Rename Duration.Str to Duration.duration-to-str (so it can be easily …
authored
135 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
136
137 # MUST: this is context dependent too
138 method Duration($element) {
139 $element.value ~~ ABC::Duration ?? $element.value.ticks !! 0;
140 }
141
cb97b26 @colomon Refactor StemToLilypond to eliminate duplication.
authored
142 method StemPitchToLilypond($stem) {
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
143 given $stem {
144 when ABC::Note {
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
145 $.context.get-Lilypond-pitch($stem)
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
146 }
cb97b26 @colomon Refactor StemToLilypond to eliminate duplication.
authored
147
4be395a @colomon Add support for stems (ie written out chords).
authored
148 when ABC::Stem {
99fd266 @colomon Make get-Lilypond-pitch not rely on parsing the note twice.
authored
149 "<" ~ $stem.notes.map({ $.context.get-Lilypond-pitch($_) }).join(' ') ~ ">"
4be395a @colomon Add support for stems (ie written out chords).
authored
150 }
cb97b26 @colomon Refactor StemToLilypond to eliminate duplication.
authored
151
35e3bd8 @colomon Add error for stems we don't recognize, rather than silently failing.
authored
152 die "Unrecognized alleged stem: " ~ $stem.perl;
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
153 }
154 }
cb97b26 @colomon Refactor StemToLilypond to eliminate duplication.
authored
155
156 method StemToLilypond($stem, $suffix = "") {
157 " " ~ self.StemPitchToLilypond($stem)
158 ~ $.context.get-Lilypond-duration($stem)
159 ~ ($stem.is-tie ?? '~' !! '')
160 ~ $suffix
161 ~ " ";
162 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
163
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
164 method WrapBar($lilypond-bar, $duration, :$beginning?) {
56c09ce @colomon Support length field and proper final bar line.
authored
165 my $ticks-in-measure = $.context.ticks-in-measure;
f133cf1 @colomon Refactor so that notes are stored up rather than output bar-by-bar.
authored
166 my $result = "";
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
167 if $beginning && $duration % $ticks-in-measure != 0 {
664f368 @colomon Remove uses of eval to convert rational strings to Rats; using defaul…
authored
168 my $note-length = 1 / $.context.length;
69d70e7 @colomon Support for cut time, dotted sixteenths and thirty-second notes, and …
authored
169 my $count = $duration % $ticks-in-measure;
170 if $count ~~ Rat {
28d8d1a @colomon Use classic trick sorear++ reminded me of to figure out if an int is …
authored
171 die "Strange partial measure found: $lilypond-bar" unless is-a-power-of-two($count.denominator);
b7a037d @colomon Clean up a couple weird duration cases.
authored
172
69d70e7 @colomon Support for cut time, dotted sixteenths and thirty-second notes, and …
authored
173 while $count.denominator > 1 {
174 $note-length *= 2; # makes twice as short
175 $count *= 2; # makes twice as long
176 }
177 }
178 $result = "\\partial { $note-length }*{ $count } ";
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
179 }
180
f133cf1 @colomon Refactor so that notes are stored up rather than output bar-by-bar.
authored
181 $result ~ $lilypond-bar;
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
182 }
183
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
184 method SectionToLilypond(@elements, $out, :$beginning?) {
185 my $first-time = $beginning // False;
f133cf1 @colomon Refactor so that notes are stored up rather than output bar-by-bar.
authored
186 my $notes = "";
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
187 my $lilypond = "";
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
188 my $duration = 0;
f133cf1 @colomon Refactor so that notes are stored up rather than output bar-by-bar.
authored
189 my $chord-duration = 0;
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
190 my $suffix = "";
41c04b4 @colomon Be smarter about extraneous end-slur marks. (To deal with Gerry Stro…
authored
191 my $in-slur = False;
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
192 for @elements -> $element {
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
193 $duration += self.Duration($element);
f133cf1 @colomon Refactor so that notes are stored up rather than output bar-by-bar.
authored
194 $chord-duration += self.Duration($element);
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
195 given $element.key {
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
196 when "stem" {
197 $lilypond ~= self.StemToLilypond($element.value, $suffix);
198 $suffix = "";
199 }
200 when "rest" {
7792339 @colomon Add +fermata+ support.
authored
201 $lilypond ~= " r{ $.context.get-Lilypond-duration($element.value) }$suffix ";
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
202 $suffix = "";
203 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
204 when "tuplet" {
ea8c786 @colomon Support sixteenth note as a note length, and better (though note yet …
authored
205 $lilypond ~= " \\times 2/{ $element.value.tuple } \{";
206 $lilypond ~= self.StemToLilypond($element.value.notes[0], "[");
207 for 1..($element.value.notes - 2) -> $i {
208 $lilypond ~= self.StemToLilypond($element.value.notes[$i]);
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
209 }
ea8c786 @colomon Support sixteenth note as a note length, and better (though note yet …
authored
210 $lilypond ~= self.StemToLilypond($element.value.notes[*-1], "]");
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
211 $lilypond ~= " } ";
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
212 $suffix = "";
1221bde @colomon Get triplets working.
authored
213 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
214 when "broken_rhythm" {
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
215 $lilypond ~= self.StemToLilypond($element.value.effective-stem1, $suffix);
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
216 # MUST: handle interior graciings
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
217 $lilypond ~= self.StemToLilypond($element.value.effective-stem2);
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
218 $suffix = "";
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
219 }
220 when "gracing" {
221 given $element.value {
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
222 when "~" { $suffix ~= "\\turn"; }
223 when "." { $suffix ~= "\\staccato"; }
28c4076 @colomon Segnos and codas and D.C.s, oh my!
authored
224 when "segno" { $lilypond ~= '\\mark \\markup { \\musicglyph #"scripts.segno" }'; }
225 when "coda" { $lilypond ~= '\\mark \\markup { \\musicglyph #"scripts.coda" }'; }
226 when "D.C." { $lilypond ~= '\\mark "D.C."'}
228f881 @colomon Add +D.S.+.
authored
227 when "D.S." { $lilypond ~= '\\mark "D.S."'}
738a897 @colomon Add crescendos and diminuendos, clean up other long graces a bit.
authored
228 when "crescendo(" | "<(" { $suffix ~= "\\<"; }
229 when "crescendo)" | "<)" { $suffix ~= "\\!"; }
230 when "diminuendo(" | ">(" { $suffix ~= "\\>"; }
231 when "diminuendo)" | ">)" { $suffix ~= "\\!"; }
232 when /^p+$/ | "mp" | "mf" | /^f+$/ | "fermata" | "accent" | "trill"
2ea4347 @colomon Add dynamics support (and a few dynamics to "Tali Foster's" so we can…
authored
233 { $suffix ~= "\\" ~ $element.value; }
772d939 @colomon Add simple trills.
authored
234 $*ERR.say: "Unrecognized gracing: " ~ $element.value.perl;
28c4076 @colomon Segnos and codas and D.C.s, oh my!
authored
235 %unrecognized_gracings{~$element.value} = 1;
7792339 @colomon Add +fermata+ support.
authored
236 }
237 }
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
238 when "barline" {
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
239 $notes ~= self.WrapBar($lilypond, $duration, :beginning($first-time));
240 $first-time = False;
9e4e1b3 @colomon Change almost all the regex methods to tokens, to prevent wild backtr…
authored
241 if $element.value eq "||" {
242 $notes ~= ' \\bar "||"';
243 } else {
244 $notes ~= " |\n";
245 }
2261a59 @colomon Refactor a bit, handle measures with other numbers of eighth notes.
authored
246 $lilypond = "";
247 $duration = 0;
2f95a2d @colomon Rewrite StemToLilypond to return the string for the note, rather than…
authored
248 }
8d09a3e @colomon Get in-line key changes working.
authored
249 when "inline_field" {
250 given $element.value.key {
251 when "K" {
56c09ce @colomon Support length field and proper final bar line.
authored
252 $!context = Context.new($element.value.value,
253 $!context.meter,
254 $!context.length);
138f1a9 @colomon Replace write-meter and write-key with meter-to-string and key-to-str…
authored
255 $lilypond ~= $!context.key-to-string;
8d09a3e @colomon Get in-line key changes working.
authored
256 }
ee29618 @colomon Allow changing meters, add crooked Newfoundland double to the ABC tun…
authored
257 when "M" {
56c09ce @colomon Support length field and proper final bar line.
authored
258 $!context = Context.new($!context.key-name,
259 $element.value.value,
260 $!context.length);
138f1a9 @colomon Replace write-meter and write-key with meter-to-string and key-to-str…
authored
261 $lilypond ~= $!context.meter-to-string;
ee29618 @colomon Allow changing meters, add crooked Newfoundland double to the ABC tun…
authored
262 }
56c09ce @colomon Support length field and proper final bar line.
authored
263 when "L" {
264 $!context = Context.new($!context.key-name,
265 $!context.meter,
266 $element.value.value);
267 }
8d09a3e @colomon Get in-line key changes working.
authored
268 }
269 }
a63e6e6 @colomon Support slurs, too.
authored
270 when "slur_begin" {
271 $suffix ~= "(";
41c04b4 @colomon Be smarter about extraneous end-slur marks. (To deal with Gerry Stro…
authored
272 $in-slur = True;
a63e6e6 @colomon Support slurs, too.
authored
273 }
274 when "slur_end" {
41c04b4 @colomon Be smarter about extraneous end-slur marks. (To deal with Gerry Stro…
authored
275 $lilypond .= subst(/(\s+)$/, { ")$_" }) if $in-slur;
276 $*ERR.say: "Warning: End-slur found without begin-slur" unless $in-slur;
277 $in-slur = False;
a63e6e6 @colomon Support slurs, too.
authored
278 }
bfee93a @colomon Support for multi-measure rests.
authored
279 when "multi_measure_rest" {
280 $lilypond ~= "\\compressFullBarRests R"
281 ~ $!context.get-Lilypond-measure-length
282 ~ "*"
283 ~ $element.value.measures_rest ~ " ";
284 }
53a7398 @colomon Add support for text above notes.
authored
285 when "chord_or_text" {
fa9b56c @colomon Fix so the chord or text handling code is actually looking at the cor…
authored
286 for @($element.value) -> $chord_or_text {
53a7398 @colomon Add support for text above notes.
authored
287 if $chord_or_text ~~ ABC::Chord {
719c0aa @colomon Track changes in chord stringification in abc2ly.
authored
288 $suffix ~= '^' ~ $chord_or_text ~ " ";
53a7398 @colomon Add support for text above notes.
authored
289 } else {
290 given $element.value {
291 when /^ '^'(.*)/ { $suffix ~= '^"' ~ $0 ~ '" ' }
292 }
293 }
294 }
295 }
aceaec7 @colomon Add grace notes.
authored
296 when "grace_notes" {
297 $*ERR.say: "Unused suffix in grace note code: $suffix" if $suffix;
298
299 $lilypond ~= "\\grace \{";
300 if $element.value.notes == 1 {
301 $lilypond ~= self.StemToLilypond($element.value.notes[0], "");
302 } else {
303 $lilypond ~= self.StemToLilypond($element.value.notes[0], "[");
304 for 1..^($element.value.notes - 1) {
305 $lilypond ~= self.StemToLilypond($element.value.notes[$_], "");
306 }
307 $lilypond ~= self.StemToLilypond($element.value.notes[*-1], "]");
308 }
309 $lilypond ~= " \} ";
310
311 $suffix = "";
312 }
8d09a3e @colomon Get in-line key changes working.
authored
313 # .say;
06b7722 @colomon Get basic rolls and staccato notes working.
authored
314 }
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
315 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
316
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
317 $out.say: "\{";
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
318 $notes ~= self.WrapBar($lilypond, $duration, :beginning($first-time));
319 $first-time = False;
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
320 $out.say: $notes;
321 $out.say: " \}";
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
322 }
323
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
324 method BodyToLilypond(@elements, $out) {
325 $out.say: "\{";
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
326 $out.print: $.context.key-to-string;
327 $out.print: $.context.meter-to-string;
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
328
329 my $start-of-section = 0;
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
330 loop (my $i = 0; $i < +@elements; $i++) {
4385d53 @colomon Make $length a bit smarter.
authored
331 # say @elements[$i].WHAT;
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
332 if @elements[$i].key eq "nth_repeat"
333 || ($i > $start-of-section
334 && @elements[$i].key eq "barline"
335 && @elements[$i].value ne "|") {
336 if @elements[$i].key eq "nth_repeat"
337 || @elements[$i].value eq ':|:' | ':|' | '::' {
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
338 $out.print: "\\repeat volta 2 "; # 2 is abitrarily chosen here!
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
339 }
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
340 self.SectionToLilypond(@elements[$start-of-section ..^ $i], $out, :beginning);
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
341 $start-of-section = $i + 1;
9e4e1b3 @colomon Change almost all the regex methods to tokens, to prevent wild backtr…
authored
342 given @elements[$i].value {
343 when '||' { $out.say: '\\bar "||"'; }
344 when '|]' { $out.say: '\\bar "|."'; }
56c09ce @colomon Support length field and proper final bar line.
authored
345 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
346 }
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
347
348 if @elements[$i].key eq "nth_repeat" {
9e4e1b3 @colomon Change almost all the regex methods to tokens, to prevent wild backtr…
authored
349 my $final-bar = "";
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
350 $out.say: "\\alternative \{";
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
351 my $endings = 0;
352 loop (; $i < +@elements; $i++) {
4385d53 @colomon Make $length a bit smarter.
authored
353 # say @elements[$i].WHAT;
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
354 if @elements[$i].key eq "barline"
355 && @elements[$i].value ne "|" {
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
356 self.SectionToLilypond(@elements[$start-of-section ..^ $i], $out);
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
357 $start-of-section = $i + 1;
56c09ce @colomon Support length field and proper final bar line.
authored
358 $final-bar = True if @elements[$i].value eq '|]';
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
359 last if ++$endings == 2;
360 }
361 }
362 if $endings == 1 {
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
363 self.SectionToLilypond(@elements[$start-of-section ..^ $i], $out);
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
364 $start-of-section = $i + 1;
9e4e1b3 @colomon Change almost all the regex methods to tokens, to prevent wild backtr…
authored
365 $final-bar = @elements[$i].value if $i < +@elements && @elements[$i].value eq '|]' | '||';
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
366 }
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
367 $out.say: "\}";
56c09ce @colomon Support length field and proper final bar line.
authored
368
9e4e1b3 @colomon Change almost all the regex methods to tokens, to prevent wild backtr…
authored
369 given $final-bar {
370 when '||' { $out.say: '\\bar "||"'; }
371 when '|]' { $out.say: '\\bar "|."'; }
56c09ce @colomon Support length field and proper final bar line.
authored
372 }
373
c4d049a @colomon Repeats are up and running, though still a bit hacky.
authored
374 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
375 }
376
377 if $start-of-section + 1 < @elements.elems {
378 if @elements[*-1].value eq ':|:' | ':|' | '::' {
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
379 $out.print: "\\repeat volta 2 "; # 2 is abitrarily chosen here!
549756a @colomon Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
380 }
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
381 self.SectionToLilypond(@elements[$start-of-section ..^ +@elements], $out, :beginning);
56c09ce @colomon Support length field and proper final bar line.
authored
382 if @elements[*-1].value eq '|]' {
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
383 $out.say: '\\bar "|."';
56c09ce @colomon Support length field and proper final bar line.
authored
384 }
549756a @colomon Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
385 }
386
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
387 $out.say: "\}";
549756a @colomon Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
388 }
102ec2f @colomon Refactor a bunch of the functions into a TuneConvertor class, so it i…
authored
389
549756a @colomon Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
390 }
391
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
392 sub TuneStreamToLilypondStream($in, $out) {
95126c9 @colomon Add current tune progress to ABC::Actions.current-tune, which greatly…
authored
393 my $actions = ABC::Actions.new;
394 my $match = ABC::Grammar.parse($in.slurp, :rule<tune_file>, :$actions);
395 die "Did not match ABC grammar: last tune understood:\n { $actions.current-tune }" unless $match;
29745ec @colomon Crude first script to translate ABC to Lilypond.
authored
396
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
397 $out.say: '\\version "2.12.3"';
398 $out.say: "#(set-default-paper-size \"{$paper-size}\")";
e6612a5 @colomon Add double bar line to the grammar, and some durations longer than a …
authored
399
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
400 for @( $match.ast ) -> $tune {
401 $*ERR.say: "Working on { $tune.header.get-first-value("T") // $tune.header.get-first-value("X") }";
402 $out.say: "\\score \{";
403
404 # say ~$tune.music;
70e5a12 @colomon Add "Tali Foster's" to r-star.abc file so we can easily test multiple…
authored
405
18bb13f @colomon Replace uses of ABC::Header.get()[0].value with ABC::Header.get-first…
authored
406 my $key = $tune.header.get-first-value("K");
407 my $meter = $tune.header.get-first-value("M");
408 my $length = $tune.header.get-first-value("L") // "1/8";
70e5a12 @colomon Add "Tali Foster's" to r-star.abc file so we can easily test multiple…
authored
409
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
410 my $convertor = TuneConvertor.new($key, $meter, $length);
411 $convertor.BodyToLilypond($tune.music, $out);
412 HeaderToLilypond($tune.header, $out);
70e5a12 @colomon Add "Tali Foster's" to r-star.abc file so we can easily test multiple…
authored
413
6b394ee @colomon Refactor a tad in preparation for better command line interface.
authored
414 $out.say: "}\n\n";
415 }
70e5a12 @colomon Add "Tali Foster's" to r-star.abc file so we can easily test multiple…
authored
416 }
417
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
418 multi sub MAIN() {
419 TuneStreamToLilypondStream($*IN, $*OUT);
420 }
421
d916fde @colomon Allow processing multiple ABC files at once, some new test stuff.
authored
422 multi sub MAIN($first-abc-file, *@other-abc-files) {
423 my @abc-files = $first-abc-file, @other-abc-files;
424 for @abc-files -> $abc-file {
425 my $ly-file = $abc-file ~ ".ly";
426 if $abc-file ~~ /^(.*) ".abc"/ {
427 $ly-file = $0 ~ ".ly";
428 }
429 $*ERR.say: "Reading $abc-file, writing $ly-file";
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
430
d916fde @colomon Allow processing multiple ABC files at once, some new test stuff.
authored
431 my $in = open $abc-file, :r or die "Unable to open $abc-file";
432 my $out = open $ly-file, :w or die "Unable to open $ly-file";
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
433
d916fde @colomon Allow processing multiple ABC files at once, some new test stuff.
authored
434 TuneStreamToLilypondStream($in, $out);
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
435
f66e5b6 @colomon Hack to hopefully improve partial bar situation.
authored
436 # $out.say: '\markup {';
437 # $out.say: ' "For more information on these tunes, please see http://midlandceltic.org/ws2011/"';
438 # $out.say: '}';
439
d916fde @colomon Allow processing multiple ABC files at once, some new test stuff.
authored
440 $out.close;
441 $in.close;
442 }
28c4076 @colomon Segnos and codas and D.C.s, oh my!
authored
443
444 $*ERR.say: "Unrecognized gracings: " ~ %unrecognized_gracings.keys.join(", ") if %unrecognized_gracings;
b90e9e2 @colomon Fix broken bits of last refactor, add two MAIN subs, one of which tak…
authored
445 }
Something went wrong with that request. Please try again.