paulrosen / abcjs

javascript for rendering abc music notation
Other
1.93k stars 284 forks source link

Is it possible to reduce the extra white space injected above each staff when using labeled tablature? #892

Closed seisiuneer closed 9 months ago

seisiuneer commented 1 year ago

Thank you for this amazing library!

Is there any way to reduce the white space injected above every staff when using named tablature?

For my converter project, I felt like the resulting notation was too spaced out on the page when using the labeled tab so I just left the labels off when users selected one of the string instrument tablature options.

seisiuneer commented 1 year ago

This change made the formatting in the attached PDF possible for my utility. It was difficult before to get all four staves on one PDF page with the sort of overall spacing I was looking for. With the current released abcjs, that fourth staff would have landed on the next page because of the excessive height of the staffs when there were labels on the tablature.

kesh_Guitar.pdf

paulrosen commented 1 year ago

Thanks! I'll look into this. I think I can piece together your source, but it would help if you pasted the parameters that you called renderAbc() with.

seisiuneer commented 1 year ago

Hi Paul,

Here's a typical example what I'm calling it with (values from the Chrome debugger) for the single tune case with a single output div:

The ABC being rendered:

X:1\n%%musicspace 20\n%%staffsep 50\nT: The Kesh\nR: Jig\nM: 6/8\nL: 1/8\nK: Gmaj\nD|: GAG GAB | ABA ABd | edd gdd | edB dBA |\nGAG GAB | ABA ABd | edd gdB |1 AGF G2D :|2 AGF G2A||\n|: B2B dBd | ege dBA | BAB dBG | ABA AGA |\nB2 B dBd | ege dBd | gfg aga |1 bgg g2A :|2 bgg g2D |]

The params:

[image: image.png]

Thanks,

Michael

On Sat, Feb 25, 2023 at 8:57 AM Paul Rosen @.***> wrote:

Thanks! I'll look into this. I think I can piece together your source, but it would help if you pasted the parameters that you called renderAbc() with.

— Reply to this email directly, view it on GitHub https://github.com/paulrosen/abcjs/issues/892#issuecomment-1445158546, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB4ZXL4OBACQNHTWFSDSVQ3WZI2WZANCNFSM6AAAAAAVE6DITU . You are receiving this because you authored the thread.Message ID: @.***>

--


Michael Eskin @.*** (619) 368-1854 (text/voice)

Home Page http://michaeleskin.com | Online Store https://michaeleskin.gumroad.com | Zoom Session http://michaeleskin.com/session | AppCordions http://appcordions.com | Flickr https://www.flickr.com/photos/eskin/albums


seisiuneer commented 11 months ago

Hi Paul! Happy Thanksgiving!

Here's my fix that both solves the spacing as well as only puts the tablature label on the first staff with tab:

TabRenderer.prototype.doLayout = function () { var staffs = this.line.staff; if (staffs) { // give up on staffline=0 in key var firstStaff = staffs[0]; if (firstStaff) { if (firstStaff.clef) { if (firstStaff.clef.stafflines == 0) { this.plugin._super.setError("No tablatures when stafflines=0"); return; } } } staffs.splice(staffs.length, 0, this.tabStaff); } var staffGroup = this.line.staffGroup; var voices = staffGroup.voices; var firstVoice = voices[0]; // take lyrics into account if any var lyricsHeight = getLyricHeight(firstVoice); var padd = 3; var prevIndex = this.staffIndex; var previousStaff = staffGroup.staffs[prevIndex]; var tabTop = this.tabSize + padd - previousStaff.bottom - lyricsHeight; if (previousStaff.isTabStaff) { tabTop = previousStaff.top; } var staffGroupInfos = { bottom: -1, isTabStaff: true, specialY: initSpecialY(), lines: this.plugin.nbLines, linePitch: this.plugin.linePitch, dy: 0.15, top: tabTop }; var nextTabPos = getNextTabPos(this, staffGroup.staffs); if (nextTabPos === -1) return; staffGroupInfos.parentIndex = nextTabPos - 1; staffGroup.staffs.splice(nextTabPos, 0, staffGroupInfos); // staffGroup.staffs.push(staffGroupInfos); staffGroup.height += this.tabSize + padd; var parentStaff = getLastStaff(staffGroup.staffs, nextTabPos); var nbVoices = 1; if (isMultiVoiceSingleStaff(staffGroup.staffs, parentStaff)) { nbVoices = parentStaff.voices.length; }

// build from staff this.tabStaff.voices = [];

for (var ii = 0; ii < nbVoices; ii++) {

var tabVoice = new VoiceElement(0, 0);

if (ii > 0) tabVoice.duplicate = true;

var nameHeight;

// MAE START OF CHANGE

// First staff with a tab name gets special treatment
if (this.plugin.isFirstStaff){

  var nameHeight = buildTabName(this, tabVoice) / spacing.STEP;

  nameHeight = Math.max(nameHeight, 1); // If there is no label for the tab line, then there needs to be a little padding

  staffGroup.staffs[this.staffIndex].top += 1;

  if (nameHeight == 1){

    staffGroup.height += spacing.STEP;

  }
  else{

    staffGroup.height += nameHeight;

  }

  this.plugin.firstTabNameHeight = nameHeight;

  this.plugin.isFirstStaff = false;

}
else{

  // Padding
  staffGroup.height += spacing.STEP;

  staffGroup.staffs[this.staffIndex].top += this.plugin.firstTabNameHeight;

}
// MAE END OF CHANGE

tabVoice.staff = staffGroupInfos;

var tabVoiceIndex = voices.length;

voices.splice(voices.length, 0, tabVoice);

var keySig = checkVoiceKeySig(voices, ii + this.staffIndex);

this.tabStaff.voices[ii] = [];

this.absolutes.build(this.plugin, voices, this.tabStaff.voices[ii], ii, this.staffIndex, keySig, tabVoiceIndex);

}

linkStaffAndTabs(staffGroup.staffs); // crossreference tabs and staff

};

and in the Guitar plugin:

/**

and the Violin plugin:

/**

Results in:

image

instead of what it was doing before with too much space injected and repeated labels:

image