abcjs 6.1.9 → 6.2.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.
Files changed (129) hide show
  1. package/RELEASE.md +42 -0
  2. package/dist/abcjs-basic-min.js +2 -2
  3. package/dist/abcjs-basic.js +4318 -4411
  4. package/dist/abcjs-basic.js.map +1 -1
  5. package/dist/abcjs-plugin-min.js +2 -2
  6. package/index.js +1 -1
  7. package/package.json +1 -1
  8. package/plugin.js +1 -1
  9. package/src/api/abc_timing_callbacks.js +7 -3
  10. package/src/api/abc_tunebook_svg.js +1 -2
  11. package/src/data/abc_tune.js +2 -2
  12. package/src/parse/abc_common.js +0 -47
  13. package/src/parse/abc_parse.js +16 -16
  14. package/src/parse/abc_parse_book.js +3 -3
  15. package/src/parse/abc_parse_directive.js +26 -7
  16. package/src/parse/abc_parse_header.js +11 -9
  17. package/src/parse/abc_parse_key_voice.js +17 -17
  18. package/src/parse/abc_parse_music.js +88 -105
  19. package/src/parse/abc_tokenizer.js +60 -60
  20. package/src/parse/tune-builder.js +19 -14
  21. package/src/synth/abc_midi_flattener.js +25 -9
  22. package/src/synth/create-synth.js +41 -0
  23. package/src/synth/note-to-midi.js +50 -0
  24. package/src/tablatures/instruments/guitar/tab-guitar.js +0 -2
  25. package/src/tablatures/instruments/string-patterns.js +46 -28
  26. package/src/tablatures/instruments/tab-note.js +26 -103
  27. package/src/tablatures/instruments/violin/tab-violin.js +0 -2
  28. package/src/tablatures/tab-absolute-elements.js +9 -31
  29. package/src/tablatures/tab-renderer.js +2 -2
  30. package/src/test/abc_parser_lint.js +7 -4
  31. package/src/write/README.md +31 -0
  32. package/src/write/creation/abstract-engraver.js +1036 -0
  33. package/src/write/creation/add-chord.js +102 -0
  34. package/src/write/{add-text-if.js → creation/add-text-if.js} +6 -6
  35. package/src/write/{calcHeight.js → creation/calc-height.js} +2 -2
  36. package/src/write/creation/create-clef.js +72 -0
  37. package/src/write/creation/create-key-signature.js +31 -0
  38. package/src/write/creation/create-note-head.js +107 -0
  39. package/src/write/creation/create-time-signature.js +55 -0
  40. package/src/write/creation/decoration.js +357 -0
  41. package/src/write/{abc_absolute_element.js → creation/elements/absolute-element.js} +14 -15
  42. package/src/write/creation/elements/beam-element.js +113 -0
  43. package/src/write/{bottom-text.js → creation/elements/bottom-text.js} +14 -15
  44. package/src/write/{abc_brace_element.js → creation/elements/brace-element.js} +5 -5
  45. package/src/write/creation/elements/free-text.js +41 -0
  46. package/src/write/{abc_relative_element.js → creation/elements/relative-element.js} +7 -7
  47. package/src/write/{separator.js → creation/elements/separator.js} +2 -2
  48. package/src/write/{abc_staff_group_element.js → creation/elements/staff-group-element.js} +4 -4
  49. package/src/write/{subtitle.js → creation/elements/subtitle.js} +3 -3
  50. package/src/write/creation/elements/tempo-element.js +63 -0
  51. package/src/write/{abc_tie_element.js → creation/elements/tie-element.js} +15 -11
  52. package/src/write/{top-text.js → creation/elements/top-text.js} +12 -12
  53. package/src/write/creation/elements/triplet-element.js +28 -0
  54. package/src/write/{abc_voice_element.js → creation/elements/voice-element.js} +3 -3
  55. package/src/write/creation/glyphs.js +226 -0
  56. package/src/write/creation/translate-chord.js +37 -0
  57. package/src/write/draw/absolute.js +5 -5
  58. package/src/write/draw/beam.js +8 -8
  59. package/src/write/draw/brace.js +33 -33
  60. package/src/write/draw/crescendo.js +4 -4
  61. package/src/write/draw/debug-box.js +1 -1
  62. package/src/write/draw/draw.js +7 -7
  63. package/src/write/draw/dynamics.js +2 -2
  64. package/src/write/draw/ending.js +6 -6
  65. package/src/write/draw/glissando.js +17 -17
  66. package/src/write/draw/group-elements.js +51 -51
  67. package/src/write/draw/horizontal-line.js +9 -9
  68. package/src/write/draw/non-music.js +1 -1
  69. package/src/write/draw/print-line.js +15 -16
  70. package/src/write/draw/print-stem.js +5 -5
  71. package/src/write/draw/print-symbol.js +12 -12
  72. package/src/write/draw/print-vertical-line.js +8 -8
  73. package/src/write/draw/relative.js +17 -16
  74. package/src/write/draw/selectables.js +5 -5
  75. package/src/write/draw/separator.js +4 -4
  76. package/src/write/draw/set-paper-size.js +2 -2
  77. package/src/write/draw/sprintf.js +31 -31
  78. package/src/write/draw/staff-group.js +36 -30
  79. package/src/write/draw/staff-line.js +2 -2
  80. package/src/write/draw/staff.js +4 -4
  81. package/src/write/draw/tab-line.js +26 -26
  82. package/src/write/draw/tempo.js +30 -30
  83. package/src/write/draw/text.js +5 -5
  84. package/src/write/draw/tie.js +18 -18
  85. package/src/write/draw/triplet.js +6 -6
  86. package/src/write/draw/voice.js +16 -17
  87. package/src/write/{abc_engraver_controller.js → engraver-controller.js} +58 -51
  88. package/src/write/{classes.js → helpers/classes.js} +6 -6
  89. package/src/write/{get-font-and-attr.js → helpers/get-font-and-attr.js} +9 -7
  90. package/src/write/{get-text-size.js → helpers/get-text-size.js} +5 -5
  91. package/src/write/{set-class.js → helpers/set-class.js} +1 -1
  92. package/src/write/{abc_spacing.js → helpers/spacing.js} +1 -1
  93. package/src/write/{highlight.js → interactive/highlight.js} +1 -1
  94. package/src/write/{selection.js → interactive/selection.js} +27 -27
  95. package/src/write/{unhighlight.js → interactive/unhighlight.js} +1 -1
  96. package/src/write/layout/beam.js +13 -13
  97. package/src/write/layout/get-left-edge-of-staff.js +4 -4
  98. package/src/write/layout/layout.js +74 -74
  99. package/src/write/layout/{setUpperAndLowerElements.js → set-upper-and-lower-elements.js} +8 -8
  100. package/src/write/layout/{staffGroup.js → staff-group.js} +32 -32
  101. package/src/write/layout/triplet.js +4 -4
  102. package/src/write/layout/{VoiceElements.js → voice-elements.js} +23 -23
  103. package/src/write/layout/voice.js +6 -6
  104. package/src/write/{abc_renderer.js → renderer.js} +35 -32
  105. package/src/write/svg.js +35 -35
  106. package/test.js +1 -1
  107. package/types/index.d.ts +36 -7
  108. package/version.js +1 -1
  109. package/src/tablatures/instruments/guitar/guitar-fonts.js +0 -19
  110. package/src/tablatures/instruments/violin/violin-fonts.js +0 -19
  111. package/src/tablatures/transposer.js +0 -110
  112. package/src/write/abc_abstract_engraver.js +0 -1026
  113. package/src/write/abc_beam_element.js +0 -113
  114. package/src/write/abc_create_clef.js +0 -72
  115. package/src/write/abc_create_key_signature.js +0 -33
  116. package/src/write/abc_create_note_head.js +0 -107
  117. package/src/write/abc_create_time_signature.js +0 -55
  118. package/src/write/abc_decoration.js +0 -357
  119. package/src/write/abc_glyphs.js +0 -224
  120. package/src/write/abc_tempo_element.js +0 -63
  121. package/src/write/abc_triplet_element.js +0 -28
  122. package/src/write/add-chord.js +0 -103
  123. package/src/write/format-jazz-chord.js +0 -15
  124. package/src/write/free-text.js +0 -41
  125. /package/src/write/{abc_crescendo_element.js → creation/elements/crescendo-element.js} +0 -0
  126. /package/src/write/{abc_dynamic_decoration.js → creation/elements/dynamic-decoration.js} +0 -0
  127. /package/src/write/{abc_ending_element.js → creation/elements/ending-element.js} +0 -0
  128. /package/src/write/{abc_glissando_element.js → creation/elements/glissando-element.js} +0 -0
  129. /package/src/write/layout/{getBarYAt.js → get-bar-y-at.js} +0 -0
@@ -0,0 +1,50 @@
1
+ var accidentals = {
2
+ "__": -2,
3
+ "_": -1,
4
+ "_/": -0.5,
5
+ "=": 0,
6
+ "": 0,
7
+ "^/": 0.5,
8
+ "^": 1,
9
+ "^^": 2
10
+ }
11
+
12
+ var notesInOrder = ['C', '-', 'D', '-', 'E', 'F', '-', 'G', '-', 'A', '-', 'B', 'c', '-', 'd', '-', 'e', 'f', '-', 'g', '-', 'a', '-', 'b']
13
+
14
+ function noteToMidi(note) {
15
+ var reg = note.match(/([_^\/]*)([ABCDEFGabcdefg])(,*)('*)/)
16
+ if (reg && reg.length === 5) {
17
+ var acc = accidentals[reg[1]]
18
+ var pitch = notesInOrder.indexOf(reg[2])
19
+ var octave = reg[4].length - reg[3].length
20
+ return 48 + pitch + acc + octave * 12;
21
+ }
22
+ return 0;
23
+ }
24
+
25
+ function midiToNote(midi) {
26
+ midi = parseInt(midi, 10) // TODO-PER: not sure how to handle quarter sharps and flats, so strip them for now.
27
+ var octave = Math.floor(midi / 12)
28
+ var pitch = midi % 12
29
+ var name = notesInOrder[pitch]
30
+ if (name === '-') {
31
+ name = '^' + notesInOrder[pitch-1]
32
+ }
33
+
34
+ if (octave > 4) {
35
+ name = name.toLowerCase()
36
+ octave -= 5
37
+ while (octave > 0) {
38
+ name += "'"
39
+ octave--
40
+ }
41
+ } else {
42
+ while (octave < 4) {
43
+ name += ','
44
+ octave++
45
+ }
46
+ }
47
+ return name
48
+ }
49
+
50
+ module.exports = {noteToMidi: noteToMidi, midiToNote: midiToNote};
@@ -5,7 +5,6 @@ var StringTablature = require('../string-tablature');
5
5
  var TabCommon = require('../../tab-common');
6
6
  var TabRenderer = require('../../tab-renderer');
7
7
  var GuitarPatterns = require('./guitar-patterns');
8
- var setGuitarFonts = require('./guitar-fonts');
9
8
 
10
9
  /**
11
10
  * upon init mainly store provided instances for later usage
@@ -32,7 +31,6 @@ Plugin.prototype.init = function (abcTune, tuneNumber, params) {
32
31
  Plugin.prototype.render = function (renderer, line, staffIndex) {
33
32
  if (this._super.inError) return;
34
33
  if (this.tablature.bypass(line)) return;
35
- setGuitarFonts(this.abcTune);
36
34
  var rndrer = new TabRenderer(this, renderer, line, staffIndex);
37
35
  rndrer.doLayout();
38
36
  };
@@ -1,3 +1,4 @@
1
+ const {noteToMidi} = require('../../synth/note-to-midi');
1
2
  var TabNote = require('./tab-note');
2
3
  var TabNotes = require('./tab-notes');
3
4
 
@@ -93,7 +94,10 @@ function sameString(self, chord) {
93
94
  function handleChordNotes(self, notes) {
94
95
  var retNotes = [];
95
96
  for (var iiii = 0; iiii < notes.length; iiii++) {
96
- var note = new TabNote.TabNote(notes[iiii].name);
97
+ if (notes[iiii].endTie)
98
+ continue;
99
+ var note = new TabNote.TabNote(notes[iiii].name, self.clefTranspose);
100
+ note.checkKeyAccidentals(self.accidentals, self.measureAccidentals)
97
101
  var curPos = toNumber(self, note);
98
102
  retNotes.push(curPos);
99
103
  }
@@ -147,26 +151,23 @@ function toNumber(self, note) {
147
151
  acc = "="
148
152
  self.measureAccidentals[note.name.toUpperCase()] = acc
149
153
  }
150
- var num = null;
151
- var str = 0;
152
- var lowestString = self.strings[self.strings.length - 1];
153
- var lowestNote = new TabNote.TabNote(lowestString[0]);
154
- if (note.isLowerThan(lowestNote) ) {
155
- return {
156
- num: "?",
157
- str: self.strings.length - 1,
158
- note: note,
159
- error: note.emit() + ': unexpected note for instrument'
160
- };
161
- }
162
- while (str < self.strings.length) {
163
- num = noteToNumber(self, note, str);
164
- if (num) {
165
- return num;
154
+ for (var i = self.stringPitches.length-1; i >= 0; i--) {
155
+ if (note.pitch + note.pitchAltered >= self.stringPitches[i]) {
156
+ var num = note.pitch + note.pitchAltered - self.stringPitches[i]
157
+ if (note.quarter === '^') num -= 0.5
158
+ else if (note.quarter === "v") num += 0.5
159
+ return {
160
+ num: Math.round(num),
161
+ str: self.stringPitches.length-1-i, // reverse the strings because string 0 is on the bottom
162
+ note: note
163
+ }
166
164
  }
167
- str++;
168
165
  }
169
- return null; // not found
166
+ return {
167
+ num: "?",
168
+ str: self.stringPitches.length-1,
169
+ note: note,
170
+ };
170
171
  }
171
172
 
172
173
  StringPatterns.prototype.stringToPitch = function (stringNumber) {
@@ -198,13 +199,16 @@ StringPatterns.prototype.notesToNumber = function (notes, graces) {
198
199
  error = retNotes.error;
199
200
  }
200
201
  } else {
201
- note = new TabNote.TabNote(notes[0].name);
202
- number = toNumber(this, note);
203
- if (number) {
204
- retNotes.push(number);
205
- } else {
206
- invalidNumber(retNotes, note);
207
- error = retNotes.error;
202
+ if (!notes[0].endTie) {
203
+ note = new TabNote.TabNote(notes[0].name, this.clefTranspose);
204
+ note.checkKeyAccidentals(this.accidentals, this.measureAccidentals)
205
+ number = toNumber(this, note);
206
+ if (number) {
207
+ retNotes.push(number);
208
+ } else {
209
+ invalidNumber(retNotes, note);
210
+ error = retNotes.error;
211
+ }
208
212
  }
209
213
  }
210
214
  }
@@ -213,7 +217,8 @@ StringPatterns.prototype.notesToNumber = function (notes, graces) {
213
217
  if (graces) {
214
218
  retGraces = [];
215
219
  for (var iiii = 0; iiii < graces.length; iiii++) {
216
- note = new TabNote.TabNote(graces[iiii].name);
220
+ note = new TabNote.TabNote(graces[iiii].name, this.clefTranspose);
221
+ note.checkKeyAccidentals(this.accidentals, this.measureAccidentals)
217
222
  number = toNumber(this, note);
218
223
  if (number) {
219
224
  retGraces.push(number);
@@ -232,7 +237,14 @@ StringPatterns.prototype.notesToNumber = function (notes, graces) {
232
237
  };
233
238
 
234
239
  StringPatterns.prototype.toString = function () {
235
- return this.tuning.join('').replaceAll(',', '').toUpperCase();
240
+ var arr = []
241
+ for (var i = 0; i < this.tuning.length; i++) {
242
+ var str = this.tuning[i].replaceAll(',', '').replaceAll("'", '').toUpperCase();
243
+ if (str[0] === '_') str = str[1] + 'b '
244
+ else if (str[0] === '^') str = str[1] + "# "
245
+ arr.push(str)
246
+ }
247
+ return arr.join('');
236
248
  };
237
249
 
238
250
  StringPatterns.prototype.tabInfos = function (plugin) {
@@ -275,7 +287,13 @@ function StringPatterns(plugin) {
275
287
  if (capo) {
276
288
  this.capo = capo;
277
289
  }
290
+ this.transpose = plugin.transpose ? plugin.transpose : 0
278
291
  this.tuning = tuning;
292
+ this.stringPitches = []
293
+ for (var i = 0; i < this.tuning.length; i++) {
294
+ var pitch = noteToMidi(this.tuning[i]) + this.capo
295
+ this.stringPitches.push(pitch)
296
+ }
279
297
  if (this.capo > 0) {
280
298
  this.capoTuning = buildCapo(this);
281
299
  }
@@ -1,3 +1,5 @@
1
+ var {noteToMidi, midiToNote} = require('../../synth/note-to-midi');
2
+
1
3
  /**
2
4
  *
3
5
  * Note structure for Tabs
@@ -6,9 +8,12 @@
6
8
  var notes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
7
9
 
8
10
 
9
- function TabNote(note) {
11
+ function TabNote(note, clefTranspose) {
12
+ var pitch = noteToMidi(note)
13
+ if (clefTranspose)
14
+ pitch += clefTranspose
15
+ var newNote = midiToNote(pitch);
10
16
  var isFlat = false;
11
- var newNote = note;
12
17
  var isSharp = false;
13
18
  var isAltered = false;
14
19
  var natural = null;
@@ -54,9 +59,11 @@ function TabNote(note) {
54
59
  newNote = note.slice(1);
55
60
  }
56
61
  }
57
- var hasComma = (note.match(/,/g) || []).length;
58
- var hasQuote = (note.match(/'/g) || []).length;
62
+ var hasComma = (newNote.match(/,/g) || []).length;
63
+ var hasQuote = (newNote.match(/'/g) || []).length;
59
64
 
65
+ this.pitch = pitch
66
+ this.pitchAltered = 0
60
67
  this.name = newNote;
61
68
  this.acc = acc;
62
69
  this.isSharp = isSharp;
@@ -76,6 +83,7 @@ function TabNote(note) {
76
83
  function cloneNote(self) {
77
84
  var newNote = self.name;
78
85
  var newTabNote = new TabNote(newNote);
86
+ newTabNote.pitch = self.pitch;
79
87
  newTabNote.hasComma = self.hasComma;
80
88
  newTabNote.isLower = self.isLower;
81
89
  newTabNote.isQuoted = self.isQuoted;
@@ -86,33 +94,11 @@ function cloneNote(self) {
86
94
  return newTabNote;
87
95
  }
88
96
  TabNote.prototype.sameNoteAs = function (note) {
89
- if ((this.name == note.name) &&
90
- (this.hasComma == note.hasComma) &&
91
- (this.isLower == note.isLower) &&
92
- (this.isQuoted == note.isQuoted) &&
93
- (this.isSharp == note.isSharp) &&
94
- (this.isFlat == note.isFlat)) {
95
- return true;
96
- } else {
97
- return false;
98
- }
97
+ return note.pitch === this.pitch
99
98
  };
100
99
 
101
100
  TabNote.prototype.isLowerThan = function (note) {
102
- var noteComparator = ['C','D','E','F','G','A','B'];
103
- if (this.hasComma > note.hasComma) return true;
104
- if (note.hasComma > this.hasComma) return false;
105
- if (this.isQuoted > note.isQuoted) return false;
106
- if (note.isQuoted > this.isQuoted) return true;
107
- if (this.isLower) {
108
- if (!note.isLower) return false;
109
- } else {
110
- if (note.isLower) return true;
111
- }
112
- var noteName = note.name[0].toUpperCase();
113
- var thisName = this.name[0].toUpperCase();
114
- if (noteComparator.indexOf(thisName) < noteComparator.indexOf(noteName)) return true;
115
- return false;
101
+ return note.pitch > this.pitch
116
102
  };
117
103
 
118
104
  TabNote.prototype.checkKeyAccidentals = function(accidentals, measureAccidentals) {
@@ -120,14 +106,13 @@ TabNote.prototype.checkKeyAccidentals = function(accidentals, measureAccidentals
120
106
  return
121
107
  if (measureAccidentals[this.name.toUpperCase()]) {
122
108
  switch (measureAccidentals[this.name.toUpperCase()]) {
123
- case "__": this.acc = -2; return;
124
- case "_": this.acc = -1; return;
125
- case "=": this.acc = 0; return;
126
- case "^": this.acc = 1; return;
127
- case "^^": this.acc = 2; return;
109
+ case "__": this.acc = -2; this.pitchAltered = -2; return;
110
+ case "_": this.acc = -1; this.pitchAltered = -1; return;
111
+ case "=": this.acc = 0; this.pitchAltered = 0; return;
112
+ case "^": this.acc = 1; this.pitchAltered = 1; return;
113
+ case "^^": this.acc = 2; this.pitchAltered = 2; return;
128
114
  }
129
- }
130
- if (accidentals) {
115
+ } else if (accidentals) {
131
116
  var curNote = this.name;
132
117
  for (var iii = 0; iii < accidentals.length; iii++) {
133
118
  var curAccidentals = accidentals[iii];
@@ -135,10 +120,12 @@ TabNote.prototype.checkKeyAccidentals = function(accidentals, measureAccidentals
135
120
  if (curAccidentals.acc == 'flat') {
136
121
  this.acc = -1;
137
122
  this.isKeyFlat = true;
123
+ this.pitchAltered = -1
138
124
  }
139
125
  if (curAccidentals.acc == 'sharp') {
140
126
  this.acc = +1;
141
127
  this.isKeySharp = true;
128
+ this.pitchAltered = 1
142
129
  }
143
130
  }
144
131
  }
@@ -163,77 +150,13 @@ TabNote.prototype.getAccidentalEquiv = function () {
163
150
 
164
151
 
165
152
  TabNote.prototype.nextNote = function () {
166
- var newTabNote = cloneNote(this);
167
-
168
- if (!this.isSharp && !this.isKeySharp ) {
169
- if (this.name != 'E' && this.name != 'B') {
170
- newTabNote.isSharp = true;
171
- return newTabNote;
172
- }
173
- } else {
174
- // cleanup
175
- newTabNote.isSharp = false;
176
- newTabNote.isKeySharp = false;
177
- }
178
- var noteIndex = notes.indexOf(this.name);
179
- if (noteIndex == notes.length - 1) {
180
- noteIndex = 0;
181
- } else {
182
- noteIndex++;
183
- }
184
- newTabNote.name = notes[noteIndex];
185
- if (newTabNote.name == 'C') {
186
- if (newTabNote.hasComma > 0) {
187
- newTabNote.hasComma--;
188
- } else {
189
- if (!newTabNote.isLower) {
190
- newTabNote.isLower = true;
191
- } else {
192
- newTabNote.isQuoted = true;
193
- }
194
- }
195
- }
196
- return newTabNote;
153
+ var note = midiToNote(this.pitch+1+this.pitchAltered)
154
+ return new TabNote(note)
197
155
  };
198
156
 
199
157
  TabNote.prototype.prevNote = function () {
200
- var newTabNote = cloneNote(this);
201
-
202
- if (this.isSharp) {
203
- newTabNote.isSharp = false;
204
- return newTabNote;
205
- }
206
- var noteIndex = notes.indexOf(this.name);
207
- if (noteIndex == 0) {
208
- noteIndex = notes.length - 1;
209
- } else {
210
- noteIndex--;
211
- }
212
- newTabNote.name = notes[noteIndex];
213
- if (newTabNote.name == 'B') {
214
- if (newTabNote.isLower) {
215
- newTabNote.hasComma = 1;
216
- } else {
217
- if (newTabNote.hasComma > 0) {
218
- newTabNote.hasComma++;
219
- } else {
220
- if (newTabNote.isQuoted > 0) {
221
- newTabNote.isQuoted -= 1;
222
- } else {
223
- newTabNote.isLower = true;
224
- }
225
- }
226
- }
227
- }
228
- if (this.isFlat) {
229
- newTabNote.isFlat = false;
230
- return newTabNote;
231
- } else {
232
- if (this.name != 'E' && this.name != 'B') {
233
- newTabNote.isSharp = true;
234
- }
235
- }
236
- return newTabNote;
158
+ var note = midiToNote(this.pitch-1+this.pitchAltered)
159
+ return new TabNote(note)
237
160
  };
238
161
 
239
162
  TabNote.prototype.emitNoAccidentals = function ( ) {
@@ -3,7 +3,6 @@ var StringTablature = require('../string-tablature');
3
3
  var TabCommon = require('../../tab-common');
4
4
  var TabRenderer = require('../../tab-renderer');
5
5
  var ViolinPatterns = require('./violin-patterns');
6
- var setViolinFonts = require('./violin-fonts');
7
6
 
8
7
 
9
8
  /**
@@ -30,7 +29,6 @@ Plugin.prototype.init = function (abcTune, tuneNumber, params) {
30
29
  Plugin.prototype.render = function (renderer, line, staffIndex) {
31
30
  if (this._super.inError) return;
32
31
  if (this.tablature.bypass(line)) return;
33
- setViolinFonts(this.abcTune);
34
32
  var rndrer = new TabRenderer(this, renderer, line, staffIndex);
35
33
  rndrer.doLayout();
36
34
  };
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Tablature Absolute elements factory
3
3
  */
4
- var AbsoluteElement = require('../write/abc_absolute_element');
5
- var RelativeElement = require('../write/abc_relative_element');
6
- var Transposer = require('./transposer');
4
+ var AbsoluteElement = require('../write/creation/elements/absolute-element');
5
+ var RelativeElement = require('../write/creation/elements/relative-element');
7
6
 
8
7
  function isObject(a) { return a != null && a.constructor === Object; }
9
8
  function cloneObject(dest, src) {
@@ -144,20 +143,6 @@ function graceInRest( absElem ) {
144
143
  return null;
145
144
  }
146
145
 
147
- function checkTransposition(plugin, transposer ,pitches, graceNotes) {
148
- if (plugin.transpose) {
149
- //transposer.transpose(plugin.transpose);
150
- for (var jj = 0; jj < pitches.length; jj++) {
151
- pitches[jj] = transposer.transposeNote(pitches[jj]);
152
- }
153
- if (graceNotes) {
154
- for (var kk = 0; kk < graceNotes.length; kk++) {
155
- graceNotes[kk] = transposer.transposeNote(graceNotes[kk]);
156
- }
157
- }
158
- }
159
- }
160
-
161
146
  function convertToNumber(plugin, pitches, graceNotes) {
162
147
  var tabPos = plugin.semantics.notesToNumber(pitches, graceNotes);
163
148
  if (tabPos.error) {
@@ -196,7 +181,6 @@ TabAbsoluteElements.prototype.build = function (plugin,
196
181
  var staffSize = getInitialStaffSize(staffAbsolute);
197
182
  var source = staffAbsolute[staffIndex+voiceIndex];
198
183
  var dest = staffAbsolute[staffSize+staffIndex+voiceIndex];
199
- var transposer = null;
200
184
  var tabPos = null;
201
185
  var defNote = null;
202
186
  if (source.children[0].abcelem.el_type != 'clef') {
@@ -214,18 +198,14 @@ TabAbsoluteElements.prototype.build = function (plugin,
214
198
  // }
215
199
  if ( (absChild.isClef) ) {
216
200
  dest.children.push(buildTabAbsolute(plugin, absX, relX));
201
+ if (absChild.abcelem.type.indexOf('-8') >= 0) plugin.semantics.strings.clefTranspose = -12
202
+ if (absChild.abcelem.type.indexOf('+8') >= 0) plugin.semantics.strings.clefTranspose = 12
217
203
  }
218
204
  switch (absChild.type) {
219
205
  case 'staff-extra key-signature':
220
206
  // refresh key accidentals
221
207
  this.accidentals = absChild.abcelem.accidentals;
222
208
  plugin.semantics.strings.accidentals = this.accidentals;
223
- if (plugin.transpose) {
224
- transposer = new Transposer(
225
- absChild.abcelem.accidentals,
226
- plugin.transpose
227
- );
228
- }
229
209
  break;
230
210
  case 'bar':
231
211
  plugin.semantics.strings.measureAccidentals = {}
@@ -258,8 +238,6 @@ TabAbsoluteElements.prototype.build = function (plugin,
258
238
  case 'rest':
259
239
  var restGraces = graceInRest(absChild);
260
240
  if (restGraces) {
261
- // check transpose
262
- checkTransposition(plugin, transposer, null, restGraces);
263
241
  // to number conversion
264
242
  tabPos = convertToNumber(plugin, null, restGraces);
265
243
  if (tabPos.error) return;
@@ -274,9 +252,7 @@ TabAbsoluteElements.prototype.build = function (plugin,
274
252
  abs.lyricDim = lyricsDim(absChild);
275
253
  var pitches = absChild.abcelem.pitches;
276
254
  var graceNotes = absChild.abcelem.gracenotes;
277
- // check transpose
278
255
  abs.type = 'tabNumber';
279
- checkTransposition(plugin, transposer, pitches, graceNotes);
280
256
  // to number conversion
281
257
  tabPos = convertToNumber(plugin, pitches, graceNotes);
282
258
  if (tabPos.error) return;
@@ -302,9 +278,11 @@ TabAbsoluteElements.prototype.build = function (plugin,
302
278
  var tabNoteRelative = buildRelativeTabNote(plugin, abs.x+absChild.heads[ll].dx, defNote, curNote, false);
303
279
  abs.children.push(tabNoteRelative);
304
280
  }
305
- defNote.abselem = abs;
306
- tabVoice.push(defNote);
307
- dest.children.push(abs);
281
+ if (defNote.notes.length > 0) {
282
+ defNote.abselem = abs;
283
+ tabVoice.push(defNote);
284
+ dest.children.push(abs);
285
+ }
308
286
  break;
309
287
  }
310
288
  }
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-debugger */
2
- var VoiceElement = require('../write/abc_voice_element');
2
+ var VoiceElement = require('../write/creation/elements/voice-element');
3
3
  var TabAbsoluteElements = require('./tab-absolute-elements');
4
- var spacing = require('../write/abc_spacing');
4
+ var spacing = require('../write/helpers/spacing');
5
5
 
6
6
  function initSpecialY() {
7
7
  return {
@@ -318,7 +318,7 @@ var ParserLint = function() {
318
318
  var midiProperties = {
319
319
  cmd: { type: 'string', Enum: [
320
320
  "nobarlines", "barlines", "beataccents", "nobeataccents", "droneon", "droneoff", "noportamento", "channel", "c",
321
- "drumon", "drumoff", "fermatafixed", "fermataproportional", "gchordon", "gchordoff", "bassvol", "chordvol",
321
+ "drumon", "drumoff", "fermatafixed", "fermataproportional", "gchordon", "gchordoff", "bassvol", "chordvol", "bassprog", "chordprog",
322
322
  "controlcombo", "temperamentnormal", "gchord", "ptstress", "beatmod", "deltaloudness", "drumbars", "pitchbend",
323
323
  "gracedivider", "makechordchannels", "randomchordattack", "chordattack", "stressmodel", "transpose",
324
324
  "rtranspose", "volinc", "program", "ratio", "snt", "bendvelocity", "control", "temperamentlinear", "beat", "beatstring",
@@ -335,6 +335,7 @@ var ParserLint = function() {
335
335
  field: "el_type",
336
336
  types: [
337
337
  { value: "clef", properties: appendPositioning(clefProperties) },
338
+ { value: "color", properties: { color: {type: "string", optional: true } } },
338
339
  { value: "bar", properties: prependPositioning(barProperties) },
339
340
  { value: "gap", properties: { type: "number", optional: true } }, // staffbreak
340
341
  { value: "key", properties: appendPositioning(keyProperties) },
@@ -462,9 +463,11 @@ var ParserLint = function() {
462
463
  infospace: { type: "number", optional: true },
463
464
  // landscape: { type: "boolean", optional: true },
464
465
  jazzchords: { type: "boolean", optional: true },
466
+ germanAlphabet: { type: "boolean", optional: true },
465
467
  leftmargin: { type: "number", optional: true },
466
468
  linesep: { type: "number", optional: true },
467
469
  lineskipfac: { type: "number", optional: true },
470
+ lineThickness: { type: "number", optional: true },
468
471
  map: { type: "string", optional: true },
469
472
  maxshrink: { type: "number", optional: true },
470
473
  maxstaffsep: { type: "number", optional: true },
@@ -741,14 +744,14 @@ var ParserLint = function() {
741
744
  this.lint = function(tune, warnings) {
742
745
  var ret = JSONSchema.validate(tune, musicSchema);
743
746
  var err = "";
744
- parseCommon.each(ret.errors, function(e) {
747
+ ret.errors.forEach(function(e) {
745
748
  err += e.property + ": " + e.message + "\n";
746
749
  });
747
750
  var out = ret.output.join("\n");
748
751
 
749
752
  var warn = warnings === undefined ? "No errors" : warnings.join('\n');
750
- warn = parseCommon.gsub(warn, '<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">', '$$$$');
751
- warn = parseCommon.gsub(warn, '</span>', '$$$$');
753
+ warn = warn.replace(/<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">/g, '$$$$$$$$');
754
+ warn = warn.replace(/<\/span>/g, '$$$$$$$$');
752
755
  return "Error:------\n" + err + "\nObj:-------\n" + out + "\nWarn:------\n" + warn;
753
756
  };
754
757
  };
@@ -0,0 +1,31 @@
1
+ # Architecture of the engraver
2
+
3
+ The engraver code is handled here. This accepts the output of the parser and does three things:
4
+
5
+ * Creates an SVG
6
+ * Adds data to the parser input
7
+ * Makes the visual elements interactive
8
+
9
+ ## Steps
10
+
11
+ There are separate passes and sub-passes to the processing. The separate passes match the subfolder organization here.
12
+
13
+ They are:
14
+
15
+ ### Element Creation
16
+
17
+ The structure passed in from the parser is traversed and all elements are created. An element consists of two parts:
18
+
19
+ * The Absolute Element: a visual piece of music that is always moved together. For instance, in the key signature of D, the absolute element is an object that contains two sharp symbols. The absolute element has an X- and Y- position in the SVG, and an array of Relative Elements.
20
+
21
+ * Relative Element: These are always attached to an absolute element. They have a relative position to the absolute element and consist of all the glyphs needed. For instance, a dotted eighth note of Bb that is trilled is an absolute element that contains an array of relative elements consisting of a trill, a flat sign, a filled note head, a stem, a flag, and a dot.
22
+
23
+ Each of these elements is a separate object, created with `new` and placed in the structure passed in from the parser.
24
+
25
+ ### Layout
26
+
27
+ After all the elements are created the size of all of them are known, so the layout process begins. There are separate layout algorithms for the horizontal and the vertical positioning.
28
+
29
+ ### Drawing
30
+
31
+ After the layout is finished, it is a rote process to draw the music. All decisions have been made. The structure is then traversed and each element is created in the SVG.