abcjs-rails 1.3 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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