abcjs 6.2.3 → 6.4.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/README.md +8 -0
- package/RELEASE.md +84 -1
- package/dist/abcjs-basic-min.js +2 -2
- package/dist/abcjs-basic.js +1775 -1034
- package/dist/abcjs-basic.js.map +1 -1
- package/dist/abcjs-plugin-min.js +2 -2
- package/index.js +3 -0
- package/package.json +1 -1
- package/plugin.js +1 -1
- package/src/api/abc_tablatures.js +48 -13
- package/src/api/tune-metrics.js +18 -0
- package/src/data/abc_tune.js +13 -2
- package/src/edit/abc_editarea.js +4 -1
- package/src/parse/abc_parse.js +2 -0
- package/src/parse/abc_parse_directive.js +23 -16
- package/src/parse/abc_parse_header.js +22 -19
- package/src/parse/abc_tokenizer.js +72 -7
- package/src/parse/tune-builder.js +60 -1
- package/src/synth/abc_midi_flattener.js +40 -462
- package/src/synth/abc_midi_sequencer.js +25 -10
- package/src/synth/chord-track.js +562 -0
- package/src/synth/create-note-map.js +2 -1
- package/src/synth/create-synth.js +91 -42
- package/src/synth/synth-controller.js +6 -2
- package/src/tablatures/instruments/string-patterns.js +11 -0
- package/src/tablatures/instruments/{violin/violin-patterns.js → tab-string-patterns.js} +6 -6
- package/src/tablatures/instruments/{violin/tab-violin.js → tab-string.js} +13 -11
- package/src/tablatures/tab-absolute-elements.js +16 -7
- package/src/tablatures/tab-renderer.js +22 -9
- package/src/test/abc_parser_lint.js +14 -12
- package/src/write/creation/abstract-engraver.js +6 -2
- package/src/write/creation/add-chord.js +102 -82
- package/src/write/creation/add-text-if.js +2 -2
- package/src/write/creation/decoration.js +16 -9
- package/src/write/creation/elements/bottom-text.js +62 -47
- package/src/write/creation/elements/rich-text.js +51 -0
- package/src/write/creation/elements/tie-element.js +23 -0
- package/src/write/creation/elements/top-text.js +37 -11
- package/src/write/creation/glyphs.js +1 -1
- package/src/write/draw/absolute.js +4 -1
- package/src/write/draw/draw.js +13 -4
- package/src/write/draw/non-music.js +3 -1
- package/src/write/draw/relative.js +1 -1
- package/src/write/draw/tempo.js +1 -1
- package/src/write/draw/text.js +10 -0
- package/src/write/engraver-controller.js +62 -17
- package/src/write/helpers/classes.js +1 -1
- package/src/write/helpers/get-font-and-attr.js +8 -1
- package/src/write/helpers/get-text-size.js +8 -1
- package/src/write/interactive/create-analysis.js +50 -0
- package/src/write/interactive/find-selectable-element.js +24 -0
- package/src/write/interactive/selection.js +5 -45
- package/src/write/layout/layout-in-grid.js +83 -0
- package/src/write/layout/layout.js +29 -24
- package/src/write/layout/set-upper-and-lower-elements.js +2 -0
- package/src/write/layout/staff-group.js +2 -2
- package/src/write/layout/voice-elements.js +1 -1
- package/src/write/layout/voice.js +1 -1
- package/src/write/renderer.js +3 -0
- package/src/write/svg.js +30 -0
- package/temp.txt +3 -0
- package/types/index.d.ts +142 -38
- package/version.js +1 -1
- package/.github/workflows/tests.yml +0 -29
- package/abc2xml_239/abc2xml.html +0 -769
- package/abc2xml_239/abc2xml.py +0 -2248
- package/abc2xml_239/abc2xml_changelog.html +0 -124
- package/abc2xml_239/lazy-river.abc +0 -26
- package/abc2xml_239/lazy-river.xml +0 -3698
- package/abc2xml_239/mean-to-me.abc +0 -22
- package/abc2xml_239/mean-to-me.xml +0 -2954
- package/abc2xml_239/pyparsing.py +0 -3672
- package/abc2xml_239/pyparsing.pyc +0 -0
- package/src/tablatures/instruments/guitar/guitar-patterns.js +0 -23
- package/src/tablatures/instruments/guitar/tab-guitar.js +0 -48
|
@@ -26,13 +26,15 @@ function CreateSynth() {
|
|
|
26
26
|
self.audioBuffers = []; // cache of the buffers so starting play can be fast.
|
|
27
27
|
self.duration = undefined; // the duration of the tune in seconds.
|
|
28
28
|
self.isRunning = false; // whether there is currently a sound buffer running.
|
|
29
|
-
|
|
29
|
+
self.options = undefined
|
|
30
|
+
self.pickupLength = 0
|
|
30
31
|
|
|
31
32
|
// Load and cache all needed sounds
|
|
32
33
|
self.init = function(options) {
|
|
33
34
|
if (!options)
|
|
34
35
|
options = {};
|
|
35
|
-
|
|
36
|
+
if (options.options)
|
|
37
|
+
self.options = options.options
|
|
36
38
|
registerAudioContext(options.audioContext); // This works no matter what - if there is already an ac it is a nop; if the context is not passed in, then it creates one.
|
|
37
39
|
var startTime = activeAudioContext().currentTime;
|
|
38
40
|
self.debugCallback = options.debugCallback;
|
|
@@ -115,6 +117,7 @@ function CreateSynth() {
|
|
|
115
117
|
var meter = options.visualObj.getMeterFraction();
|
|
116
118
|
if (meter.den)
|
|
117
119
|
self.meterSize = options.visualObj.getMeterFraction().num / options.visualObj.getMeterFraction().den;
|
|
120
|
+
self.pickupLength = options.visualObj.getPickupLength()
|
|
118
121
|
} else if (options.sequence)
|
|
119
122
|
self.flattened = options.sequence;
|
|
120
123
|
else
|
|
@@ -124,6 +127,7 @@ function CreateSynth() {
|
|
|
124
127
|
self.sequenceCallback = params.sequenceCallback;
|
|
125
128
|
self.callbackContext = params.callbackContext;
|
|
126
129
|
self.onEnded = params.onEnded;
|
|
130
|
+
self.meterFraction = options.visualObj.getMeterFraction();
|
|
127
131
|
|
|
128
132
|
var allNotes = {};
|
|
129
133
|
var cached = [];
|
|
@@ -136,18 +140,19 @@ function CreateSynth() {
|
|
|
136
140
|
if (event.pitch !== undefined) {
|
|
137
141
|
var pitchNumber = event.pitch;
|
|
138
142
|
var noteName = pitchToNoteName[pitchNumber];
|
|
143
|
+
var inst = event.instrument !== undefined ? instrumentIndexToName[event.instrument] : currentInstrument
|
|
139
144
|
if (noteName) {
|
|
140
|
-
if (!allNotes[
|
|
141
|
-
allNotes[
|
|
142
|
-
if (!soundsCache[
|
|
143
|
-
allNotes[
|
|
145
|
+
if (!allNotes[inst])
|
|
146
|
+
allNotes[inst] = {};
|
|
147
|
+
if (!soundsCache[inst] || !soundsCache[inst][noteName])
|
|
148
|
+
allNotes[inst][noteName] = true;
|
|
144
149
|
else {
|
|
145
|
-
var label2 =
|
|
150
|
+
var label2 = inst+":"+noteName
|
|
146
151
|
if (cached.indexOf(label2) < 0)
|
|
147
152
|
cached.push(label2);
|
|
148
153
|
}
|
|
149
154
|
} else {
|
|
150
|
-
var label =
|
|
155
|
+
var label = inst+":"+noteName
|
|
151
156
|
console.log("Can't find note: ", pitchNumber, label);
|
|
152
157
|
if (errorNotes.indexOf(label) < 0)
|
|
153
158
|
errorNotes.push(label)
|
|
@@ -309,8 +314,10 @@ function CreateSynth() {
|
|
|
309
314
|
self.stop();
|
|
310
315
|
|
|
311
316
|
var noteMapTracks = createNoteMap(self.flattened);
|
|
312
|
-
|
|
313
|
-
|
|
317
|
+
|
|
318
|
+
if (self.options.swing)
|
|
319
|
+
addSwing(noteMapTracks, self.options.swing, self.meterFraction, self.pickupLength)
|
|
320
|
+
|
|
314
321
|
if (self.sequenceCallback)
|
|
315
322
|
self.sequenceCallback(noteMapTracks, self.callbackContext);
|
|
316
323
|
|
|
@@ -545,38 +552,80 @@ function CreateSynth() {
|
|
|
545
552
|
}
|
|
546
553
|
};
|
|
547
554
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
555
|
+
function addSwing(noteMapTracks, swing, meterFraction, pickupLength) {
|
|
556
|
+
|
|
557
|
+
// we can only swing in X/4 and X/8 meters.
|
|
558
|
+
if (meterFraction.den != 4 && meterFraction.den != 8)
|
|
559
|
+
return;
|
|
560
|
+
|
|
561
|
+
swing = parseFloat(swing);
|
|
562
|
+
|
|
563
|
+
// 50 (or less) is no swing,
|
|
564
|
+
if (isNaN(swing) || swing <= 50)
|
|
565
|
+
return;
|
|
566
|
+
|
|
567
|
+
// 66 is triplet swing 2:1, and
|
|
568
|
+
// 60 is swing with a ratio of 3:2.
|
|
569
|
+
// 75 is the maximum swing where the first eight is played as a dotted eight and the second as a sixteenth.
|
|
570
|
+
if (swing > 75)
|
|
571
|
+
swing = 75;
|
|
572
|
+
|
|
573
|
+
// convert the swing percentage to a percentage of increase for the first half of the beat
|
|
574
|
+
swing = swing/50 - 1;
|
|
575
|
+
|
|
576
|
+
// The volume of the swung notes is increased by this factor
|
|
577
|
+
// could be also in the settings. Try out values such 0.1, 0.2
|
|
578
|
+
var volumeIncrease = 0.0;
|
|
579
|
+
|
|
580
|
+
// the beatLength in X/8 meters
|
|
581
|
+
var beatLength = 0.25;
|
|
582
|
+
|
|
583
|
+
// in X/8 meters the 16s swing so the beatLength is halved
|
|
584
|
+
if (meterFraction.den === 8)
|
|
585
|
+
beatLength = beatLength/2;
|
|
586
|
+
|
|
587
|
+
// duration of a half beat
|
|
588
|
+
var halfbeatLength = beatLength/2;
|
|
589
|
+
|
|
590
|
+
// the extra duration of the first swung notes and the delay of the second notes
|
|
591
|
+
var swingDuration = halfbeatLength * swing;
|
|
592
|
+
|
|
593
|
+
for (var t = 0; t < noteMapTracks.length; t++) {
|
|
594
|
+
var track = noteMapTracks[t];
|
|
595
|
+
for (var i = 0; i < track.length; i++) {
|
|
596
|
+
var event = track[i];
|
|
597
|
+
if (
|
|
598
|
+
// is halfbeat
|
|
599
|
+
(event.start-pickupLength) % halfbeatLength == 0 && (event.start-pickupLength) % beatLength != 0
|
|
600
|
+
&& (
|
|
601
|
+
// the previous note is on the beat or before OR there is no previous note
|
|
602
|
+
i == 0
|
|
603
|
+
|| track[i-1].start <= track[i].start - halfbeatLength
|
|
604
|
+
)
|
|
605
|
+
&& (
|
|
606
|
+
// the next note is on the beat or after OR there is no next note
|
|
607
|
+
i == track.length - 1
|
|
608
|
+
|| track[i+1].start >= track[i].start + halfbeatLength
|
|
609
|
+
)
|
|
610
|
+
) {
|
|
611
|
+
var oldEventStart = event.start;
|
|
612
|
+
|
|
613
|
+
event.start += swingDuration;
|
|
614
|
+
|
|
615
|
+
// Increase volume of swung notes
|
|
616
|
+
event.volume *= 1 + volumeIncrease;
|
|
617
|
+
|
|
618
|
+
// if there is a previous note ending at the start of this note, extend its end
|
|
619
|
+
// and decrease its volume
|
|
620
|
+
if (i > 0 && track[i-1].end == oldEventStart) {
|
|
621
|
+
track[i-1].end = event.start;
|
|
622
|
+
track[i-1].volume *= 1 - volumeIncrease;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
580
629
|
}
|
|
581
630
|
|
|
582
631
|
module.exports = CreateSynth;
|
|
@@ -21,6 +21,10 @@ function SynthController() {
|
|
|
21
21
|
self.load = function (selector, cursorControl, visualOptions) {
|
|
22
22
|
if (!visualOptions)
|
|
23
23
|
visualOptions = {};
|
|
24
|
+
if (visualOptions.displayPlay === undefined)
|
|
25
|
+
visualOptions.displayPlay = true
|
|
26
|
+
if (visualOptions.displayProgress === undefined)
|
|
27
|
+
visualOptions.displayProgress = true
|
|
24
28
|
self.control = new CreateSynthControl(selector, {
|
|
25
29
|
loopHandler: visualOptions.displayLoop ? self.toggleLoop : undefined,
|
|
26
30
|
restartHandler: visualOptions.displayRestart ? self.restart : undefined,
|
|
@@ -41,7 +45,7 @@ function SynthController() {
|
|
|
41
45
|
self.setTune = function(visualObj, userAction, audioParams) {
|
|
42
46
|
self.visualObj = visualObj;
|
|
43
47
|
self.disable(false);
|
|
44
|
-
self.options = audioParams;
|
|
48
|
+
self.options = audioParams ? audioParams : {};
|
|
45
49
|
|
|
46
50
|
if (self.control) {
|
|
47
51
|
self.pause();
|
|
@@ -195,7 +199,7 @@ function SynthController() {
|
|
|
195
199
|
|
|
196
200
|
self._randomAccess = function (ev) {
|
|
197
201
|
var background = (ev.target.classList.contains('abcjs-midi-progress-indicator')) ? ev.target.parentNode : ev.target;
|
|
198
|
-
var percent = (ev.x - background.
|
|
202
|
+
var percent = (ev.x - background.getBoundingClientRect().left) / background.offsetWidth;
|
|
199
203
|
if (percent < 0)
|
|
200
204
|
percent = 0;
|
|
201
205
|
if (percent > 1)
|
|
@@ -265,6 +265,17 @@ StringPatterns.prototype.tabInfos = function (plugin) {
|
|
|
265
265
|
return '';
|
|
266
266
|
};
|
|
267
267
|
|
|
268
|
+
// MAE 27 Nov 2023
|
|
269
|
+
StringPatterns.prototype.suppress = function (plugin) {
|
|
270
|
+
var _super = plugin._super;
|
|
271
|
+
var suppress = _super.params.suppress;
|
|
272
|
+
if (suppress){
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
};
|
|
277
|
+
// MAE 27 Nov 2023 End
|
|
278
|
+
|
|
268
279
|
/**
|
|
269
280
|
* Common patterns for all string instruments
|
|
270
281
|
* @param {} plugin
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
var StringPatterns = require('
|
|
1
|
+
var StringPatterns = require('./string-patterns');
|
|
2
2
|
|
|
3
|
-
function
|
|
3
|
+
function TabStringPatterns(plugin, defaultTuning) {
|
|
4
4
|
this.tuning = plugin._super.params.tuning;
|
|
5
5
|
if (!this.tuning) {
|
|
6
|
-
this.tuning =
|
|
6
|
+
this.tuning = defaultTuning;
|
|
7
7
|
}
|
|
8
8
|
plugin.tuning = this.tuning;
|
|
9
9
|
this.strings = new StringPatterns(plugin);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
TabStringPatterns.prototype.notesToNumber = function (notes, graces) {
|
|
13
13
|
var converter = this.strings;
|
|
14
14
|
return converter.notesToNumber(notes, graces);
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
TabStringPatterns.prototype.stringToPitch = function (stringNumber) {
|
|
18
18
|
var converter = this.strings;
|
|
19
19
|
return converter.stringToPitch(stringNumber);
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
module.exports =
|
|
23
|
+
module.exports = TabStringPatterns;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
var StringTablature = require('
|
|
3
|
-
var TabCommon = require('
|
|
4
|
-
var TabRenderer = require('
|
|
5
|
-
var
|
|
2
|
+
var StringTablature = require('./string-tablature');
|
|
3
|
+
var TabCommon = require('../tab-common');
|
|
4
|
+
var TabRenderer = require('../tab-renderer');
|
|
5
|
+
var TabStringPatterns = require('./tab-string-patterns');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -11,18 +11,20 @@ var ViolinPatterns = require('./violin-patterns');
|
|
|
11
11
|
* @param {*} tuneNumber the parsed tune AST tree
|
|
12
12
|
* @param {*} params complementary args provided to Tablature Plugin
|
|
13
13
|
*/
|
|
14
|
-
Plugin.prototype.init = function (abcTune, tuneNumber, params) {
|
|
14
|
+
Plugin.prototype.init = function (abcTune, tuneNumber, params, staffNumber, tabSettings) {
|
|
15
15
|
var _super = new TabCommon(abcTune, tuneNumber, params);
|
|
16
16
|
this.abcTune = abcTune;
|
|
17
17
|
this._super = _super;
|
|
18
18
|
this.linePitch = 3;
|
|
19
|
-
this.nbLines =
|
|
20
|
-
this.isTabBig =
|
|
19
|
+
this.nbLines = tabSettings.defaultTuning.length;
|
|
20
|
+
this.isTabBig = tabSettings.isTabBig;
|
|
21
|
+
this.tabSymbolOffset = tabSettings.tabSymbolOffset;
|
|
21
22
|
this.capo = params.capo;
|
|
22
23
|
this.transpose = params.visualTranspose;
|
|
24
|
+
this.hideTabSymbol = params.hideTabSymbol;
|
|
23
25
|
this.tablature = new StringTablature(this.nbLines,
|
|
24
26
|
this.linePitch);
|
|
25
|
-
var semantics = new
|
|
27
|
+
var semantics = new TabStringPatterns(this, tabSettings.defaultTuning);
|
|
26
28
|
this.semantics = semantics;
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -38,8 +40,8 @@ function Plugin() {}
|
|
|
38
40
|
//
|
|
39
41
|
// Tablature plugin definition
|
|
40
42
|
//
|
|
41
|
-
var
|
|
42
|
-
return { name: '
|
|
43
|
+
var AbcStringTab = function () {
|
|
44
|
+
return { name: 'StringTab', tablature: Plugin };
|
|
43
45
|
};
|
|
44
46
|
|
|
45
|
-
module.exports =
|
|
47
|
+
module.exports = AbcStringTab;
|
|
@@ -60,13 +60,22 @@ function buildTabAbsolute(plugin, absX, relX) {
|
|
|
60
60
|
icon: tabIcon,
|
|
61
61
|
Ypos: tabYPos
|
|
62
62
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
|
|
63
|
+
|
|
64
|
+
// Offset the TAB symbol position if specified in the tab description
|
|
65
|
+
tabYPos += plugin.tabSymbolOffset;
|
|
66
|
+
|
|
67
|
+
// For tablature like whistle tab where you want the TAB symbol hidden
|
|
68
|
+
if (!plugin.hideTabSymbol){
|
|
69
|
+
|
|
70
|
+
var tabAbsolute = new AbsoluteElement(element, 0, 0, "symbol", 0);
|
|
71
|
+
tabAbsolute.x = absX;
|
|
72
|
+
var tabRelative = new RelativeElement(tabIcon, 0, 0, 7.5, "tab");
|
|
73
|
+
tabRelative.x = relX;
|
|
74
|
+
tabAbsolute.children.push(tabRelative);
|
|
75
|
+
if (tabAbsolute.abcelem.el_type == 'tab') {
|
|
76
|
+
tabRelative.pitch = tabYPos;
|
|
77
|
+
}
|
|
78
|
+
|
|
70
79
|
}
|
|
71
80
|
return tabAbsolute;
|
|
72
81
|
}
|
|
@@ -37,12 +37,24 @@ function buildTabName(self, dest) {
|
|
|
37
37
|
var controller = self.renderer.controller;
|
|
38
38
|
var textSize = controller.getTextSize;
|
|
39
39
|
var tabName = stringSemantics.tabInfos(self.plugin);
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
var suppress = stringSemantics.suppress(self.plugin);
|
|
41
|
+
var doDraw = true;
|
|
42
|
+
|
|
43
|
+
if (suppress){
|
|
44
|
+
doDraw = false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if (doDraw){
|
|
49
|
+
var size = textSize.calc(tabName, 'tablabelfont', 'text instrumentname');
|
|
50
|
+
dest.tabNameInfos = {
|
|
51
|
+
textSize: {height:size.height,width:size.width},
|
|
52
|
+
name: tabName
|
|
53
|
+
};
|
|
54
|
+
return size.height;
|
|
55
|
+
}
|
|
56
|
+
return 0
|
|
57
|
+
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
/**
|
|
@@ -230,8 +242,10 @@ TabRenderer.prototype.doLayout = function () {
|
|
|
230
242
|
if (ii > 0) tabVoice.duplicate = true;
|
|
231
243
|
var nameHeight = buildTabName(this, tabVoice) / spacing.STEP;
|
|
232
244
|
nameHeight = Math.max(nameHeight, 1) // If there is no label for the tab line, then there needs to be a little padding
|
|
233
|
-
|
|
234
|
-
staffGroup.
|
|
245
|
+
// This was pushing down the top staff by the tab label height
|
|
246
|
+
//staffGroup.staffs[this.staffIndex].top += nameHeight;
|
|
247
|
+
staffGroup.staffs[this.staffIndex].top += 1;
|
|
248
|
+
staffGroup.height += nameHeight;
|
|
235
249
|
tabVoice.staff = staffGroupInfos;
|
|
236
250
|
var tabVoiceIndex = voices.length
|
|
237
251
|
voices.splice(voices.length, 0, tabVoice);
|
|
@@ -242,5 +256,4 @@ TabRenderer.prototype.doLayout = function () {
|
|
|
242
256
|
linkStaffAndTabs(staffGroup.staffs); // crossreference tabs and staff
|
|
243
257
|
};
|
|
244
258
|
|
|
245
|
-
|
|
246
259
|
module.exports = TabRenderer;
|
|
@@ -51,18 +51,18 @@
|
|
|
51
51
|
var parseCommon = require('../parse/abc_common');
|
|
52
52
|
var JSONSchema = require('./jsonschema-b4');
|
|
53
53
|
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
var ParserLint = function() {
|
|
55
|
+
"use strict";
|
|
56
|
+
var decorationList = { type: 'array', optional: true, items: { type: 'string', Enum: [
|
|
57
|
+
"trill", "lowermordent", "uppermordent", "mordent", "pralltriller", "accent",
|
|
58
|
+
"fermata", "invertedfermata", "tenuto", "0", "1", "2", "3", "4", "5", "+", "wedge",
|
|
59
|
+
"open", "thumb", "snap", "turn", "roll", "irishroll", "breath", "shortphrase", "mediumphrase", "longphrase",
|
|
60
|
+
"segno", "coda", "D.S.", "D.C.", "fine", "crescendo(", "crescendo)", "diminuendo(", "diminuendo)", "glissando(", "glissando)",
|
|
61
|
+
"p", "pp", "f", "ff", "mf", "mp", "ppp", "pppp", "fff", "ffff", "sfz", "repeatbar", "repeatbar2", "slide",
|
|
62
|
+
"upbow", "downbow", "staccato", "trem1", "trem2", "trem3", "trem4",
|
|
63
|
+
"/", "//", "///", "////", "turnx", "invertedturn", "invertedturnx", "arpeggio", "trill(", "trill)", "xstem",
|
|
64
|
+
"mark", "marcato", "umarcato", "D.C.alcoda", "D.C.alfine", "D.S.alcoda", "D.S.alfine", "editorial", "courtesy"
|
|
65
|
+
] } };
|
|
66
66
|
|
|
67
67
|
var tempoProperties = {
|
|
68
68
|
duration: { type: "array", optional: true, output: "join", requires: [ 'bpm'], items: { type: "number"} },
|
|
@@ -427,6 +427,7 @@ var ParserLint = function () {
|
|
|
427
427
|
var formattingProperties = {
|
|
428
428
|
type:"object",
|
|
429
429
|
properties: {
|
|
430
|
+
accentAbove: { type: "boolean", optional: true },
|
|
430
431
|
alignbars: { type: "number", optional: true },
|
|
431
432
|
aligncomposer: { type: "string", Enum: [ 'left', 'center','right' ], optional: true },
|
|
432
433
|
annotationfont: fontType,
|
|
@@ -555,6 +556,7 @@ var ParserLint = function () {
|
|
|
555
556
|
subtitlespace: { type: "number", optional: true },
|
|
556
557
|
sysstaffsep: { type: "number", optional: true },
|
|
557
558
|
systemsep: { type: "number", optional: true },
|
|
559
|
+
stafftopmargin: { type: "number", optional: true },
|
|
558
560
|
tabgracefont: fontType,
|
|
559
561
|
tablabelfont: fontType,
|
|
560
562
|
tabnumberfont: fontType,
|
|
@@ -53,6 +53,7 @@ var AbstractEngraver = function (getTextSize, tuneNumber, options) {
|
|
|
53
53
|
this.percmap = options.percmap;
|
|
54
54
|
this.initialClef = options.initialClef
|
|
55
55
|
this.jazzchords = !!options.jazzchords
|
|
56
|
+
this.accentAbove = !!options.accentAbove
|
|
56
57
|
this.germanAlphabet = !!options.germanAlphabet
|
|
57
58
|
this.reset();
|
|
58
59
|
};
|
|
@@ -830,7 +831,10 @@ AbstractEngraver.prototype.createNote = function (elem, nostem, isSingleLineStaf
|
|
|
830
831
|
}
|
|
831
832
|
|
|
832
833
|
if (elem.decoration) {
|
|
833
|
-
this.
|
|
834
|
+
// TODO-PER: nostem is true if this is beamed. In that case we don't know where to place the decoration yet so just make a guess. This should be refactored to not place decorations until after the beams are determined.
|
|
835
|
+
// This should probably be combined with moveDecorations()
|
|
836
|
+
var bottom = nostem ? Math.min(-3, abselem.bottom - 6) : abselem.bottom
|
|
837
|
+
this.decoration.createDecoration(voice, elem.decoration, abselem.top, (notehead) ? notehead.w : 0, abselem, roomtaken, dir, bottom, elem.positioning, this.hasVocals, this.accentAbove);
|
|
834
838
|
}
|
|
835
839
|
|
|
836
840
|
if (elem.barNumber) {
|
|
@@ -989,7 +993,7 @@ AbstractEngraver.prototype.createBarLine = function (voice, elem, isFirstStaff)
|
|
|
989
993
|
}
|
|
990
994
|
|
|
991
995
|
if (elem.decoration) {
|
|
992
|
-
this.decoration.createDecoration(voice, elem.decoration, 12, (thick) ? 3 : 1, abselem, 0, "down", 2, elem.positioning, this.hasVocals);
|
|
996
|
+
this.decoration.createDecoration(voice, elem.decoration, 12, (thick) ? 3 : 1, abselem, 0, "down", 2, elem.positioning, this.hasVocals, this.accentAbove);
|
|
993
997
|
}
|
|
994
998
|
|
|
995
999
|
if (thick) {
|