abcjs 6.0.0-beta.7 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/tests.yml +29 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/CONTRIBUTING.md +1 -0
- package/LICENSE.md +1 -1
- package/README.md +92 -3
- package/RELEASE.md +957 -1
- package/abcjs-audio.css +14 -5
- package/dist/.gitignore +1 -2
- package/dist/abcjs-basic-min.js +3 -0
- package/dist/abcjs-basic-min.js.LICENSE +23 -0
- package/dist/abcjs-basic.js +28231 -0
- package/dist/abcjs-basic.js.map +1 -0
- package/dist/abcjs-plugin-min.js +3 -0
- package/dist/abcjs-plugin-min.js.LICENSE +23 -0
- package/dist/report-basic.html +37 -0
- package/dist/report-before-glyph-compress.html +37 -0
- package/dist/report-brown-ts-target-es5.html +37 -0
- package/dist/report-dev-orig-no-babel.html +37 -0
- package/dist/report-synth.html +37 -0
- package/docker-build.sh +1 -0
- package/glyphs.json +1 -0
- package/index.js +27 -2
- package/{static-wrappers/license.js → license.js} +1 -1
- package/package.json +26 -29
- package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
- package/src/api/abc_animation.js +1 -17
- package/src/api/abc_tablatures.js +144 -0
- package/src/api/abc_timing_callbacks.js +234 -116
- package/src/api/abc_tunebook.js +18 -67
- package/src/api/abc_tunebook_svg.js +38 -46
- package/src/data/abc_tune.js +232 -972
- package/src/data/deline-tune.js +199 -0
- package/src/edit/abc_editarea.js +112 -0
- package/src/edit/abc_editor.js +95 -221
- package/src/midi/abc_midi_create.js +48 -50
- package/src/parse/abc_common.js +0 -14
- package/src/parse/abc_parse.js +167 -1321
- package/src/parse/abc_parse_book.js +62 -0
- package/src/parse/abc_parse_directive.js +164 -41
- package/src/parse/abc_parse_header.js +116 -145
- package/src/parse/abc_parse_key_voice.js +26 -20
- package/src/parse/abc_parse_music.js +1337 -0
- package/src/parse/abc_tokenizer.js +21 -15
- package/src/parse/abc_transpose.js +3 -15
- package/src/parse/tune-builder.js +896 -0
- package/src/parse/wrap_lines.js +205 -453
- package/src/synth/abc_midi_flattener.js +1292 -0
- package/src/{midi → synth}/abc_midi_renderer.js +44 -17
- package/src/synth/abc_midi_sequencer.js +648 -0
- package/src/synth/active-audio-context.js +3 -14
- package/src/synth/cents-to-factor.js +10 -0
- package/src/synth/create-note-map.js +21 -32
- package/src/synth/create-synth-control.js +20 -103
- package/src/synth/create-synth.js +185 -77
- package/src/synth/download-buffer.js +7 -21
- package/src/synth/get-midi-file.js +13 -20
- package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
- package/src/synth/images/loop.svg.js +65 -0
- package/src/synth/images/pause.svg.js +10 -0
- package/src/synth/images/play.svg.js +9 -0
- package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
- package/src/synth/instrument-index-to-name.js +1 -16
- package/src/synth/load-note.js +37 -76
- package/src/synth/pitch-to-note-name.js +0 -15
- package/src/synth/pitches-to-perc.js +64 -0
- package/src/synth/place-note.js +78 -68
- package/src/synth/play-event.js +17 -18
- package/src/synth/register-audio-context.js +11 -23
- package/src/synth/sounds-cache.js +0 -15
- package/src/synth/supports-audio.js +9 -23
- package/src/synth/synth-controller.js +80 -49
- package/src/synth/synth-sequence.js +20 -34
- package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
- package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
- package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
- package/src/tablatures/instruments/string-patterns.js +277 -0
- package/src/tablatures/instruments/string-tablature.js +56 -0
- package/src/tablatures/instruments/tab-note.js +282 -0
- package/src/tablatures/instruments/tab-notes.js +41 -0
- package/src/tablatures/instruments/violin/tab-violin.js +47 -0
- package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
- package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
- package/src/tablatures/tab-absolute-elements.js +310 -0
- package/src/tablatures/tab-common.js +29 -0
- package/src/tablatures/tab-renderer.js +243 -0
- package/src/tablatures/transposer.js +110 -0
- package/src/test/abc_midi_lint.js +5 -22
- package/src/test/abc_midi_sequencer_lint.js +11 -14
- package/src/test/abc_parser_lint.js +136 -32
- package/src/test/abc_vertical_lint.js +94 -32
- package/src/test/rendering-lint.js +38 -5
- package/src/write/abc_absolute_element.js +112 -120
- package/src/write/abc_abstract_engraver.js +102 -253
- package/src/write/abc_beam_element.js +30 -290
- package/src/write/abc_brace_element.js +12 -121
- package/src/write/abc_create_clef.js +21 -32
- package/src/write/abc_create_key_signature.js +8 -26
- package/src/write/abc_create_note_head.js +107 -0
- package/src/write/abc_create_time_signature.js +2 -21
- package/src/write/abc_crescendo_element.js +3 -50
- package/src/write/abc_decoration.js +7 -30
- package/src/write/abc_dynamic_decoration.js +3 -37
- package/src/write/abc_ending_element.js +1 -57
- package/src/write/abc_engraver_controller.js +111 -234
- package/src/write/abc_glyphs.js +9 -19
- package/src/write/abc_relative_element.js +57 -97
- package/src/write/abc_renderer.js +10 -832
- package/src/write/abc_spacing.js +0 -15
- package/src/write/abc_staff_group_element.js +14 -349
- package/src/write/abc_tempo_element.js +9 -117
- package/src/write/abc_tie_element.js +5 -68
- package/src/write/abc_triplet_element.js +6 -124
- package/src/write/abc_voice_element.js +7 -222
- package/src/write/add-chord.js +103 -0
- package/src/write/add-text-if.js +33 -0
- package/src/write/bottom-text.js +79 -0
- package/src/write/calcHeight.js +17 -0
- package/src/write/classes.js +100 -0
- package/src/write/draw/absolute.js +68 -0
- package/src/write/draw/beam.js +56 -0
- package/src/write/draw/brace.js +106 -0
- package/src/write/draw/crescendo.js +38 -0
- package/src/write/draw/debug-box.js +8 -0
- package/src/write/draw/draw.js +56 -0
- package/src/write/draw/dynamics.js +20 -0
- package/src/write/draw/ending.js +46 -0
- package/src/write/draw/group-elements.js +66 -0
- package/src/write/draw/horizontal-line.js +25 -0
- package/src/write/draw/non-music.js +50 -0
- package/src/write/draw/print-line.js +24 -0
- package/src/write/draw/print-path.js +7 -0
- package/src/write/draw/print-stem.js +30 -0
- package/src/write/draw/print-symbol.js +59 -0
- package/src/write/draw/print-vertical-line.js +18 -0
- package/src/write/draw/relative.js +77 -0
- package/src/write/draw/round-number.js +5 -0
- package/src/write/draw/selectables.js +59 -0
- package/src/write/draw/separator.js +16 -0
- package/src/write/draw/set-paper-size.js +45 -0
- package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
- package/src/write/draw/staff-group.js +226 -0
- package/src/write/draw/staff-line.js +9 -0
- package/src/write/draw/staff.js +33 -0
- package/src/write/draw/tab-line.js +40 -0
- package/src/write/draw/tempo.js +45 -0
- package/src/write/draw/text.js +71 -0
- package/src/write/draw/tie.js +97 -0
- package/src/write/draw/triplet.js +46 -0
- package/src/write/draw/voice.js +102 -0
- package/src/write/format-jazz-chord.js +15 -0
- package/src/write/free-text.js +41 -0
- package/src/write/get-font-and-attr.js +37 -0
- package/src/write/get-text-size.js +56 -0
- package/src/write/highlight.js +11 -0
- package/src/write/layout/VoiceElements.js +121 -0
- package/src/write/layout/beam.js +213 -0
- package/src/write/layout/get-left-edge-of-staff.js +56 -0
- package/src/write/layout/getBarYAt.js +6 -0
- package/src/write/layout/layout.js +94 -0
- package/src/write/layout/setUpperAndLowerElements.js +232 -0
- package/src/write/layout/staffGroup.js +146 -0
- package/src/write/layout/triplet.js +75 -0
- package/src/write/layout/voice.js +137 -0
- package/src/write/selection.js +188 -70
- package/src/write/separator.js +10 -0
- package/src/write/set-class.js +21 -0
- package/src/write/subtitle.js +12 -0
- package/src/write/svg.js +95 -43
- package/src/write/top-text.js +54 -0
- package/src/write/unhighlight.js +11 -0
- package/temp.txt +17 -0
- package/test.js +27 -64
- package/types/index.d.ts +1095 -0
- package/version.js +1 -1
- package/.babelrc +0 -5
- package/.eslintrc +0 -3
- package/.gitmodules +0 -3
- package/abcjs-midi.css +0 -166
- package/build-utils/loadPresets.js +0 -14
- package/build-utils/presets/webpack.analyze.js +0 -6
- package/build-utils/presets/webpack.optimize.js +0 -30
- package/build-utils/webpack.development.js +0 -14
- package/build-utils/webpack.production.js +0 -35
- package/deploy-docs.sh +0 -25
- package/docs/README.md +0 -33
- package/fix-versions.sh +0 -23
- package/mei.js +0 -43
- package/midi.js +0 -62
- package/src/api/abc_tunebook_midi.js +0 -116
- package/src/midi/abc_midi_controls.js +0 -701
- package/src/midi/abc_midi_flattener.js +0 -1119
- package/src/midi/abc_midi_js_preparer.js +0 -243
- package/src/midi/abc_midi_sequencer.js +0 -401
- package/src/midi/abc_midi_ui_generator.js +0 -86
- package/src/plugin/abc_plugin_midi.js +0 -220
- package/src/synth/images/loop.svg +0 -61
- package/src/synth/images/pause.svg +0 -6
- package/src/synth/images/play.svg +0 -5
- package/src/transform/abc2abc_write.js +0 -395
- package/static-wrappers/basic.js +0 -2
- package/static-wrappers/midi.js +0 -2
- package/static-wrappers/plugin-midi.js +0 -6
- package/static-wrappers/plugin.js +0 -6
- package/webpack.config.js +0 -29
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// abc_parse_book.js: parses a string representing ABC Music Notation into a usable internal structure.
|
|
2
|
+
|
|
3
|
+
var parseCommon = require('./abc_common');
|
|
4
|
+
|
|
5
|
+
var bookParser = function(book) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var directives = "";
|
|
9
|
+
book = parseCommon.strip(book);
|
|
10
|
+
var tuneStrings = book.split("\nX:");
|
|
11
|
+
// Put back the X: that we lost when splitting the tunes.
|
|
12
|
+
for (var i = 1; i < tuneStrings.length; i++)
|
|
13
|
+
tuneStrings[i] = "X:" + tuneStrings[i];
|
|
14
|
+
// Keep track of the character position each tune starts with.
|
|
15
|
+
var pos = 0;
|
|
16
|
+
var tunes = [];
|
|
17
|
+
parseCommon.each(tuneStrings, function(tune) {
|
|
18
|
+
tunes.push({ abc: tune, startPos: pos});
|
|
19
|
+
pos += tune.length + 1; // We also lost a newline when splitting, so count that.
|
|
20
|
+
});
|
|
21
|
+
if (tunes.length > 1 && !parseCommon.startsWith(tunes[0].abc, 'X:')) { // If there is only one tune, the X: might be missing, otherwise assume the top of the file is "intertune"
|
|
22
|
+
// There could be file-wide directives in this, if so, we need to insert it into each tune. We can probably get away with
|
|
23
|
+
// just looking for file-wide directives here (before the first tune) and inserting them at the bottom of each tune, since
|
|
24
|
+
// the tune is parsed all at once. The directives will be seen before the engraver begins processing.
|
|
25
|
+
var dir = tunes.shift();
|
|
26
|
+
var arrDir = dir.abc.split('\n');
|
|
27
|
+
parseCommon.each(arrDir, function(line) {
|
|
28
|
+
if (parseCommon.startsWith(line, '%%'))
|
|
29
|
+
directives += line + '\n';
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
var header = directives;
|
|
33
|
+
|
|
34
|
+
// Now, the tune ends at a blank line, so truncate it if needed. There may be "intertune" stuff.
|
|
35
|
+
parseCommon.each(tunes, function(tune) {
|
|
36
|
+
var end = tune.abc.indexOf('\n\n');
|
|
37
|
+
if (end > 0)
|
|
38
|
+
tune.abc = tune.abc.substring(0, end);
|
|
39
|
+
tune.pure = tune.abc;
|
|
40
|
+
tune.abc = directives + tune.abc;
|
|
41
|
+
|
|
42
|
+
// for the user's convenience, parse and store the title separately. The title is between the first T: and the next \n
|
|
43
|
+
tune.title = "";
|
|
44
|
+
var title = tune.pure.split("T:");
|
|
45
|
+
if (title.length > 1) {
|
|
46
|
+
title = title[1].split("\n");
|
|
47
|
+
tune.title = parseCommon.strip(title[0]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// for the user's convenience, parse and store the id separately. The id is between the first X: and the next \n
|
|
51
|
+
var id = tune.pure.substring(2, tune.pure.indexOf("\n"));
|
|
52
|
+
tune.id = parseCommon.strip(id);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
header: header,
|
|
57
|
+
tunes: tunes
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
module.exports = bookParser;
|
|
62
|
+
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
// Copyright (C) 2010-2020 Paul Rosen (paul at paulrosen dot net)
|
|
2
|
-
//
|
|
3
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
4
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
5
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
6
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
-
//
|
|
8
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
-
//
|
|
10
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
11
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
12
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
13
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
14
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
15
|
-
|
|
16
1
|
var parseCommon = require('./abc_common');
|
|
17
2
|
|
|
18
3
|
var parseDirective = {};
|
|
@@ -23,11 +8,13 @@ var parseDirective = {};
|
|
|
23
8
|
var warn;
|
|
24
9
|
var multilineVars;
|
|
25
10
|
var tune;
|
|
26
|
-
|
|
11
|
+
var tuneBuilder;
|
|
12
|
+
parseDirective.initialize = function(tokenizer_, warn_, multilineVars_, tune_, tuneBuilder_) {
|
|
27
13
|
tokenizer = tokenizer_;
|
|
28
14
|
warn = warn_;
|
|
29
15
|
multilineVars = multilineVars_;
|
|
30
16
|
tune = tune_;
|
|
17
|
+
tuneBuilder = tuneBuilder_;
|
|
31
18
|
initializeFonts();
|
|
32
19
|
};
|
|
33
20
|
|
|
@@ -52,6 +39,9 @@ var parseDirective = {};
|
|
|
52
39
|
tune.formatting.footerfont = { face: "\"Times New Roman\"", size: 12, weight: "normal", style: "normal", decoration: "none" };
|
|
53
40
|
tune.formatting.headerfont = { face: "\"Times New Roman\"", size: 12, weight: "normal", style: "normal", decoration: "none" };
|
|
54
41
|
tune.formatting.voicefont = { face: "\"Times New Roman\"", size: 13, weight: "bold", style: "normal", decoration: "none" };
|
|
42
|
+
tune.formatting.tablabelfont = { face: "\"Trebuchet MS\"", size: 16, weight: "normal", style: "normal", decoration: "none" };
|
|
43
|
+
tune.formatting.tabnumberfont = { face: "\"Arial\"", size: 11, weight: "normal", style: "normal", decoration: "none" };
|
|
44
|
+
tune.formatting.tabgracefont = { face: "\"Arial\"", size: 8, weight: "normal", style: "normal", decoration: "none" };
|
|
55
45
|
|
|
56
46
|
// these are the default fonts for these element types. In the printer, these fonts might change as the tune progresses.
|
|
57
47
|
tune.formatting.annotationfont = multilineVars.annotationfont;
|
|
@@ -67,7 +57,7 @@ var parseDirective = {};
|
|
|
67
57
|
tune.formatting.wordsfont = multilineVars.wordsfont;
|
|
68
58
|
}
|
|
69
59
|
|
|
70
|
-
var fontTypeCanHaveBox = { gchordfont: true, measurefont: true, partsfont: true };
|
|
60
|
+
var fontTypeCanHaveBox = { gchordfont: true, measurefont: true, partsfont: true, annotationfont: true, composerfont: true, historyfont: true, infofont: true, subtitlefont: true, textfont: true, titlefont: true, voicefont: true };
|
|
71
61
|
|
|
72
62
|
var fontTranslation = function(fontFace) {
|
|
73
63
|
// This translates Postscript fonts for a web alternative.
|
|
@@ -349,6 +339,74 @@ var parseDirective = {};
|
|
|
349
339
|
tune.formatting.scale = num;
|
|
350
340
|
|
|
351
341
|
};
|
|
342
|
+
// starts at 35
|
|
343
|
+
var drumNames = [
|
|
344
|
+
"acoustic-bass-drum",
|
|
345
|
+
"bass-drum-1",
|
|
346
|
+
"side-stick",
|
|
347
|
+
"acoustic-snare",
|
|
348
|
+
"hand-clap",
|
|
349
|
+
"electric-snare",
|
|
350
|
+
"low-floor-tom",
|
|
351
|
+
"closed-hi-hat",
|
|
352
|
+
"high-floor-tom",
|
|
353
|
+
"pedal-hi-hat",
|
|
354
|
+
"low-tom",
|
|
355
|
+
"open-hi-hat",
|
|
356
|
+
"low-mid-tom",
|
|
357
|
+
"hi-mid-tom",
|
|
358
|
+
"crash-cymbal-1",
|
|
359
|
+
"high-tom",
|
|
360
|
+
"ride-cymbal-1",
|
|
361
|
+
"chinese-cymbal",
|
|
362
|
+
"ride-bell",
|
|
363
|
+
"tambourine",
|
|
364
|
+
"splash-cymbal",
|
|
365
|
+
"cowbell",
|
|
366
|
+
"crash-cymbal-2",
|
|
367
|
+
"vibraslap",
|
|
368
|
+
"ride-cymbal-2",
|
|
369
|
+
"hi-bongo",
|
|
370
|
+
"low-bongo",
|
|
371
|
+
"mute-hi-conga",
|
|
372
|
+
"open-hi-conga",
|
|
373
|
+
"low-conga",
|
|
374
|
+
"high-timbale",
|
|
375
|
+
"low-timbale",
|
|
376
|
+
"high-agogo",
|
|
377
|
+
"low-agogo",
|
|
378
|
+
"cabasa",
|
|
379
|
+
"maracas",
|
|
380
|
+
"short-whistle",
|
|
381
|
+
"long-whistle",
|
|
382
|
+
"short-guiro",
|
|
383
|
+
"long-guiro",
|
|
384
|
+
"claves",
|
|
385
|
+
"hi-wood-block",
|
|
386
|
+
"low-wood-block",
|
|
387
|
+
"mute-cuica",
|
|
388
|
+
"open-cuica",
|
|
389
|
+
"mute-triangle",
|
|
390
|
+
"open-triangle",
|
|
391
|
+
];
|
|
392
|
+
|
|
393
|
+
var interpretPercMap = function(restOfString) {
|
|
394
|
+
var tokens = restOfString.split(/\s+/); // Allow multiple spaces.
|
|
395
|
+
if (tokens.length !== 2 && tokens.length !== 3)
|
|
396
|
+
return { error: 'Expected parameters "abc-note", "drum-sound", and optionally "note-head"'};
|
|
397
|
+
var key = tokens[0];
|
|
398
|
+
// The percussion sound can either be a MIDI number or a drum name. If it is not a number then check for a name.
|
|
399
|
+
var pitch = parseInt(tokens[1], 10);
|
|
400
|
+
if ((isNaN(pitch) || pitch < 35 || pitch > 81) && tokens[1]) {
|
|
401
|
+
pitch = drumNames.indexOf(tokens[1].toLowerCase()) + 35;
|
|
402
|
+
}
|
|
403
|
+
if ((isNaN(pitch) || pitch < 35 || pitch > 81))
|
|
404
|
+
return { error: 'Expected drum name, received "' + tokens[1] + '"' };
|
|
405
|
+
var value = { sound: pitch };
|
|
406
|
+
if (tokens.length === 3)
|
|
407
|
+
value.noteHead = tokens[2];
|
|
408
|
+
return { key: key, value: value };
|
|
409
|
+
};
|
|
352
410
|
|
|
353
411
|
var getRequiredMeasurement = function(cmd, tokens) {
|
|
354
412
|
var points = tokenizer.getMeasurement(tokens);
|
|
@@ -459,10 +517,6 @@ var parseDirective = {};
|
|
|
459
517
|
var midiCmdParam5Integer = [
|
|
460
518
|
"drone"
|
|
461
519
|
];
|
|
462
|
-
var midiCmdParam1IntegerOptionalOctave = [
|
|
463
|
-
"bassprog",
|
|
464
|
-
"chordprog"
|
|
465
|
-
];
|
|
466
520
|
var midiCmdParam1String1Integer = [
|
|
467
521
|
"portamento"
|
|
468
522
|
];
|
|
@@ -618,8 +672,8 @@ var parseDirective = {};
|
|
|
618
672
|
}
|
|
619
673
|
}
|
|
620
674
|
|
|
621
|
-
if (
|
|
622
|
-
|
|
675
|
+
if (tuneBuilder.hasBeginMusic())
|
|
676
|
+
tuneBuilder.appendElement('midi', -1, -1, { cmd: midi_cmd, params: midi_params });
|
|
623
677
|
else {
|
|
624
678
|
if (tune.formatting['midi'] === undefined)
|
|
625
679
|
tune.formatting['midi'] = {};
|
|
@@ -659,6 +713,7 @@ var parseDirective = {};
|
|
|
659
713
|
restOfString = tokenizer.stripComment(restOfString);
|
|
660
714
|
var cmd = tokens.shift().token.toLowerCase();
|
|
661
715
|
var scratch = "";
|
|
716
|
+
var line;
|
|
662
717
|
switch (cmd)
|
|
663
718
|
{
|
|
664
719
|
// The following directives were added to abc_parser_lint, but haven't been implemented here.
|
|
@@ -671,7 +726,6 @@ var parseDirective = {};
|
|
|
671
726
|
// exprabove: { type: "boolean", optional: true },
|
|
672
727
|
// exprbelow: { type: "boolean", optional: true },
|
|
673
728
|
// gchordbox: { type: "boolean", optional: true },
|
|
674
|
-
// graceslurs: { type: "boolean", optional: true },
|
|
675
729
|
// gracespacebefore: { type: "number", optional: true },
|
|
676
730
|
// gracespaceinside: { type: "number", optional: true },
|
|
677
731
|
// gracespaceafter: { type: "number", optional: true },
|
|
@@ -691,10 +745,26 @@ var parseDirective = {};
|
|
|
691
745
|
// titleformat: { type: "string", optional: true },
|
|
692
746
|
case "bagpipes":tune.formatting.bagpipes = true;break;
|
|
693
747
|
case "flatbeams":tune.formatting.flatbeams = true;break;
|
|
748
|
+
case "jazzchords":tune.formatting.jazzchords = true;break;
|
|
694
749
|
case "landscape":multilineVars.landscape = true;break;
|
|
695
750
|
case "papersize":multilineVars.papersize = restOfString;break;
|
|
696
|
-
case "
|
|
697
|
-
|
|
751
|
+
case "graceslurs":
|
|
752
|
+
if (tokens.length !== 1)
|
|
753
|
+
return "Directive graceslurs requires one parameter: 0 or 1";
|
|
754
|
+
if (tokens[0].token === '0' || tokens[0].token === 'false')
|
|
755
|
+
tune.formatting.graceSlurs = false;
|
|
756
|
+
else if (tokens[0].token === '1' || tokens[0].token === 'true')
|
|
757
|
+
tune.formatting.graceSlurs = true;
|
|
758
|
+
else
|
|
759
|
+
return "Directive graceslurs requires one parameter: 0 or 1 (received " + tokens[0].token + ')';
|
|
760
|
+
break;
|
|
761
|
+
case "stretchlast":
|
|
762
|
+
var sl = parseStretchLast(tokens);
|
|
763
|
+
if (sl.value !== undefined)
|
|
764
|
+
tune.formatting.stretchlast = sl.value;
|
|
765
|
+
if (sl.error)
|
|
766
|
+
return sl.error;
|
|
767
|
+
break;
|
|
698
768
|
case "titlecaps":multilineVars.titlecaps = true;break;
|
|
699
769
|
case "titleleft":tune.formatting.titleleft = true;break;
|
|
700
770
|
case "measurebox":tune.formatting.measurebox = true;break;
|
|
@@ -734,21 +804,21 @@ var parseDirective = {};
|
|
|
734
804
|
var voiceScale = tokens.shift();
|
|
735
805
|
if (multilineVars.currentVoice) {
|
|
736
806
|
multilineVars.currentVoice.scale = voiceScale.floatt;
|
|
737
|
-
|
|
807
|
+
tuneBuilder.changeVoiceScale(multilineVars.currentVoice.scale);
|
|
738
808
|
}
|
|
739
809
|
return null;
|
|
740
810
|
case "vskip":
|
|
741
811
|
var vskip = Math.round(getRequiredMeasurement(cmd, tokens));
|
|
742
812
|
if (vskip.error)
|
|
743
813
|
return vskip.error;
|
|
744
|
-
|
|
814
|
+
tuneBuilder.addSpacing(vskip);
|
|
745
815
|
return null;
|
|
746
816
|
case "scale":
|
|
747
817
|
setScale(cmd, tokens);
|
|
748
818
|
break;
|
|
749
819
|
case "sep":
|
|
750
820
|
if (tokens.length === 0)
|
|
751
|
-
|
|
821
|
+
tuneBuilder.addSeparator(14,14,85, { startChar: multilineVars.iChar, endChar: multilineVars.iChar+5}); // If no parameters are given, then there is a default size.
|
|
752
822
|
else {
|
|
753
823
|
var points = tokenizer.getMeasurement(tokens);
|
|
754
824
|
if (points.used === 0)
|
|
@@ -764,7 +834,7 @@ var parseDirective = {};
|
|
|
764
834
|
if (points.used === 0 || tokens.length !== 0)
|
|
765
835
|
return "Directive \"" + cmd + "\" requires 3 numbers: space above, space below, length of line";
|
|
766
836
|
var lenLine = points.value;
|
|
767
|
-
|
|
837
|
+
tuneBuilder.addSeparator(spaceAbove, spaceBelow, lenLine, { startChar: multilineVars.iChar, endChar: multilineVars.iChar+restOfString.length});
|
|
768
838
|
}
|
|
769
839
|
break;
|
|
770
840
|
case "barsperstaff":
|
|
@@ -804,16 +874,28 @@ var parseDirective = {};
|
|
|
804
874
|
if (tokens.length !== 1 || tokens[0].type !== 'number') {
|
|
805
875
|
return 'Directive setbarnb requires a number as a parameter.';
|
|
806
876
|
}
|
|
807
|
-
multilineVars.currBarNumber =
|
|
877
|
+
multilineVars.currBarNumber = tuneBuilder.setBarNumberImmediate(tokens[0].intt);
|
|
808
878
|
break;
|
|
809
879
|
case "begintext":
|
|
810
|
-
|
|
880
|
+
var textBlock = '';
|
|
881
|
+
line = tokenizer.nextLine();
|
|
882
|
+
while(line && line.indexOf('%%endtext') !== 0) {
|
|
883
|
+
if (parseCommon.startsWith(line, "%%"))
|
|
884
|
+
textBlock += line.substring(2) + "\n";
|
|
885
|
+
else
|
|
886
|
+
textBlock += line + "\n";
|
|
887
|
+
line = tokenizer.nextLine();
|
|
888
|
+
}
|
|
889
|
+
tuneBuilder.addText(textBlock, { startChar: multilineVars.iChar, endChar: multilineVars.iChar+textBlock.length+7});
|
|
811
890
|
break;
|
|
812
891
|
case "continueall":
|
|
813
892
|
multilineVars.continueall = true;
|
|
814
893
|
break;
|
|
815
894
|
case "beginps":
|
|
816
|
-
|
|
895
|
+
line = tokenizer.nextLine();
|
|
896
|
+
while(line && line.indexOf('%%endps') !== 0) {
|
|
897
|
+
tokenizer.nextLine();
|
|
898
|
+
}
|
|
817
899
|
warn("Postscript ignored", str, 0);
|
|
818
900
|
break;
|
|
819
901
|
case "deco":
|
|
@@ -823,11 +905,11 @@ var parseDirective = {};
|
|
|
823
905
|
break;
|
|
824
906
|
case "text":
|
|
825
907
|
var textstr = tokenizer.translateString(restOfString);
|
|
826
|
-
|
|
908
|
+
tuneBuilder.addText(parseDirective.parseFontChangeLine(textstr), { startChar: multilineVars.iChar, endChar: multilineVars.iChar+restOfString.length+7});
|
|
827
909
|
break;
|
|
828
910
|
case "center":
|
|
829
911
|
var centerstr = tokenizer.translateString(restOfString);
|
|
830
|
-
|
|
912
|
+
tuneBuilder.addCentered(parseDirective.parseFontChangeLine(centerstr));
|
|
831
913
|
break;
|
|
832
914
|
case "font":
|
|
833
915
|
// don't need to do anything for this; it is a useless directive
|
|
@@ -891,8 +973,8 @@ var parseDirective = {};
|
|
|
891
973
|
multilineVars.staves.push({index: multilineVars.staves.length, numVoices: 0});
|
|
892
974
|
}
|
|
893
975
|
var staff = parseCommon.last(multilineVars.staves);
|
|
894
|
-
if (bracket !== undefined) staff.bracket = bracket;
|
|
895
|
-
if (brace !== undefined) staff.brace = brace;
|
|
976
|
+
if (bracket !== undefined && staff.bracket === undefined) staff.bracket = bracket;
|
|
977
|
+
if (brace !== undefined && staff.brace === undefined) staff.brace = brace;
|
|
896
978
|
if (continueBar) staff.connectBarLines = 'end';
|
|
897
979
|
if (multilineVars.voices[id] === undefined) {
|
|
898
980
|
multilineVars.voices[id] = {staffNum: staff.index, index: staff.numVoices};
|
|
@@ -977,7 +1059,7 @@ var parseDirective = {};
|
|
|
977
1059
|
|
|
978
1060
|
case "newpage":
|
|
979
1061
|
var pgNum = tokenizer.getInt(restOfString);
|
|
980
|
-
|
|
1062
|
+
tuneBuilder.addNewPage(pgNum.digits === 0 ? -1 : pgNum.value);
|
|
981
1063
|
break;
|
|
982
1064
|
|
|
983
1065
|
case "abc":
|
|
@@ -989,7 +1071,7 @@ var parseDirective = {};
|
|
|
989
1071
|
case "-version":
|
|
990
1072
|
case "-charset":
|
|
991
1073
|
var subCmd = arr.shift();
|
|
992
|
-
|
|
1074
|
+
tuneBuilder.addMetaText(cmd+subCmd, arr.join(' '), { startChar: multilineVars.iChar, endChar: multilineVars.iChar+restOfString.length+5});
|
|
993
1075
|
break;
|
|
994
1076
|
default:
|
|
995
1077
|
return "Unknown directive: " + cmd+arr[0];
|
|
@@ -1012,7 +1094,7 @@ var parseDirective = {};
|
|
|
1012
1094
|
if (footerArr.length > 3)
|
|
1013
1095
|
warn("Too many tabs in " + cmd + ": " + footerArr.length + " found.", restOfString, 0);
|
|
1014
1096
|
|
|
1015
|
-
|
|
1097
|
+
tuneBuilder.addMetaTextObj(cmd, footer, { startChar: multilineVars.iChar, endChar: multilineVars.iChar+str.length});
|
|
1016
1098
|
break;
|
|
1017
1099
|
|
|
1018
1100
|
case "midi":
|
|
@@ -1024,9 +1106,18 @@ var parseDirective = {};
|
|
|
1024
1106
|
else
|
|
1025
1107
|
parseMidiCommand(midi, tune, restOfString);
|
|
1026
1108
|
break;
|
|
1109
|
+
case "percmap":
|
|
1110
|
+
var percmap = interpretPercMap(restOfString);
|
|
1111
|
+
if (percmap.error)
|
|
1112
|
+
warn(percmap.error, str, 8);
|
|
1113
|
+
else {
|
|
1114
|
+
if (!tune.formatting.percmap)
|
|
1115
|
+
tune.formatting.percmap = {};
|
|
1116
|
+
tune.formatting.percmap[percmap.key] = percmap.value;
|
|
1117
|
+
}
|
|
1118
|
+
break;
|
|
1027
1119
|
|
|
1028
1120
|
case "map":
|
|
1029
|
-
case "percmap":
|
|
1030
1121
|
case "playtempo":
|
|
1031
1122
|
case "auquality":
|
|
1032
1123
|
case "continuous":
|
|
@@ -1064,6 +1155,9 @@ var parseDirective = {};
|
|
|
1064
1155
|
case "vocalfont":
|
|
1065
1156
|
case "wordsfont":
|
|
1066
1157
|
case "annotationfont":
|
|
1158
|
+
case "tablabelfont":
|
|
1159
|
+
case "tabnumberfont":
|
|
1160
|
+
case "tabgracefont":
|
|
1067
1161
|
getChangingFont(cmd, tokens, value);
|
|
1068
1162
|
break;
|
|
1069
1163
|
case "scale":
|
|
@@ -1077,12 +1171,41 @@ var parseDirective = {};
|
|
|
1077
1171
|
case "freegchord":
|
|
1078
1172
|
scratch = addMultilineVarBool('freegchord', cmd, tokens);
|
|
1079
1173
|
if (scratch !== null) warn(scratch);
|
|
1174
|
+
break;
|
|
1175
|
+
case "fontboxpadding":
|
|
1176
|
+
if (tokens.length !== 1 || tokens[0].type !== 'number')
|
|
1177
|
+
warn("Directive \"" + cmd + "\" requires a number as a parameter.");
|
|
1178
|
+
tune.formatting.fontboxpadding = tokens[0].floatt;
|
|
1179
|
+
break;
|
|
1180
|
+
case "stretchlast":
|
|
1181
|
+
var sl = parseStretchLast(tokens);
|
|
1182
|
+
if (sl.value !== undefined)
|
|
1183
|
+
tune.formatting.stretchlast = sl.value;
|
|
1184
|
+
if (sl.error)
|
|
1185
|
+
return sl.error;
|
|
1186
|
+
break;
|
|
1080
1187
|
default:
|
|
1081
1188
|
warn("Formatting directive unrecognized: ", cmd, 0);
|
|
1082
1189
|
}
|
|
1083
1190
|
}
|
|
1084
1191
|
}
|
|
1085
1192
|
};
|
|
1193
|
+
|
|
1194
|
+
function parseStretchLast(tokens) {
|
|
1195
|
+
if (tokens.length === 0)
|
|
1196
|
+
return { value: 1 }; // if there is no value then the presence of this is the same as "true"
|
|
1197
|
+
else if (tokens.length === 1) {
|
|
1198
|
+
if (tokens[0].type === "number") {
|
|
1199
|
+
if (tokens[0].floatt >= 0 || tokens[0].floatt <= 1)
|
|
1200
|
+
return {value: tokens[0].floatt};
|
|
1201
|
+
} else if (tokens[0].token === 'false') {
|
|
1202
|
+
return { value: 0 };
|
|
1203
|
+
} else if (tokens[0].token === 'true') {
|
|
1204
|
+
return {value: 1};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
return { error: "Directive stretchlast requires zero or one parameter: false, true, or number between 0 and 1 (received " + tokens[0].token + ')' };
|
|
1208
|
+
}
|
|
1086
1209
|
})();
|
|
1087
1210
|
|
|
1088
1211
|
module.exports = parseDirective;
|