Skip to content

Commit

Permalink
Merge branch 'dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrosen committed Feb 25, 2022
2 parents 80c8780 + cc26153 commit 946eab4
Show file tree
Hide file tree
Showing 31 changed files with 1,691 additions and 521 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:16.10.0

RUN npm install -g [email protected].0
RUN npm install -g [email protected].1

RUN mkdir /srv/app && chown node:node /srv/app

Expand Down
54 changes: 25 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ This library makes it easy to incorporate **sheet music** into your **websites**

Full documentation is here: [abcjs documentation](https://paulrosen.github.io/abcjs/)

## Announcement: version 6.0.0

After way too long, abcjs 6.0.0 is now out of beta.

There are only a few bug fixes since the last beta.

The current plan is to continue doing bug fixes and minor features to the 6.x.x branch, but version 7 is already in planning.

## Informal roadmap for version 7.0.0

There will be some architecture changes which will go in a 7.0.0 release:

* Improve the API for controlling the synth. That is, make the parameters less confusing.
* Create a plugin architecture so that large features that are not widely used can be added without bloating this library.
* Change the build to use typescript while still maintaining legacy browser capability.
* Reduce the size of the library by optimizing code.
* Control the spacing of the elements on the line better: support equal size measures, and support allowing control of the spacing between notes.
* Improved documentation, particularly for synth.
* Bug fixes.

I anticipate that for a user that wants the most common functionality, the size of the library might be cut in half.

Thanks, Paul


## Major New Feature! 6.0.0-beta.36

String tablature is now available by adding an option to the `renderAbc` parameters. See [tablature documentation](https://paulrosen.github.io/abcjs/visual/tablature.html)
Expand Down Expand Up @@ -67,35 +92,6 @@ The last version in each major version number is still available in the active b

In this beta the default soundfont was changed to https://paulrosen.github.io/midi-js-soundfonts/abcjs/ Hopefully you will find that sounds better. If you set the soundfont directly then you won't notice any change. If you prefer the old soundfont, use the `soundFontUrl: "https://paulrosen.github.io/midi-js-soundfonts/FluidR3_GM/"` option when calling the synth functions.

## Informal roadmap
I'm getting close to taking version 6.0.0 out of beta.

These are the changes that are planned:
* Test and improve the sound of the soundfont.
* Add all the typescript definitions.
* Bug fixes.

If you have a particular issue that is impeding your usage of this library, please mention it in the issue.

After the 6.0.0 release, I'll be working on some more architecture changes which will go in a 7.0.0 release:

* Improve the API for controlling the synth. That is, make the parameters less confusing.
* Create a plugin architecture so that large features that are not widely used can be added without bloating this library.
* Change the build to use typescript while still maintaining legacy browser capability.
* Reduce the size of the library by optimizing code.
* Control the spacing of the elements on the line better: support equal size measures, and support allowing control of the spacing between notes.
* Improved documentation, particularly for synth.
* Bug fixes.

Thanks, Paul

## Future breaking changes
For most users of abcjs there probably won't be any more breaking changes in this beta.

There will probably still be some changes to the structure of the SVG that is created but if you aren't doing post-processing you won't notice except for better layout of the music.

There might be a few changes to the data that is returned from the callbacks, both the click listener and timing callbacks. Hopefully that will just be added data and won't affect any code.

## Issues

Thanks so much for the bug reports and feature requests that are pouring into the issues. I appreciate you taking the time to help improve abcjs. This is not a full time project, though, so I can't promise a quick turn around on the issues. I am going to attempt to be caught up on responding once a week at least.
Expand Down
26 changes: 26 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# Version 6.0.0

## Bugs

* Fix the bar number display when wrapping.

* Don't add extra padding when creating minimal music (like one note)

* Fix selection data for unaligned words

* Pass back actual selectable element when one of its children is clicked.

* Don't put extra classes and data- attributes on compound symbols (like "12/8")

* Fix spacing for triplet number

* Don't add extra space at the bottom if there is no bottom text.

* Allow aria-label to not be set.

* Fix adding class names to dynamics and some other elements.

* Fix regression where the left line of multi-staff music was misplaced if the bottom line is for percussion.

* gracenotes now are processed through %%percmap

# Version 6.0.0-beta.39

## Bugs
Expand Down
4 changes: 2 additions & 2 deletions dist/abcjs-basic-min.js

Large diffs are not rendered by default.

89 changes: 63 additions & 26 deletions dist/abcjs-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -3657,7 +3657,7 @@ var Parse = function Parse() {
addHintMeasures();
}

wrap.wrapLines(tune, multilineVars.lineBreaks);
wrap.wrapLines(tune, multilineVars.lineBreaks, multilineVars.barNumbers);
};
};

Expand Down Expand Up @@ -11424,7 +11424,7 @@ module.exports = TuneBuilder;
/***/ (function(module) {

// wrap_lines.js: does line wrap on an already parsed tune.
function wrapLines(tune, lineBreaks) {
function wrapLines(tune, lineBreaks, barNumbers) {
if (!lineBreaks || tune.lines.length === 0) return; // tune.lines contains nested arrays: there is an array of lines (that's the part this function rewrites),
// there is an array of staffs per line (for instance, piano will have 2, orchestra will have many)
// there is an array of voices per staff (for instance, 4-part harmony might have bass and tenor on a single staff)
Expand All @@ -11434,11 +11434,11 @@ function wrapLines(tune, lineBreaks) {
});
var linesBreakElements = findLineBreaks(lines, lineBreaks); //console.log(JSON.stringify(linesBreakElements))

tune.lines = addLineBreaks(lines, linesBreakElements);
tune.lines = addLineBreaks(lines, linesBreakElements, barNumbers);
tune.lineBreaks = linesBreakElements;
}

function addLineBreaks(lines, linesBreakElements) {
function addLineBreaks(lines, linesBreakElements, barNumbers) {
// linesBreakElements is an array of all of the elements that break for a new line
// The objects in the array look like:
// {"ogLine":0,"line":0,"staff":0,"voice":0,"start":0, "end":21}
Expand All @@ -11450,6 +11450,7 @@ function addLineBreaks(lines, linesBreakElements) {
var lastKeySig = []; // This is per staff - if the key changed then this will be populated.

var lastStem = [];
var currentBarNumber = 1;

for (var i = 0; i < linesBreakElements.length; i++) {
var action = linesBreakElements[i];
Expand All @@ -11467,6 +11468,11 @@ function addLineBreaks(lines, linesBreakElements) {
outputLines[action.line].staff[action.staff] = {
voices: []
};

if (barNumbers !== undefined && action.staff === 0 && action.line > 0) {
outputLines[action.line].staff[action.staff].barNumber = currentBarNumber;
}

var keys = Object.keys(inputStaff);

for (var k = 0; k < keys.length; k++) {
Expand Down Expand Up @@ -11511,6 +11517,15 @@ function addLineBreaks(lines, linesBreakElements) {
break;
}
}

if (barNumbers !== undefined && action.staff === 0 && action.voice === 0) {
for (kk = 0; kk < currVoice.length; kk++) {
if (currVoice[kk].el_type === 'bar') {
currentBarNumber++;
if (kk === currVoice.length - 1) delete currVoice[kk].barNumber;else currVoice[kk].barNumber = currentBarNumber;
}
}
}
} else {
outputLines[action.line] = lines[action.ogLine];
}
Expand Down Expand Up @@ -12860,8 +12875,15 @@ var pitchesToPerc = __webpack_require__(/*! ./pitches-to-perc */ "./src/synth/pi

for (g = 0; g < graces.length; g++) {
grace = graces[g];
var actualPitch = adjustPitch(grace);

if (currentInstrument === drumInstrument && percmap) {
var name = pitchesToPerc(grace);
if (name && percmap[name]) actualPitch = percmap[name].sound;
}

var pitch = {
pitch: adjustPitch(grace),
pitch: actualPitch,
duration: grace.duration * multiplier
};
pitch = adjustForMicroTone(pitch);
Expand Down Expand Up @@ -21194,7 +21216,7 @@ var EngraverController = function EngraverController(paper, params) {
this.renderer.controller = this; // TODO-GD needed for highlighting

this.renderer.foregroundColor = params.foregroundColor ? params.foregroundColor : "currentColor";
if (params.ariaLabel) this.renderer.ariaLabel = params.ariaLabel;
if (params.ariaLabel !== undefined) this.renderer.ariaLabel = params.ariaLabel;
this.renderer.minPadding = params.minPadding ? params.minPadding : 0;
this.reset();
};
Expand Down Expand Up @@ -22786,10 +22808,10 @@ TripletElem.prototype.middleNote = function (elem) {
};

TripletElem.prototype.setCloseAnchor = function (anchor2) {
this.anchor2 = anchor2; // TODO-PER: Unfortunately, I don't know if there is a beam above until after the vertical positioning is done,
// so I don't know whether to leave room for the number above. Therefore, If there is a beam on the first note, I'll leave room just in case.
this.anchor2 = anchor2; // TODO-PER: This used to be just for beamed triplets but it looks like bracketed triplets need extra room, too. The only one that doesn't is stem down and beamed
//if (this.anchor1.parent.beam)

if (this.anchor1.parent.beam) this.endingHeightAbove = 4;
if (!this.anchor1.parent.beam || this.anchor1.stemDir === 'up') this.endingHeightAbove = 4;
};

module.exports = TripletElem;
Expand Down Expand Up @@ -23149,7 +23171,10 @@ BottomText.prototype.unalignedWords = function (unalignedWords, paddingLeft, spa
});
this.rows.push({
endGroup: "unalignedWords",
absElemType: "unalignedWords"
absElemType: "unalignedWords",
startChar: -1,
endChar: -1,
name: "unalignedWords"
});
};

Expand Down Expand Up @@ -23230,8 +23255,9 @@ var calcHeight = function calcHeight(staffGroup) {
var staff = staffGroup.voices[i].staff;

if (!staffGroup.voices[i].duplicate) {
height += staff.top;
if (staff.bottom < 0) height += -staff.bottom;
height += staff.top; //if (staff.bottom < 0)

height += -staff.bottom;
}
}

Expand Down Expand Up @@ -23738,9 +23764,13 @@ function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, se
}

classes.reset();
renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?

nonMusic(renderer, abcTune.bottomText, selectables);
if (abcTune.bottomText && abcTune.bottomText.rows && abcTune.bottomText.rows.length > 0) {
renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?

nonMusic(renderer, abcTune.bottomText, selectables);
}

setPaperSize(renderer, maxWidth, scale, responsive);
return {
staffgroups: staffgroups,
Expand Down Expand Up @@ -24132,9 +24162,11 @@ function printSymbol(renderer, x, offset, symbol, options) {
if (!symbol) return null;

if (symbol.length > 1 && symbol.indexOf(".") < 0) {
var groupClass = elementGroup.isInGroup() ? '' : options.klass; // If this is already in a group then don't repeat the classes for the sub-group)

renderer.paper.openGroup({
"data-name": options.name,
klass: options.klass
klass: groupClass
});
var dx = 0;

Expand All @@ -24143,8 +24175,7 @@ function printSymbol(renderer, x, offset, symbol, options) {
ycorr = glyphs.getYCorr(s);
el = glyphs.printSymbol(x + dx, renderer.calcY(offset + ycorr), s, renderer.paper, {
stroke: options.stroke,
fill: options.fill,
"data-name": options.name
fill: options.fill
});

if (el) {
Expand Down Expand Up @@ -24532,11 +24563,14 @@ function setPaperSize(renderer, maxwidth, scale, responsive) {
// TODO-PER: We are letting the page get as long as it needs now, but eventually that should go to a second page.
// for accessibility

var text = "Sheet Music";
if (renderer.abctune && renderer.abctune.metaText && renderer.abctune.metaText.title) text += " for \"" + renderer.abctune.metaText.title + '"';
renderer.paper.setTitle(text);
var label = renderer.ariaLabel ? renderer.ariaLabel : text;
renderer.paper.setAttribute("aria-label", label); // for dragging - don't select during drag
if (renderer.ariaLabel !== '') {
var text = "Sheet Music";
if (renderer.abctune && renderer.abctune.metaText && renderer.abctune.metaText.title) text += " for \"" + renderer.abctune.metaText.title + '"';
renderer.paper.setTitle(text);
var label = renderer.ariaLabel ? renderer.ariaLabel : text;
renderer.paper.setAttribute("aria-label", label);
} // for dragging - don't select during drag


var styles = ["-webkit-touch-callout: none;", "-webkit-user-select: none;", "-khtml-user-select: none;", "-moz-user-select: none;", "-ms-user-select: none;", "user-select: none;"];
renderer.paper.insertStyles(".abcjs-dragging-in-progress text, .abcjs-dragging-in-progress tspan {" + styles.join(" ") + "}");
Expand Down Expand Up @@ -24997,12 +25031,14 @@ function printStaff(renderer, startx, endx, numLines, linePitch, dy) {

if (numLines === 1) {
printStaffLine(renderer, startx, endx, 6, klass);
firstYLine = renderer.calcY(10);
lastYLine = renderer.calcY(2);
} else {
for (var i = numLines - 1; i >= 0; i--) {
var curpitch = (i + 1) * pitch;
lastYLine = renderer.calcY(curpitch);

if (firstYLine == 0) {
if (firstYLine === 0) {
firstYLine = lastYLine;
}

Expand Down Expand Up @@ -27413,6 +27449,7 @@ function notifySelect(target, dragStep, dragMax, dragIndex, ev) {
analysis.clickedName = closest.dataset.name;
analysis.parentClasses = parent.classList;
analysis.clickedClasses = closest.classList;
analysis.selectableElement = target.svgEl;

for (var i = 0; i < this.listeners.length; i++) {
this.listeners[i](target.absEl.abcelem, target.absEl.tuneNumber, classes.join(' '), analysis, {
Expand Down Expand Up @@ -27915,7 +27952,7 @@ Svg.prototype.path = function (attr) {

for (var key in attr) {
if (attr.hasOwnProperty(key)) {
if (key === 'path') el.setAttributeNS(null, 'd', attr.path);else if (attr[key] !== undefined) el.setAttributeNS(null, key, attr[key]);
if (key === 'path') el.setAttributeNS(null, 'd', attr.path);else if (key === 'klass') el.setAttributeNS(null, "class", attr[key]);else if (attr[key] !== undefined) el.setAttributeNS(null, key, attr[key]);
}
}

Expand All @@ -27928,7 +27965,7 @@ Svg.prototype.pathToBack = function (attr) {

for (var key in attr) {
if (attr.hasOwnProperty(key)) {
if (key === 'path') el.setAttributeNS(null, 'd', attr.path);else el.setAttributeNS(null, key, attr[key]);
if (key === 'path') el.setAttributeNS(null, 'd', attr.path);else if (key === 'klass') el.setAttributeNS(null, "class", attr[key]);else el.setAttributeNS(null, key, attr[key]);
}
}

Expand Down Expand Up @@ -28149,7 +28186,7 @@ module.exports = unhighlight;
\********************/
/***/ (function(module) {

var version = '6.0.0-beta.39';
var version = '6.0.0';
module.exports = version;

/***/ })
Expand Down
2 changes: 1 addition & 1 deletion dist/abcjs-basic.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/abcjs-plugin-min.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions docs/visual/click-listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ An object containing the following info about the item clicked:
clickedName: "", // If the item is compound, then this is the name on the part that was clicked.
parentClasses: "", // The classes on the parent item
clickedClasses: "", // The classes on the clicked element
selectableElement: HTMLElement, // The parent element that was selected.
}
```
The svg elements may be wrapped in a `<g>` because there is more than one element that is contained. For instance, in `[Ac]` (when L:1/8), there is a `<g>` that contains an element for a notehead on the `A` line, a notehead on the `c` line, a stem, and an eighth note flag. Clicking anywhere on that `<g>` will cause the name to be "note" but if you click directly on a notehead, the name will still be "note" but the clickedName will be "A" or "c".
Expand All @@ -53,3 +54,5 @@ See the [Dragging](./dragging.md) page for more details.
## mouseEvent

The original event that triggered this callback.

Note that it might be more useful to use `analysis.selectableElement` than to use `mouseEvent.target`. The latter will be what the mouse actually clicked on, but that might not be what the user was intending because of two cases: If the SVG itself was clicked on, then the closest element will be returned as clicked because otherwise the target can be really narrow. Second, if the element is compound (for instance the dynamic `mp`) then the user will have clicked on either the `m` or the `p` but probably the intent was to select the immediate parent, which is a `<g>` tag that contains the info on the element.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "abcjs",
"version": "6.0.0-beta.39",
"version": "6.0.0",
"description": "Renderer for abc music notation",
"main": "index.js",
"types": "types/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/parse/abc_parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ var Parse = function() {
addHintMeasures();
}

wrap.wrapLines(tune, multilineVars.lineBreaks);
wrap.wrapLines(tune, multilineVars.lineBreaks, multilineVars.barNumbers);
};
};

Expand Down
Loading

0 comments on commit 946eab4

Please sign in to comment.