abcjs 6.4.2 → 6.4.4

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.
@@ -1,5 +1,5 @@
1
1
  /**!
2
- Copyright (c) 2009-2023 Paul Rosen and Gregory Dyke
2
+ Copyright (c) 2009-2024 Paul Rosen and Gregory Dyke
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**!
2
- Copyright (c) 2009-2023 Paul Rosen and Gregory Dyke
2
+ Copyright (c) 2009-2024 Paul Rosen and Gregory Dyke
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
package/license.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**!
2
- Copyright (c) 2009-2023 Paul Rosen and Gregory Dyke
2
+ Copyright (c) 2009-2024 Paul Rosen and Gregory Dyke
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abcjs",
3
- "version": "6.4.2",
3
+ "version": "6.4.4",
4
4
  "description": "Renderer for abc music notation",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
package/plugin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**!
2
- Copyright (c) 2009-2023 Paul Rosen and Gregory Dyke
2
+ Copyright (c) 2009-2024 Paul Rosen and Gregory Dyke
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
@@ -551,6 +551,8 @@ var Tune = function() {
551
551
 
552
552
  this.getBpm = function(tempo) {
553
553
  var bpm;
554
+ if (!tempo)
555
+ tempo = this.metaText ? this.metaText.tempo : null;
554
556
  if (tempo) {
555
557
  bpm = tempo.bpm;
556
558
  var beatLength = this.getBeatLength();
@@ -294,8 +294,7 @@ MusicParser.prototype.parseMusic = function(line) {
294
294
  else if (bar.endEnding)
295
295
  multilineVars.barFirstEndingNum = undefined;
296
296
  if (bar.type !== 'bar_invisible' && multilineVars.measureNotEmpty) {
297
- var isFirstVoice = multilineVars.currentVoice === undefined || (multilineVars.currentVoice.staffNum === 0 && multilineVars.currentVoice.index === 0);
298
- if (isFirstVoice) {
297
+ if (isFirstVoice()) {
299
298
  multilineVars.currBarNumber++;
300
299
  if (multilineVars.barNumbers && multilineVars.currBarNumber % multilineVars.barNumbers === 0)
301
300
  bar.barNumber = multilineVars.currBarNumber;
@@ -510,6 +509,8 @@ MusicParser.prototype.parseMusic = function(line) {
510
509
  if (el.startTie !== undefined) el.pitches[0].startTie = el.startTie;
511
510
  } else {
512
511
  el.rest = core.rest;
512
+ if (core.rest.type === 'multimeasure' && isFirstVoice())
513
+ multilineVars.currBarNumber += core.rest.text - 1 // The minus one is because the measure with the rest is already counted once normally.
513
514
  if (core.endSlur !== undefined) el.endSlur = core.endSlur;
514
515
  if (core.endTie !== undefined) el.rest.endTie = core.endTie;
515
516
  if (core.startSlur !== undefined) el.startSlur = core.startSlur;
@@ -615,23 +616,38 @@ var letter_to_chord = function(line, i) {
615
616
  chord[1] = chord[1].substring(1);
616
617
  chord[2] = 'right';
617
618
  } else if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '@') {
618
- // @-15,5.7
619
- chord[1] = chord[1].substring(1);
620
- var x = tokenizer.getFloat(chord[1]);
621
- if (x.digits === 0)
622
- warn("Missing first position in absolutely positioned annotation.", line , i);
623
- chord[1] = chord[1].substring(x.digits);
624
- if (chord[1][0] !== ',')
625
- warn("Missing comma absolutely positioned annotation.", line , i);
626
- chord[1] = chord[1].substring(1);
627
- var y = tokenizer.getFloat(chord[1]);
628
- if (y.digits === 0)
629
- warn("Missing second position in absolutely positioned annotation.", line , i);
630
- chord[1] = chord[1].substring(y.digits);
631
- var ws = tokenizer.skipWhiteSpace(chord[1]);
632
- chord[1] = chord[1].substring(ws);
633
- chord[2] = null;
634
- chord[3] = { x: x.value, y: y.value };
619
+ // @-15,5.7
620
+ chord[1] = chord[1].substring(1);
621
+ var x = tokenizer.getFloat(chord[1]);
622
+ if (x.digits === 0){
623
+ warn("Missing first position in absolutely positioned annotation.", line, i);
624
+ chord[1] = chord[1].replace("@","");
625
+ chord[2] = 'above';
626
+ return chord;
627
+ }
628
+ chord[1] = chord[1].substring(x.digits);
629
+ if (chord[1][0] !== ','){
630
+ warn("Missing comma absolutely positioned annotation.", line, i);
631
+ chord[1] = chord[1].replace("@","");
632
+ chord[2] = 'above';
633
+ return chord;
634
+ }
635
+ chord[1] = chord[1].substring(1);
636
+ var y = tokenizer.getFloat(chord[1]);
637
+ if (y.digits === 0){
638
+ warn("Missing second position in absolutely positioned annotation.", line, i);
639
+ chord[1] = chord[1].replace("@","");
640
+ chord[2] = 'above';
641
+ return chord;
642
+ }
643
+ chord[1] = chord[1].substring(y.digits);
644
+ var ws = tokenizer.skipWhiteSpace(chord[1]);
645
+ chord[1] = chord[1].substring(ws);
646
+ chord[2] = null;
647
+ chord[3] = {
648
+ x: x.value,
649
+ y: y.value
650
+ };
635
651
  } else {
636
652
  if (multilineVars.freegchord !== true) {
637
653
  chord[1] = chord[1].replace(/([ABCDEFG0-9])b/g, "$1♭");
@@ -1015,8 +1031,7 @@ MusicParser.prototype.startNewLine = function() {
1015
1031
  params.currentVoiceName = voices[mv]
1016
1032
  }
1017
1033
  }
1018
- var isFirstVoice = multilineVars.currentVoice === undefined || (multilineVars.currentVoice.staffNum === 0 && multilineVars.currentVoice.index === 0);
1019
- if (multilineVars.barNumbers === 0 && isFirstVoice && multilineVars.currBarNumber !== 1)
1034
+ if (multilineVars.barNumbers === 0 && isFirstVoice() && multilineVars.currBarNumber !== 1)
1020
1035
  params.barNumber = multilineVars.currBarNumber;
1021
1036
  tuneBuilder.startNewLine(params);
1022
1037
  if (multilineVars.key.impliedNaturals)
@@ -1300,4 +1315,8 @@ var getBrokenRhythm = function(line, index) {
1300
1315
  return null;
1301
1316
  };
1302
1317
 
1318
+ function isFirstVoice() {
1319
+ return multilineVars.currentVoice === undefined || (multilineVars.currentVoice.staffNum === 0 && multilineVars.currentVoice.index === 0);
1320
+ }
1321
+
1303
1322
  module.exports = MusicParser;
@@ -382,7 +382,7 @@ var TuneBuilder = function (tune) {
382
382
 
383
383
  this.getCurrentVoice = function () {
384
384
  //console.log("getCurrentVoice", tune.lineNum)
385
- var currLine = tune.lines[tune.lineNum];
385
+ var currLine = getPrevMusicLine(tune.lines, tune.lineNum)
386
386
  if (!currLine)
387
387
  return null;
388
388
  var currStaff = currLine.staff[tune.staffNum];
@@ -803,6 +803,16 @@ function wrapMusicLines(lines, barsperstaff) {
803
803
  return false;
804
804
  }
805
805
 
806
+ function getPrevMusicLine(lines, currentLine) {
807
+ // If the current line doesn't have music, search backwards until one is found.
808
+ while (currentLine >= 0) {
809
+ if (lines[currentLine].staff)
810
+ return lines[currentLine];
811
+ currentLine--;
812
+ }
813
+ return null;
814
+ }
815
+
806
816
  function getNextMusicLine(lines, currentLine) {
807
817
  currentLine++;
808
818
  while (lines.length > currentLine) {
@@ -415,10 +415,10 @@ var pitchesToPerc = require('./pitches-to-perc');
415
415
 
416
416
  switch (noteModification) {
417
417
  case "trill":
418
- var note = 1;
418
+ var note = 2;
419
419
  while (runningDuration > 0) {
420
420
  currentTrack.push({ cmd: 'note', pitch: p.pitch+note, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
421
- note = (note === 1) ? 0 : 1;
421
+ note = (note === 2) ? 0 : 2;
422
422
  runningDuration -= shortestNote;
423
423
  start += shortestNote;
424
424
  }
@@ -427,7 +427,7 @@ var pitchesToPerc = require('./pitches-to-perc');
427
427
  currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
428
428
  runningDuration -= shortestNote;
429
429
  start += shortestNote;
430
- currentTrack.push({ cmd: 'note', pitch: p.pitch+1, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
430
+ currentTrack.push({ cmd: 'note', pitch: p.pitch+2, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
431
431
  runningDuration -= shortestNote;
432
432
  start += shortestNote;
433
433
  currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start, duration: runningDuration, gap: 0, instrument: currentInstrument });
@@ -436,18 +436,17 @@ var pitchesToPerc = require('./pitches-to-perc');
436
436
  currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
437
437
  runningDuration -= shortestNote;
438
438
  start += shortestNote;
439
- currentTrack.push({ cmd: 'note', pitch: p.pitch-1, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
439
+ currentTrack.push({ cmd: 'note', pitch: p.pitch-2, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
440
440
  runningDuration -= shortestNote;
441
441
  start += shortestNote;
442
442
  currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start, duration: runningDuration, gap: 0, instrument: currentInstrument });
443
443
  break;
444
444
  case "turn":
445
- shortestNote = p.duration / 5;
446
- currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
447
- currentTrack.push({ cmd: 'note', pitch: p.pitch+1, volume: p.volume, start: start+shortestNote, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
448
- currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start+shortestNote*2, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
449
- currentTrack.push({ cmd: 'note', pitch: p.pitch+1, volume: p.volume, start: start+shortestNote*3, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
450
- currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start+shortestNote*4, duration: shortestNote, gap: 0, instrument: currentInstrument });
445
+ shortestNote = p.duration / 4;
446
+ currentTrack.push({ cmd: 'note', pitch: p.pitch+2, volume: p.volume, start: start, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
447
+ currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start+shortestNote, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
448
+ currentTrack.push({ cmd: 'note', pitch: p.pitch-1, volume: p.volume, start: start+shortestNote*2, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
449
+ currentTrack.push({ cmd: 'note', pitch: p.pitch, volume: p.volume, start: start+shortestNote*3, duration: shortestNote, gap: 0, instrument: currentInstrument, style: 'decoration' });
451
450
  break;
452
451
  case "roll":
453
452
  while (runningDuration > 0) {
@@ -198,6 +198,15 @@ ChordTrack.prototype.interpretChord = function (name) {
198
198
  while (chordTranspose > 8)
199
199
  chordTranspose -= 12;
200
200
  bass += chordTranspose;
201
+
202
+ // MAE 31 Aug 2024 - For visual transpose backup range issue
203
+ // If transposed below A or above G, bring it back in the normal backup range
204
+ if (bass < 33){
205
+ bass += 12;
206
+ }
207
+ else if (bass > 44){
208
+ bass -= 12;
209
+ }
201
210
 
202
211
  // MAE 17 Jun 2024 - Supporting octave shifted bass and chords
203
212
  var unshiftedBass = bass;
@@ -104,7 +104,7 @@ var midiSequencerLint = function(tune) {
104
104
  ret += element.channel;
105
105
  ret += '\n';
106
106
  break;
107
- case "gchord":
107
+ case "gchordOn":
108
108
  ret += "\t\t";
109
109
  ret += element.tacet ? 'tacet' : 'on';
110
110
  ret += '\n';
@@ -943,7 +943,8 @@ AbstractEngraver.prototype.addMeasureNumber = function (number, abselem) {
943
943
  var dx = 0;
944
944
  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.
945
945
  dx += measureNumDim.width / 2
946
- var vert = measureNumDim.width > 10 && abselem.abcelem.type === "treble" ? 13 : 11
946
+ // MAE 1 Oct 2024 - Change 13 to 13.5 since previously bar numbers were very slightly overlapping the top of the clef
947
+ var vert = measureNumDim.width > 10 && abselem.abcelem.type === "treble" ? 13.5 : 11
947
948
  abselem.addFixed(new RelativeElement(number, dx, measureNumDim.width, vert + measureNumDim.height / spacing.STEP, { type: "barNumber", dim: this.getTextSize.attr("measurefont", 'bar-number') }));
948
949
  };
949
950
 
@@ -177,22 +177,33 @@ AbsoluteElement.prototype.setLimit = function (member, child) {
177
177
  };
178
178
 
179
179
  AbsoluteElement.prototype._addChild = function (child) {
180
- // console.log("Relative:",child);
181
- child.parent = this;
182
- this.children[this.children.length] = child;
183
- this.pushTop(child.top);
184
- this.pushBottom(child.bottom);
185
- this.setLimit('tempoHeightAbove', child);
186
- this.setLimit('partHeightAbove', child);
187
- this.setLimit('volumeHeightAbove', child);
188
- this.setLimit('dynamicHeightAbove', child);
189
- this.setLimit('endingHeightAbove', child);
190
- this.setLimit('chordHeightAbove', child);
191
- this.setLimit('lyricHeightAbove', child);
192
- this.setLimit('lyricHeightBelow', child);
193
- this.setLimit('chordHeightBelow', child);
194
- this.setLimit('volumeHeightBelow', child);
195
- this.setLimit('dynamicHeightBelow', child);
180
+ // console.log("Relative:",child);
181
+
182
+ // MAE 30 Sep 2024 - To avoid extra space for chords if there is only a bar number on the clef
183
+ var okToPushTop = true;
184
+ if ((this.abcelem.el_type == "clef") && (child.type == "barNumber")){
185
+ okToPushTop = false;
186
+ }
187
+
188
+ child.parent = this;
189
+ this.children[this.children.length] = child;
190
+
191
+ if (okToPushTop){
192
+ this.pushTop(child.top);
193
+ }
194
+
195
+ this.pushBottom(child.bottom);
196
+ this.setLimit('tempoHeightAbove', child);
197
+ this.setLimit('partHeightAbove', child);
198
+ this.setLimit('volumeHeightAbove', child);
199
+ this.setLimit('dynamicHeightAbove', child);
200
+ this.setLimit('endingHeightAbove', child);
201
+ this.setLimit('chordHeightAbove', child);
202
+ this.setLimit('lyricHeightAbove', child);
203
+ this.setLimit('lyricHeightBelow', child);
204
+ this.setLimit('chordHeightBelow', child);
205
+ this.setLimit('volumeHeightBelow', child);
206
+ this.setLimit('dynamicHeightBelow', child);
196
207
  };
197
208
 
198
209
  AbsoluteElement.prototype.pushTop = function (top) {
@@ -225,4 +225,30 @@ TieElem.prototype.avoidCollisionAbove = function () {
225
225
  }
226
226
  };
227
227
 
228
+ TieElem.prototype.getYBounds = function () {
229
+ var lineStartX = 10 // TODO-PER: I'm not sure where to get this number from but it probably doesn't matter much
230
+ var lineEndX = 1000 // TODO-PER: I'm not sure where to get this number from but it probably doesn't matter much
231
+ if (this.isTie) {
232
+ this.calcTieDirection();
233
+ this.calcX(lineStartX, lineEndX);
234
+ this.calcTieY();
235
+
236
+ } else {
237
+ this.calcSlurDirection();
238
+ this.calcX(lineStartX, lineEndX);
239
+ this.calcSlurY();
240
+ }
241
+ var top;
242
+ var bottom;
243
+ // TODO-PER: It's hard to tell how far the arc is, so I'm just using 3 as the max
244
+ if (this.above) {
245
+ bottom = Math.min(this.startY, this.endY)
246
+ top = bottom + 3
247
+ } else {
248
+ top = Math.min(this.startY, this.endY)
249
+ bottom = top - 3
250
+ }
251
+ return [ top, bottom ]
252
+ };
253
+
228
254
  module.exports = TieElem;
@@ -128,6 +128,14 @@ function setUpperAndLowerVoiceElements(positionY, voice, spacing) {
128
128
  case 'EndingElem':
129
129
  setUpperAndLowerEndingElements(positionY, abselem);
130
130
  break;
131
+ case 'TieElem':
132
+ // If a tie element is the highest or lowest thing then space might need to make room for it.
133
+ var yBounds = abselem.getYBounds()
134
+ voice.staff.top = Math.max(voice.staff.top, yBounds[0])
135
+ voice.staff.top = Math.max(voice.staff.top, yBounds[1])
136
+ voice.staff.bottom = Math.min(voice.staff.bottom, yBounds[0])
137
+ voice.staff.bottom = Math.min(voice.staff.bottom, yBounds[1])
138
+ break;
131
139
  }
132
140
  }
133
141
  }
package/test.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**!
2
- Copyright (c) 2009-2023 Paul Rosen and Gregory Dyke
2
+ Copyright (c) 2009-2024 Paul Rosen and Gregory Dyke
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
package/types/index.d.ts CHANGED
@@ -886,7 +886,7 @@ declare module 'abcjs' {
886
886
  getBarLength: NumberFunction;
887
887
  getBeatLength: NumberFunction;
888
888
  getBeatsPerMeasure: NumberFunction;
889
- getBpm: NumberFunction;
889
+ getBpm: (tempo?:TempoProperties) => number;
890
890
  getMeter: () => Meter;
891
891
  getMeterFraction: () => MeterFraction;
892
892
  getPickupLength: NumberFunction;
package/version.js CHANGED
@@ -1,3 +1,3 @@
1
- var version = '6.4.2';
1
+ var version = '6.4.4';
2
2
 
3
3
  module.exports = version;
package/temp.txt DELETED
@@ -1,12 +0,0 @@
1
- commit 747c5538cdfbb37eb6234356944b05855ff2921a
2
- Author: paulrosen <junk@paulrosen.net>
3
- Date: Sun Aug 4 10:08:14 2024 -0400
4
-
5
-
6
-
7
- commit 5b3d3d0f3f951e6dea3c22ded60b6baa9776e64c
8
- Author: paulrosen <junk@paulrosen.net>
9
- Date: Sun Jul 28 19:20:32 2024 -0400
10
-
11
- Start to refactor tablature and flatten the structure.
12
-