abcjs 6.1.6 → 6.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abcjs",
3
- "version": "6.1.6",
3
+ "version": "6.1.8",
4
4
  "description": "Renderer for abc music notation",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -10,7 +10,8 @@
10
10
  "build:basic": "npm run webpack -- --mode development --config-name basic",
11
11
  "build:basic-min": "npm run webpack -- --mode production --config-name basic",
12
12
  "build:plugin": "npm run webpack -- --mode production --config-name plugin",
13
- "test": "echo 'To run tests, open the file tests/all.html in a browser.'",
13
+ "test-server": "npx http-server",
14
+ "test": "concurrently \"http-server\" \"npx opener http://localhost:8080/tests/all.html\"",
14
15
  "docs:dev": "vuepress dev docs",
15
16
  "docs:build": "vuepress build docs",
16
17
  "build:analyze": "npm run build:basic -- --env analyze"
@@ -43,15 +44,18 @@
43
44
  },
44
45
  "homepage": "https://abcjs.net",
45
46
  "devDependencies": {
46
- "@babel/core": "7.14.3",
47
- "@babel/preset-env": "7.14.4",
47
+ "@babel/core": "7.20.2",
48
+ "@babel/preset-env": "7.20.2",
48
49
  "@tarp/require": "1.4.3",
49
- "babel-loader": "8.2.2",
50
- "chai": "4.3.4",
51
- "mocha": "8.4.0",
50
+ "babel-loader": "9.1.0",
51
+ "chai": "4.3.7",
52
+ "concurrently": "7.5.0",
53
+ "http-server": "14.1.1",
54
+ "mocha": "10.1.0",
55
+ "opener": "1.5.2",
52
56
  "vuepress": "2.0.0-beta.26",
53
- "vuex": "4.0.0",
54
- "webpack-bundle-analyzer": "4.4.2",
55
- "webpack-cli": "4.9.0"
57
+ "vuex": "4.1.0",
58
+ "webpack-bundle-analyzer": "4.7.0",
59
+ "webpack-cli": "4.10.0"
56
60
  }
57
61
  }
@@ -399,6 +399,8 @@ var Tune = function() {
399
399
 
400
400
  var voices = group.voices;
401
401
  for (var v = 0; v < voices.length; v++) {
402
+ if (voices[v].staff && voices[v].staff.isTabStaff)
403
+ continue;
402
404
  var noteFound = false;
403
405
  if (!voicesArr[v])
404
406
  voicesArr[v] = [];
@@ -78,6 +78,7 @@ var Parse = function() {
78
78
  this.hasMainTitle = false;
79
79
  this.default_length = 0.125;
80
80
  this.clef = { type: 'treble', verticalPos: 0 };
81
+ this.octave = 0;
81
82
  this.next_note_duration = 0;
82
83
  this.start_new_line = true;
83
84
  this.is_in_header = true;
@@ -408,6 +408,16 @@ var parseKeyVoice = {};
408
408
  multilineVars.clef.staffscale = tokens[0].floatt;
409
409
  tokens.shift();
410
410
  break;
411
+ case "octave":
412
+ tokens.shift();
413
+ if (tokens.length === 0) { warn("Expected = after octave", str, 0); return ret; }
414
+ token = tokens.shift();
415
+ if (token.token !== "=") { warn("Expected = after octave", str, token.start); break; }
416
+ if (tokens.length === 0) { warn("Expected parameter after octave=", str, 0); return ret; }
417
+ if (tokens[0].type !== 'number') { warn("Expected number after octave", str, tokens[0].start); break; }
418
+ multilineVars.octave = tokens[0].intt;
419
+ tokens.shift();
420
+ break;
411
421
  case "style":
412
422
  tokens.shift();
413
423
  if (tokens.length === 0) { warn("Expected = after style", str, 0); return ret; }
@@ -716,7 +726,6 @@ var parseKeyVoice = {};
716
726
  addNextTokenToVoiceInfo(id, 'staffscale', 'number');
717
727
  break;
718
728
  case 'octave':
719
- // TODO-PER: This is accepted, but not implemented, yet.
720
729
  addNextTokenToVoiceInfo(id, 'octave', 'number');
721
730
  break;
722
731
  case 'volume':
@@ -1128,6 +1128,7 @@ var getCoreNote = function(line, index, el, canHaveBrokenRhythm) {
1128
1128
  case 'g':
1129
1129
  if (state === 'startSlur' || state === 'sharp2' || state === 'flat2' || state === 'pitch') {
1130
1130
  el.pitch = pitches[line.charAt(index)];
1131
+ el.pitch += 7 * (multilineVars.currentVoice && multilineVars.currentVoice.octave !== undefined ? multilineVars.currentVoice.octave : multilineVars.octave);
1131
1132
  el.name = line.charAt(index);
1132
1133
  if (el.accidental)
1133
1134
  el.name = accMap[el.accidental] + el.name;
@@ -55,6 +55,18 @@ var pitchMap = {
55
55
  n13: "=b",
56
56
  s13: "^b",
57
57
  x13: "b",
58
+ f14: "_c'",
59
+ n14: "=c'",
60
+ s14: "^c'",
61
+ x14: "c'",
62
+ f15: "_d'",
63
+ n15: "=d'",
64
+ s15: "^d'",
65
+ x15: "d'",
66
+ f16: "_e'",
67
+ n16: "=e'",
68
+ s16: "^e'",
69
+ x16: "e'",
58
70
  }
59
71
 
60
72
  function pitchesToPerc(pitchObj) {
@@ -103,7 +103,7 @@ function handleChordNotes(self, notes) {
103
103
 
104
104
  function noteToNumber(self, note, stringNumber, secondPosition , firstSize) {
105
105
  var strings = self.strings;
106
- note.checkKeyAccidentals(self.accidentals) ;
106
+ note.checkKeyAccidentals(self.accidentals, self.measureAccidentals) ;
107
107
  if (secondPosition) {
108
108
  strings = secondPosition;
109
109
  }
@@ -131,6 +131,22 @@ function noteToNumber(self, note, stringNumber, secondPosition , firstSize) {
131
131
  }
132
132
 
133
133
  function toNumber(self, note) {
134
+ if (note.isAltered || note.natural) {
135
+ var acc;
136
+ if (note.isFlat) {
137
+ if (note.isDouble)
138
+ acc = "__"
139
+ else
140
+ acc = "_"
141
+ } else if (note.isSharp) {
142
+ if (note.isDouble)
143
+ acc = "^^"
144
+ else
145
+ acc = "^"
146
+ } else if (note.natural)
147
+ acc = "="
148
+ self.measureAccidentals[note.name.toUpperCase()] = acc
149
+ }
134
150
  var num = null;
135
151
  var str = 0;
136
152
  var lowestString = self.strings[self.strings.length - 1];
@@ -254,6 +270,7 @@ function StringPatterns(plugin) {
254
270
  // override default
255
271
  this.highestNote = highestNote;
256
272
  }
273
+ this.measureAccidentals = {}
257
274
  this.capo = 0;
258
275
  if (capo) {
259
276
  this.capo = capo;
@@ -115,7 +115,18 @@ TabNote.prototype.isLowerThan = function (note) {
115
115
  return false;
116
116
  };
117
117
 
118
- TabNote.prototype.checkKeyAccidentals = function(accidentals) {
118
+ TabNote.prototype.checkKeyAccidentals = function(accidentals, measureAccidentals) {
119
+ if (this.isAltered || this.natural)
120
+ return
121
+ if (measureAccidentals[this.name.toUpperCase()]) {
122
+ 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;
128
+ }
129
+ }
119
130
  if (accidentals) {
120
131
  var curNote = this.name;
121
132
  for (var iii = 0; iii < accidentals.length; iii++) {
@@ -27,6 +27,8 @@ function cloneAbsolute(absSrc) {
27
27
  if (returned.abcelem.el_type === "note")
28
28
  returned.abcelem.el_type = 'tabNumber';
29
29
  }
30
+ // TODO-PER: This fixes the classes because the element isn't created at the right time.
31
+ absSrc.cloned = returned
30
32
  return returned;
31
33
  }
32
34
 
@@ -226,6 +228,7 @@ TabAbsoluteElements.prototype.build = function (plugin,
226
228
  }
227
229
  break;
228
230
  case 'bar':
231
+ plugin.semantics.strings.measureAccidentals = {}
229
232
  var lastBar = false;
230
233
  if (ii === source.children.length-1) {
231
234
  // used for final line bar drawing
@@ -228,6 +228,7 @@ TabRenderer.prototype.doLayout = function () {
228
228
  for (var ii = 0; ii < nbVoices; ii++) {
229
229
  var tabVoice = new VoiceElement(0, 0);
230
230
  var nameHeight = buildTabName(this, tabVoice) / spacing.STEP;
231
+ nameHeight = Math.max(nameHeight, 1) // If there is no label for the tab line, then there needs to be a little padding
231
232
  staffGroup.staffs[this.staffIndex].top += nameHeight;
232
233
  staffGroup.height += nameHeight * spacing.STEP;
233
234
  tabVoice.staff = staffGroupInfos;
@@ -920,8 +920,11 @@ AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff
920
920
 
921
921
  AbstractEngraver.prototype.addMeasureNumber = function (number, abselem) {
922
922
  var measureNumDim = this.getTextSize.calc(number, "measurefont", 'bar-number');
923
- var dx = measureNumDim.width > 18 && abselem.abcelem.type === "treble" ? -7 : 0;
924
- abselem.addFixed(new RelativeElement(number, dx, measureNumDim.width, 11+measureNumDim.height / spacing.STEP, {type:"barNumber", dim: this.getTextSize.attr("measurefont", 'bar-number')}));
923
+ var dx = 0;
924
+ if (abselem.isClef) // If this is a clef rather than bar line, then the number shouldn't be centered because it could overlap the left side. This is an easy way to let it be centered but move it over, too.
925
+ dx += measureNumDim.width / 2
926
+ var vert = measureNumDim.width > 10 && abselem.abcelem.type === "treble" ? 13 : 11
927
+ abselem.addFixed(new RelativeElement(number, dx, measureNumDim.width, vert+measureNumDim.height / spacing.STEP, {type:"barNumber", dim: this.getTextSize.attr("measurefont", 'bar-number')}));
925
928
  };
926
929
 
927
930
  AbstractEngraver.prototype.createBarLine = function (voice, elem, isFirstStaff) {
@@ -79,6 +79,10 @@ Classes.prototype.generate = function (c) {
79
79
  return "";
80
80
  var ret = [];
81
81
  if (c && c.length > 0) ret.push(c);
82
+ if (c === "tab-number") // TODO-PER-HACK! straighten out the tablature
83
+ return ret.join(' ')
84
+ if (c === "text instrument-name")
85
+ return "abcjs-text abcjs-instrument-name"
82
86
  if (this.lineNumber !== null) ret.push("l"+this.lineNumber);
83
87
  if (this.measureNumber !== null) ret.push("m"+this.measureNumber);
84
88
  if (this.measureNumber !== null) ret.push("mm"+this.measureTotal()); // measureNumber is null between measures so this is still the test for measureTotal
@@ -32,6 +32,14 @@ function drawAbsolute(renderer, params, bartop, selectables, staffPos) {
32
32
  }
33
33
  var g = elementGroup.endGroup(klass, params.type);
34
34
  if (g) {
35
+ // TODO-PER-HACK! This corrects the classes because the tablature is not being created at the right time.
36
+ if (params.cloned) {
37
+ params.cloned.overrideClasses = g.className.baseVal
38
+ }
39
+ if (params.overrideClasses) {
40
+ var type = g.classList && g.classList.length > 0 ? g.classList[0] + ' ' : ''
41
+ g.setAttribute("class", type + params.overrideClasses)
42
+ }
35
43
  if (isTempo) {
36
44
  params.startChar = params.abcelem.startChar;
37
45
  params.endChar = params.abcelem.endChar;
@@ -357,10 +357,10 @@ function notifySelect(target, dragStep, dragMax, dragIndex, ev) {
357
357
  if (target.staffPos)
358
358
  analysis.staffPos = target.staffPos;
359
359
  var closest = ev.target;
360
- while (closest && !closest.dataset.name && closest.tagName.toLowerCase() !== 'svg')
360
+ while (closest && closest.dataset && !closest.dataset.name && closest.tagName.toLowerCase() !== 'svg')
361
361
  closest = closest.parentNode;
362
362
  var parent = ev.target;
363
- while (parent && !parent.dataset.index && parent.tagName.toLowerCase() !== 'svg')
363
+ while (parent && parent.dataset && !parent.dataset.index && parent.tagName.toLowerCase() !== 'svg')
364
364
  parent = parent.parentNode;
365
365
  analysis.name = parent.dataset.name;
366
366
  analysis.clickedName = closest.dataset.name;
package/version.js CHANGED
@@ -1,3 +1,3 @@
1
- var version = '6.1.6';
1
+ var version = '6.1.8';
2
2
 
3
3
  module.exports = version;