abcjs-rails 1.3 → 1.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.
@@ -65,8 +65,11 @@ ABCJS.TuneBook = function(book) {
65
65
 
66
66
  // for the user's convenience, parse and store the title separately. The title is between the first T: and the next \n
67
67
  var title = tune.pure.split("T:");
68
- title = title[1].split("\n");
69
- tune.title = title[0].replace(/^\s+|\s+$/g, '');;
68
+ if (title.length > 1) {
69
+ title = title[1].split("\n");
70
+ tune.title = title[0].replace(/^\s+|\s+$/g, '');;
71
+ } else
72
+ tune.title = "";
70
73
 
71
74
  // for the user's convenience, parse and store the id separately. The id is between the first X: and the next \n
72
75
  var id = tune.pure.substring(2,tune.pure.indexOf("\n"));
@@ -302,38 +302,39 @@ window.ABCJS.data.Tune = function() {
302
302
 
303
303
  // TODO-PER: This could be done faster as we go instead of as the last step.
304
304
  function fixClefPlacement(el) {
305
+ window.ABCJS.parse.parseKeyVoice.fixClef(el);
305
306
  //if (el.el_type === 'clef') {
306
- var min = -2;
307
- var max = 5;
308
- switch(el.type) {
309
- case 'treble+8':
310
- case 'treble-8':
311
- break;
312
- case 'bass':
313
- case 'bass+8':
314
- case 'bass-8':
315
- el.verticalPos = 20 + el.verticalPos; min += 6; max += 6;
316
- break;
317
- case 'tenor':
318
- case 'tenor+8':
319
- case 'tenor-8':
320
- el.verticalPos = - el.verticalPos; min = -40; max = 40;
321
- // el.verticalPos+=2; min += 6; max += 6;
322
- break;
323
- case 'alto':
324
- case 'alto+8':
325
- case 'alto-8':
326
- el.verticalPos = - el.verticalPos; min = -40; max = 40;
327
- // el.verticalPos-=2; min += 4; max += 4;
328
- break;
329
- }
330
- if (el.verticalPos < min) {
331
- while (el.verticalPos < min)
332
- el.verticalPos += 7;
333
- } else if (el.verticalPos > max) {
334
- while (el.verticalPos > max)
335
- el.verticalPos -= 7;
336
- }
307
+ // var min = -2;
308
+ // var max = 5;
309
+ // switch(el.type) {
310
+ // case 'treble+8':
311
+ // case 'treble-8':
312
+ // break;
313
+ // case 'bass':
314
+ // case 'bass+8':
315
+ // case 'bass-8':
316
+ // el.verticalPos = 20 + el.verticalPos; min += 6; max += 6;
317
+ // break;
318
+ // case 'tenor':
319
+ // case 'tenor+8':
320
+ // case 'tenor-8':
321
+ // el.verticalPos = - el.verticalPos; min = -40; max = 40;
322
+ //// el.verticalPos+=2; min += 6; max += 6;
323
+ // break;
324
+ // case 'alto':
325
+ // case 'alto+8':
326
+ // case 'alto-8':
327
+ // el.verticalPos = - el.verticalPos; min = -40; max = 40;
328
+ //// el.verticalPos-=2; min += 4; max += 4;
329
+ // break;
330
+ // }
331
+ // if (el.verticalPos < min) {
332
+ // while (el.verticalPos < min)
333
+ // el.verticalPos += 7;
334
+ // } else if (el.verticalPos > max) {
335
+ // while (el.verticalPos > max)
336
+ // el.verticalPos -= 7;
337
+ // }
337
338
  //}
338
339
  }
339
340
 
@@ -504,6 +505,16 @@ window.ABCJS.data.Tune = function() {
504
505
  if (type === 'clef')
505
506
  this.lines[this.lineNum].staff[this.staffNum].workingClef = hashParams;
506
507
 
508
+ // If this is the first item in this staff, then we might have to initialize the staff, first.
509
+ if (this.lines[this.lineNum].staff.length <= this.staffNum) {
510
+ this.lines[this.lineNum].staff[this.staffNum] = {};
511
+ this.lines[this.lineNum].staff[this.staffNum].clef = window.ABCJS.parse.clone(this.lines[this.lineNum].staff[0].clef);
512
+ this.lines[this.lineNum].staff[this.staffNum].key = window.ABCJS.parse.clone(this.lines[this.lineNum].staff[0].key);
513
+ this.lines[this.lineNum].staff[this.staffNum].meter = window.ABCJS.parse.clone(this.lines[this.lineNum].staff[0].meter);
514
+ this.lines[this.lineNum].staff[this.staffNum].workingClef = window.ABCJS.parse.clone(this.lines[this.lineNum].staff[0].workingClef);
515
+ this.lines[this.lineNum].staff[this.staffNum].voices = [[]];
516
+ }
517
+
507
518
  // These elements should not be added twice, so if the element exists on this line without a note or bar before it, just replace the staff version.
508
519
  var voice = this.lines[this.lineNum].staff[this.staffNum].voices[this.voiceNum];
509
520
  for (var i = 0; i < voice.length; i++) {
@@ -567,7 +567,10 @@ ABCJS.midi.MidiWriter.prototype.writeABCElement = function(elem) {
567
567
  ABCJS.midi.MidiWriter.prototype.writeNote = function(elem) {
568
568
 
569
569
  if (elem.startTriplet) {
570
- this.multiplier=2/3;
570
+ if (elem.startTriplet === 2)
571
+ this.multiplier = 3/2;
572
+ else
573
+ this.multiplier=(elem.startTriplet-1)/elem.startTriplet;
571
574
  }
572
575
 
573
576
  var mididuration = elem.duration*this.baseduration*this.multiplier;
@@ -1313,6 +1313,8 @@ window.ABCJS.parse.Parse = function() {
1313
1313
  if (switches && switches.print)
1314
1314
  tune.media = 'print';
1315
1315
  multilineVars.reset();
1316
+ header.reset(tokenizer, warn, multilineVars, tune);
1317
+
1316
1318
  // Take care of whatever line endings come our way
1317
1319
  strTune = window.ABCJS.parse.gsub(strTune, '\r\n', '\n');
1318
1320
  strTune = window.ABCJS.parse.gsub(strTune, '\r', '\n');
@@ -23,9 +23,11 @@ if (!window.ABCJS.parse)
23
23
  window.ABCJS.parse = {};
24
24
 
25
25
  window.ABCJS.parse.ParseHeader = function(tokenizer, warn, multilineVars, tune) {
26
- window.ABCJS.parse.parseKeyVoice.initialize(tokenizer, warn, multilineVars, tune);
27
- window.ABCJS.parse.parseDirective.initialize(tokenizer, warn, multilineVars, tune);
28
-
26
+ this.reset = function(tokenizer, warn, multilineVars, tune) {
27
+ window.ABCJS.parse.parseKeyVoice.initialize(tokenizer, warn, multilineVars, tune);
28
+ window.ABCJS.parse.parseDirective.initialize(tokenizer, warn, multilineVars, tune);
29
+ };
30
+ this.reset(tokenizer, warn, multilineVars, tune);
29
31
 
30
32
  this.setTitle = function(title) {
31
33
  if (multilineVars.hasMainTitle)
@@ -170,37 +170,57 @@ window.ABCJS.parse.parseKeyVoice = {};
170
170
  return keys[keyName];
171
171
  };
172
172
 
173
+ var clefLines = {
174
+ 'treble': { clef: 'treble', pitch: 4, mid: 0 },
175
+ 'treble+8': { clef: 'treble+8', pitch: 4, mid: 0 },
176
+ 'treble-8': { clef: 'treble-8', pitch: 4, mid: 0 },
177
+ 'treble1': { clef: 'treble', pitch: 2, mid: 2 },
178
+ 'treble2': { clef: 'treble', pitch: 4, mid: 0 },
179
+ 'treble3': { clef: 'treble', pitch: 6, mid: -2 },
180
+ 'treble4': { clef: 'treble', pitch: 8, mid: -4 },
181
+ 'treble5': { clef: 'treble', pitch: 10, mid: -6 },
182
+ 'perc': { clef: 'perc', pitch: 6, mid: 0 },
183
+ 'none': { clef: 'none', mid: 0 },
184
+ 'bass': { clef: 'bass', pitch: 8, mid: -12 },
185
+ 'bass+8': { clef: 'bass+8', pitch: 8, mid: -12 },
186
+ 'bass-8': { clef: 'bass-8', pitch: 8, mid: -12 },
187
+ 'bass+16': { clef: 'bass', pitch: 8, mid: -12 },
188
+ 'bass-16': { clef: 'bass', pitch: 8, mid: -12 },
189
+ 'bass1': { clef: 'bass', pitch: 2, mid: -6 },
190
+ 'bass2': { clef: 'bass', pitch: 4, mid: -8 },
191
+ 'bass3': { clef: 'bass', pitch: 6, mid: -10 },
192
+ 'bass4': { clef: 'bass', pitch: 8, mid: -12 },
193
+ 'bass5': { clef: 'bass', pitch: 10, mid: -14 },
194
+ 'tenor': { clef: 'alto', pitch: 8, mid: -8 },
195
+ 'tenor1': { clef: 'alto', pitch: 2, mid: -2 },
196
+ 'tenor2': { clef: 'alto', pitch: 4, mid: -4 },
197
+ 'tenor3': { clef: 'alto', pitch: 6, mid: -6 },
198
+ 'tenor4': { clef: 'alto', pitch: 8, mid: -8 },
199
+ 'tenor5': { clef: 'alto', pitch: 10, mid: -10 },
200
+ 'alto': { clef: 'alto', pitch: 6, mid: -6 },
201
+ 'alto1': { clef: 'alto', pitch: 2, mid: -2 },
202
+ 'alto2': { clef: 'alto', pitch: 4, mid: -4 },
203
+ 'alto3': { clef: 'alto', pitch: 6, mid: -6 },
204
+ 'alto4': { clef: 'alto', pitch: 8, mid: -8 },
205
+ 'alto5': { clef: 'alto', pitch: 10, mid: -10 },
206
+ 'alto+8': { clef: 'alto+8', pitch: 6, mid: -6 },
207
+ 'alto-8': { clef: 'alto-8', pitch: 6, mid: -6 }
208
+ };
209
+
173
210
  var calcMiddle = function(clef, oct) {
174
- var mid = 0;
175
- switch(clef) {
176
- case 'treble':
177
- case 'perc':
178
- case 'none':
179
- case 'treble+8':
180
- case 'treble-8':
181
- break;
182
- case 'bass3':
183
- case 'bass':
184
- case 'bass+8':
185
- case 'bass-8':
186
- case 'bass+16':
187
- case 'bass-16':
188
- mid = -12;
189
- break;
190
- case 'tenor':
191
- mid = -8;
192
- break;
193
- case 'alto2':
194
- case 'alto1':
195
- case 'alto':
196
- case 'alto+8':
197
- case 'alto-8':
198
- mid = -6;
199
- break;
200
- }
211
+ var value = clefLines[clef];
212
+ var mid = value ? value.mid : 0;
201
213
  return mid+oct;
202
214
  };
203
215
 
216
+ window.ABCJS.parse.parseKeyVoice.fixClef = function(clef) {
217
+ var value = clefLines[clef.type];
218
+ if (value) {
219
+ clef.clefPos = value.pitch;
220
+ clef.type = value.clef;
221
+ }
222
+ };
223
+
204
224
  window.ABCJS.parse.parseKeyVoice.deepCopyKey = function(key) {
205
225
  var ret = { accidentals: [], root: key.root, acc: key.acc, mode: key.mode };
206
226
  window.ABCJS.parse.each(key.accidentals, function(k) {
@@ -44,7 +44,7 @@ ABCJS.write.StaffGroupElement.prototype.finished = function() {
44
44
  return true;
45
45
  };
46
46
 
47
- ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, printer) {
47
+ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, printer, debug) {
48
48
  this.spacingunits = 0; // number of space units taken up (as opposed to fixed width). Layout engine then decides how many a pixels a space unit should be
49
49
  this.minspace = 1000; // a big number to start off with
50
50
  var x = printer.paddingleft;
@@ -62,6 +62,7 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, printer) {
62
62
  this.startx=x;
63
63
 
64
64
  var currentduration = 0;
65
+ if (debug) console.log("init layout");
65
66
  for (i=0;i<this.voices.length;i++) {
66
67
  this.voices[i].beginLayout(x);
67
68
  }
@@ -73,6 +74,8 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, printer) {
73
74
  if (!this.voices[i].layoutEnded() && (!currentduration || this.voices[i].getDurationIndex()<currentduration))
74
75
  currentduration=this.voices[i].getDurationIndex();
75
76
  }
77
+ if (debug) console.log("currentduration: ",currentduration);
78
+
76
79
 
77
80
  // isolate voices at current duration level
78
81
  var currentvoices = [];
@@ -80,8 +83,10 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, printer) {
80
83
  for (i=0;i<this.voices.length;i++) {
81
84
  if (this.voices[i].getDurationIndex() !== currentduration) {
82
85
  othervoices.push(this.voices[i]);
86
+ //console.log("out: voice ",i);
83
87
  } else {
84
88
  currentvoices.push(this.voices[i]);
89
+ if (debug) console.log("in: voice ",i);
85
90
  }
86
91
  }
87
92
 
@@ -200,6 +205,7 @@ ABCJS.write.VoiceElement.prototype.addOther = function (child) {
200
205
  ABCJS.write.VoiceElement.prototype.updateIndices = function () {
201
206
  if (!this.layoutEnded()) {
202
207
  this.durationindex += this.children[this.i].duration;
208
+ if (this.children[this.i].duration===0) this.durationindex = Math.round(this.durationindex*64)/64; // everytime we meet a barline, do rounding to nearest 64th
203
209
  this.i++;
204
210
  this.minx = this.nextminx;
205
211
  }
@@ -282,8 +288,9 @@ ABCJS.write.VoiceElement.prototype.draw = function (printer, bartop) {
282
288
 
283
289
  };
284
290
 
285
-
286
- ABCJS.write.AbsoluteElement = function(abcelem, duration, minspacing) { // spacing which must be taken on top of the width
291
+ // duration - actual musical duration - different from notehead duration in triplets. refer to abcelem to get the notehead duration
292
+ // minspacing - spacing which must be taken on top of the width defined by the duration
293
+ ABCJS.write.AbsoluteElement = function(abcelem, duration, minspacing) {
287
294
  this.abcelem = abcelem;
288
295
  this.duration = duration;
289
296
  this.minspacing = minspacing || 0;
@@ -744,7 +751,7 @@ ABCJS.write.BeamElem.prototype.drawStems = function(printer) {
744
751
 
745
752
  var sy = (this.asc) ? 1.5*ABCJS.write.spacing.STEP: -1.5*ABCJS.write.spacing.STEP;
746
753
  if (this.isgrace) sy = sy*2/3;
747
- for (var durlog=ABCJS.write.getDurlog(this.elems[i].duration); durlog<-3; durlog++) {
754
+ for (var durlog=ABCJS.write.getDurlog(this.elems[i].abcelem.duration); durlog<-3; durlog++) { // get the duration via abcelem because of triplets
748
755
  if (auxbeams[-4-durlog]) {
749
756
  auxbeams[-4-durlog].single = false;
750
757
  } else {
@@ -754,7 +761,7 @@ ABCJS.write.BeamElem.prototype.drawStems = function(printer) {
754
761
  }
755
762
 
756
763
  for (var j=auxbeams.length-1;j>=0;j--) {
757
- if (i===ii-1 || ABCJS.write.getDurlog(this.elems[i+1].duration)>(-j-4)) {
764
+ if (i===ii-1 || ABCJS.write.getDurlog(this.elems[i+1].abcelem.duration)>(-j-4)) {
758
765
 
759
766
  var auxbeamendx = x;
760
767
  var auxbeamendy = bary + sy*(j+1);
@@ -49,6 +49,7 @@ ABCJS.write.Layout = function(glyphs, bagpipes) {
49
49
  this.s = 0; // current staff number
50
50
  this.v = 0; // current voice number on current staff
51
51
  this.stafflines = 5;
52
+ this.tripletmultiplier = 1;
52
53
  };
53
54
 
54
55
  ABCJS.write.Layout.prototype.getCurrentVoiceId = function() {
@@ -255,14 +256,24 @@ ABCJS.write.Layout.prototype.printNote = function(elem, nostem, dontDraw) { //st
255
256
  var width, p1, p2, dx;
256
257
 
257
258
  var duration = ABCJS.write.getDuration(elem);
258
- var durlog = Math.floor(Math.log(duration)/Math.log(2));
259
+ if (duration === 0) { duration = 0.25; nostem = true; } //PER: zero duration will draw a quarter note head.
260
+ var durlog = Math.floor(Math.log(duration)/Math.log(2)); //TODO use getDurlog
259
261
  var dot=0;
260
262
 
261
263
  for (var tot = Math.pow(2,durlog), inc=tot/2; tot<duration; dot++,tot+=inc,inc/=2);
262
264
 
263
- var abselem = new ABCJS.write.AbsoluteElement(elem, duration, 1);
265
+
266
+ if (elem.startTriplet) {
267
+ if (elem.startTriplet === 2)
268
+ this.tripletmultiplier = 3/2;
269
+ else
270
+ this.tripletmultiplier=(elem.startTriplet-1)/elem.startTriplet;
271
+ }
272
+
264
273
 
274
+ var abselem = new ABCJS.write.AbsoluteElement(elem, duration * this.tripletmultiplier, 1);
265
275
 
276
+
266
277
  if (elem.rest) {
267
278
  var restpitch = 7;
268
279
  if (this.stemdir==="down") restpitch = 3;
@@ -306,8 +317,8 @@ ABCJS.write.Layout.prototype.printNote = function(elem, nostem, dontDraw) { //st
306
317
  var delta = (dir==="down")?prev.pitch-curr.pitch:curr.pitch-prev.pitch;
307
318
  if (delta<=1 && !prev.printer_shift) {
308
319
  curr.printer_shift=(delta)?"different":"same";
309
- if (curr.pitch > 11 || curr.pitch < 1) { // PER: add extra ledger line
310
- additionalLedgers.push(curr.pitch - (curr.pitch%2));
320
+ if (curr.verticalPos > 11 || curr.verticalPos < 1) { // PER: add extra ledger line
321
+ additionalLedgers.push(curr.verticalPos - (curr.verticalPos%2));
311
322
  }
312
323
  if (dir==="down") {
313
324
  this.roomtaken = this.glyphs.getSymbolWidth(this.chartable.note[-durlog])+2;
@@ -495,11 +506,19 @@ ABCJS.write.Layout.prototype.printNote = function(elem, nostem, dontDraw) { //st
495
506
  abselem.addRight(new ABCJS.write.RelativeElement(elem.chord[i].name, x, this.glyphs.getSymbolWidth(elem.chord[i].name[0])+4, y, {type:"text"}));
496
507
  break;
497
508
  case "below":
498
- y = -3;
499
- abselem.addChild(new ABCJS.write.RelativeElement(elem.chord[i].name, x, 0, y, {type:"text"}));
509
+ y = elem.minpitch-4;
510
+ if (y > -3) y = -3;
511
+ var eachLine = elem.chord[i].name.split("\n");
512
+ for (var ii = 0; ii < eachLine.length; ii++) {
513
+ abselem.addChild(new ABCJS.write.RelativeElement(eachLine[ii], x, 0, y, {type:"text"}));
514
+ y -= 3; // TODO-PER: This should actually be based on the font height.
515
+ }
500
516
  break;
501
517
  default:
502
- abselem.addChild(new ABCJS.write.RelativeElement(elem.chord[i].name, x, 0, y, {type:"text"}));
518
+ if (elem.chord[i].rel_position)
519
+ abselem.addChild(new ABCJS.write.RelativeElement(elem.chord[i].name, x+elem.chord[i].rel_position.x, 0, elem.minpitch+elem.chord[i].rel_position.y/ABCJS.write.spacing.STEP, {type:"text"}));
520
+ else
521
+ abselem.addChild(new ABCJS.write.RelativeElement(elem.chord[i].name, x, 0, y, {type:"text"}));
503
522
  }
504
523
  }
505
524
  }
@@ -514,6 +533,7 @@ ABCJS.write.Layout.prototype.printNote = function(elem, nostem, dontDraw) { //st
514
533
  if (elem.endTriplet && this.triplet) {
515
534
  this.triplet.anchor2 = notehead;
516
535
  this.triplet = null;
536
+ this.tripletmultiplier = 1;
517
537
  }
518
538
 
519
539
  return abselem;
@@ -767,9 +787,9 @@ ABCJS.write.Layout.prototype.printDecoration = function(decoration, pitch, width
767
787
  abselem.addChild(new ABCJS.write.RelativeElement(dec, deltax, this.glyphs.getSymbolWidth(dec), ypos));
768
788
  }
769
789
  if (compoundDec) { // PER: added new decorations
770
- ypos = (dir) ? pitch+1:pitch+9;
790
+ ypos = (dir === 'down') ? pitch+1:pitch+9;
771
791
  deltax = width/2;
772
- deltax += (dir) ? -5 : 3;
792
+ deltax += (dir === 'down') ? -5 : 3;
773
793
  for (var xx = 0; xx < compoundDec[1]; xx++) {
774
794
  ypos -= 1;
775
795
  abselem.addChild(new ABCJS.write.RelativeElement(compoundDec[0], deltax, this.glyphs.getSymbolWidth(compoundDec[0]), ypos));
@@ -875,32 +895,30 @@ ABCJS.write.Layout.prototype.printBarLine = function (elem) {
875
895
  ABCJS.write.Layout.prototype.printClef = function(elem) {
876
896
  var clef = "clefs.G";
877
897
  var octave = 0;
878
- var pitch = 4;
879
898
  var abselem = new ABCJS.write.AbsoluteElement(elem,0,10);
880
899
  switch (elem.type) {
881
900
  case "treble": break;
882
- case "tenor": clef="clefs.C"; pitch=8; break;
883
- case "alto": clef="clefs.C"; pitch=6; break;
884
- case "bass": clef="clefs.F"; pitch=8; break;
901
+ case "tenor": clef="clefs.C"; break;
902
+ case "alto": clef="clefs.C"; break;
903
+ case "bass": clef="clefs.F"; break;
885
904
  case 'treble+8': octave = 1; break;
886
- case 'tenor+8':clef="clefs.C"; pitch=8; break;
887
- case 'bass+8': clef="clefs.F"; pitch=8; break;
888
- case 'alto+8': clef="clefs.C"; pitch=6; break;
905
+ case 'tenor+8':clef="clefs.C"; octave = 1; break;
906
+ case 'bass+8': clef="clefs.F"; octave = 1; break;
907
+ case 'alto+8': clef="clefs.C"; octave = 1; break;
889
908
  case 'treble-8': octave = -1; break;
890
- case 'tenor-8':clef="clefs.C"; pitch=8; break;
891
- case 'bass-8': clef="clefs.F"; pitch=8; break;
892
- case 'alto-8': clef="clefs.C"; pitch=6; break;
909
+ case 'tenor-8':clef="clefs.C"; octave = -1; break;
910
+ case 'bass-8': clef="clefs.F"; octave = -1; break;
911
+ case 'alto-8': clef="clefs.C"; octave = -1; break;
893
912
  case 'none': clef=""; break;
894
- case 'perc': clef="clefs.perc"; pitch=6; break;
913
+ case 'perc': clef="clefs.perc"; break;
895
914
  default: abselem.addChild(new ABCJS.write.RelativeElement("clef="+elem.type, 0, 0, 0, {type:"debug"}));
896
915
  }
897
- if (elem.verticalPos) {
898
- pitch = elem.verticalPos;
899
- }
900
-
916
+ // if (elem.verticalPos) {
917
+ // pitch = elem.verticalPos;
918
+ // }
901
919
  var dx =10;
902
920
  if (clef!=="") {
903
- abselem.addRight(new ABCJS.write.RelativeElement(clef, dx, this.glyphs.getSymbolWidth(clef), pitch));
921
+ abselem.addRight(new ABCJS.write.RelativeElement(clef, dx, this.glyphs.getSymbolWidth(clef), elem.clefPos));
904
922
  }
905
923
  if (octave!==0) {
906
924
  var scale= 2/3;
@@ -411,8 +411,8 @@ ABCJS.write.Printer.prototype.printTune = function (abctune) {
411
411
  if (abcline.staff) {
412
412
  var staffgroup = this.layouter.printABCLine(abcline.staff);
413
413
  var newspace = this.space;
414
- for (var it=0;it<3;it++) {
415
- staffgroup.layout(newspace,this);
414
+ for (var it=0;it<3;it++) { // TODO shouldn't need this triple pass any more
415
+ staffgroup.layout(newspace,this, false);
416
416
  if (line && line===abctune.lines.length-1 && staffgroup.w/this.width<0.66 && !abctune.formatting.stretchlast) break; // don't stretch last line too much unless it is 1st
417
417
  var relspace = staffgroup.spacingunits*newspace;
418
418
  var constspace = staffgroup.w-relspace;
@@ -426,7 +426,7 @@ ABCJS.write.Printer.prototype.printTune = function (abctune) {
426
426
  staffgroup.draw(this,this.y);
427
427
  if (staffgroup.w>maxwidth) maxwidth = staffgroup.w;
428
428
  this.staffgroups[this.staffgroups.length] = staffgroup;
429
- this.y = staffgroup.y+staffgroup.height;
429
+ this.y = staffgroup.y+staffgroup.height;
430
430
  this.y+=ABCJS.write.spacing.STAVEHEIGHT*0.2;
431
431
  } else if (abcline.subtitle && line!==0) {
432
432
  this.printSubtitleLine(abcline);
@@ -1,5 +1,5 @@
1
1
  module Abcjs
2
2
  module Rails
3
- VERSION = "1.3"
3
+ VERSION = "1.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abcjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.3'
4
+ version: '1.4'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-22 00:00:00.000000000 Z
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties