abcjs 6.4.1 → 6.4.3
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/LICENSE.md +1 -1
- package/RELEASE.md +46 -0
- package/dist/abcjs-basic-min.js +2 -2
- package/dist/abcjs-basic-min.js.LICENSE +1 -1
- package/dist/abcjs-basic.js +1271 -1179
- package/dist/abcjs-basic.js.map +1 -1
- package/dist/abcjs-plugin-min.js +2 -2
- package/dist/abcjs-plugin-min.js.LICENSE +1 -1
- package/index.js +1 -1
- package/license.js +1 -1
- package/package.json +1 -1
- package/plugin.js +1 -1
- package/src/api/abc_tunebook.js +1 -2
- package/src/api/abc_tunebook_svg.js +0 -1
- package/src/data/abc_tune.js +2 -0
- package/src/midi/abc_midi_create.js +22 -7
- package/src/parse/abc_common.js +3 -11
- package/src/parse/abc_parse.js +1 -1
- package/src/parse/abc_parse_directive.js +44 -3
- package/src/parse/abc_parse_header.js +6 -4
- package/src/parse/abc_parse_key_voice.js +10 -6
- package/src/parse/abc_parse_music.js +54 -22
- package/src/parse/tune-builder.js +675 -643
- package/src/synth/abc_midi_flattener.js +3 -1
- package/src/synth/abc_midi_sequencer.js +18 -3
- package/src/synth/chord-track.js +90 -18
- package/src/synth/create-synth-control.js +1 -2
- package/src/tablatures/abc_tablatures.js +184 -0
- package/src/tablatures/instruments/string-patterns.js +266 -268
- package/src/tablatures/instruments/string-tablature.js +38 -35
- package/src/tablatures/instruments/tab-note.js +186 -181
- package/src/tablatures/instruments/tab-notes.js +30 -35
- package/src/tablatures/instruments/tab-string.js +43 -25
- package/src/tablatures/render/tab-absolute-elements.js +303 -0
- package/src/tablatures/render/tab-renderer.js +244 -0
- package/src/test/abc_parser_lint.js +2 -3
- package/src/write/creation/abstract-engraver.js +1 -1
- package/src/write/creation/elements/tie-element.js +26 -0
- package/src/write/engraver-controller.js +1 -1
- package/src/write/layout/set-upper-and-lower-elements.js +8 -0
- package/test.js +1 -1
- package/types/index.d.ts +2 -2
- package/version.js +1 -1
- package/src/api/abc_tablatures.js +0 -184
- package/src/tablatures/instruments/tab-string-patterns.js +0 -23
- package/src/tablatures/tab-absolute-elements.js +0 -301
- package/src/tablatures/tab-common.js +0 -29
- package/src/tablatures/tab-renderer.js +0 -259
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-debugger */
|
|
2
|
-
var VoiceElement = require('../write/creation/elements/voice-element');
|
|
3
|
-
var TabAbsoluteElements = require('./tab-absolute-elements');
|
|
4
|
-
var spacing = require('../write/helpers/spacing');
|
|
5
|
-
|
|
6
|
-
function initSpecialY() {
|
|
7
|
-
return {
|
|
8
|
-
tempoHeightAbove: 0,
|
|
9
|
-
partHeightAbove: 0,
|
|
10
|
-
volumeHeightAbove: 0,
|
|
11
|
-
dynamicHeightAbove: 0,
|
|
12
|
-
endingHeightAbove: 0,
|
|
13
|
-
chordHeightAbove: 0,
|
|
14
|
-
lyricHeightAbove: 0,
|
|
15
|
-
lyricHeightBelow: 0,
|
|
16
|
-
chordHeightBelow: 0,
|
|
17
|
-
volumeHeightBelow: 0,
|
|
18
|
-
dynamicHeightBelow: 0
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function getLyricHeight(voice) {
|
|
23
|
-
var maxLyricHeight = 0;
|
|
24
|
-
for (var ii = 0; ii < voice.children.length; ii++) {
|
|
25
|
-
var curAbs = voice.children[ii];
|
|
26
|
-
if (curAbs.specialY) {
|
|
27
|
-
if (curAbs.specialY.lyricHeightBelow > maxLyricHeight) {
|
|
28
|
-
maxLyricHeight = curAbs.specialY.lyricHeightBelow;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return maxLyricHeight; // add spacing
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function buildTabName(self, dest) {
|
|
36
|
-
var stringSemantics = self.plugin.semantics.strings;
|
|
37
|
-
var controller = self.renderer.controller;
|
|
38
|
-
var textSize = controller.getTextSize;
|
|
39
|
-
var tabName = stringSemantics.tabInfos(self.plugin);
|
|
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
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Laying out tabs
|
|
62
|
-
* @param {*} renderer
|
|
63
|
-
* @param {*} line
|
|
64
|
-
* @param {*} staffIndex
|
|
65
|
-
* @param {*} tablatureLayout
|
|
66
|
-
*/
|
|
67
|
-
function TabRenderer(plugin, renderer, line, staffIndex) {
|
|
68
|
-
this.renderer = renderer;
|
|
69
|
-
this.plugin = plugin;
|
|
70
|
-
this.line = line;
|
|
71
|
-
this.absolutes = new TabAbsoluteElements();
|
|
72
|
-
this.staffIndex = staffIndex ;
|
|
73
|
-
this.tabStaff = {
|
|
74
|
-
clef: {
|
|
75
|
-
type: 'TAB'
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
this.tabSize = (plugin.linePitch * plugin.nbLines);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function islastTabInStaff(index, staffGroup) {
|
|
82
|
-
if (staffGroup[index].isTabStaff) {
|
|
83
|
-
if (index === staffGroup.length - 1) return true;
|
|
84
|
-
if (staffGroup[index + 1].isTabStaff) {
|
|
85
|
-
return false;
|
|
86
|
-
} else {
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function getStaffNumbers(staffs) {
|
|
94
|
-
var nbStaffs = 0;
|
|
95
|
-
for (var ii = 0; ii < staffs.length; ii++) {
|
|
96
|
-
if (!staffs[ii].isTabStaff) {
|
|
97
|
-
nbStaffs++;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return nbStaffs;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function getParentStaffIndex(staffs, index) {
|
|
104
|
-
for (var ii = index; ii >= 0; ii--) {
|
|
105
|
-
if (!staffs[ii].isTabStaff) {
|
|
106
|
-
return ii;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return -1;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
function linkStaffAndTabs(staffs) {
|
|
114
|
-
for (var ii = 0; ii < staffs.length; ii++) {
|
|
115
|
-
if (staffs[ii].isTabStaff) {
|
|
116
|
-
// link to parent staff
|
|
117
|
-
var parentIndex = getParentStaffIndex(staffs, ii);
|
|
118
|
-
staffs[ii].hasStaff = staffs[parentIndex];
|
|
119
|
-
if (!staffs[parentIndex].hasTab) staffs[parentIndex].hasTab = [];
|
|
120
|
-
staffs[parentIndex].hasTab.push(staffs[ii]);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isMultiVoiceSingleStaff(staffs , parent) {
|
|
126
|
-
if ( getStaffNumbers(staffs) === 1) {
|
|
127
|
-
if (parent.voices.length > 1) return true;
|
|
128
|
-
}
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
function getNextTabPos(self,staffGroup) {
|
|
134
|
-
var tabIndex = self.staffIndex;
|
|
135
|
-
var startIndex = 0;
|
|
136
|
-
var handledVoices = 0;
|
|
137
|
-
var inProgress = true;
|
|
138
|
-
var nbVoices = 0;
|
|
139
|
-
while (inProgress) {
|
|
140
|
-
//for (var ii = 0; ii < staffGroup.length; ii++) {
|
|
141
|
-
if (!staffGroup[startIndex])
|
|
142
|
-
return -1;
|
|
143
|
-
if (!staffGroup[startIndex].isTabStaff) {
|
|
144
|
-
nbVoices = staffGroup[startIndex].voices.length; // get number of staff voices
|
|
145
|
-
}
|
|
146
|
-
if (staffGroup[startIndex].isTabStaff) {
|
|
147
|
-
handledVoices++;
|
|
148
|
-
if (islastTabInStaff(startIndex, staffGroup)) {
|
|
149
|
-
if (handledVoices < nbVoices) return startIndex + 1;
|
|
150
|
-
}
|
|
151
|
-
} else {
|
|
152
|
-
handledVoices = 0;
|
|
153
|
-
if (startIndex >= tabIndex) {
|
|
154
|
-
if (startIndex+1 == staffGroup.length) return startIndex +1;
|
|
155
|
-
if (!staffGroup[startIndex + 1].isTabStaff) return startIndex + 1;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
startIndex++;
|
|
159
|
-
// out of space case
|
|
160
|
-
if (startIndex > staffGroup.length) return -1;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function getLastStaff(staffs, lastTab) {
|
|
165
|
-
for (var ii = lastTab; ii >= 0 ; ii-- ) {
|
|
166
|
-
if (!staffs[ii].isTabStaff) {
|
|
167
|
-
return staffs[ii];
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function checkVoiceKeySig(voices, ii) {
|
|
174
|
-
var curVoice = voices[ii];
|
|
175
|
-
// on multivoice multistaff only the first voice has key signature
|
|
176
|
-
// folling consecutive do not have one => we should provide the first voice key sig back then
|
|
177
|
-
var elem0 = curVoice.children[0].abcelem;
|
|
178
|
-
if (elem0.el_type === 'clef') return null;
|
|
179
|
-
if (ii == 0) {
|
|
180
|
-
// not found => clef=none case
|
|
181
|
-
return 'none';
|
|
182
|
-
}
|
|
183
|
-
return voices[ii-1].children[0];
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
TabRenderer.prototype.doLayout = function () {
|
|
187
|
-
var staffs = this.line.staff;
|
|
188
|
-
if (staffs) {
|
|
189
|
-
// give up on staffline=0 in key
|
|
190
|
-
var firstStaff = staffs[0];
|
|
191
|
-
if (firstStaff) {
|
|
192
|
-
if (firstStaff.clef) {
|
|
193
|
-
if (firstStaff.clef.stafflines == 0) {
|
|
194
|
-
this.plugin._super.setError("No tablatures when stafflines=0");
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
staffs.splice(
|
|
200
|
-
staffs.length, 0,
|
|
201
|
-
this.tabStaff
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
var staffGroup = this.line.staffGroup;
|
|
205
|
-
|
|
206
|
-
var voices = staffGroup.voices;
|
|
207
|
-
var firstVoice = voices[0];
|
|
208
|
-
// take lyrics into account if any
|
|
209
|
-
var lyricsHeight = getLyricHeight(firstVoice);
|
|
210
|
-
var padd = 3;
|
|
211
|
-
var prevIndex = this.staffIndex;
|
|
212
|
-
var previousStaff = staffGroup.staffs[prevIndex];
|
|
213
|
-
var tabTop = this.tabSize + padd - previousStaff.bottom - lyricsHeight;
|
|
214
|
-
if (previousStaff.isTabStaff) {
|
|
215
|
-
tabTop = previousStaff.top;
|
|
216
|
-
}
|
|
217
|
-
var staffGroupInfos = {
|
|
218
|
-
bottom: -1,
|
|
219
|
-
isTabStaff: true,
|
|
220
|
-
specialY: initSpecialY(),
|
|
221
|
-
lines: this.plugin.nbLines,
|
|
222
|
-
linePitch: this.plugin.linePitch,
|
|
223
|
-
dy: 0.15,
|
|
224
|
-
top: tabTop,
|
|
225
|
-
};
|
|
226
|
-
var nextTabPos = getNextTabPos(this,staffGroup.staffs);
|
|
227
|
-
if (nextTabPos === -1)
|
|
228
|
-
return;
|
|
229
|
-
staffGroupInfos.parentIndex = nextTabPos - 1;
|
|
230
|
-
staffGroup.staffs.splice(nextTabPos, 0, staffGroupInfos);
|
|
231
|
-
// staffGroup.staffs.push(staffGroupInfos);
|
|
232
|
-
staffGroup.height += this.tabSize + padd;
|
|
233
|
-
var parentStaff = getLastStaff(staffGroup.staffs, nextTabPos);
|
|
234
|
-
var nbVoices = 1;
|
|
235
|
-
if (isMultiVoiceSingleStaff(staffGroup.staffs,parentStaff)) {
|
|
236
|
-
nbVoices = parentStaff.voices.length;
|
|
237
|
-
}
|
|
238
|
-
// build from staff
|
|
239
|
-
this.tabStaff.voices = [];
|
|
240
|
-
for (var ii = 0; ii < nbVoices; ii++) {
|
|
241
|
-
var tabVoice = new VoiceElement(0, 0);
|
|
242
|
-
if (ii > 0) tabVoice.duplicate = true;
|
|
243
|
-
var nameHeight = buildTabName(this, tabVoice) / spacing.STEP;
|
|
244
|
-
nameHeight = Math.max(nameHeight, 1) // If there is no label for the tab line, then there needs to be a little padding
|
|
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;
|
|
249
|
-
tabVoice.staff = staffGroupInfos;
|
|
250
|
-
var tabVoiceIndex = voices.length
|
|
251
|
-
voices.splice(voices.length, 0, tabVoice);
|
|
252
|
-
var keySig = checkVoiceKeySig(voices, ii + this.staffIndex);
|
|
253
|
-
this.tabStaff.voices[ii] = [];
|
|
254
|
-
this.absolutes.build(this.plugin, voices, this.tabStaff.voices[ii], ii , this.staffIndex ,keySig, tabVoiceIndex);
|
|
255
|
-
}
|
|
256
|
-
linkStaffAndTabs(staffGroup.staffs); // crossreference tabs and staff
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
module.exports = TabRenderer;
|