Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

abcjs

Package Overview
Dependencies
Maintainers
1
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

abcjs - npm Package Compare versions

Comparing version 6.1.9 to 6.2.0

src/synth/note-to-midi.js

2

index.js

@@ -45,3 +45,3 @@ /**!

var glyphs = require('./src/write/abc_glyphs');
var glyphs = require('./src/write/creation/glyphs');
abcjs.setGlyph = glyphs.setSymbol;

@@ -48,0 +48,0 @@ abcjs.strTranspose = strTranspose;

{
"name": "abcjs",
"version": "6.1.9",
"version": "6.2.0",
"description": "Renderer for abc music notation",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -31,3 +31,3 @@ /**!

var Parse = require('./src/parse/abc_parse');
var EngraverController = require('./src/write/abc_engraver_controller');
var EngraverController = require('./src/write/engraver-controller');

@@ -34,0 +34,0 @@ var Plugin = function() {

@@ -131,3 +131,3 @@ var TimingCallbacks = function(target, params) {

endMs = self.noteTimings[next].milliseconds;
next = self.currentEvent - 1;
next = Math.max(0, self.currentEvent - 1);
while (next >= 0 && self.noteTimings[next].left === null)

@@ -157,4 +157,8 @@ next--;

var gapPx = ev.endX - ev.left; // The length in pixels
var offPx = offMs * gapPx / gapMs;
var offPx = gapMs ? offMs * gapPx / gapMs : 0;
position.left = ev.left + offPx;
// See if this is before the first event - that is the case where there are "prep beats"
if (self.currentEvent === 0 && ev.milliseconds > timestamp-self.startTime)
position.left = undefined
debugInfo = {

@@ -166,3 +170,3 @@ timestamp: timestamp,

offMs: offMs,
offPs: offPx,
offPx: offPx,
gapMs: gapMs,

@@ -169,0 +173,0 @@ gapPx: gapPx

var tunebook = require('./abc_tunebook');
var Tune = require('../data/abc_tune');
var EngraverController = require('../write/abc_engraver_controller');
var EngraverController = require('../write/engraver-controller');
var Parse = require('../parse/abc_parse');
var wrap = require('../parse/wrap_lines');
var parseCommon = require("../parse/abc_common");
// var tablatures = require('./abc_tablatures');

@@ -9,0 +8,0 @@

// abc_tune.js: a computer usable internal structure representing one tune.
var parseCommon = require('../parse/abc_common');
var spacing = require('../write/abc_spacing');
var spacing = require('../write/helpers/spacing');
var sequence = require('../synth/abc_midi_sequencer');

@@ -614,3 +614,3 @@ var flatten = require('../synth/abc_midi_flattener');

var seq = sequence(this, options);
return flatten(seq, options, this.formatting.percmap);
return flatten(seq, options, this.formatting.percmap, this.formatting.midi);
};

@@ -617,0 +617,0 @@ this.deline = function(options) {

@@ -37,6 +37,2 @@ // abc_parse.js: parses a string representing ABC Music Notation into a usable internal structure.

parseCommon.gsub = function(source, pattern, replacement) {
return source.split(pattern).join(replacement);
};
parseCommon.strip = function(str) {

@@ -55,7 +51,2 @@ return str.replace(/^\s+/, '').replace(/\s+$/, '');

parseCommon.each = function(arr, iterator, context) {
for (var i = 0, length = arr.length; i < length; i++)
iterator.apply(context, [arr[i],i]);
};
parseCommon.last = function(arr) {

@@ -67,41 +58,3 @@ if (arr.length === 0)

parseCommon.compact = function(arr) {
var output = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i])
output.push(arr[i]);
}
return output;
};
parseCommon.detect = function(arr, iterator) {
for (var i = 0; i < arr.length; i++) {
if (iterator(arr[i]))
return true;
}
return false;
};
// The following is a polyfill for Object.remove for IE9, IE10, and IE11.
// from:https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md
try {
(function (arr) {
arr.forEach(function (item) {
if (item.hasOwnProperty('remove')) {
return;
}
Object.defineProperty(item, 'remove', {
configurable: true,
enumerable: true,
writable: true,
value: function remove() {
if (this.parentNode !== null)
this.parentNode.removeChild(this);
}
});
});
})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
} catch(e) {
// if we aren't in a browser, this code will crash, but it is not needed then either.
}
module.exports = parseCommon;

@@ -18,3 +18,3 @@ // abc_parse_book.js: parses a string representing ABC Music Notation into a usable internal structure.

var tunes = [];
parseCommon.each(tuneStrings, function(tune) {
tuneStrings.forEach(function(tune) {
tunes.push({ abc: tune, startPos: pos});

@@ -29,3 +29,3 @@ pos += tune.length + 1; // We also lost a newline when splitting, so count that.

var arrDir = dir.abc.split('\n');
parseCommon.each(arrDir, function(line) {
arrDir.forEach(function(line) {
if (parseCommon.startsWith(line, '%%'))

@@ -38,3 +38,3 @@ directives += line + '\n';

// Now, the tune ends at a blank line, so truncate it if needed. There may be "intertune" stuff.
parseCommon.each(tunes, function(tune) {
tunes.forEach(function(tune) {
var end = tune.abc.indexOf('\n\n');

@@ -41,0 +41,0 @@ if (end > 0)

@@ -333,3 +333,3 @@ var parseCommon = require('./abc_common');

var scratch = "";
parseCommon.each(tokens, function(tok) {
tokens.forEach(function(tok) {
scratch += tok.token;

@@ -489,2 +489,4 @@ });

"chordvol",
"bassprog",
"chordprog",
"c",

@@ -691,11 +693,11 @@ "channel",

for (var i = 1; i < textParts.length; i++) {
if (textParts[i].charAt(0) === '0')
if (textParts[i][0] === '0')
textarr.push({ text: textParts[i].substring(1) });
else if (textParts[i].charAt(0) === '1' && multilineVars.setfont[1])
else if (textParts[i][0] === '1' && multilineVars.setfont[1])
textarr.push({font: multilineVars.setfont[1], text: textParts[i].substring(1) });
else if (textParts[i].charAt(0) === '2' && multilineVars.setfont[2])
else if (textParts[i][0] === '2' && multilineVars.setfont[2])
textarr.push({font: multilineVars.setfont[2], text: textParts[i].substring(1) });
else if (textParts[i].charAt(0) === '3' && multilineVars.setfont[3])
else if (textParts[i][0] === '3' && multilineVars.setfont[3])
textarr.push({font: multilineVars.setfont[3], text: textParts[i].substring(1) });
else if (textParts[i].charAt(0) === '4' && multilineVars.setfont[4])
else if (textParts[i][0] === '4' && multilineVars.setfont[4])
textarr.push({font: multilineVars.setfont[4], text: textParts[i].substring(1) });

@@ -752,2 +754,3 @@ else

case "jazzchords":tune.formatting.jazzchords = true;break;
case "germanAlphabet":tune.formatting.germanAlphabet = true;break;
case "landscape":multilineVars.landscape = true;break;

@@ -765,2 +768,9 @@ case "papersize":multilineVars.papersize = restOfString;break;

break;
case "lineThickness":
var lt = parseStretchLast(tokens);
if (lt.value !== undefined)
tune.formatting.lineThickness = lt.value;
if (lt.error)
return lt.error;
break;
case "stretchlast":

@@ -815,2 +825,11 @@ var sl = parseStretchLast(tokens);

return null;
case "voicecolor":
if (tokens.length !== 1) // this could either be of type alpha or quote, but it's ok if it is a number
return "voicecolor requires one string as a parameter";
var voiceColor = tokens.shift();
if (multilineVars.currentVoice) {
multilineVars.currentVoice.color = voiceColor.token;
tuneBuilder.changeVoiceColor(multilineVars.currentVoice.color);
}
return null;
case "vskip":

@@ -1090,3 +1109,3 @@ var vskip = Math.round(getRequiredMeasurement(cmd, tokens));

footerStr = restOfString.substring(footerStr.start, footerStr.end);
if (footerStr.charAt(0) === '"' && footerStr.charAt(footerStr.length-1) === '"' )
if (footerStr[0] === '"' && footerStr[footerStr.length-1] === '"' )
footerStr = footerStr.substring(1, footerStr.length-1);

@@ -1093,0 +1112,0 @@ var footerArr = footerStr.split('\t');

@@ -192,3 +192,3 @@ // abc_parse_header.js: parses a the header fields from a string representing ABC Music Notation into a usable internal structure.

this.setDefaultLength = function(line, start, end) {
var len = parseCommon.gsub(line.substring(start, end), " ", "");
var len = line.substring(start, end).replace(/ /g, "");
var len_arr = len.split('/');

@@ -350,3 +350,3 @@ if (len_arr.length === 2) {

i +=ws;
if (line.length >= i+5 && line.charAt(i) === '[' && line.charAt(i+2) === ':') {
if (line.length >= i+5 && line[i] === '[' && line[i+2] === ':') {
var e = line.indexOf(']', i);

@@ -398,3 +398,3 @@ var startChar = multilineVars.iChar + i;

}
return [ e-i+1+ws, line.charAt(i+1), line.substring(i+3, e)];
return [ e-i+1+ws, line[i+1], line.substring(i+3, e)];
}

@@ -406,5 +406,7 @@ break;

//startNewLine();
return [ e-i+1+ws, line.charAt(i+1), line.substring(i+3, e)];
return [ e-i+1+ws, line[i+1], line.substring(i+3, e)];
}
break;
case "[r:":
return [ e-i+1+ws ];

@@ -452,7 +454,7 @@ default:

else if (tempo.type === 'immediate') tuneBuilder.appendElement('tempo', multilineVars.iChar + i, multilineVars.iChar + line.length, tempo.tempo);
return [ e, line.charAt(i), parseCommon.strip(line.substring(i+2))];
return [ e, line[i], parseCommon.strip(line.substring(i+2))];
case "V:":
parseKeyVoice.parseVoice(line, i+2, line.length);
// startNewLine();
return [ line.length, line.charAt(i), parseCommon.strip(line.substring(i+2))];
return [ line.length, line[i], parseCommon.strip(line.substring(i+2))];
default:

@@ -482,3 +484,3 @@ // TODO: complain about unhandled header

this.parseHeader = function(line) {
var field = metaTextHeaders[line.charAt(0)];
var field = metaTextHeaders[line[0]];
if (field !== undefined) {

@@ -493,3 +495,3 @@ if (field === 'unalignedWords')

var endChar = startChar + line.length;
switch(line.charAt(0))
switch(line[0])
{

@@ -499,3 +501,3 @@ case 'H':

line = tokenizer.peekLine()
while (line && line.charAt(1) !== ':') {
while (line && line[1] !== ':') {
tokenizer.nextLine()

@@ -502,0 +504,0 @@ tuneBuilder.addMetaText("history", tokenizer.translateString(tokenizer.stripComment(line)), { startChar: multilineVars.iChar, endChar: multilineVars.iChar+line.length});

@@ -86,3 +86,3 @@ var parseCommon = require('./abc_common');

var ret = { accidentals: [], root: key.root, acc: key.acc, mode: key.mode };
parseCommon.each(key.accidentals, function(k) {
key.accidentals.forEach(function(k) {
ret.accidentals.push(parseCommon.clone(k));

@@ -99,3 +99,3 @@ });

var mid = clef.verticalPos;
parseCommon.each(key.accidentals, function(acc) {
key.accidentals.forEach(function(acc) {
var pitch = pitches[acc.note];

@@ -106,3 +106,3 @@ pitch = pitch - mid;

if (key.impliedNaturals)
parseCommon.each(key.impliedNaturals, function(acc) {
key.impliedNaturals.forEach(function(acc) {
var pitch = pitches[acc.note];

@@ -114,3 +114,3 @@ pitch = pitch - mid;

if (mid < -10) {
parseCommon.each(key.accidentals, function(acc) {
key.accidentals.forEach(function(acc) {
acc.verticalPos -= 7;

@@ -125,3 +125,3 @@ if (acc.verticalPos >= 11 || (acc.verticalPos === 10 && acc.acc === 'flat'))

if (key.impliedNaturals)
parseCommon.each(key.impliedNaturals, function(acc) {
key.impliedNaturals.forEach(function(acc) {
acc.verticalPos -= 7;

@@ -136,3 +136,3 @@ if (acc.verticalPos >= 11 || (acc.verticalPos === 10 && acc.acc === 'flat'))

} else if (mid < -4) {
parseCommon.each(key.accidentals, function(acc) {
key.accidentals.forEach(function(acc) {
acc.verticalPos -= 7;

@@ -143,3 +143,3 @@ if (mid === -8 && (acc.note === 'f' || acc.note === 'g') && acc.acc === 'sharp' )

if (key.impliedNaturals)
parseCommon.each(key.impliedNaturals, function(acc) {
key.impliedNaturals.forEach(function(acc) {
acc.verticalPos -= 7;

@@ -150,7 +150,7 @@ if (mid === -8 && (acc.note === 'f' || acc.note === 'g') && acc.acc === 'sharp' )

} else if (mid >= 7) {
parseCommon.each(key.accidentals, function(acc) {
key.accidentals.forEach(function(acc) {
acc.verticalPos += 7;
});
if (key.impliedNaturals)
parseCommon.each(key.impliedNaturals, function(acc) {
key.impliedNaturals.forEach(function(acc) {
acc.verticalPos += 7;

@@ -169,5 +169,5 @@ });

var i = 0;
var p = str.charAt(i++);
var p = str[i++];
if (p === '^' || p === '_')
p = str.charAt(i++);
p = str[i++];
var mid = pitches[p];

@@ -177,4 +177,4 @@ if (mid === undefined)

for ( ; i < str.length; i++) {
if (str.charAt(i) === ',') mid -= 7;
else if (str.charAt(i) === "'") mid += 7;
if (str[i] === ',') mid -= 7;
else if (str[i] === "'") mid += 7;
else break;

@@ -541,3 +541,3 @@ }

warn("Expected value for " + name + " in voice: " + attr.err, line, start);
else if (attr.token.length === 0 && line.charAt(start) !== '"')
else if (attr.token.length === 0 && line[start] !== '"')
warn("Expected value for " + name + " in voice", line, start);

@@ -554,3 +554,3 @@ else

warn("Expected value for " + name + " in voice: " + attr.err, line, start);
else if (attr.token.length === 0 && line.charAt(start) !== '"')
else if (attr.token.length === 0 && line[start] !== '"')
warn("Expected value for " + name + " in voice", line, start);

@@ -570,3 +570,3 @@ else {

warn("Expected value for " + name + " in voice: " + attr.err, line, start);
else if (attr.token.length === 0 && line.charAt(start) !== '"')
else if (attr.token.length === 0 && line[start] !== '"')
warn("Expected value for " + name + " in voice", line, start);

@@ -590,3 +590,3 @@ else {

warn("Expected one of (_B, _E, _b, _e) for " + name + " in voice: " + attr.warn, line, start);
else if (attr.token.length === 0 && line.charAt(start) !== '"')
else if (attr.token.length === 0 && line[start] !== '"')
warn("Expected one of (_B, _E, _b, _e) for " + name + " in voice", line, start);

@@ -593,0 +593,0 @@ else {

@@ -85,3 +85,3 @@ var parseCommon = require('./abc_common');

// If this is single voice music then the voice index isn't set, so we use the first voice.
var voiceIndex = multilineVars.currentVoice ? multilineVars.currentVoice.index : 0;
var voiceIndex = multilineVars.currentVoice ? multilineVars.currentVoice.staffNum * 100 + multilineVars.currentVoice.index : 0;
if (multilineVars.inTie[overlayLevel][voiceIndex]) {

@@ -102,5 +102,5 @@ if (el.pitches !== undefined || el.rest.type !== 'spacer')

// see if there is nothing but a comment on this line. If so, just ignore it. A full line comment is optional white space followed by %
while (tokenizer.isWhiteSpace(line.charAt(i)) && i < line.length)
while (tokenizer.isWhiteSpace(line[i]) && i < line.length)
i++;
if (i === line.length || line.charAt(i) === '%')
if (i === line.length || line[i] === '%')
return;

@@ -131,3 +131,3 @@

var startI = i;
if (line.charAt(i) === '%')
if (line[i] === '%')
break;

@@ -164,3 +164,3 @@

}
if (i > 0 && line.charAt(i-1) === '\x12') {
if (i > 0 && line[i-1] === '\x12') {
// there is one case where a line continuation isn't the same as being on the same line, and that is if the next character after it is a header.

@@ -210,3 +210,3 @@ ret = header.letter_to_body_header(line, i);

} else {
if (nonDecorations.indexOf(line.charAt(i)) === -1)
if (nonDecorations.indexOf(line[i]) === -1)
ret = letter_to_accent(line, i);

@@ -334,3 +334,3 @@ else ret = [ 0 ];

// handle chords.
if (line.charAt(i) === '[') {
if (line[i] === '[') {
var chordStartChar = i;

@@ -382,3 +382,3 @@ i++;

delete chordNote.endChar;
} else if (line.charAt(i) === ' ') {
} else if (line[i] === ' ') {
// Spaces are not allowed in chords, but we can recover from it by ignoring it.

@@ -388,3 +388,3 @@ warn("Spaces are not allowed in chords", line, i);

} else {
if (i < line.length && line.charAt(i) === ']') {
if (i < line.length && line[i] === ']') {
// consume the close bracket

@@ -399,3 +399,3 @@ i++;

if (isInTie(multilineVars, overlayLevel, el)) {
parseCommon.each(el.pitches, function(pitch) { pitch.endTie = true; });
el.pitches.forEach(function(pitch) { pitch.endTie = true; });
setIsInTie(multilineVars, overlayLevel, false);

@@ -413,3 +413,3 @@ }

while (i < line.length && !postChordDone) {
switch (line.charAt(i)) {
switch (line[i]) {
case ' ':

@@ -423,3 +423,3 @@ case '\t':

case '-':
parseCommon.each(el.pitches, function(pitch) { pitch.startTie = {}; });
el.pitches.forEach(function(pitch) { pitch.startTie = {}; });
setIsInTie(multilineVars, overlayLevel, true);

@@ -450,5 +450,6 @@ break;

i = fraction.index;
if (line.charAt(i) === ' ')
var ch = line[i]
if (ch === ' ')
rememberEndBeam = true;
if (line.charAt(i) === '-' || line.charAt(i) === ')' || line.charAt(i) === ' ' || line.charAt(i) === '<' || line.charAt(i) === '>')
if (ch === '-' || ch === ')' || ch === ' ' || ch === '<' || ch === '>')
i--; // Subtracting one because one is automatically added below

@@ -575,3 +576,3 @@ else

if (i === startI) { // don't know what this is, so ignore it.
if (line.charAt(i) !== ' ' && line.charAt(i) !== '`')
if (line[i] !== ' ' && line[i] !== '`')
warn("Unknown character ignored", line, i);

@@ -589,3 +590,3 @@ i++;

// If this is single voice music then the voice index isn't set, so we use the first voice.
var voiceIndex = multilineVars.currentVoice ? multilineVars.currentVoice.index : 0;
var voiceIndex = multilineVars.currentVoice ? multilineVars.currentVoice.staffNum * 100 + multilineVars.currentVoice.index : 0;
if (multilineVars.inTie[overlayLevel] === undefined)

@@ -597,3 +598,3 @@ multilineVars.inTie[overlayLevel] = [];

var letter_to_chord = function(line, i) {
if (line.charAt(i) === '"')
if (line[i] === '"')
{

@@ -606,15 +607,15 @@ var chord = tokenizer.getBrackettedSubstring(line, i, 5);

// (note that the 2.0 draft standard defines them as not chords, but annotations and also defines @.)
if (chord[0] > 0 && chord[1].length > 0 && chord[1].charAt(0) === '^') {
if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '^') {
chord[1] = chord[1].substring(1);
chord[2] = 'above';
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1].charAt(0) === '_') {
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '_') {
chord[1] = chord[1].substring(1);
chord[2] = 'below';
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1].charAt(0) === '<') {
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '<') {
chord[1] = chord[1].substring(1);
chord[2] = 'left';
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1].charAt(0) === '>') {
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '>') {
chord[1] = chord[1].substring(1);
chord[2] = 'right';
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1].charAt(0) === '@') {
} else if (chord[0] > 0 && chord[1].length > 0 && chord[1][0] === '@') {
// @-15,5.7

@@ -656,3 +657,3 @@ chord[1] = chord[1].substring(1);

// Grace notes are an array of: startslur, note, endslur, space; where note is accidental, pitch, duration
if (line.charAt(i) === '{') {
if (line[i] === '{') {
// fetch the gracenotes string and consume that into the array

@@ -673,3 +674,3 @@ var gra = tokenizer.getBrackettedSubstring(line, i, 1, '}');

var acciaccatura = false;
if (gra[1].charAt(ii) === '/') {
if (gra[1][ii] === '/') {
acciaccatura = true;

@@ -703,7 +704,7 @@ ii++;

// We shouldn't get anything but notes or a space here, so report an error
if (gra[1].charAt(ii) === ' ') {
if (gra[1][ii] === ' ') {
if (gracenotes.length > 0)
gracenotes[gracenotes.length-1].endBeam = true;
} else
warn("Unknown character '" + gra[1].charAt(ii) + "' while parsing grace note", line, i);
warn("Unknown character '" + gra[1][ii] + "' while parsing grace note", line, i);
ii++;

@@ -719,5 +720,5 @@ }

function letter_to_overlay(line, i) {
if (line.charAt(i) === '&') {
if (line[i] === '&') {
var start = i;
while (line.charAt(i) && line.charAt(i) !== ':' && line.charAt(i) !== '|')
while (line[i] && line[i] !== ':' && line[i] !== '|')
i++;

@@ -770,29 +771,21 @@ return [ i-start, line.substring(start+1, i) ];

var letter_to_accent = function(line, i) {
var macro = multilineVars.macros[line.charAt(i)];
var macro = multilineVars.macros[line[i]];
if (macro !== undefined) {
if (macro.charAt(0) === '!' || macro.charAt(0) === '+')
if (macro[0] === '!' || macro[0] === '+')
macro = macro.substring(1);
if (macro.charAt(macro.length-1) === '!' || macro.charAt(macro.length-1) === '+')
if (macro[macro.length-1] === '!' || macro[macro.length-1] === '+')
macro = macro.substring(0, macro.length-1);
if (parseCommon.detect(legalAccents, function(acc) {
return (macro === acc);
}))
if (legalAccents.includes(macro))
return [ 1, macro ];
else if (parseCommon.detect(volumeDecorations, function(acc) {
return (macro === acc);
})) {
else if (volumeDecorations.includes(macro)) {
if (multilineVars.volumePosition === 'hidden')
macro = "";
return [1, macro];
} else if (parseCommon.detect(dynamicDecorations, function(acc) {
} else if (dynamicDecorations.includes(macro)) {
if (multilineVars.dynamicPosition === 'hidden')
macro = "";
return (macro === acc);
})) {
return [1, macro];
} else {
if (!parseCommon.detect(multilineVars.ignoredDecorations, function(dec) {
return (macro === dec);
}))
if (!multilineVars.ignoredDecorations.includes(macro))
warn("Unknown macro: " + macro, line, i);

@@ -802,3 +795,3 @@ return [1, '' ];

}
switch (line.charAt(i))
switch (line[i])
{

@@ -816,11 +809,7 @@ case '.':

// Be sure that the accent is recognizable.
if (ret[1].length > 1 && (ret[1].charAt(0) === '^' || ret[1].charAt(0) ==='_'))
if (ret[1].length > 1 && (ret[1][0] === '^' || ret[1][0] ==='_'))
ret[1] = ret[1].substring(1); // TODO-PER: The test files have indicators forcing the ornament to the top or bottom, but that isn't in the standard. We'll just ignore them.
if (parseCommon.detect(legalAccents, function(acc) {
return (ret[1] === acc);
}))
if (legalAccents.includes(ret[1]))
return ret;
if (parseCommon.detect(volumeDecorations, function(acc) {
return (ret[1] === acc);
})) {
if (volumeDecorations.includes(ret[1])) {
if (multilineVars.volumePosition === 'hidden' )

@@ -830,5 +819,3 @@ ret[1] = '';

}
if (parseCommon.detect(dynamicDecorations, function(acc) {
return (ret[1] === acc);
})) {
if (dynamicDecorations.includes(ret[1])) {
if (multilineVars.dynamicPosition === 'hidden' )

@@ -839,18 +826,11 @@ ret[1] = '';

if (parseCommon.detect(accentPseudonyms, function(acc) {
if (ret[1] === acc[0]) {
ret[1] = acc[1];
return true;
} else
return false;
}))
var ind = accentPseudonyms.findIndex(function (acc) { return ret[1] === acc[0]})
if (ind >= 0) {
ret[1] = accentPseudonyms[ind][1];
return ret;
}
if (parseCommon.detect(accentDynamicPseudonyms, function(acc) {
if (ret[1] === acc[0]) {
ret[1] = acc[1];
return true;
} else
return false;
})) {
ind = accentDynamicPseudonyms.findIndex(function (acc) { return ret[1] === acc[0]})
if (ind >= 0) {
ret[1] = accentDynamicPseudonyms[ind][1];
if (multilineVars.dynamicPosition === 'hidden' )

@@ -860,5 +840,6 @@ ret[1] = '';

}
// We didn't find the accent in the list, so consume the space, but don't return an accent.
// Although it is possible that ! was used as a line break, so accept that.
if (line.charAt(i) === '!' && (ret[0] === 1 || line.charAt(i+ret[0]-1) !== '!'))
if (line[i] === '!' && (ret[0] === 1 || line[i+ret[0]-1] !== '!'))
return [1, null ];

@@ -883,3 +864,3 @@ warn("Unknown decoration: " + ret[1], line, i);

var start = i;
while (tokenizer.isWhiteSpace(line.charAt(i)))
while (tokenizer.isWhiteSpace(line[i]))
i++;

@@ -907,6 +888,6 @@ return [ i-start ];

for (var ws = 0; ws < line.length; ws++)
if (line.charAt(curr_pos + ret.len + ws) !== ' ')
if (line[curr_pos + ret.len + ws] !== ' ')
break;
var orig_bar_len = ret.len;
if (line.charAt(curr_pos+ret.len+ws) === '[') {
if (line[curr_pos+ret.len+ws] === '[') {
ret.len += ws + 1;

@@ -916,3 +897,3 @@ }

// It can also be a quoted string. It is unclear whether that construct requires '[', but it seems like it would. otherwise it would be confused with a regular chord.
if (line.charAt(curr_pos+ret.len) === '"' && line.charAt(curr_pos+ret.len-1) === '[') {
if (line[curr_pos+ret.len] === '"' && line[curr_pos+ret.len-1] === '[') {
var ending = tokenizer.getBrackettedSubstring(line, curr_pos+ret.len, 5);

@@ -948,12 +929,12 @@ return [ret.len+ending[0], ret.token, ending[1]];

}
while (line.charAt(i) === '(' || tokenizer.isWhiteSpace(line.charAt(i))) {
if (line.charAt(i) === '(') {
if (i+1 < line.length && (line.charAt(i+1) >= '2' && line.charAt(i+1) <= '9')) {
while (line[i] === '(' || tokenizer.isWhiteSpace(line[i])) {
if (line[i] === '(') {
if (i+1 < line.length && (line[i+1] >= '2' && line[i+1] <= '9')) {
if (ret.triplet !== undefined)
warn("Can't nest triplets", line, i);
else {
ret.triplet = line.charAt(i+1) - '0';
ret.triplet = line[i+1] - '0';
ret.tripletQ = tripletQ[ret.triplet];
ret.num_notes = ret.triplet;
if (i+2 < line.length && line.charAt(i+2) === ':') {
if (i+2 < line.length && line[i+2] === ':') {
// We are expecting "(p:q:r" or "(p:q" or "(p::r"

@@ -971,14 +952,14 @@ // That is: "put p notes into the time of q for the next r notes"

// (9 notes in the time of n
if (i+3 < line.length && line.charAt(i+3) === ':') {
if (i+3 < line.length && line[i+3] === ':') {
// The second number, 'q', is not present.
if (i+4 < line.length && (line.charAt(i+4) >= '1' && line.charAt(i+4) <= '9')) {
ret.num_notes = line.charAt(i+4) - '0';
if (i+4 < line.length && (line[i+4] >= '1' && line[i+4] <= '9')) {
ret.num_notes = line[i+4] - '0';
i += 3;
} else
warn("expected number after the two colons after the triplet to mark the duration", line, i);
} else if (i+3 < line.length && (line.charAt(i+3) >= '1' && line.charAt(i+3) <= '9')) {
ret.tripletQ = line.charAt(i+3) - '0';
if (i+4 < line.length && line.charAt(i+4) === ':') {
if (i+5 < line.length && (line.charAt(i+5) >= '1' && line.charAt(i+5) <= '9')) {
ret.num_notes = line.charAt(i+5) - '0';
} else if (i+3 < line.length && (line[i+3] >= '1' && line[i+3] <= '9')) {
ret.tripletQ = line[i+3] - '0';
if (i+4 < line.length && line[i+4] === ':') {
if (i+5 < line.length && (line[i+5] >= '1' && line[i+5] <= '9')) {
ret.num_notes = line[i+5] - '0';
i += 4;

@@ -1038,3 +1019,3 @@ }

if (multilineVars.currentVoice) {
parseCommon.each(multilineVars.staves, function(st) {
multilineVars.staves.forEach(function(st) {
st.meter = multilineVars.meter;

@@ -1077,2 +1058,4 @@ });

params.scale = multilineVars.currentVoice.scale;
if (multilineVars.currentVoice.color)
params.color = multilineVars.currentVoice.color;
if (multilineVars.currentVoice.style)

@@ -1119,3 +1102,3 @@ params.style = multilineVars.currentVoice.style;

while (1) {
switch(line.charAt(index)) {
switch(line[index]) {
case '(':

@@ -1164,5 +1147,5 @@ if (state === 'startSlur') {

if (state === 'startSlur' || state === 'sharp2' || state === 'flat2' || state === 'pitch') {
el.pitch = pitches[line.charAt(index)];
el.pitch = pitches[line[index]];
el.pitch += 7 * (multilineVars.currentVoice && multilineVars.currentVoice.octave !== undefined ? multilineVars.currentVoice.octave : multilineVars.octave);
el.name = line.charAt(index);
el.name = line[index];
if (el.accidental)

@@ -1182,3 +1165,3 @@ el.name = accMap[el.accidental] + el.name;

(multilineVars.currentVoice && multilineVars.currentVoice.clef === "perc")) {
var key = line.charAt(index);
var key = line[index];
if (el.accidental) {

@@ -1209,3 +1192,3 @@ key = accMap[el.accidental] + key;

if (state === 'startSlur') {
el.rest = { type: rests[line.charAt(index)] };
el.rest = { type: rests[line[index]] };
// There shouldn't be some of the properties that notes have. If some sneak in due to bad syntax in the abc file,

@@ -1254,4 +1237,4 @@ // just nix them here.

el.endChar = fraction.index;
while (fraction.index < line.length && (tokenizer.isWhiteSpace(line.charAt(fraction.index)) || line.charAt(fraction.index) === '-')) {
if (line.charAt(fraction.index) === '-')
while (fraction.index < line.length && (tokenizer.isWhiteSpace(line[fraction.index]) || line[fraction.index] === '-')) {
if (line[fraction.index] === '-')
el.startTie = {};

@@ -1287,3 +1270,3 @@ else

// Peek ahead to the next character. If it is a space, then we have an end beam.
if (tokenizer.isWhiteSpace(line.charAt(index + 1)))
if (tokenizer.isWhiteSpace(line[index + 1]))
addEndBeam(el);

@@ -1303,7 +1286,7 @@ el.endChar = index+1;

do {
if (line.charAt(index) === '.' && line.charAt(index+1) === '-') {
if (line[index] === '.' && line[index+1] === '-') {
dottedTie = true;
index++;
}
if (line.charAt(index) === '-') {
if (line[index] === '-') {
el.startTie = {};

@@ -1315,6 +1298,6 @@ if (dottedTie)

} while (index < line.length &&
(tokenizer.isWhiteSpace(line.charAt(index)) || line.charAt(index) === '-') ||
(line.charAt(index) === '.' && line.charAt(index+1) === '-'));
(tokenizer.isWhiteSpace(line[index]) || line[index] === '-') ||
(line[index] === '.' && line[index+1] === '-'));
el.endChar = index;
if (!durationSetByPreviousNote && canHaveBrokenRhythm && (line.charAt(index) === '<' || line.charAt(index) === '>')) { // TODO-PER: Don't need the test for < and >, but that makes the endChar work out for the regression test.
if (!durationSetByPreviousNote && canHaveBrokenRhythm && (line[index] === '<' || line[index] === '>')) { // TODO-PER: Don't need the test for < and >, but that makes the endChar work out for the regression test.
index--;

@@ -1360,7 +1343,7 @@ state = 'broken_rhythm';

var getBrokenRhythm = function(line, index) {
switch (line.charAt(index)) {
switch (line[index]) {
case '>':
if (index < line.length - 2 && line.charAt(index + 1) === '>' && line.charAt(index + 2) === '>') // triple >>>
if (index < line.length - 2 && line[index + 1] === '>' && line[index + 2] === '>') // triple >>>
return [3, 1.875, 0.125];
else if (index < line.length - 1 && line.charAt(index + 1) === '>') // double >>
else if (index < line.length - 1 && line[index + 1] === '>') // double >>
return [2, 1.75, 0.25];

@@ -1370,5 +1353,5 @@ else

case '<':
if (index < line.length - 2 && line.charAt(index + 1) === '<' && line.charAt(index + 2) === '<') // triple <<<
if (index < line.length - 2 && line[index + 1] === '<' && line[index + 2] === '<') // triple <<<
return [3, 0.125, 1.875];
else if (index < line.length - 1 && line.charAt(index + 1) === '<') // double <<
else if (index < line.length - 1 && line[index + 1] === '<') // double <<
return [2, 0.25, 1.75];

@@ -1375,0 +1358,0 @@ else

@@ -184,6 +184,6 @@ // abc_parse.js: parses a string representing ABC Music Notation into a usable internal structure.

var encode = function(str) {
var ret = parseCommon.gsub(str, '\x12', ' ');
ret = parseCommon.gsub(ret, '&', '&amp;');
ret = parseCommon.gsub(ret, '<', '&lt;');
return parseCommon.gsub(ret, '>', '&gt;');
var ret = str.replace(/\x12/g, ' ');
ret = ret.replace(/&/g, '&amp;');
ret = ret.replace(/</g, '&lt;');
return ret.replace(/>/g, '&gt;');
};

@@ -193,4 +193,4 @@

if (!line) line = " ";
var bad_char = line.charAt(col_num);
if (bad_char === ' ')
var bad_char = line[col_num];
if (bad_char === ' ' || !bad_char)
bad_char = "SPACE";

@@ -222,3 +222,3 @@ var clean_line = encode(line.substring(col_num - 64, col_num)) + '<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">' + bad_char + '</span>' + encode(line.substring(col_num + 1).substring(0,64));

words = parseCommon.strip(words);
if (words.charAt(words.length-1) !== '-')
if (words[words.length-1] !== '-')
words = words + ' '; // Just makes it easier to parse below, since every word has a divider after it.

@@ -235,4 +235,4 @@ var word_list = [];

if (replace)
word = parseCommon.gsub(word,'~', ' ');
var div = words.charAt(i);
word = word.replace(/~/g, ' ');
var div = words[i];
if (div !== '_' && div !== '-')

@@ -287,3 +287,3 @@ div = ' ';

var inSlur = false;
parseCommon.each(line, function(el) {
line.forEach(function(el) {
if (word_list.length !== 0) {

@@ -328,3 +328,3 @@ if (word_list[0].skip) {

words = parseCommon.strip(words);
if (words.charAt(words.length-1) !== '-')
if (words[words.length-1] !== '-')
words = words + ' '; // Just makes it easier to parse below, since every word has a divider after it.

@@ -340,4 +340,4 @@ var word_list = [];

if (replace)
word = parseCommon.gsub(word, '~', ' ');
var div = words.charAt(i);
word = word.replace(/~/g, ' ');
var div = words[i];
if (div !== '_' && div !== '-')

@@ -352,3 +352,3 @@ div = ' ';

for (var i = 0; i < words.length; i++) {
switch (words.charAt(i)) {
switch (words[i]) {
case ' ':

@@ -383,3 +383,3 @@ case '\x12':

var inSlur = false;
parseCommon.each(line, function(el) {
line.forEach(function(el) {
if (word_list.length !== 0) {

@@ -428,3 +428,3 @@ if (word_list[0].skip) {

}
if (line.length < 2 || line.charAt(1) !== ':' || music.lineContinuation) {
if (line.length < 2 || line[1] !== ':' || music.lineContinuation) {
music.parseMusic(line);

@@ -431,0 +431,0 @@ return

@@ -16,3 +16,3 @@ // abc_tokenizer.js: tokenizes an ABC Music Notation string to support abc_parse.

for (var i = 0; i < str.length; i++) {
if (!this.isWhiteSpace(str.charAt(i)))
if (!this.isWhiteSpace(str[i]))
return i;

@@ -27,3 +27,3 @@ }

for (var i = index; i < line.length; i++) {
if (!this.isWhiteSpace(line.charAt(i)))
if (!this.isWhiteSpace(line[i]))
return i-index;

@@ -39,3 +39,3 @@ }

return {len: 0};
switch (str.charAt(i)) {
switch (str[i]) {
case 'A':return {len: i+1, token: 'A'};

@@ -63,3 +63,3 @@ case 'B':return {len: i+1, token: 'B'};

return {len: 0};
switch (str.charAt(0)) {
switch (str[0]) {
case '#':return {len: 1, token: '#'};

@@ -74,3 +74,3 @@ case 'b':return {len: 1, token: 'b'};

// This returns the index of the next non-alphabetic char, or the entire length of the string if not found.
while (start < str.length && ((str.charAt(start) >= 'a' && str.charAt(start) <= 'z') || (str.charAt(start) >= 'A' && str.charAt(start) <= 'Z')))
while (start < str.length && ((str[start] >= 'a' && str[start] <= 'z') || (str[start] >= 'A' && str[start] <= 'Z')))
start++;

@@ -84,3 +84,3 @@ return start;

var firstThree = str.substring(i,i+3).toLowerCase();
if (firstThree.length > 1 && firstThree.charAt(1) === ' ' || firstThree.charAt(1) === '^' || firstThree.charAt(1) === '_' || firstThree.charAt(1) === '=') firstThree = firstThree.charAt(0); // This will handle the case of 'm'
if (firstThree.length > 1 && firstThree[1] === ' ' || firstThree[1] === '^' || firstThree[1] === '_' || firstThree[1] === '=') firstThree = firstThree[0]; // This will handle the case of 'm'
switch (firstThree) {

@@ -167,10 +167,10 @@ case 'mix':return {len: skipAlpha(str, i), token: 'Mix'};

this.getBarLine = function(line, i) {
switch (line.charAt(i)) {
switch (line[i]) {
case ']':
++i;
switch (line.charAt(i)) {
switch (line[i]) {
case '|': return {len: 2, token: "bar_thick_thin"};
case '[':
++i;
if ((line.charAt(i) >= '1' && line.charAt(i) <= '9') || line.charAt(i) === '"')
if ((line[i] >= '1' && line[i] <= '9') || line[i] === '"')
return {len: 2, token: "bar_invisible"};

@@ -184,13 +184,13 @@ return {len: 1, warn: "Unknown bar symbol"};

++i;
switch (line.charAt(i)) {
switch (line[i]) {
case ':': return {len: 2, token: "bar_dbl_repeat"};
case '|': // :|
++i;
switch (line.charAt(i)) {
switch (line[i]) {
case ']': // :|]
++i;
switch (line.charAt(i)) {
switch (line[i]) {
case '|': // :|]|
++i;
if (line.charAt(i) === ':') return {len: 5, token: "bar_dbl_repeat"};
if (line[i] === ':') return {len: 5, token: "bar_dbl_repeat"};
return {len: 3, token: "bar_right_repeat"};

@@ -203,3 +203,3 @@ default:

++i;
if (line.charAt(i) === ':') return {len: 4, token: "bar_dbl_repeat"};
if (line[i] === ':') return {len: 4, token: "bar_dbl_repeat"};
return {len: 3, token: "bar_right_repeat"};

@@ -216,5 +216,5 @@ default:

++i;
if (line.charAt(i) === '|') { // [|
if (line[i] === '|') { // [|
++i;
switch (line.charAt(i)) {
switch (line[i]) {
case ':': return {len: 3, token: "bar_left_repeat"};

@@ -225,3 +225,3 @@ case ']': return {len: 3, token: "bar_invisible"};

} else {
if ((line.charAt(i) >= '1' && line.charAt(i) <= '9') || line.charAt(i) === '"')
if ((line[i] >= '1' && line[i] <= '9') || line[i] === '"')
return {len: 1, token: "bar_invisible"};

@@ -233,11 +233,11 @@ return {len: 0};

++i;
switch (line.charAt(i)) {
switch (line[i]) {
case ']': return {len: 2, token: "bar_thin_thick"};
case '|': // ||
++i;
if (line.charAt(i) === ':') return {len: 3, token: "bar_left_repeat"};
if (line[i] === ':') return {len: 3, token: "bar_left_repeat"};
return {len: 2, token: "bar_thin_thin"};
case ':': // |:
var colons = 0;
while (line.charAt(i+colons) === ':') colons++;
while (line[i+colons] === ':') colons++;
return { len: 1+colons, token: "bar_left_repeat"};

@@ -254,3 +254,3 @@ default: return {len: 1, token: "bar_thin"};

for (var i = 0; i < str.length; i++) {
if (legalChars.indexOf(str.charAt(i)) < 0)
if (legalChars.indexOf(str[i]) < 0)
return {len: i, token: str.substring(0, i)};

@@ -264,3 +264,3 @@ }

var i = start;
while (i < end && !this.isWhiteSpace(str.charAt(i)))
while (i < end && !this.isWhiteSpace(str[i]))
i++;

@@ -326,3 +326,3 @@ return str.substring(start, i);

if (tokens.length === 0) return {accs: accs, warn: 'Expected note name after ' + acc};
switch (tokens[0].token.charAt(0))
switch (tokens[0].token[0])
{

@@ -345,3 +345,3 @@ case 'a':

accs = [];
accs.push({ acc: acc, note: tokens[0].token.charAt(0) });
accs.push({ acc: acc, note: tokens[0].token[0] });
if (tokens[0].token.length === 1)

@@ -374,3 +374,3 @@ tokens.shift();

var acc = null;
switch (str.charAt(i))
switch (str[i])
{

@@ -380,3 +380,3 @@ case '^':

case '=':
acc = str.charAt(i);
acc = str[i];
break;

@@ -388,3 +388,3 @@ default:return {len: 0};

return {len: 1, warn: 'Expected note name after accidental'};
switch (str.charAt(i))
switch (str[i])
{

@@ -405,11 +405,11 @@ case 'a':

case 'G':
return {len: i+1, token: {acc: accTranslation[acc], note: str.charAt(i)}};
return {len: i+1, token: {acc: accTranslation[acc], note: str[i]}};
case '^':
case '_':
case '/':
acc += str.charAt(i);
acc += str[i];
i++;
if (finished(str, i))
return {len: 2, warn: 'Expected note name after accidental'};
switch (str.charAt(i))
switch (str[i])
{

@@ -430,3 +430,3 @@ case 'a':

case 'G':
return {len: i+1, token: {acc: accTranslation[acc], note: str.charAt(i)}};
return {len: i+1, token: {acc: accTranslation[acc], note: str[i]}};
default:

@@ -451,5 +451,5 @@ return {len: 2, warn: 'Expected note name after accidental'};

end = comment;
while (start < end && (line.charAt(start) === ' ' || line.charAt(start) === '\t' || line.charAt(start) === '\x12'))
while (start < end && (line[start] === ' ' || line[start] === '\t' || line[start] === '\x12'))
start++;
while (start < end && (line.charAt(end-1) === ' ' || line.charAt(end-1) === '\t' || line.charAt(end-1) === '\x12'))
while (start < end && (line[end-1] === ' ' || line[end-1] === '\t' || line[end-1] === '\x12'))
end--;

@@ -481,32 +481,32 @@ return {start: start, end: end};

while (start < end) {
if (line.charAt(start) === '"') {
if (line[start] === '"') {
i = start+1;
while (i < end && line.charAt(i) !== '"') i++;
while (i < end && line[i] !== '"') i++;
tokens.push({ type: 'quote', token: line.substring(start+1, i), start: start+1, end: i});
i++;
} else if (isLetter(line.charAt(start))) {
} else if (isLetter(line[start])) {
i = start+1;
if (alphaUntilWhiteSpace)
while (i < end && !this.isWhiteSpace(line.charAt(i))) i++;
while (i < end && !this.isWhiteSpace(line[i])) i++;
else
while (i < end && isLetter(line.charAt(i))) i++;
tokens.push({ type: 'alpha', token: line.substring(start, i), continueId: isNumber(line.charAt(i)), start: start, end: i});
while (i < end && isLetter(line[i])) i++;
tokens.push({ type: 'alpha', token: line.substring(start, i), continueId: isNumber(line[i]), start: start, end: i});
start = i + 1;
} else if (line.charAt(start) === '.' && isNumber(line.charAt(i+1))) {
} else if (line[start] === '.' && isNumber(line[i+1])) {
i = start+1;
var int2 = null;
var float2 = null;
while (i < end && isNumber(line.charAt(i))) i++;
while (i < end && isNumber(line[i])) i++;
float2 = parseFloat(line.substring(start, i));
tokens.push({ type: 'number', token: line.substring(start, i), intt: int2, floatt: float2, continueId: isLetter(line.charAt(i)), start: start, end: i});
tokens.push({ type: 'number', token: line.substring(start, i), intt: int2, floatt: float2, continueId: isLetter(line[i]), start: start, end: i});
start = i + 1;
} else if (isNumber(line.charAt(start)) || (line.charAt(start) === '-' && isNumber(line.charAt(i+1)))) {
} else if (isNumber(line[start]) || (line[start] === '-' && isNumber(line[i+1]))) {
i = start+1;
var intt = null;
var floatt = null;
while (i < end && isNumber(line.charAt(i))) i++;
if (line.charAt(i) === '.' && isNumber(line.charAt(i+1))) {
while (i < end && isNumber(line[i])) i++;
if (line[i] === '.' && isNumber(line[i+1])) {
i++;
while (i < end && isNumber(line.charAt(i))) i++;
while (i < end && isNumber(line[i])) i++;
} else

@@ -516,8 +516,8 @@ intt = parseInt(line.substring(start, i));

floatt = parseFloat(line.substring(start, i));
tokens.push({ type: 'number', token: line.substring(start, i), intt: intt, floatt: floatt, continueId: isLetter(line.charAt(i)), start: start, end: i});
tokens.push({ type: 'number', token: line.substring(start, i), intt: intt, floatt: floatt, continueId: isLetter(line[i]), start: start, end: i});
start = i + 1;
} else if (line.charAt(start) === ' ' || line.charAt(start) === '\t') {
} else if (line[start] === ' ' || line[start] === '\t') {
i = start+1;
} else {
tokens.push({ type: 'punct', token: line.charAt(start), start: start, end: start+1});
tokens.push({ type: 'punct', token: line[start], start: start, end: start+1});
i = start+1;

@@ -533,6 +533,6 @@ }

var i = start;
while (i < end && this.isWhiteSpace(line.charAt(i)) || line.charAt(i) === '=')
while (i < end && this.isWhiteSpace(line[i]) || line[i] === '=')
i++;
if (line.charAt(i) === '"') {
if (line[i] === '"') {
var close = line.indexOf('"', i+1);

@@ -544,3 +544,3 @@ if (close === -1 || close >= end)

var ii = i;
while (ii < end && !this.isWhiteSpace(line.charAt(ii)) && line.charAt(ii) !== '=')
while (ii < end && !this.isWhiteSpace(line[ii]) && line[ii] !== '=')
ii++;

@@ -595,3 +595,3 @@ return {len: ii-start+1, token: line.substring(i, ii)};

var out = null;
parseCommon.each(arr, function(s) {
arr.forEach(function(s) {
if (out === null)

@@ -622,3 +622,3 @@ out = s;

while (index < line.length) {
switch (line.charAt(index)) {
switch (line[index]) {
case '0':num = num*10;index++;break;

@@ -644,3 +644,3 @@ case '1':num = num*10+1;index++;break;

var den = 1;
if (line.charAt(index) !== '/') {
if (line[index] !== '/') {
var ret = this.getNumber(line, index);

@@ -650,7 +650,7 @@ num = ret.num;

}
if (line.charAt(index) === '/') {
if (line[index] === '/') {
index++;
if (line.charAt(index) === '/') {
if (line[index] === '/') {
var div = 0.5;
while (line.charAt(index++) === '/')
while (line[index++] === '/')
div = div /2;

@@ -756,3 +756,3 @@ return {value: num * div, index: index-1};

// but in the error case it might not be.
var matchChar = _matchChar || line.charAt(i);
var matchChar = _matchChar || line[i];
var pos = i+1;

@@ -764,3 +764,3 @@ var esc = false;

}
if (line.charAt(pos) === matchChar)
if (line[pos] === matchChar)
return [pos-i+1,substInChord(line.substring(i+1, pos)), true];

@@ -767,0 +767,0 @@ else // we hit the end of line, so we'll just pick an arbitrary num of chars so the line doesn't disappear.

@@ -71,3 +71,3 @@ var parseKeyVoice = require('../parse/abc_parse_key_voice');

}
} else if (event.el_type === "scale" || event.el_type === "stem" || event.el_type === "overlay" || event.el_type === "style" || event.el_type === "transpose") {
} else if (event.el_type === "scale" || event.el_type === "stem" || event.el_type === "overlay" || event.el_type === "style" || event.el_type === "transpose" || event.el_type === "color") {
// These types of events are duplicated on the overlay layer.

@@ -182,6 +182,6 @@ overlayVoice[k].voice.push(event);

if (anyDeleted) {
tune.lines = parseCommon.compact(tune.lines);
parseCommon.each(tune.lines, function(line) {
tune.lines = tune.lines.filter(function (line) { return !!line });
tune.lines.forEach(function(line) {
if (line.staff)
line.staff = parseCommon.compact(line.staff);
line.staff = line.staff.filter(function (line) { return !!line });
});

@@ -217,5 +217,5 @@ }

if (anyDeleted) {
parseCommon.each(tune.lines, function(line) {
tune.lines.forEach(function(line) {
if (line.staff)
line.staff = parseCommon.compact(line.staff);
line.staff = line.staff.filter(function (staff) { return !!staff });
});

@@ -259,3 +259,3 @@ }

var offNum = chordPos*100+1;
parseCommon.each(obj.endSlur, function(x) { if (offNum === x) --offNum; });
obj.endSlur.forEach(function(x) { if (offNum === x) --offNum; });
currSlur[staffNum][voiceNum][chordPos] = [offNum];

@@ -283,8 +283,8 @@ }

if (usedNums) {
parseCommon.each(usedNums, function(x) { if (nextNum === x) ++nextNum; });
parseCommon.each(usedNums, function(x) { if (nextNum === x) ++nextNum; });
parseCommon.each(usedNums, function(x) { if (nextNum === x) ++nextNum; });
usedNums.forEach(function(x) { if (nextNum === x) ++nextNum; });
usedNums.forEach(function(x) { if (nextNum === x) ++nextNum; });
usedNums.forEach(function(x) { if (nextNum === x) ++nextNum; });
}
parseCommon.each(currSlur[staffNum][voiceNum][chordPos], function(x) { if (nextNum === x) ++nextNum; });
parseCommon.each(currSlur[staffNum][voiceNum][chordPos], function(x) { if (nextNum === x) ++nextNum; });
currSlur[staffNum][voiceNum][chordPos].forEach(function(x) { if (nextNum === x) ++nextNum; });
currSlur[staffNum][voiceNum][chordPos].forEach(function(x) { if (nextNum === x) ++nextNum; });

@@ -520,7 +520,7 @@ currSlur[staffNum][voiceNum][chordPos].push(nextNum);

var mid = currStaff.workingClef.verticalPos;
parseCommon.each(hp.pitches, function(p) { p.verticalPos = p.pitch - mid; });
hp.pitches.forEach(function(p) { p.verticalPos = p.pitch - mid; });
}
if (hp.gracenotes !== undefined) {
var mid2 = currStaff.workingClef.verticalPos;
parseCommon.each(hp.gracenotes, function(p) { p.verticalPos = p.pitch - mid2; });
hp.gracenotes.forEach(function(p) { p.verticalPos = p.pitch - mid2; });
}

@@ -711,2 +711,5 @@ currStaff.voices[This.voiceNum].push(hp);

};
this.changeVoiceColor = function(color) {
self.appendElement('color', null, null, { color: color} );
};

@@ -744,2 +747,4 @@ this.startNewLine = function(params) {

self.appendElement('scale', null, null, { size: params.scale} );
if (params.color)
self.appendElement('color', null, null, { color: params.color} );
};

@@ -746,0 +751,0 @@ var createStaff = function(params) {

@@ -35,2 +35,3 @@ // abc_midi_flattener.js: Turn a linear series of events into a series of MIDI commands.

var chordChannel;
var bassInstrument = 0;
var chordInstrument = 0;

@@ -58,2 +59,3 @@ var drumInstrument = 128;

var drumDefinition = {};
var drumBars;

@@ -68,4 +70,5 @@ var pickupLength = 0;

flatten = function(voices, options, percmap_) {
flatten = function(voices, options, percmap_, midiOptions) {
if (!options) options = {};
if (!midiOptions) midiOptions = {};
barAccidentals = [];

@@ -93,4 +96,6 @@ accidentals = [0,0,0,0,0,0,0];

currentChords = [];
boomVolume = 64;
chickVolume = 48;
bassInstrument = midiOptions.bassprog && midiOptions.bassprog.length === 1 ? midiOptions.bassprog[0] : 0;
chordInstrument = midiOptions.chordprog && midiOptions.chordprog.length === 1 ? midiOptions.chordprog[0] : 0;
boomVolume = midiOptions.bassvol && midiOptions.bassvol.length === 1 ? midiOptions.bassvol[0] : 64;
chickVolume = midiOptions.chordvol && midiOptions.chordvol.length === 1 ? midiOptions.chordvol[0] : 48;
lastChord = undefined;

@@ -114,2 +119,3 @@ chordLastBar = undefined;

drumDefinition = {};
drumBars = 1;

@@ -153,2 +159,3 @@ if (voices.length > 0 && voices[0].length > 0)

beatFraction = getBeatFraction(meter);
alignDrumToMeter();
break;

@@ -198,2 +205,3 @@ case "tempo":

drumDefinition = normalizeDrumDefinition(element.params);
alignDrumToMeter();
break;

@@ -1005,5 +1013,5 @@ case "gchord":

if (!intervals) {
if (modifier.slice(0,2).toLowerCase() === 'ma' || modifier.charAt(0) === 'M')
if (modifier.slice(0,2).toLowerCase() === 'ma' || modifier[0] === 'M')
intervals = chordIntervals.M;
else if (modifier.charAt(0) === 'm' || modifier.charAt(0) === '-')
else if (modifier[0] === 'm' || modifier[0] === '-')
intervals = chordIntervals.m;

@@ -1024,3 +1032,3 @@ else

if (boom !== undefined)
chordTrack.push({cmd: 'note', pitch: boom, volume: volume, start: lastBarTime+beat*durationRounded(beatLength), duration: durationRounded(noteLength), gap: 0, instrument: chordInstrument});
chordTrack.push({cmd: 'note', pitch: boom, volume: volume, start: lastBarTime+beat*durationRounded(beatLength), duration: durationRounded(noteLength), gap: 0, instrument: bassInstrument});
}

@@ -1220,2 +1228,11 @@

}
drumBars = params.bars ? params.bars : 1;
return ret;
}
function alignDrumToMeter() {
if (!drumDefinition ||!drumDefinition.pattern) {
return;
}
var ret = drumDefinition;
// Now normalize the pattern to cover the correct number of measures. The note lengths passed are relative to each other and need to be scaled to fit a measure.

@@ -1226,7 +1243,6 @@ var totalTime = 0;

totalTime += ret.pattern[ii].len;
var numBars = params.bars ? params.bars : 1;
var factor = totalTime / numBars / measuresPerBeat;
var factor = totalTime / drumBars / measuresPerBeat;
for (ii = 0; ii < ret.pattern.length; ii++)
ret.pattern[ii].len = ret.pattern[ii].len / factor;
return ret;
drumDefinition = ret;
}

@@ -1233,0 +1249,0 @@

@@ -29,2 +29,3 @@ var getNote = require('./load-note');

self.isRunning = false; // whether there is currently a sound buffer running.
// self.options = undefined

@@ -35,2 +36,3 @@ // Load and cache all needed sounds

options = {};
// self.options = options
registerAudioContext(options.audioContext); // This works no matter what - if there is already an ac it is a nop; if the context is not passed in, then it creates one.

@@ -288,2 +290,4 @@ var startTime = activeAudioContext().currentTime;

var noteMapTracks = createNoteMap(self.flattened);
// if (self.options.swing)
// addSwing(noteMapTracks, self.options.swing, self.beatsPerMeasure)
if (self.sequenceCallback)

@@ -483,2 +487,6 @@ self.sequenceCallback(noteMapTracks, self.callbackContext);

self.getAudioBuffer = function() {
return self.audioBuffers[0];
};
/////////////// Private functions //////////////

@@ -513,4 +521,37 @@

};
// // this is a first attempt at adding a little bit of swing to the output, but the algorithm isn't correct.
// function addSwing(noteMapTracks, swing, beatsPerMeasure) {
// console.log("addSwing", noteMapTracks, swing, beatsPerMeasure)
// // Swing should be between -0.9 and 0.9. Make sure the input is between them.
// // Then that is the percentage to add to the first beat, so a negative number moves the second beat earlier.
// // A value of zero is the same as no swing at all.
// // This only works when there are an even number of beats in a measure.
// if (beatsPerMeasure % 2 !== 0)
// return;
// swing = parseFloat(swing)
// if (isNaN(swing))
// return
// if (swing < -0.9)
// swing = -0.9
// if (swing > 0.9)
// swing = 0.9
// var beatLength = (1 / beatsPerMeasure)*2
// swing = beatLength * swing
// for (var t = 0; t < noteMapTracks.length; t++) {
// var track = noteMapTracks[t];
// for (var i = 0; i < track.length; i++) {
// var event = track[i];
// if (event.start % beatLength) {
// // This is the off beat
// event.start += swing;
// } else {
// // This is the beat
// event.end += swing;
// }
// }
// }
// }
}
module.exports = CreateSynth;

@@ -8,3 +8,2 @@ /*

var GuitarPatterns = require('./guitar-patterns');
var setGuitarFonts = require('./guitar-fonts');

@@ -36,3 +35,2 @@ /**

if (this.tablature.bypass(line)) return;
setGuitarFonts(this.abcTune);
var rndrer = new TabRenderer(this, renderer, line, staffIndex);

@@ -39,0 +37,0 @@ rndrer.doLayout();

@@ -0,1 +1,2 @@

const {noteToMidi} = require('../../synth/note-to-midi');
var TabNote = require('./tab-note');

@@ -96,3 +97,6 @@ var TabNotes = require('./tab-notes');

for (var iiii = 0; iiii < notes.length; iiii++) {
var note = new TabNote.TabNote(notes[iiii].name);
if (notes[iiii].endTie)
continue;
var note = new TabNote.TabNote(notes[iiii].name, self.clefTranspose);
note.checkKeyAccidentals(self.accidentals, self.measureAccidentals)
var curPos = toNumber(self, note);

@@ -151,22 +155,19 @@ retNotes.push(curPos);

}
var num = null;
var str = 0;
var lowestString = self.strings[self.strings.length - 1];
var lowestNote = new TabNote.TabNote(lowestString[0]);
if (note.isLowerThan(lowestNote) ) {
return {
num: "?",
str: self.strings.length - 1,
note: note,
error: note.emit() + ': unexpected note for instrument'
};
}
while (str < self.strings.length) {
num = noteToNumber(self, note, str);
if (num) {
return num;
for (var i = self.stringPitches.length-1; i >= 0; i--) {
if (note.pitch + note.pitchAltered >= self.stringPitches[i]) {
var num = note.pitch + note.pitchAltered - self.stringPitches[i]
if (note.quarter === '^') num -= 0.5
else if (note.quarter === "v") num += 0.5
return {
num: Math.round(num),
str: self.stringPitches.length-1-i, // reverse the strings because string 0 is on the bottom
note: note
}
}
str++;
}
return null; // not found
return {
num: "?",
str: self.stringPitches.length-1,
note: note,
};
}

@@ -203,9 +204,12 @@

} else {
note = new TabNote.TabNote(notes[0].name);
number = toNumber(this, note);
if (number) {
retNotes.push(number);
} else {
invalidNumber(retNotes, note);
error = retNotes.error;
if (!notes[0].endTie) {
note = new TabNote.TabNote(notes[0].name, this.clefTranspose);
note.checkKeyAccidentals(this.accidentals, this.measureAccidentals)
number = toNumber(this, note);
if (number) {
retNotes.push(number);
} else {
invalidNumber(retNotes, note);
error = retNotes.error;
}
}

@@ -219,3 +223,4 @@ }

for (var iiii = 0; iiii < graces.length; iiii++) {
note = new TabNote.TabNote(graces[iiii].name);
note = new TabNote.TabNote(graces[iiii].name, this.clefTranspose);
note.checkKeyAccidentals(this.accidentals, this.measureAccidentals)
number = toNumber(this, note);

@@ -239,3 +244,10 @@ if (number) {

StringPatterns.prototype.toString = function () {
return this.tuning.join('').replaceAll(',', '').toUpperCase();
var arr = []
for (var i = 0; i < this.tuning.length; i++) {
var str = this.tuning[i].replaceAll(',', '').replaceAll("'", '').toUpperCase();
if (str[0] === '_') str = str[1] + 'b '
else if (str[0] === '^') str = str[1] + "# "
arr.push(str)
}
return arr.join('');
};

@@ -283,3 +295,9 @@

}
this.transpose = plugin.transpose ? plugin.transpose : 0
this.tuning = tuning;
this.stringPitches = []
for (var i = 0; i < this.tuning.length; i++) {
var pitch = noteToMidi(this.tuning[i]) + this.capo
this.stringPitches.push(pitch)
}
if (this.capo > 0) {

@@ -286,0 +304,0 @@ this.capoTuning = buildCapo(this);

@@ -0,1 +1,3 @@

var {noteToMidi, midiToNote} = require('../../synth/note-to-midi');
/**

@@ -9,5 +11,8 @@ *

function TabNote(note) {
function TabNote(note, clefTranspose) {
var pitch = noteToMidi(note)
if (clefTranspose)
pitch += clefTranspose
var newNote = midiToNote(pitch);
var isFlat = false;
var newNote = note;
var isSharp = false;

@@ -58,5 +63,7 @@ var isAltered = false;

}
var hasComma = (note.match(/,/g) || []).length;
var hasQuote = (note.match(/'/g) || []).length;
var hasComma = (newNote.match(/,/g) || []).length;
var hasQuote = (newNote.match(/'/g) || []).length;
this.pitch = pitch
this.pitchAltered = 0
this.name = newNote;

@@ -81,2 +88,3 @@ this.acc = acc;

var newTabNote = new TabNote(newNote);
newTabNote.pitch = self.pitch;
newTabNote.hasComma = self.hasComma;

@@ -92,29 +100,7 @@ newTabNote.isLower = self.isLower;

TabNote.prototype.sameNoteAs = function (note) {
if ((this.name == note.name) &&
(this.hasComma == note.hasComma) &&
(this.isLower == note.isLower) &&
(this.isQuoted == note.isQuoted) &&
(this.isSharp == note.isSharp) &&
(this.isFlat == note.isFlat)) {
return true;
} else {
return false;
}
return note.pitch === this.pitch
};
TabNote.prototype.isLowerThan = function (note) {
var noteComparator = ['C','D','E','F','G','A','B'];
if (this.hasComma > note.hasComma) return true;
if (note.hasComma > this.hasComma) return false;
if (this.isQuoted > note.isQuoted) return false;
if (note.isQuoted > this.isQuoted) return true;
if (this.isLower) {
if (!note.isLower) return false;
} else {
if (note.isLower) return true;
}
var noteName = note.name[0].toUpperCase();
var thisName = this.name[0].toUpperCase();
if (noteComparator.indexOf(thisName) < noteComparator.indexOf(noteName)) return true;
return false;
return note.pitch > this.pitch
};

@@ -127,10 +113,9 @@

switch (measureAccidentals[this.name.toUpperCase()]) {
case "__": this.acc = -2; return;
case "_": this.acc = -1; return;
case "=": this.acc = 0; return;
case "^": this.acc = 1; return;
case "^^": this.acc = 2; return;
case "__": this.acc = -2; this.pitchAltered = -2; return;
case "_": this.acc = -1; this.pitchAltered = -1; return;
case "=": this.acc = 0; this.pitchAltered = 0; return;
case "^": this.acc = 1; this.pitchAltered = 1; return;
case "^^": this.acc = 2; this.pitchAltered = 2; return;
}
}
if (accidentals) {
} else if (accidentals) {
var curNote = this.name;

@@ -143,2 +128,3 @@ for (var iii = 0; iii < accidentals.length; iii++) {

this.isKeyFlat = true;
this.pitchAltered = -1
}

@@ -148,2 +134,3 @@ if (curAccidentals.acc == 'sharp') {

this.isKeySharp = true;
this.pitchAltered = 1
}

@@ -173,73 +160,9 @@ }

TabNote.prototype.nextNote = function () {
var newTabNote = cloneNote(this);
if (!this.isSharp && !this.isKeySharp ) {
if (this.name != 'E' && this.name != 'B') {
newTabNote.isSharp = true;
return newTabNote;
}
} else {
// cleanup
newTabNote.isSharp = false;
newTabNote.isKeySharp = false;
}
var noteIndex = notes.indexOf(this.name);
if (noteIndex == notes.length - 1) {
noteIndex = 0;
} else {
noteIndex++;
}
newTabNote.name = notes[noteIndex];
if (newTabNote.name == 'C') {
if (newTabNote.hasComma > 0) {
newTabNote.hasComma--;
} else {
if (!newTabNote.isLower) {
newTabNote.isLower = true;
} else {
newTabNote.isQuoted = true;
}
}
}
return newTabNote;
var note = midiToNote(this.pitch+1+this.pitchAltered)
return new TabNote(note)
};
TabNote.prototype.prevNote = function () {
var newTabNote = cloneNote(this);
if (this.isSharp) {
newTabNote.isSharp = false;
return newTabNote;
}
var noteIndex = notes.indexOf(this.name);
if (noteIndex == 0) {
noteIndex = notes.length - 1;
} else {
noteIndex--;
}
newTabNote.name = notes[noteIndex];
if (newTabNote.name == 'B') {
if (newTabNote.isLower) {
newTabNote.hasComma = 1;
} else {
if (newTabNote.hasComma > 0) {
newTabNote.hasComma++;
} else {
if (newTabNote.isQuoted > 0) {
newTabNote.isQuoted -= 1;
} else {
newTabNote.isLower = true;
}
}
}
}
if (this.isFlat) {
newTabNote.isFlat = false;
return newTabNote;
} else {
if (this.name != 'E' && this.name != 'B') {
newTabNote.isSharp = true;
}
}
return newTabNote;
var note = midiToNote(this.pitch-1+this.pitchAltered)
return new TabNote(note)
};

@@ -246,0 +169,0 @@

@@ -6,3 +6,2 @@

var ViolinPatterns = require('./violin-patterns');
var setViolinFonts = require('./violin-fonts');

@@ -34,3 +33,2 @@

if (this.tablature.bypass(line)) return;
setViolinFonts(this.abcTune);
var rndrer = new TabRenderer(this, renderer, line, staffIndex);

@@ -37,0 +35,0 @@ rndrer.doLayout();

/**
* Tablature Absolute elements factory
*/
var AbsoluteElement = require('../write/abc_absolute_element');
var RelativeElement = require('../write/abc_relative_element');
var Transposer = require('./transposer');
var AbsoluteElement = require('../write/creation/elements/absolute-element');
var RelativeElement = require('../write/creation/elements/relative-element');

@@ -147,16 +146,2 @@ function isObject(a) { return a != null && a.constructor === Object; }

function checkTransposition(plugin, transposer ,pitches, graceNotes) {
if (plugin.transpose) {
//transposer.transpose(plugin.transpose);
for (var jj = 0; jj < pitches.length; jj++) {
pitches[jj] = transposer.transposeNote(pitches[jj]);
}
if (graceNotes) {
for (var kk = 0; kk < graceNotes.length; kk++) {
graceNotes[kk] = transposer.transposeNote(graceNotes[kk]);
}
}
}
}
function convertToNumber(plugin, pitches, graceNotes) {

@@ -200,3 +185,2 @@ var tabPos = plugin.semantics.notesToNumber(pitches, graceNotes);

var dest = staffAbsolute[staffSize+staffIndex+voiceIndex];
var transposer = null;
var tabPos = null;

@@ -219,2 +203,4 @@ var defNote = null;

dest.children.push(buildTabAbsolute(plugin, absX, relX));
if (absChild.abcelem.type.indexOf('-8') >= 0) plugin.semantics.strings.clefTranspose = -12
if (absChild.abcelem.type.indexOf('+8') >= 0) plugin.semantics.strings.clefTranspose = 12
}

@@ -226,8 +212,2 @@ switch (absChild.type) {

plugin.semantics.strings.accidentals = this.accidentals;
if (plugin.transpose) {
transposer = new Transposer(
absChild.abcelem.accidentals,
plugin.transpose
);
}
break;

@@ -265,4 +245,2 @@ case 'bar':

if (restGraces) {
// check transpose
checkTransposition(plugin, transposer, null, restGraces);
// to number conversion

@@ -282,5 +260,3 @@ tabPos = convertToNumber(plugin, null, restGraces);

var graceNotes = absChild.abcelem.gracenotes;
// check transpose
abs.type = 'tabNumber';
checkTransposition(plugin, transposer, pitches, graceNotes);
// to number conversion

@@ -311,5 +287,7 @@ tabPos = convertToNumber(plugin, pitches, graceNotes);

}
defNote.abselem = abs;
tabVoice.push(defNote);
dest.children.push(abs);
if (defNote.notes.length > 0) {
defNote.abselem = abs;
tabVoice.push(defNote);
dest.children.push(abs);
}
break;

@@ -316,0 +294,0 @@ }

/* eslint-disable no-debugger */
var VoiceElement = require('../write/abc_voice_element');
var VoiceElement = require('../write/creation/elements/voice-element');
var TabAbsoluteElements = require('./tab-absolute-elements');
var spacing = require('../write/abc_spacing');
var spacing = require('../write/helpers/spacing');

@@ -6,0 +6,0 @@ function initSpecialY() {

@@ -321,3 +321,3 @@ // abc_parser_lint.js: Analyzes the output of abc_parse.

"nobarlines", "barlines", "beataccents", "nobeataccents", "droneon", "droneoff", "noportamento", "channel", "c",
"drumon", "drumoff", "fermatafixed", "fermataproportional", "gchordon", "gchordoff", "bassvol", "chordvol",
"drumon", "drumoff", "fermatafixed", "fermataproportional", "gchordon", "gchordoff", "bassvol", "chordvol", "bassprog", "chordprog",
"controlcombo", "temperamentnormal", "gchord", "ptstress", "beatmod", "deltaloudness", "drumbars", "pitchbend",

@@ -339,2 +339,3 @@ "gracedivider", "makechordchannels", "randomchordattack", "chordattack", "stressmodel", "transpose",

{ value: "clef", properties: appendPositioning(clefProperties) },
{ value: "color", properties: { color: {type: "string", optional: true } } },
{ value: "bar", properties: prependPositioning(barProperties) },

@@ -467,5 +468,7 @@ { value: "gap", properties: { type: "number", optional: true } }, // staffbreak

jazzchords: { type: "boolean", optional: true },
germanAlphabet: { type: "boolean", optional: true },
leftmargin: { type: "number", optional: true },
linesep: { type: "number", optional: true },
lineskipfac: { type: "number", optional: true },
lineThickness: { type: "number", optional: true },
map: { type: "string", optional: true },

@@ -747,3 +750,3 @@ maxshrink: { type: "number", optional: true },

var err = "";
parseCommon.each(ret.errors, function(e) {
ret.errors.forEach(function(e) {
err += e.property + ": " + e.message + "\n";

@@ -754,4 +757,4 @@ });

var warn = warnings === undefined ? "No errors" : warnings.join('\n');
warn = parseCommon.gsub(warn, '<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">', '$$$$');
warn = parseCommon.gsub(warn, '</span>', '$$$$');
warn = warn.replace(/<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">/g, '$$$$$$$$');
warn = warn.replace(/<\/span>/g, '$$$$$$$$');
return "Error:------\n" + err + "\nObj:-------\n" + out + "\nWarn:------\n" + warn;

@@ -758,0 +761,0 @@ };

var drawTempo = require('./tempo');
var drawRelativeElement = require('./relative');
var spacing = require('../abc_spacing');
var setClass = require('../set-class');
var spacing = require('../helpers/spacing');
var setClass = require('../helpers/set-class');
var elementGroup = require('./group-elements');

@@ -12,3 +12,3 @@

elementGroup.beginGroup(renderer.paper, renderer.controller);
for (var i=0; i<params.children.length; i++) {
for (var i = 0; i < params.children.length; i++) {
var child = params.children[i];

@@ -26,3 +26,3 @@ switch (child.type) {

params.counters = renderer.controller.classes.getCurrent();
klass += ' d' + Math.round(params.durationClass*1000)/1000;
klass += ' d' + Math.round(params.durationClass * 1000) / 1000;
klass = klass.replace(/\./g, '-');

@@ -71,3 +71,3 @@ if (params.abcelem.pitches) {

params.notePositions.push({
x: params.heads[jj].x + params.heads[jj].w/2,
x: params.heads[jj].x + params.heads[jj].w / 2,
y: staffPos.zero - params.heads[jj].pitch * spacing.STEP

@@ -74,0 +74,0 @@ });

@@ -12,5 +12,5 @@ var printPath = require('./print-path');

var slope = getSlope(renderer, beam.startX, beam.startY, beam.endX, beam.endY);
var xes = [ ];
for (var j = 0; j < beam.split.length; j+=2) {
xes.push([beam.split[j], beam.split[j+1]]);
var xes = [];
for (var j = 0; j < beam.split.length; j += 2) {
xes.push([beam.split[j], beam.split[j + 1]]);
}

@@ -25,4 +25,4 @@ for (j = 0; j < xes.length; j++) {

}
var durationClass = ("abcjs-d"+params.duration).replace(/\./g,"-");
var klasses = renderer.controller.classes.generate('beam-elem '+durationClass);
var durationClass = ("abcjs-d" + params.duration).replace(/\./g, "-");
var klasses = renderer.controller.classes.generate('beam-elem ' + durationClass);
var el = printPath(renderer, {

@@ -43,4 +43,4 @@ path: pathString,

endX = roundNumber(endX);
var startY2 = roundNumber(startY+dy);
var endY2 = roundNumber(endY+dy);
var startY2 = roundNumber(startY + dy);
var endY2 = roundNumber(endY + dy);
return "M" + startX + " " + startY + " L" + endX + " " + endY +

@@ -56,5 +56,5 @@ "L" + endX + " " + endY2 + " L" + startX + " " + startY2 + "z";

var x = currentX - startX;
return startY + x*slope;
return startY + x * slope;
}
module.exports = drawBeam;
var sprintf = require('./sprintf');
var spacing = require('../abc_spacing');
var spacing = require('../helpers/spacing');
var renderText = require('./text');

@@ -8,10 +8,10 @@

// The STEP offset here moves it to the top and bottom lines
var startY = params.startVoice.staff.absoluteY - spacing.STEP*10;
var startY = params.startVoice.staff.absoluteY - spacing.STEP * 10;
if (params.endVoice && params.endVoice.staff)
params.endY = params.endVoice.staff.absoluteY - spacing.STEP*2;
params.endY = params.endVoice.staff.absoluteY - spacing.STEP * 2;
else if (params.lastContinuedVoice && params.lastContinuedVoice.staff)
params.endY = params.lastContinuedVoice.staff.absoluteY - spacing.STEP*2;
params.endY = params.lastContinuedVoice.staff.absoluteY - spacing.STEP * 2;
else
params.endY = params.startVoice.staff.absoluteY - spacing.STEP*2;
return draw(renderer, params.x,startY, params.endY, params.type, params.header, selectables);
params.endY = params.startVoice.staff.absoluteY - spacing.STEP * 2;
return draw(renderer, params.x, startY, params.endY, params.type, params.header, selectables);
}

@@ -21,31 +21,31 @@

xLeft += spacing.STEP;
var xLineWidth = spacing.STEP*0.75;
var yOverlap = spacing.STEP*0.75;
var xLineWidth = spacing.STEP * 0.75;
var yOverlap = spacing.STEP * 0.75;
var height = yBottom - yTop;
// Straight line
var pathString = sprintf("M %f %f l %f %f l %f %f l %f %f z",
xLeft, yTop-yOverlap, // top left line
0, height+yOverlap*2, // bottom left line
xLeft, yTop - yOverlap, // top left line
0, height + yOverlap * 2, // bottom left line
xLineWidth, 0, // bottom right line
0, - (height+yOverlap*2) // top right line
0, - (height + yOverlap * 2) // top right line
);
// Top arm
var wCurve = spacing.STEP*2;
var wCurve = spacing.STEP * 2;
var hCurve = spacing.STEP;
pathString += sprintf("M %f %f q %f %f %f %f q %f %f %f %f z",
xLeft+xLineWidth, yTop-yOverlap, // top left arm
wCurve*0.6, hCurve*0.2,
xLeft + xLineWidth, yTop - yOverlap, // top left arm
wCurve * 0.6, hCurve * 0.2,
wCurve, -hCurve, // right point
-wCurve*0.1, hCurve*0.3,
-wCurve, hCurve+spacing.STEP // left bottom
-wCurve * 0.1, hCurve * 0.3,
-wCurve, hCurve + spacing.STEP // left bottom
);
// Bottom arm
pathString += sprintf("M %f %f q %f %f %f %f q %f %f %f %f z",
xLeft+xLineWidth, yTop+yOverlap+height, // bottom left arm
wCurve*0.6, -hCurve*0.2,
xLeft + xLineWidth, yTop + yOverlap + height, // bottom left arm
wCurve * 0.6, -hCurve * 0.2,
wCurve, hCurve, // right point
-wCurve*0.1, -hCurve*0.3,
-wCurve, -hCurve-spacing.STEP // left bottom
-wCurve * 0.1, -hCurve * 0.3,
-wCurve, -hCurve - spacing.STEP // left bottom
);
return renderer.paper.path({path:pathString, stroke:renderer.foregroundColor, fill:renderer.foregroundColor, 'class': renderer.controller.classes.generate(type), "data-name": type});
return renderer.paper.path({ path: pathString, stroke: renderer.foregroundColor, fill: renderer.foregroundColor, 'class': renderer.controller.classes.generate(type), "data-name": type });
}

@@ -59,3 +59,3 @@

[7.5, -8, 21, 0, 18.5, -10.5, 7.5],
[0, yHeight/5.5, yHeight/3.14, yHeight/2, yHeight/2.93, yHeight/4.88, 0]);
[0, yHeight / 5.5, yHeight / 3.14, yHeight / 2, yHeight / 2.93, yHeight / 4.88, 0]);

@@ -65,5 +65,5 @@ pathString += curve(xLeft,

[0, 17.5, -7.5, 6.6, -5, 20, 0],
[yHeight/2, yHeight/1.46, yHeight/1.22, yHeight, yHeight/1.19, yHeight/1.42, yHeight/2]);
[yHeight / 2, yHeight / 1.46, yHeight / 1.22, yHeight, yHeight / 1.19, yHeight / 1.42, yHeight / 2]);
return renderer.paper.path({path:pathString, stroke:renderer.foregroundColor, fill:renderer.foregroundColor, 'class': renderer.controller.classes.generate(type), "data-name": type});
return renderer.paper.path({ path: pathString, stroke: renderer.foregroundColor, fill: renderer.foregroundColor, 'class': renderer.controller.classes.generate(type), "data-name": type });
}

@@ -73,9 +73,9 @@

return sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z",
xLeft+xCurve[0], yTop+yCurve[0],
xLeft+xCurve[1], yTop+yCurve[1],
xLeft+xCurve[2], yTop+yCurve[2],
xLeft+xCurve[3], yTop+yCurve[3],
xLeft+xCurve[4], yTop+yCurve[4],
xLeft+xCurve[5], yTop+yCurve[5],
xLeft+xCurve[6], yTop+yCurve[6]);
xLeft + xCurve[0], yTop + yCurve[0],
xLeft + xCurve[1], yTop + yCurve[1],
xLeft + xCurve[2], yTop + yCurve[2],
xLeft + xCurve[3], yTop + yCurve[3],
xLeft + xCurve[4], yTop + yCurve[4],
xLeft + xCurve[5], yTop + yCurve[5],
xLeft + xCurve[6], yTop + yCurve[6]);
}

@@ -86,3 +86,3 @@

if (header) {
renderer.paper.openGroup({klass: renderer.controller.classes.generate("staff-extra voice-name"), "data-name": type});
renderer.paper.openGroup({ klass: renderer.controller.classes.generate("staff-extra voice-name"), "data-name": type });
var position = yTop + (yBottom - yTop) / 2;

@@ -108,3 +108,3 @@ position = position - renderer.controller.getTextSize.baselineToCenter(header, "voicefont", 'staff-extra voice-name', 0, 1);

}
selectables.wrapSvgEl({el_type: type, startChar: -1, endChar: -1}, ret);
selectables.wrapSvgEl({ el_type: type, startChar: -1, endChar: -1 }, ret);

@@ -111,0 +111,0 @@ return ret;

@@ -17,7 +17,7 @@ var sprintf = require('./sprintf');

if (params.dir === "<") {
el = drawLine(renderer, y+height/2, y, y+height/2, y+height, left, right);
el = drawLine(renderer, y + height / 2, y, y + height / 2, y + height, left, right);
} else {
el = drawLine(renderer, y, y+height/2, y+height, y+height/2, left, right);
el = drawLine(renderer, y, y + height / 2, y + height, y + height / 2, left, right);
}
selectables.wrapSvgEl({el_type: "dynamicDecoration", startChar: -1, endChar: -1}, el);
selectables.wrapSvgEl({ el_type: "dynamicDecoration", startChar: -1, endChar: -1 }, el);
return [el];

@@ -36,5 +36,5 @@ }

left, y1, right, y2, left, y3, right, y4);
return printPath(renderer, {path:pathString, highlight: "stroke", stroke:renderer.foregroundColor, 'class': renderer.controller.classes.generate('dynamics decoration'), "data-name": "dynamics"});
return printPath(renderer, { path: pathString, highlight: "stroke", stroke: renderer.foregroundColor, 'class': renderer.controller.classes.generate('dynamics decoration'), "data-name": "dynamics" });
};
module.exports = drawCrescendo;
function printDebugBox(renderer, attr, comment) {
var box = renderer.paper.rectBeneath(attr);
if (comment)
renderer.paper.text(comment, {x: 0, y: attr.y+7, "text-anchor": "start", "font-size":"14px", fill: "rgba(0,0,255,.4)", stroke: "rgba(0,0,255,.4)" });
renderer.paper.text(comment, { x: 0, y: attr.y + 7, "text-anchor": "start", "font-size": "14px", fill: "rgba(0,0,255,.4)", stroke: "rgba(0,0,255,.4)" });
return box;

@@ -6,0 +6,0 @@ }

var drawStaffGroup = require('./staff-group');
var setPaperSize = require('./set-paper-size');
var nonMusic = require('./non-music');
var spacing = require('../abc_spacing');
var spacing = require('../helpers/spacing');
var Selectables = require('./selectables');

@@ -25,4 +25,4 @@

addStaffPadding(renderer, renderer.spacing.staffSeparation, staffgroups[staffgroups.length - 1], abcLine.staffGroup);
var staffgroup = engraveStaffLine(renderer, abcLine.staffGroup, selectables,line);
staffgroup.line = lineOffset+line; // If there are non-music lines then the staffgroup array won't line up with the line array, so this keeps track.
var staffgroup = engraveStaffLine(renderer, abcLine.staffGroup, selectables, line);
staffgroup.line = lineOffset + line; // If there are non-music lines then the staffgroup array won't line up with the line array, so this keeps track.
staffgroups.push(staffgroup);

@@ -48,4 +48,4 @@ renderer.paper.closeGroup()

function engraveStaffLine(renderer, staffGroup, selectables,lineNumber) {
drawStaffGroup(renderer, staffGroup, selectables,lineNumber);
function engraveStaffLine(renderer, staffGroup, selectables, lineNumber) {
drawStaffGroup(renderer, staffGroup, selectables, lineNumber);
var height = staffGroup.height * spacing.STEP;

@@ -57,3 +57,3 @@ renderer.y += height;

function addStaffPadding(renderer, staffSeparation, lastStaffGroup, thisStaffGroup) {
var lastStaff = lastStaffGroup.staffs[lastStaffGroup.staffs.length-1];
var lastStaff = lastStaffGroup.staffs[lastStaffGroup.staffs.length - 1];
var lastBottomLine = -(lastStaff.bottom - 2); // The 2 is because the scale goes to 2 below the last line.

@@ -64,5 +64,5 @@ var nextTopLine = thisStaffGroup.staffs[0].top - 10; // Because 10 represents the top line.

if (separationInPixels < staffSeparation)
renderer.moveY(staffSeparation-separationInPixels);
renderer.moveY(staffSeparation - separationInPixels);
}
module.exports = draw;

@@ -12,7 +12,7 @@ var printSymbol = require('./print-symbol');

klass: renderer.controller.classes.generate('decoration dynamics'),
fill:renderer.foregroundColor,
fill: renderer.foregroundColor,
stroke: "none",
name: "dynamics"
});
selectables.wrapSvgEl({el_type: "dynamicDecoration", startChar: -1, endChar: -1, decoration: params.dec}, el);
selectables.wrapSvgEl({ el_type: "dynamicDecoration", startChar: -1, endChar: -1, decoration: params.dec }, el);
return [el];

@@ -19,0 +19,0 @@ }

@@ -14,5 +14,5 @@ var sprintf = require('./sprintf');

if (params.anchor1) {
linestartx = roundNumber(params.anchor1.x+params.anchor1.w);
linestartx = roundNumber(params.anchor1.x + params.anchor1.w);
pathString += sprintf("M %f %f L %f %f ",
linestartx, y, linestartx, roundNumber(y+height));
linestartx, y, linestartx, roundNumber(y + height));
}

@@ -23,3 +23,3 @@

pathString += sprintf("M %f %f L %f %f ",
lineendx, y, lineendx, roundNumber(y+height));
lineendx, y, lineendx, roundNumber(y + height));
}

@@ -30,4 +30,4 @@

renderer.paper.openGroup({klass: renderer.controller.classes.generate("ending"), "data-name": "ending"});
printPath(renderer, {path: pathString, stroke: renderer.foregroundColor, fill: renderer.foregroundColor, "data-name": "line"});
renderer.paper.openGroup({ klass: renderer.controller.classes.generate("ending"), "data-name": "ending" });
printPath(renderer, { path: pathString, stroke: renderer.foregroundColor, fill: renderer.foregroundColor, "data-name": "line" });
if (params.anchor1)

@@ -45,3 +45,3 @@ renderText(renderer, {

var g = renderer.paper.closeGroup();
selectables.wrapSvgEl({el_type: "ending", startChar: -1, endChar: -1}, g);
selectables.wrapSvgEl({ el_type: "ending", startChar: -1, endChar: -1 }, g);
return [g];

@@ -48,0 +48,0 @@ }

@@ -12,14 +12,14 @@ var sprintf = require('./sprintf');

var rightY = renderer.calcY(params.anchor2.heads[0].pitch)
var leftX = params.anchor1.x + params.anchor1.w/2
var rightX = params.anchor2.x + params.anchor2.w/2
var leftX = params.anchor1.x + params.anchor1.w / 2
var rightX = params.anchor2.x + params.anchor2.w / 2
var len = lineLength(leftX, leftY, rightX, rightY)
var marginLeft = params.anchor1.w/2 + margin
var marginRight = params.anchor2.w/2 + margin
var marginLeft = params.anchor1.w / 2 + margin
var marginRight = params.anchor2.w / 2 + margin
var s = slope(leftX, leftY, rightX, rightY)
var leftYAdj = getY(leftY, s, marginLeft)
var rightYAdj = getY(rightY, s, -marginRight)
var num = numSquigglies(len-marginLeft-marginRight)
var num = numSquigglies(len - marginLeft - marginRight)
var el = drawSquiggly(renderer, leftX+marginLeft, leftYAdj, num, s)
selectables.wrapSvgEl({el_type: "glissando", startChar: -1, endChar: -1}, el);
var el = drawSquiggly(renderer, leftX + marginLeft, leftYAdj, num, s)
selectables.wrapSvgEl({ el_type: "glissando", startChar: -1, endChar: -1 }, el);
return [el];

@@ -32,11 +32,11 @@ }

var h = rightY - leftY
return Math.sqrt(w*w + h*h)
return Math.sqrt(w * w + h * h)
}
function slope(leftX, leftY, rightX, rightY) {
return (rightY-leftY) / (rightX - leftX)
return (rightY - leftY) / (rightX - leftX)
}
function getY(y, slope, xOfs) {
return roundNumber(y + (xOfs)*slope);
return roundNumber(y + (xOfs) * slope);
}

@@ -46,3 +46,3 @@

var endLen = 5; // The width of the end - that is, the non repeating part
return Math.max(2, Math.floor((length - endLen*2) / 6));
return Math.max(2, Math.floor((length - endLen * 2) / 6));
}

@@ -64,3 +64,3 @@

var drawSquiggly = function(renderer, x, y, num, slope) {
var drawSquiggly = function (renderer, x, y, num, slope) {
var p = sprintf("M %f %f", x, y);

@@ -70,11 +70,11 @@ p += segment(leftStart, slope)

for (i = 0; i < num; i++) {
p+=segment(top, slope)
p += segment(top, slope)
}
p += segment(right, slope)
for ( i = 0; i < num; i++)
p+=segment(bottom, slope)
p+=segment(leftEnd, slope) + 'z'
return printPath(renderer, {path:p, highlight: "stroke", stroke:renderer.foregroundColor, 'class': renderer.controller.classes.generate('decoration'), "data-name": "glissando"});
for (i = 0; i < num; i++)
p += segment(bottom, slope)
p += segment(leftEnd, slope) + 'z'
return printPath(renderer, { path: p, highlight: "stroke", stroke: renderer.foregroundColor, 'class': renderer.controller.classes.generate('decoration'), "data-name": "glissando" });
}
module.exports = drawGlissando;

@@ -7,61 +7,61 @@ /**

function Group() {
this.ingroup = false;
}
function Group() {
this.ingroup = false;
}
Group.prototype.beginGroup = function (paper, controller) {
this.paper = paper;
this.controller = controller;
this.path = [];
this.lastM = [0, 0];
this.ingroup = true;
this.paper.openGroup();
};
Group.prototype.beginGroup = function (paper, controller) {
this.paper = paper;
this.controller = controller;
this.path = [];
this.lastM = [0, 0];
this.ingroup = true;
this.paper.openGroup();
};
Group.prototype.isInGroup = function() {
return this.ingroup;
}
Group.prototype.isInGroup = function () {
return this.ingroup;
}
Group.prototype.addPath = function (path) {
path = path || [];
if (path.length === 0) return;
path[0][0] = "m";
path[0][1] = roundNumber(path[0][1] - this.lastM[0]);
path[0][2] = roundNumber(path[0][2] - this.lastM[1]);
this.lastM[0] += path[0][1];
this.lastM[1] += path[0][2];
this.path.push(path[0]);
for (var i = 1, ii = path.length; i < ii; i++) {
if (path[i][0] === "m") {
this.lastM[0] += path[i][1];
this.lastM[1] += path[i][2];
}
this.path.push(path[i]);
Group.prototype.addPath = function (path) {
path = path || [];
if (path.length === 0) return;
path[0][0] = "m";
path[0][1] = roundNumber(path[0][1] - this.lastM[0]);
path[0][2] = roundNumber(path[0][2] - this.lastM[1]);
this.lastM[0] += path[0][1];
this.lastM[1] += path[0][2];
this.path.push(path[0]);
for (var i = 1, ii = path.length; i < ii; i++) {
if (path[i][0] === "m") {
this.lastM[0] += path[i][1];
this.lastM[1] += path[i][2];
}
};
this.path.push(path[i]);
}
};
/**
* End a group of glyphs that will always be moved, scaled and highlighted together
*/
Group.prototype.endGroup = function (klass, name) {
this.ingroup = false;
//if (this.path.length === 0) return null;
var path = "";
for (var i = 0; i < this.path.length; i++)
path += this.path[i].join(" ");
this.path = [];
/**
* End a group of glyphs that will always be moved, scaled and highlighted together
*/
Group.prototype.endGroup = function (klass, name) {
this.ingroup = false;
//if (this.path.length === 0) return null;
var path = "";
for (var i = 0; i < this.path.length; i++)
path += this.path[i].join(" ");
this.path = [];
var ret = this.paper.closeGroup();
if (ret) {
ret.setAttribute("class", this.controller.classes.generate(klass))
ret.setAttribute("fill", this.controller.renderer.foregroundColor)
ret.setAttribute("stroke", "none")
ret.setAttribute("data-name", name)
}
return ret;
};
var ret = this.paper.closeGroup();
if (ret) {
ret.setAttribute("class", this.controller.classes.generate(klass))
ret.setAttribute("fill", this.controller.renderer.foregroundColor)
ret.setAttribute("stroke", "none")
ret.setAttribute("data-name", name)
}
return ret;
};
// There is just a singleton of this object.
var elementGroup = new Group();
// There is just a singleton of this object.
var elementGroup = new Group();
module.exports = elementGroup;

@@ -10,17 +10,17 @@ // For debugging, it is sometimes useful to know where you are vertically.

y = Math.round(y);
renderer.paper.text(""+Math.round(y), {x: 10, y: y, "text-anchor": "start", "font-size":"18px", fill: fill, stroke: fill });
renderer.paper.text("" + Math.round(y), { x: 10, y: y, "text-anchor": "start", "font-size": "18px", fill: fill, stroke: fill });
var x1 = 50;
var x2 = width;
var pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y-dy, x1+x2, y-dy,
x2, y+dy, x1, y+dy);
renderer.paper.pathToBack({path:pathString, stroke:"none", fill:fill, 'class': renderer.controller.classes.generate('staff')});
for (var i = 1; i < width/100; i++) {
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", i*100-dy, y-5, i*100-dy, y+5,
i*100+dy, y-5, i*100+dy, y+5);
renderer.paper.pathToBack({path:pathString, stroke:"none", fill:fill, 'class': renderer.controller.classes.generate('staff')});
var pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y - dy, x1 + x2, y - dy,
x2, y + dy, x1, y + dy);
renderer.paper.pathToBack({ path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff') });
for (var i = 1; i < width / 100; i++) {
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", i * 100 - dy, y - 5, i * 100 - dy, y + 5,
i * 100 + dy, y - 5, i * 100 + dy, y + 5);
renderer.paper.pathToBack({ path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff') });
}
if (comment)
renderer.paper.text(comment, {x: width+70, y: y, "text-anchor": "start", "font-size":"18px", fill: fill, stroke: fill });
renderer.paper.text(comment, { x: width + 70, y: y, "text-anchor": "start", "font-size": "18px", fill: fill, stroke: fill });
}
module.exports = printHorizontalLine;

@@ -34,3 +34,3 @@ var drawSeparator = require('./separator');

} else if (row.startGroup) {
renderer.paper.openGroup({klass: row.klass, "data-name": row.name});
renderer.paper.openGroup({ klass: row.klass, "data-name": row.name });
} else if (row.endGroup) {

@@ -37,0 +37,0 @@ // TODO-PER: also create a history element with the title "row.endGroup"

var sprintf = require('./sprintf');
var roundNumber = require("./round-number");
function printLine(renderer, x1, x2, y , klass, name ,dy ) {
if (!dy ) dy = 0.35;
var fill = renderer.foregroundColor;
x1 = roundNumber(x1);
x2 = roundNumber(x2);
var y1 = roundNumber(y - dy);
var y2 = roundNumber(y + dy);
var pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y1, x2, y1,
x2, y2, x1, y2);
var options = { path: pathString, stroke: "none", fill: fill };
if (name)
options['data-name'] = name;
if (klass)
options['class'] = klass;
var ret = renderer.paper.pathToBack(options);
function printLine(renderer, x1, x2, y, klass, name, dy) {
var fill = renderer.foregroundColor;
x1 = roundNumber(x1);
x2 = roundNumber(x2);
var y1 = roundNumber(y - dy);
var y2 = roundNumber(y + dy);
var pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y1, x2, y1,
x2, y2, x1, y2);
var options = { path: pathString, stroke: "none", fill: fill };
if (name)
options['data-name'] = name;
if (klass)
options['class'] = klass;
var ret = renderer.paper.pathToBack(options);
return ret;
return ret;
}

@@ -22,0 +21,0 @@

@@ -5,3 +5,3 @@ var elementGroup = require('./group-elements');

function printStem(renderer, x, dx, y1, y2, klass, name) {
if (dx<0 || y1<y2) { // correct path "handedness" for intersection with other elements
if (dx < 0 || y1 < y2) { // correct path "handedness" for intersection with other elements
var tmp = roundNumber(y2);

@@ -15,5 +15,5 @@ y2 = roundNumber(y1);

x = roundNumber(x);
var x2 = roundNumber(x+dx);
var pathArray = [["M",x,y1],["L", x, y2],["L", x2, y2],["L",x2,y1],["z"]];
var attr = { path: ""};
var x2 = roundNumber(x + dx);
var pathArray = [["M", x, y1], ["L", x, y2], ["L", x2, y2], ["L", x2, y1], ["z"]];
var attr = { path: "" };
for (var i = 0; i < pathArray.length; i++)

@@ -26,3 +26,3 @@ attr.path += pathArray[i].join(" ");

if (!elementGroup.isInGroup()) {
attr.stroke ="none";
attr.stroke = "none";
attr.fill = renderer.foregroundColor;

@@ -29,0 +29,0 @@ }

var renderText = require('./text');
var glyphs = require('../abc_glyphs');
var glyphs = require('../creation/glyphs');
var elementGroup = require('./group-elements');

@@ -17,13 +17,13 @@

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: groupClass});
renderer.paper.openGroup({ "data-name": options.name, klass: groupClass });
var dx = 0;
for (var i = 0; i < symbol.length; i++) {
var s = symbol.charAt(i);
var s = symbol[i];
ycorr = glyphs.getYCorr(s);
el = glyphs.printSymbol(x + dx, renderer.calcY(offset + ycorr), s, renderer.paper, {stroke: options.stroke, fill: options.fill});
el = glyphs.printSymbol(x + dx, renderer.calcY(offset + ycorr), s, renderer.paper, { stroke: options.stroke, fill: options.fill });
if (el) {
if (i < symbol.length - 1)
dx += kernSymbols(s, symbol.charAt(i + 1), glyphs.getSymbolWidth(s));
dx += kernSymbols(s, symbol[i + 1], glyphs.getSymbolWidth(s));
} else {
renderText(renderer, { x: x, y: renderer.y, text: "no symbol:" + symbol, type: "debugfont", klass: 'debug-msg', anchor: 'start'}, false);
renderText(renderer, { x: x, y: renderer.y, text: "no symbol:" + symbol, type: "debugfont", klass: 'debug-msg', anchor: 'start' }, false);
}

@@ -36,5 +36,5 @@ }

if (elementGroup.isInGroup()) {
el = glyphs.printSymbol(x, renderer.calcY(offset + ycorr), symbol, renderer.paper, {"data-name": options.name});
el = glyphs.printSymbol(x, renderer.calcY(offset + ycorr), symbol, renderer.paper, { "data-name": options.name });
} else {
el = glyphs.printSymbol(x, renderer.calcY(offset + ycorr), symbol, renderer.paper, {klass: options.klass, stroke: options.stroke, fill: options.fill, "data-name": options.name});
el = glyphs.printSymbol(x, renderer.calcY(offset + ycorr), symbol, renderer.paper, { klass: options.klass, stroke: options.stroke, fill: options.fill, "data-name": options.name });
}

@@ -44,3 +44,3 @@ if (el) {

}
renderText(renderer, { x: x, y: renderer.y, text: "no symbol:" + symbol, type: "debugfont", klass: 'debug-msg', anchor: 'start'}, false);
renderText(renderer, { x: x, y: renderer.y, text: "no symbol:" + symbol, type: "debugfont", klass: 'debug-msg', anchor: 'start' }, false);
return null;

@@ -54,7 +54,7 @@ }

if (lastSymbol === 'f' && thisSymbol === 'f')
width = width*2/3;
width = width * 2 / 3;
if (lastSymbol === 'p' && thisSymbol === 'p')
width = width*5/6;
width = width * 5 / 6;
if (lastSymbol === 'f' && thisSymbol === 'z')
width = width*5/8;
width = width * 5 / 8;
return width;

@@ -61,0 +61,0 @@ }

var sprintf = require("./sprintf");
function printVerticalLine (renderer, x, y1, y2) {
function printVerticalLine(renderer, x, y1, y2) {
var dy = 0.35;

@@ -8,9 +8,9 @@ var fill = "#00aaaa";

x + dy, y1, x + dy, y2);
renderer.paper.pathToBack({path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff')});
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x - 20, y1, x - 20, y1+3,
x, y1, x, y1+3);
renderer.paper.pathToBack({path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff')});
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x + 20, y2, x + 20, y2+3,
x, y2, x, y2+3);
renderer.paper.pathToBack({path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff')});
renderer.paper.pathToBack({ path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff') });
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x - 20, y1, x - 20, y1 + 3,
x, y1, x, y1 + 3);
renderer.paper.pathToBack({ path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff') });
pathString = sprintf("M %f %f L %f %f L %f %f L %f %f z", x + 20, y2, x + 20, y2 + 3,
x, y2, x, y2 + 3);
renderer.paper.pathToBack({ path: pathString, stroke: "none", fill: fill, 'class': renderer.controller.classes.generate('staff') });

@@ -17,0 +17,0 @@ }

@@ -10,3 +10,3 @@ var renderText = require('./text');

var y = renderer.calcY(params.pitch);
switch(params.type) {
switch (params.type) {
case "symbol":

@@ -20,4 +20,4 @@ if (params.c === null) return null;

klass: renderer.controller.classes.generate(klass),
// fill:"none",
// stroke: renderer.foregroundColor,
// fill:"none",
// stroke: renderer.foregroundColor,
name: params.name

@@ -38,34 +38,35 @@ });

}
params.graphelem = renderText(renderer, { x: params.x, y: y, text: "" + params.c, type: tabFont, klass: renderer.controller.classes.generate(tabClass), anchor: hAnchor, centerVertically: false, dim: params.dim , cursor: 'default'}, false);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: "" + params.c, type: tabFont, klass: renderer.controller.classes.generate(tabClass), anchor: hAnchor, centerVertically: false, dim: params.dim, cursor: 'default' }, false);
break;
case "barNumber":
params.graphelem = renderText(renderer, { x: params.x, y: y, text: ""+params.c, type: "measurefont", klass: renderer.controller.classes.generate('bar-number'), anchor: "middle", dim: params.dim, name: "bar-number"}, true);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: "" + params.c, type: "measurefont", klass: renderer.controller.classes.generate('bar-number'), anchor: "middle", dim: params.dim, name: "bar-number" }, true);
break;
case "lyric":
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: "vocalfont", klass: renderer.controller.classes.generate('lyric'), anchor: "middle", dim: params.dim, name: "lyric"}, false);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: "vocalfont", klass: renderer.controller.classes.generate('lyric'), anchor: "middle", dim: params.dim, name: "lyric" }, false);
break;
case "chord":
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'gchordfont', klass: renderer.controller.classes.generate("chord"), anchor: "middle", dim: params.dim, lane: params.getLane(), name: "chord"}, false);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'gchordfont', klass: renderer.controller.classes.generate("chord"), anchor: "middle", dim: params.dim, lane: params.getLane(), name: "chord" }, false);
break;
case "decoration":
// The +6 is to compensate for the placement of text in svg: to be on the same row as symbols, the y-coord needs to compensate for the center line.
params.graphelem = renderText(renderer, { x: params.x, y: y+6, text: params.c, type: 'annotationfont', klass: renderer.controller.classes.generate("annotation"), anchor: params.anchor, centerVertically: true, dim: params.dim}, false);
params.graphelem = renderText(renderer, { x: params.x, y: y + 6, text: params.c, type: 'annotationfont', klass: renderer.controller.classes.generate("annotation"), anchor: params.anchor, centerVertically: true, dim: params.dim }, false);
break;
case "text":
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'annotationfont', klass: renderer.controller.classes.generate("annotation"), anchor: "start", centerVertically: params.centerVertically, dim: params.dim, lane: params.getLane(), name: "annotation"}, false);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'annotationfont', klass: renderer.controller.classes.generate("annotation"), anchor: "start", centerVertically: params.centerVertically, dim: params.dim, lane: params.getLane(), name: "annotation" }, false);
break;
case "multimeasure-text":
params.graphelem = renderText(renderer, { x: params.x+params.w/2, y: y, text: params.c, type: 'tempofont', klass: renderer.controller.classes.generate("rest"), anchor: "middle", centerVertically: false, dim: params.dim}, false);
params.graphelem = renderText(renderer, { x: params.x + params.w / 2, y: y, text: params.c, type: 'tempofont', klass: renderer.controller.classes.generate("rest"), anchor: "middle", centerVertically: false, dim: params.dim }, false);
break;
case "part":
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'partsfont', klass: renderer.controller.classes.generate("part"), anchor: "start", dim: params.dim, name: params.c}, true);
params.graphelem = renderText(renderer, { x: params.x, y: y, text: params.c, type: 'partsfont', klass: renderer.controller.classes.generate("part"), anchor: "start", dim: params.dim, name: params.c }, true);
break;
case "bar":
params.graphelem = printStem(renderer, params.x, params.linewidth, y, (bartop)?bartop:renderer.calcY(params.pitch2), null, "bar"); break; // bartop can't be 0
params.graphelem = printStem(renderer, params.x, params.linewidth + renderer.lineThickness, y, (bartop) ? bartop : renderer.calcY(params.pitch2), null, "bar"); break; // bartop can't be 0
case "stem":
params.graphelem = printStem(renderer, params.x, params.linewidth, y, renderer.calcY(params.pitch2), 'abcjs-stem', 'stem'); break;
var stemWidth = params.linewidth > 0 ? params.linewidth + renderer.lineThickness : params.linewidth - renderer.lineThickness
params.graphelem = printStem(renderer, params.x, stemWidth, y, renderer.calcY(params.pitch2), 'abcjs-stem', 'stem'); break;
case "ledger":
params.graphelem = printStaffLine(renderer, params.x, params.x+params.w, params.pitch, "abcjs-ledger", "ledger"); break;
params.graphelem = printStaffLine(renderer, params.x, params.x + params.w, params.pitch, "abcjs-ledger", "ledger", 0.35 + renderer.lineThickness); break;
}
if (params.scalex!==1 && params.graphelem) {
if (params.scalex !== 1 && params.graphelem) {
scaleExistingElem(renderer.paper, params.graphelem, params.scalex, params.scaley, params.x, y);

@@ -77,5 +78,5 @@ }

function scaleExistingElem(paper, elem, scaleX, scaleY, x, y) {
paper.setAttributeOnElement(elem, { style: "transform:scale("+scaleX+","+scaleY + ");transform-origin:" + x + "px " + y + "px;"});
paper.setAttributeOnElement(elem, { style: "transform:scale(" + scaleX + "," + scaleY + ");transform-origin:" + x + "px " + y + "px;" });
}
module.exports = drawRelativeElement;

@@ -1,3 +0,3 @@

var highlight = require('../highlight');
var unhighlight = require('../unhighlight');
var highlight = require('../interactive/highlight');
var unhighlight = require('../interactive/unhighlight');

@@ -20,5 +20,5 @@ function Selectables(paper, selectTypes, tuneNumber) {

if (this.selectTypes === undefined)
params = { selectable: false, "data-index": this.elements.length}; // This is the old behavior.
params = { selectable: false, "data-index": this.elements.length }; // This is the old behavior.
else
params = { selectable: true, tabindex: 0, "data-index": this.elements.length};
params = { selectable: true, tabindex: 0, "data-index": this.elements.length };
this.paper.setAttributeOnElement(svgEl, params);

@@ -49,3 +49,3 @@ var sel = { absEl: absEl, svgEl: svgEl, isDraggable: isNoteOrTabNumber };

Selectables.prototype.wrapSvgEl = function(abcelem, el) {
Selectables.prototype.wrapSvgEl = function (abcelem, el) {
var absEl = {

@@ -52,0 +52,0 @@ tuneNumber: this.tuneNumber,

@@ -6,12 +6,12 @@ function drawSeparator(renderer, width) {

var staffWidth = renderer.controller.width;
var x1 = (staffWidth - width)/2;
var x1 = (staffWidth - width) / 2;
var x2 = x1 + width;
var pathString = 'M ' + x1 + ' ' + y +
' L ' + x2 + ' ' + y +
' L ' + x2 + ' ' + (y+1) +
' L ' + x1 + ' ' + (y+1) +
' L ' + x2 + ' ' + (y + 1) +
' L ' + x1 + ' ' + (y + 1) +
' L ' + x1 + ' ' + y + ' z';
renderer.paper.pathToBack({path:pathString, stroke:stroke, fill:fill, 'class': renderer.controller.classes.generate('defined-text')});
renderer.paper.pathToBack({ path: pathString, stroke: stroke, fill: fill, 'class': renderer.controller.classes.generate('defined-text') });
}
module.exports = drawSeparator;
function setPaperSize(renderer, maxwidth, scale, responsive) {
var w = (maxwidth+renderer.padding.right)*scale;
var h = (renderer.y+renderer.padding.bottom)*scale;
var w = (maxwidth + renderer.padding.right) * scale;
var h = (renderer.y + renderer.padding.bottom) * scale;
if (renderer.isPrint)

@@ -5,0 +5,0 @@ h = Math.max(h, 1056); // 11in x 72pt/in x 1.33px/pt

@@ -32,35 +32,35 @@ /**

var sprintf = function() {
var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
while (f) {
if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
else if (m = /^\x25{2}/.exec(f)) o.push('%');
else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments.");
if (/[^s]/.test(m[7]) && (typeof(a) != 'number'))
throw("Expecting number but found " + typeof(a));
switch (m[7]) {
case 'b': a = a.toString(2); break;
case 'c': a = String.fromCharCode(a); break;
case 'd': a = parseInt(a); break;
case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
case 'o': a = a.toString(8); break;
case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
case 'u': a = Math.abs(a); break;
case 'x': a = a.toString(16); break;
case 'X': a = a.toString(16).toUpperCase(); break;
}
a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
x = m[5] - String(a).length;
p = m[5] ? str_repeat(c, x) : '';
o.push(m[4] ? a + p : p + a);
}
else throw ("Huh ?!");
f = f.substring(m[0].length);
}
return o.join('');
var sprintf = function () {
var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
while (f) {
if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
else if (m = /^\x25{2}/.exec(f)) o.push('%');
else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw ("Too few arguments.");
if (/[^s]/.test(m[7]) && (typeof (a) != 'number'))
throw ("Expecting number but found " + typeof (a));
switch (m[7]) {
case 'b': a = a.toString(2); break;
case 'c': a = String.fromCharCode(a); break;
case 'd': a = parseInt(a); break;
case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
case 'o': a = a.toString(8); break;
case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
case 'u': a = Math.abs(a); break;
case 'x': a = a.toString(16); break;
case 'X': a = a.toString(16).toUpperCase(); break;
}
a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
c = m[3] ? m[3] == '0' ? '0' : m[3][1] : ' ';
x = m[5] - String(a).length;
p = m[5] ? str_repeat(c, x) : '';
o.push(m[4] ? a + p : p + a);
}
else throw ("Huh ?!");
f = f.substring(m[0].length);
}
return o.join('');
};
module.exports = sprintf;

@@ -1,2 +0,2 @@

var spacing = require('../abc_spacing');
var spacing = require('../helpers/spacing');
var drawBrace = require('./brace');

@@ -9,3 +9,3 @@ var drawVoice = require('./voice');

function drawStaffGroup(renderer, params, selectables,lineNumber) {
function drawStaffGroup(renderer, params, selectables, lineNumber) {
// We enter this method with renderer.y pointing to the topmost coordinate that we're allowed to draw.

@@ -29,9 +29,10 @@ // All of the children that will be drawn have a relative "pitch" set, where zero is the first ledger line below the staff.

if (renderer.showDebug) {
if (renderer.showDebug.indexOf("box") >= 0) {
if (renderer.showDebug.indexOf("box") >= 0 && staff1.voices) {
boxAllElements(renderer, params.voices, staff1.voices);
}
if (renderer.showDebug.indexOf("grid") >= 0) {
renderer.paper.dottedLine({x1: renderer.padding.left, x2: renderer.padding.left+renderer.controller.width, y1: startY, y2: startY, stroke: "#0000ff"});
renderer.paper.dottedLine({ x1: renderer.padding.left, x2: renderer.padding.left + renderer.controller.width, y1: startY, y2: startY, stroke: "#0000ff" });
printDebugBox(renderer,
{ x: renderer.padding.left,
{
x: renderer.padding.left,
y: renderer.calcY(staff1.originalTop),

@@ -43,3 +44,4 @@ width: renderer.controller.width,

"fill-opacity": 0.1,
"stroke-opacity": 0.1 });
"stroke-opacity": 0.1
});
colorIndex = 0;

@@ -77,6 +79,6 @@ debugPrintGridItem(staff1, 'chordHeightAbove');

var bartop = 0;
for (var i=0;i<params.voices.length;i++) {
for (var i = 0; i < params.voices.length; i++) {
var staff = params.voices[i].staff;
var tabName = params.voices[i].tabNameInfos;
renderer.y = staff.absoluteY ;
renderer.y = staff.absoluteY;
renderer.controller.classes.incrVoice();

@@ -86,11 +88,11 @@ //renderer.y = staff.y;

if (!params.voices[i].duplicate) {
// renderer.moveY(spacing.STEP, staff.top);
if (!topLine) topLine = renderer.calcY(10);
bottomLine = renderer.calcY(linePitch);
// renderer.moveY(spacing.STEP, staff.top);
if (!topLine) topLine = renderer.calcY(10);
bottomLine = renderer.calcY(linePitch);
if (staff.lines !== 0) {
if (staff.linePitch) {
linePitch = staff.linePitch;
linePitch = staff.linePitch;
}
renderer.controller.classes.newMeasure();
var lines = printStaff(renderer, params.startx, params.w, staff.lines, staff.linePitch, staff.dy);
var lines = printStaff(renderer, params.startx, params.w, staff.lines, staff.linePitch, 0.35);
bottomLine = lines[1];

@@ -118,5 +120,5 @@ staff.bottomLine = bottomLine;

zero: renderer.y,
height: params.height*spacing.STEP
height: params.height * spacing.STEP
});
var tabNameHeight = 0;
var tabNameHeight = 0;
if (tabName) {

@@ -127,3 +129,3 @@ // print tab infos on staffBottom

var leftMargin = 8;
r.rows.push({ left: params.startx+leftMargin, text: tabName.name, font: 'tablabelfont', klass: 'text instrument-name', anchor: 'start' });
r.rows.push({ left: params.startx + leftMargin, text: tabName.name, font: 'tablabelfont', klass: 'text instrument-name', anchor: 'start' });
r.rows.push({ move: tabName.textSize.height });

@@ -136,5 +138,5 @@ nonMusic(renderer, r);

if (!params.voices[i].duplicate) {
bartop = renderer.calcY(2 + tabNameHeight); // This connects the bar lines between two different staves.
// if (staff.bottom < 0)
// renderer.moveY(spacing.STEP, -staff.bottom);
bartop = renderer.calcY(2 + tabNameHeight); // This connects the bar lines between two different staves.
// if (staff.bottom < 0)
// renderer.moveY(spacing.STEP, -staff.bottom);
}

@@ -154,5 +156,5 @@ }

function debugPrintGridItem(staff, key) {
var colors = [ "rgb(207,27,36)", "rgb(168,214,80)", "rgb(110,161,224)", "rgb(191,119,218)", "rgb(195,30,151)",
"rgb(31,170,177)", "rgb(220,166,142)" ];
if (staff.positionY[key]) {
var colors = ["rgb(207,27,36)", "rgb(168,214,80)", "rgb(110,161,224)", "rgb(191,119,218)", "rgb(195,30,151)",
"rgb(31,170,177)", "rgb(220,166,142)"];
if (staff.positionY && staff.positionY[key]) {
var height = staff.specialY[key] * spacing.STEP;

@@ -164,3 +166,4 @@ if (key === "chordHeightAbove" && staff.specialY.chordLines && staff.specialY.chordLines.above)

printDebugBox(renderer,
{ x: renderer.padding.left,
{
x: renderer.padding.left,
y: renderer.calcY(staff.positionY[key]),

@@ -172,3 +175,4 @@ width: renderer.controller.width,

"fill-opacity": 0.4,
"stroke-opacity": 0.4 },
"stroke-opacity": 0.4
},
key.substr(0, 4));

@@ -204,5 +208,6 @@ colorIndex += 1; if (colorIndex > 6) colorIndex = 0;

continue;
var height = (coords.t - coords.b)*spacing.STEP;
var height = (coords.t - coords.b) * spacing.STEP;
printDebugBox(renderer,
{ x: coords.x,
{
x: coords.x,
y: renderer.calcY(coords.t),

@@ -215,3 +220,3 @@ width: coords.w,

"stroke-opacity": 0.8
});
});

@@ -223,7 +228,8 @@ for (var k = 0; k < elem.children.length; k++) {

var y = renderer.calcY(relElem.pitch);
y += relElem.dim.font.size*relElem.getLane();
y += relElem.dim.font.size * relElem.getLane();
printDebugBox(renderer,
{ x: chord.left,
{
x: chord.left,
y: y,
width: chord.right-chord.left,
width: chord.right - chord.left,
height: relElem.dim.font.size,

@@ -230,0 +236,0 @@ fill: "none",

var printLine = require('./print-line');
function printStaffLine(renderer, x1,x2, pitch, klass, name , dy) {
function printStaffLine(renderer, x1, x2, pitch, klass, name, dy) {
var y = renderer.calcY(pitch);
return printLine(renderer,x1,x2,y,klass,name,dy);
return printLine(renderer, x1, x2, y, klass, name, dy);
}

@@ -7,0 +7,0 @@

var printStaffLine = require('./staff-line');
function printStaff(renderer, startx, endx, numLines , linePitch , dy) {
function printStaff(renderer, startx, endx, numLines, linePitch, dy) {
var klass = "abcjs-top-line";

@@ -14,3 +14,3 @@ var pitch = 2;

if (numLines === 1) {
printStaffLine(renderer, startx,endx,6, klass);
printStaffLine(renderer, startx, endx, 6, klass, null, dy + renderer.lineThickness);
firstYLine = renderer.calcY(10);

@@ -26,3 +26,3 @@ lastYLine = renderer.calcY(2);

}
printStaffLine(renderer, startx, endx, curpitch, klass , null , dy) ;
printStaffLine(renderer, startx, endx, curpitch, klass, null, dy + renderer.lineThickness);
klass = undefined;

@@ -32,5 +32,5 @@ }

renderer.paper.closeGroup();
return [firstYLine,lastYLine];
return [firstYLine, lastYLine];
}
module.exports = printStaff;

@@ -5,34 +5,34 @@ var sprintf = require('./sprintf');

function TabLine(renderer , klass , dx , name) {
this.renderer = renderer;
if (!dx) dx = 0.35; // default
this.dx = dx;
this.klass = klass;
this.name = name;
var fill = renderer.foregroundColor;
this.options = { stroke: "none", fill: fill };
if (name)
this.options['data-name'] = name;
if (klass)
this.options['class'] = klass;
function TabLine(renderer, klass, dx, name) {
this.renderer = renderer;
if (!dx) dx = 0.35; // default
this.dx = dx;
this.klass = klass;
this.name = name;
var fill = renderer.foregroundColor;
this.options = { stroke: "none", fill: fill };
if (name)
this.options['data-name'] = name;
if (klass)
this.options['class'] = klass;
}
TabLine.prototype.printVertical = function (y1, y2, x) {
return printStem(this.renderer,
x,
this.dx,
y1,
y2,
this.options.klass,
this.options.name);
return printStem(this.renderer,
x,
this.dx,
y1,
y2,
this.options.klass,
this.options.name);
}
TabLine.prototype.printHorizontal = function (x1, x2, y) {
x1 = roundNumber(x1);
x2 = roundNumber(x2);
var y1 = roundNumber(y - this.dx);
var y2 = roundNumber(y + this.dx);
this.options.path = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y1, x2, y1,
x2, y2, x1, y2);
return this.renderer.paper.pathToBack(this.options);
x1 = roundNumber(x1);
x2 = roundNumber(x2);
var y1 = roundNumber(y - this.dx);
var y2 = roundNumber(y + this.dx);
this.options.path = sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y1, x2, y1,
x2, y2, x1, y2);
return this.renderer.paper.pathToBack(this.options);
}

@@ -39,0 +39,0 @@

@@ -11,33 +11,33 @@ var drawRelativeElement = require('./relative');

params.tempo.el_type = "tempo";
// renderer.wrapInAbsElem(params.tempo, "abcjs-tempo", function () {
//renderer.paper.openGroup({klass: renderer.controller.classes.generate("tempo wha")});
// The text is aligned with extra room for descenders but numbers look like they are a little too high, so bump it a little.
// renderer.wrapInAbsElem(params.tempo, "abcjs-tempo", function () {
//renderer.paper.openGroup({klass: renderer.controller.classes.generate("tempo wha")});
// The text is aligned with extra room for descenders but numbers look like they are a little too high, so bump it a little.
var descenderHeight = 2;
var y = renderer.calcY(params.pitch) + 2;
var text;
var size;
if (params.tempo.preString) {
text = renderText(renderer, {x:x, y: y, text: params.tempo.preString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, "dominant-baseline": "ideographic", name: "pre"}, true);
size = renderer.controller.getTextSize.calc(params.tempo.preString, 'tempofont', 'tempo', text);
var preWidth = size.width;
var charWidth = preWidth / params.tempo.preString.length; // Just get some average number to increase the spacing.
x += preWidth + charWidth;
}
if (params.note) {
params.note.setX(x);
for (var i = 0; i < params.note.children.length; i++)
drawRelativeElement(renderer, params.note.children[i], x);
x += (params.note.w + 5);
var str = "= " + params.tempo.bpm;
text = renderText(renderer, {x:x, y: y, text: str, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "beats"});
size = renderer.controller.getTextSize.calc(str, 'tempofont', 'tempo', text);
var postWidth = size.width;
var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
x += postWidth + charWidth2;
}
if (params.tempo.postString) {
renderText(renderer, {x:x, y: y, text: params.tempo.postString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "post"}, true);
}
//tempoGroup = renderer.paper.closeGroup();
// });
var y = renderer.calcY(params.pitch) + 2;
var text;
var size;
if (params.tempo.preString) {
text = renderText(renderer, { x: x, y: y, text: params.tempo.preString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, "dominant-baseline": "ideographic", name: "pre" }, true);
size = renderer.controller.getTextSize.calc(params.tempo.preString, 'tempofont', 'tempo', text);
var preWidth = size.width;
var charWidth = preWidth / params.tempo.preString.length; // Just get some average number to increase the spacing.
x += preWidth + charWidth;
}
if (params.note) {
params.note.setX(x);
for (var i = 0; i < params.note.children.length; i++)
drawRelativeElement(renderer, params.note.children[i], x);
x += (params.note.w + 5);
var str = "= " + params.tempo.bpm;
text = renderText(renderer, { x: x, y: y, text: str, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "beats" });
size = renderer.controller.getTextSize.calc(str, 'tempofont', 'tempo', text);
var postWidth = size.width;
var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
x += postWidth + charWidth2;
}
if (params.tempo.postString) {
renderText(renderer, { x: x, y: y, text: params.tempo.postString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "post" }, true);
}
//tempoGroup = renderer.paper.closeGroup();
// });
//return [tempoGroup];

@@ -44,0 +44,0 @@ }

@@ -6,3 +6,3 @@ var roundNumber = require("./round-number");

if (params.lane) {
var laneMargin = params.dim.font.size*0.25;
var laneMargin = params.dim.font.size * 0.25;
y += (params.dim.font.size + laneMargin) * params.lane;

@@ -16,3 +16,3 @@ }

} else
hash = renderer.controller.getFontAndAttr.calc(params.type, params.klass);
hash = renderer.controller.getFontAndAttr.calc(params.type, params.klass);
if (params.anchor)

@@ -37,3 +37,3 @@ hash.attr["text-anchor"] = params.anchor;

if (!alreadyInGroup)
renderer.paper.openGroup({klass: hash.attr['class'], fill: renderer.foregroundColor, "data-name": params.name});
renderer.paper.openGroup({ klass: hash.attr['class'], fill: renderer.foregroundColor, "data-name": params.name });
if (hash.attr["text-anchor"] === "end") {

@@ -59,3 +59,3 @@ hash.attr.x -= hash.font.padding;

if (hash.attr["text-anchor"] === "middle") {
delta = size.width / 2 + hash.font.padding;
delta = size.width / 2 + hash.font.padding;
} else if (hash.attr["text-anchor"] === "end") {

@@ -68,3 +68,3 @@ delta = size.width + hash.font.padding * 2;

}
renderer.paper.rect({ "data-name": "box", x: Math.round(params.x - delta), y: Math.round(y - deltaY), width: Math.round(size.width + hash.font.padding*2), height: Math.round(size.height + hash.font.padding*2)});
renderer.paper.rect({ "data-name": "box", x: Math.round(params.x - delta), y: Math.round(y - deltaY), width: Math.round(size.width + hash.font.padding * 2), height: Math.round(size.height + hash.font.padding * 2) });
if (!alreadyInGroup)

@@ -71,0 +71,0 @@ elem = renderer.paper.closeGroup();

@@ -18,4 +18,4 @@ var sprintf = require('./sprintf');

klass = "abcjs-hint";
var fudgeY = params.fixedY ? 1.5 : 0; // TODO-PER: This just compensates for drawArc, which contains too much knowledge of ties and slurs.
var el = drawArc(renderer, params.startX, params.endX, params.startY+fudgeY, params.endY+fudgeY, params.above, klass, params.isTie, params.dotted);
var fudgeY = params.fixedY ? 1.5 : 0; // TODO-PER: This just compensates for drawArc, which contains too much knowledge of ties and slurs.
var el = drawArc(renderer, params.startX, params.endX, params.startY + fudgeY, params.endY + fudgeY, params.above, klass, params.isTie, params.dotted);
selectables.wrapSvgEl({ el_type: "slur", startChar: -1, endChar: -1 }, el);

@@ -50,3 +50,3 @@ return [el];

var drawArc = function(renderer, x1, x2, pitch1, pitch2, above, klass, isTie, dotted) {
var drawArc = function (renderer, x1, x2, pitch1, pitch2, above, klass, isTie, dotted) {
// If it is a tie vs. a slur, draw it shallower.

@@ -57,4 +57,4 @@ var spacing = isTie ? 1.2 : 1.5;

x2 = roundNumber(x2 + 4);
pitch1 = pitch1 + ((above)?spacing:-spacing);
pitch2 = pitch2 + ((above)?spacing:-spacing);
pitch1 = pitch1 + ((above) ? spacing : -spacing);
pitch2 = pitch2 + ((above) ? spacing : -spacing);
var y1 = roundNumber(renderer.calcY(pitch1));

@@ -64,16 +64,16 @@ var y2 = roundNumber(renderer.calcY(pitch2));

//unit direction vector
var dx = x2-x1;
var dy = y2-y1;
var norm= Math.sqrt(dx*dx+dy*dy);
var ux = dx/norm;
var uy = dy/norm;
var dx = x2 - x1;
var dy = y2 - y1;
var norm = Math.sqrt(dx * dx + dy * dy);
var ux = dx / norm;
var uy = dy / norm;
var flatten = norm/3.5;
var flatten = norm / 3.5;
var maxFlatten = isTie ? 10 : 25; // If it is a tie vs. a slur, draw it shallower.
var curve = ((above)?-1:1)*Math.min(maxFlatten, Math.max(4, flatten));
var curve = ((above) ? -1 : 1) * Math.min(maxFlatten, Math.max(4, flatten));
var controlx1 = roundNumber(x1+flatten*ux-curve*uy);
var controly1 = roundNumber(y1+flatten*uy+curve*ux);
var controlx2 = roundNumber(x2-flatten*ux-curve*uy);
var controly2 = roundNumber(y2-flatten*uy+curve*ux);
var controlx1 = roundNumber(x1 + flatten * ux - curve * uy);
var controly1 = roundNumber(y1 + flatten * uy + curve * ux);
var controlx2 = roundNumber(x2 - flatten * ux - curve * uy);
var controly2 = roundNumber(y2 - flatten * uy + curve * ux);
var thickness = 2;

@@ -90,3 +90,3 @@ if (klass)

controlx1, controly1, controlx2, controly2, x2, y2);
ret = renderer.paper.path({path:pathString2, stroke:renderer.foregroundColor, fill:"none", 'stroke-dasharray': "5 5", 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur"});
ret = renderer.paper.path({ path: pathString2, stroke: renderer.foregroundColor, fill: "none", 'stroke-dasharray': "5 5", 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" });
} else {

@@ -96,3 +96,3 @@ var pathString = sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z", x1, y1,

roundNumber(controlx2 - thickness * uy), roundNumber(controly2 + thickness * ux), roundNumber(controlx1 - thickness * uy), roundNumber(controly1 + thickness * ux), x1, y1);
ret = renderer.paper.path({path:pathString, stroke:"none", fill:renderer.foregroundColor, 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur"});
ret = renderer.paper.path({ path: pathString, stroke: "none", fill: renderer.foregroundColor, 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" });
}

@@ -99,0 +99,0 @@

@@ -7,3 +7,3 @@ var sprintf = require('./sprintf');

function drawTriplet(renderer, params, selectables) {
renderer.paper.openGroup({ klass: renderer.controller.classes.generate('triplet '+params.durationClass), "data-name": "triplet"});
renderer.paper.openGroup({ klass: renderer.controller.classes.generate('triplet ' + params.durationClass), "data-name": "triplet" });
if (!params.hasBeam) {

@@ -13,3 +13,3 @@ drawBracket(renderer, params.anchor1.x, params.startNote, params.anchor2.x + params.anchor2.w, params.endNote);

// HACK: adjust the position of "3". It is too high in all cases so we fudge it by subtracting 1 here.
renderText(renderer, {x: params.xTextPos, y: renderer.calcY(params.yTextPos - 1), text: "" + params.number, type: 'tripletfont', anchor: "middle", centerVertically: true, noClass: true, name: ""+params.number}, true);
renderText(renderer, { x: params.xTextPos, y: renderer.calcY(params.yTextPos - 1), text: "" + params.number, type: 'tripletfont', anchor: "middle", centerVertically: true, noClass: true, name: "" + params.number }, true);
var g = renderer.paper.closeGroup();

@@ -35,3 +35,3 @@ selectables.wrapSvgEl({ el_type: "triplet", startChar: -1, endChar: -1 }, g);

// figure out midpoints to draw the broken line.
var midX = x1 + (x2-x1)/2;
var midX = x1 + (x2 - x1) / 2;
//var midY = y1 + (y2-y1)/2;

@@ -42,9 +42,9 @@ var gapWidth = 8;

var leftEndY = y1 + (leftEndX - x1) * slope;
pathString += drawLine( x1, y1, leftEndX, leftEndY);
pathString += drawLine(x1, y1, leftEndX, leftEndY);
var rightStartX = midX + gapWidth;
var rightStartY = y1 + (rightStartX - x1) * slope;
pathString += drawLine( rightStartX, rightStartY, x2, y2);
printPath(renderer, {path: pathString, stroke: renderer.foregroundColor, "data-name": "triplet-bracket"});
pathString += drawLine(rightStartX, rightStartY, x2, y2);
printPath(renderer, { path: pathString, stroke: renderer.foregroundColor, "data-name": "triplet-bracket" });
}
module.exports = drawTriplet;

@@ -12,7 +12,10 @@ var drawGlissando = require('./glissando');

function drawVoice(renderer, params, bartop, selectables, staffPos) {
var width = params.w-1;
var width = params.w - 1;
renderer.staffbottom = params.staff.bottom;
var saveColor = renderer.foregroundColor
if (params.color)
renderer.foregroundColor = params.color
if (params.header) { // print voice name
var textEl = renderText(renderer, {x: renderer.padding.left, y: renderer.calcY(params.headerPosition), text: params.header, type: 'voicefont', klass: 'staff-extra voice-name', anchor: 'start', centerVertically: true, name: "voice-name"}, true);
var textEl = renderText(renderer, { x: renderer.padding.left, y: renderer.calcY(params.headerPosition), text: params.header, type: 'voicefont', klass: 'staff-extra voice-name', anchor: 'start', centerVertically: true, name: "voice-name" }, true);
selectables.wrapSvgEl({ el_type: "voiceName", startChar: -1, endChar: -1, text: params.header }, textEl);

@@ -24,3 +27,3 @@ }

var foundNote = false;
for (i=0; i < params.children.length; i++) {
for (i = 0; i < params.children.length; i++) {
child = params.children[i];

@@ -34,17 +37,12 @@ if (child.type === 'note' || child.type === 'rest')

}
switch (child.type) {
// case "tempo":
// child.elemset = drawTempo(renderer, child);
// break;
default:
if (params.staff.isTabStaff) {
child.invisible = false;
if ( child.type == 'bar' ) {
if (child.abcelem.lastBar) {
bartop = params.topLine;
}
}
}
drawAbsolute(renderer, child,(params.barto || i === params.children.length - 1) ? bartop : 0, selectables, staffPos);
if (params.staff.isTabStaff) {
child.invisible = false;
if (child.type == 'bar') {
if (child.abcelem.lastBar) {
bartop = params.topLine;
}
}
}
drawAbsolute(renderer, child, (params.barto || i === params.children.length - 1) ? bartop : 0, selectables, staffPos);
if (child.type === 'note' || isNonSpacerRest(child))

@@ -98,2 +96,3 @@ renderer.controller.classes.incrNote();

}
renderer.foregroundColor = saveColor

@@ -100,0 +99,0 @@ }

@@ -1,6 +0,6 @@

var RelativeElement = require('../abc_relative_element');
var spacing = require('../abc_spacing');
var getBarYAt = require('./getBarYAt');
var RelativeElement = require('../creation/elements/relative-element');
var spacing = require('../helpers/spacing');
var getBarYAt = require('./get-bar-y-at');
var layoutBeam = function(beam) {
var layoutBeam = function (beam) {
if (beam.elems.length === 0 || beam.allrests) return;

@@ -31,3 +31,3 @@

var getDurlog = function(duration) {
var getDurlog = function (duration) {
// TODO-PER: This is a hack to prevent a Chrome lockup. Duration should have been defined already,

@@ -39,3 +39,3 @@ // but there's definitely a case where it isn't. [Probably something to do with triplets.]

// console.log("getDurlog: " + duration);
return Math.floor(Math.log(duration)/Math.log(2));
return Math.floor(Math.log(duration) / Math.log(2));
};

@@ -83,3 +83,3 @@

endX += (asc) ? endhead.w : 0.6;
return [ startX, endX ];
return [startX, endX];
}

@@ -107,3 +107,3 @@

return [ startY, endY];
return [startY, endY];
}

@@ -175,7 +175,7 @@

}
if (i > 0 && elem.abcelem.beambr && elem.abcelem.beambr <= (index+1)) {
if (i > 0 && elem.abcelem.beambr && elem.abcelem.beambr <= (index + 1)) {
if (!auxBeams[index].split)
auxBeams[index].split = [auxBeams[index].x];
var xPos = calcXPos(asc, elems[i-1], elem);
if (auxBeams[index].split[auxBeams[index].split.length-1] >= xPos[0]) {
var xPos = calcXPos(asc, elems[i - 1], elem);
if (auxBeams[index].split[auxBeams[index].split.length - 1] >= xPos[0]) {
// the reduction in beams leaves a note unattached so create a small flag for it.

@@ -203,5 +203,5 @@ xPos[0] += elem.w;

var split = auxBeams[j].split;
if (b.endX <= split[split.length-1]) {
if (b.endX <= split[split.length - 1]) {
// the reduction in beams leaves the last note by itself, so create a little flag for it
split[split.length-1] -= elem.w;
split[split.length - 1] -= elem.w;
}

@@ -208,0 +208,0 @@ split.push(b.endX);

@@ -8,6 +8,6 @@ function getLeftEdgeOfStaff(renderer, getTextSize, voices, brace, bracket) {

var size;
for (i=0;i<voices.length;i++) {
if(voices[i].header) {
for (i = 0; i < voices.length; i++) {
if (voices[i].header) {
size = getTextSize.calc(voices[i].header, 'voicefont', '');
voiceheaderw = Math.max(voiceheaderw,size.width);
voiceheaderw = Math.max(voiceheaderw, size.width);
}

@@ -36,3 +36,3 @@ }

var size = getTextSize.calc(brace[i].header, 'voicefont', '');
voiceheaderw = Math.max(voiceheaderw,size.width);
voiceheaderw = Math.max(voiceheaderw, size.width);
}

@@ -39,0 +39,0 @@ }

var layoutVoice = require('./voice');
var setUpperAndLowerElements = require('./setUpperAndLowerElements');
var layoutStaffGroup = require('./staffGroup');
var setUpperAndLowerElements = require('./set-upper-and-lower-elements');
var layoutStaffGroup = require('./staff-group');
var getLeftEdgeOfStaff = require('./get-left-edge-of-staff');
var layout = function (renderer, abctune, width, space) {
var i;
var abcLine;
// Adjust the x-coordinates to their absolute positions
var maxWidth = width;
for(i=0; i<abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staff) {
setXSpacing(renderer, width, space, abcLine.staffGroup, abctune.formatting, i === abctune.lines.length - 1, false);
if (abcLine.staffGroup.w > maxWidth) maxWidth = abcLine.staffGroup.w;
}
var i;
var abcLine;
// Adjust the x-coordinates to their absolute positions
var maxWidth = width;
for (i = 0; i < abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staff) {
setXSpacing(renderer, width, space, abcLine.staffGroup, abctune.formatting, i === abctune.lines.length - 1, false);
if (abcLine.staffGroup.w > maxWidth) maxWidth = abcLine.staffGroup.w;
}
}
// Layout the beams and add the stems to the beamed notes.
for(i=0; i<abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staffGroup && abcLine.staffGroup.voices) {
for (var j = 0; j < abcLine.staffGroup.voices.length; j++)
layoutVoice(abcLine.staffGroup.voices[j]);
setUpperAndLowerElements(renderer, abcLine.staffGroup);
}
// Layout the beams and add the stems to the beamed notes.
for (i = 0; i < abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staffGroup && abcLine.staffGroup.voices) {
for (var j = 0; j < abcLine.staffGroup.voices.length; j++)
layoutVoice(abcLine.staffGroup.voices[j]);
setUpperAndLowerElements(renderer, abcLine.staffGroup);
}
}
// Set the staff spacing
// TODO-PER: we should have been able to do this by the time we called setUpperAndLowerElements, but for some reason the "bottom" element seems to be set as a side effect of setting the X spacing.
for(i=0; i<abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staffGroup) {
abcLine.staffGroup.setHeight();
}
// Set the staff spacing
// TODO-PER: we should have been able to do this by the time we called setUpperAndLowerElements, but for some reason the "bottom" element seems to be set as a side effect of setting the X spacing.
for (i = 0; i < abctune.lines.length; i++) {
abcLine = abctune.lines[i];
if (abcLine.staffGroup) {
abcLine.staffGroup.setHeight();
}
return maxWidth;
}
// Do the x-axis positioning for a single line (a group of related staffs)
var setXSpacing = function (renderer, width, space, staffGroup, formatting, isLastLine, debug) {
var leftEdge = getLeftEdgeOfStaff(renderer, staffGroup.getTextSize, staffGroup.voices, staffGroup.brace, staffGroup.bracket);
var newspace = space;
for (var it = 0; it < 8; it++) { // TODO-PER: shouldn't need multiple passes, but each pass gets it closer to the right spacing. (Only affects long lines: normal lines break out of this loop quickly.)
var ret = layoutStaffGroup(newspace, renderer, debug, staffGroup, leftEdge);
newspace = calcHorizontalSpacing(isLastLine, formatting.stretchlast, width+renderer.padding.left, staffGroup.w, newspace, ret.spacingUnits, ret.minSpace, renderer.padding.left+renderer.padding.right);
if (debug)
console.log("setXSpace", it, staffGroup.w, newspace, staffGroup.minspace);
if (newspace === null) break;
}
centerWholeRests(staffGroup.voices);
};
return maxWidth;
}
// Do the x-axis positioning for a single line (a group of related staffs)
var setXSpacing = function (renderer, width, space, staffGroup, formatting, isLastLine, debug) {
var leftEdge = getLeftEdgeOfStaff(renderer, staffGroup.getTextSize, staffGroup.voices, staffGroup.brace, staffGroup.bracket);
var newspace = space;
for (var it = 0; it < 8; it++) { // TODO-PER: shouldn't need multiple passes, but each pass gets it closer to the right spacing. (Only affects long lines: normal lines break out of this loop quickly.)
var ret = layoutStaffGroup(newspace, renderer, debug, staffGroup, leftEdge);
newspace = calcHorizontalSpacing(isLastLine, formatting.stretchlast, width + renderer.padding.left, staffGroup.w, newspace, ret.spacingUnits, ret.minSpace, renderer.padding.left + renderer.padding.right);
if (debug)
console.log("setXSpace", it, staffGroup.w, newspace, staffGroup.minspace);
if (newspace === null) break;
}
centerWholeRests(staffGroup.voices);
};
function calcHorizontalSpacing(isLastLine, stretchLast, targetWidth, lineWidth, spacing, spacingUnits, minSpace, padding) {
if (isLastLine) {
if (stretchLast === undefined) {
if (lineWidth / targetWidth < 0.66) return null; // keep this for backward compatibility. The break isn't quite the same for some reason.
} else {
// "Stretch the last music line of a tune when it lacks less than the float fraction of the page width."
var lack = 1 - (lineWidth+padding) / targetWidth;
var stretch = lack < stretchLast;
if (!stretch) return null; // don't stretch last line too much
}
function calcHorizontalSpacing(isLastLine, stretchLast, targetWidth, lineWidth, spacing, spacingUnits, minSpace, padding) {
if (isLastLine) {
if (stretchLast === undefined) {
if (lineWidth / targetWidth < 0.66) return null; // keep this for backward compatibility. The break isn't quite the same for some reason.
} else {
// "Stretch the last music line of a tune when it lacks less than the float fraction of the page width."
var lack = 1 - (lineWidth + padding) / targetWidth;
var stretch = lack < stretchLast;
if (!stretch) return null; // don't stretch last line too much
}
if (Math.abs(targetWidth-lineWidth) < 2) return null; // if we are already near the target width, we're done.
var relSpace = spacingUnits * spacing;
var constSpace = lineWidth - relSpace;
if (spacingUnits > 0) {
spacing = (targetWidth - constSpace) / spacingUnits;
if (spacing * minSpace > 50) {
spacing = 50 / minSpace;
}
return spacing;
}
if (Math.abs(targetWidth - lineWidth) < 2) return null; // if we are already near the target width, we're done.
var relSpace = spacingUnits * spacing;
var constSpace = lineWidth - relSpace;
if (spacingUnits > 0) {
spacing = (targetWidth - constSpace) / spacingUnits;
if (spacing * minSpace > 50) {
spacing = 50 / minSpace;
}
return null;
return spacing;
}
return null;
}
function centerWholeRests(voices) {
// whole rests are a special case: if they are by themselves in a measure, then they should be centered.
// (If they are not by themselves, that is probably a user error, but we'll just center it between the two items to either side of it.)
for (var i = 0; i < voices.length; i++) {
var voice = voices[i];
// Look through all of the elements except for the first and last. If the whole note appears there then there isn't anything to center it between anyway.
for (var j = 1; j < voice.children.length-1; j++) {
var absElem = voice.children[j];
if (absElem.abcelem.rest && (absElem.abcelem.rest.type === 'whole' || absElem.abcelem.rest.type === 'multimeasure')) {
var before = voice.children[j-1];
var after = voice.children[j+1];
absElem.center(before, after);
}
function centerWholeRests(voices) {
// whole rests are a special case: if they are by themselves in a measure, then they should be centered.
// (If they are not by themselves, that is probably a user error, but we'll just center it between the two items to either side of it.)
for (var i = 0; i < voices.length; i++) {
var voice = voices[i];
// Look through all of the elements except for the first and last. If the whole note appears there then there isn't anything to center it between anyway.
for (var j = 1; j < voice.children.length - 1; j++) {
var absElem = voice.children[j];
if (absElem.abcelem.rest && (absElem.abcelem.rest.type === 'whole' || absElem.abcelem.rest.type === 'multimeasure')) {
var before = voice.children[j - 1];
var after = voice.children[j + 1];
absElem.center(before, after);
}
}
}
}
module.exports = layout;

@@ -1,2 +0,2 @@

var getBarYAt = require('./getBarYAt');
var getBarYAt = require('./get-bar-y-at');

@@ -10,3 +10,3 @@ function layoutTriplet(element) {

// We also need to check if the beam doesn't contain other notes so that `(3 dcdcc` will do a bracket.
if (element.hasBeam && (beam.elems[0] !== element.anchor1.parent || beam.elems[beam.elems.length-1] !== element.anchor2.parent))
if (element.hasBeam && (beam.elems[0] !== element.anchor1.parent || beam.elems[beam.elems.length - 1] !== element.anchor2.parent))
element.hasBeam = false;

@@ -17,3 +17,3 @@

var left = isAbove(beam) ? element.anchor1.x + element.anchor1.w : element.anchor1.x;
element.yTextPos = heightAtMidpoint(left, element.anchor2.x, beam);
element.yTextPos = heightAtMidpoint(left, element.anchor2.x, beam);
element.yTextPos += isAbove(beam) ? 3 : -2; // This creates some space between the beam and the number.

@@ -74,5 +74,5 @@ element.xTextPos = xAtMidpoint(left, element.anchor2.x);

function xAtMidpoint(startX, endX) {
return startX + (endX - startX)/2;
return startX + (endX - startX) / 2;
}
module.exports = layoutTriplet;
var layoutBeam = require('./beam');
var getBarYAt = require('./getBarYAt');
var getBarYAt = require('./get-bar-y-at');
var layoutTriplet = require('./triplet');
var layoutVoice = function(voice) {
var layoutVoice = function (voice) {
for (var i = 0; i < voice.beams.length; i++) {

@@ -69,3 +69,3 @@ if (voice.beams[i].type === 'BeamElem') {

rightMost.push(xCoords.right);
relElem.putChordInLane(rightMost.length-1);
relElem.putChordInLane(rightMost.length - 1);
}

@@ -94,3 +94,3 @@ }

}
for (j = absElems[i].children.length-1; j >=0; j--) {
for (j = absElems[i].children.length - 1; j >= 0; j--) {
relElem = absElems[i].children[j];

@@ -126,4 +126,4 @@ if (relElem.chordHeightBelow) {

relElem.invertLane(numLanesAbove);
// } else if (relElem.chordHeightBelow) {
// relElem.invertLane(below);
// } else if (relElem.chordHeightBelow) {
// relElem.invertLane(below);
}

@@ -130,0 +130,0 @@ }

@@ -13,3 +13,3 @@ // abc_voice_element.js: Definition of the VoiceElement class.

Svg.prototype.clear = function() {
Svg.prototype.clear = function () {
if (this.svg) {

@@ -27,3 +27,3 @@ var wrapper = this.svg.parentNode;

Svg.prototype.setTitle = function(title) {
Svg.prototype.setTitle = function (title) {
var titleEl = document.createElement("title");

@@ -35,3 +35,3 @@ var titleNode = document.createTextNode(title);

Svg.prototype.setResponsiveWidth = function(w, h) {
Svg.prototype.setResponsiveWidth = function (w, h) {
// this technique is from: http://thenewcode.com/744/Make-SVG-Responsive, thx to https://github.com/iantresman

@@ -65,3 +65,3 @@ this.svg.setAttribute("viewBox", "0 0 " + w + " " + h);

Svg.prototype.setSize = function(w, h) {
Svg.prototype.setSize = function (w, h) {
this.svg.setAttribute('width', w);

@@ -71,11 +71,11 @@ this.svg.setAttribute('height', h);

Svg.prototype.setAttribute = function(attr, value) {
Svg.prototype.setAttribute = function (attr, value) {
this.svg.setAttribute(attr, value);
};
Svg.prototype.setScale = function(scale) {
Svg.prototype.setScale = function (scale) {
if (scale !== 1) {
this.svg.style.transform = "scale("+scale+","+scale+")";
this.svg.style['-ms-transform'] = "scale("+scale+","+scale+")";
this.svg.style['-webkit-transform'] = "scale("+scale+","+scale+")";
this.svg.style.transform = "scale(" + scale + "," + scale + ")";
this.svg.style['-ms-transform'] = "scale(" + scale + "," + scale + ")";
this.svg.style['-webkit-transform'] = "scale(" + scale + "," + scale + ")";
this.svg.style['transform-origin'] = "0 0";

@@ -93,10 +93,10 @@ this.svg.style['-ms-transform-origin-x'] = "0";

Svg.prototype.insertStyles = function(styles) {
Svg.prototype.insertStyles = function (styles) {
var el = document.createElementNS(svgNS, "style");
el.textContent = styles;
this.svg.insertBefore(el, this.svg.firstChild); // prepend is not available on older browsers.
// this.svg.prepend(el);
// this.svg.prepend(el);
};
Svg.prototype.setParentStyles = function(attr) {
Svg.prototype.setParentStyles = function (attr) {
// This is needed to get the size right when there is scaling involved.

@@ -134,3 +134,3 @@ for (var key in attr) {

Svg.prototype.rect = function(attr) {
Svg.prototype.rect = function (attr) {
// This uses path instead of rect so that it can be hollow and the color changes with "fill" instead of "stroke".

@@ -150,3 +150,3 @@ var lines = [];

Svg.prototype.dottedLine = function(attr) {
Svg.prototype.dottedLine = function (attr) {
var el = document.createElementNS(svgNS, 'line');

@@ -162,3 +162,3 @@ el.setAttribute("x1", attr.x1);

Svg.prototype.rectBeneath = function(attr) {
Svg.prototype.rectBeneath = function (attr) {
var el = document.createElementNS(svgNS, 'rect');

@@ -180,3 +180,3 @@ el.setAttribute("x", attr.x);

Svg.prototype.text = function(text, attr, target) {
Svg.prototype.text = function (text, attr, target) {
var el = document.createElementNS(svgNS, 'text');

@@ -189,3 +189,3 @@ el.setAttribute("stroke", "none");

}
var lines = (""+text).split("\n");
var lines = ("" + text).split("\n");
for (var i = 0; i < lines.length; i++) {

@@ -225,3 +225,3 @@ var line = document.createElementNS(svgNS, 'tspan');

Svg.prototype.guessWidth = function(text, attr) {
Svg.prototype.guessWidth = function (text, attr) {
var svg = this.createDummySvg();

@@ -231,9 +231,9 @@ var el = this.text(text, attr, svg);

try {
size = el.getBBox();
size = el.getBBox();
if (isNaN(size.height) || !size.height) // TODO-PER: I don't think this can happen unless there isn't a browser at all.
size = { width: attr['font-size']/2, height: attr['font-size'] + 2 }; // Just a wild guess.
size = { width: attr['font-size'] / 2, height: attr['font-size'] + 2 }; // Just a wild guess.
else
size = {width: size.width, height: size.height};
size = { width: size.width, height: size.height };
} catch (ex) {
size = { width: attr['font-size']/2, height: attr['font-size'] + 2 }; // Just a wild guess.
size = { width: attr['font-size'] / 2, height: attr['font-size'] + 2 }; // Just a wild guess.
}

@@ -244,3 +244,3 @@ svg.removeChild(el);

Svg.prototype.createDummySvg = function() {
Svg.prototype.createDummySvg = function () {
if (!this.dummySvg) {

@@ -264,5 +264,5 @@ this.dummySvg = createSvg();

Svg.prototype.getTextSize = function(text, attr, el) {
Svg.prototype.getTextSize = function (text, attr, el) {
if (typeof text === 'number')
text = ''+text;
text = '' + text;
if (!text || text.match(/^\s+$/))

@@ -282,7 +282,7 @@ return { width: 0, height: 0 };

try {
size = el.getBBox();
size = el.getBBox();
if (isNaN(size.height) || !size.height)
size = this.guessWidth(text, attr);
else
size = {width: size.width, height: size.height};
size = { width: size.width, height: size.height };
} catch (ex) {

@@ -302,3 +302,3 @@ size = this.guessWidth(text, attr);

Svg.prototype.openGroup = function(options) {
Svg.prototype.openGroup = function (options) {
options = options ? options : {};

@@ -323,3 +323,3 @@ var el = document.createElementNS(svgNS, "g");

Svg.prototype.closeGroup = function() {
Svg.prototype.closeGroup = function () {
var g = this.currentGroup.shift();

@@ -334,3 +334,3 @@ if (g && g.children.length === 0) {

Svg.prototype.path = function(attr) {
Svg.prototype.path = function (attr) {
var el = document.createElementNS(svgNS, "path");

@@ -351,3 +351,3 @@ for (var key in attr) {

Svg.prototype.pathToBack = function(attr) {
Svg.prototype.pathToBack = function (attr) {
var el = document.createElementNS(svgNS, "path");

@@ -368,3 +368,3 @@ for (var key in attr) {

Svg.prototype.append = function(el) {
Svg.prototype.append = function (el) {
if (this.currentGroup.length > 0)

@@ -376,3 +376,3 @@ this.currentGroup[0].appendChild(el);

Svg.prototype.prepend = function(el) {
Svg.prototype.prepend = function (el) {
// The entire group is prepended, so don't prepend the individual elements.

@@ -385,3 +385,3 @@ if (this.currentGroup.length > 0)

Svg.prototype.setAttributeOnElement = function(el, attr) {
Svg.prototype.setAttributeOnElement = function (el, attr) {
for (var key in attr) {

@@ -394,3 +394,3 @@ if (attr.hasOwnProperty(key)) {

Svg.prototype.moveElementToChild = function(parent, child) {
Svg.prototype.moveElementToChild = function (parent, child) {
parent.appendChild(child);

@@ -397,0 +397,0 @@ };

@@ -27,3 +27,3 @@ /**!

var Parse = require('./src/parse/abc_parse');
var EngraverController = require('./src/write/abc_engraver_controller')
var EngraverController = require('./src/write/engraver-controller')

@@ -30,0 +30,0 @@ abcjs.signature = "abcjs-test v" + version;

@@ -54,3 +54,3 @@ declare module 'abcjs' {

export type MidiCommands = "nobarlines" | "barlines" | "beataccents" | "nobeataccents" | "droneon" | "droneoff" | "noportamento" | "channel" | "c" |
"drumon" | "drumoff" | "fermatafixed" | "fermataproportional" | "gchordon" | "gchordoff" | "bassvol" | "chordvol" |
"drumon" | "drumoff" | "fermatafixed" | "fermataproportional" | "gchordon" | "gchordoff" | "bassvol" | "chordvol" | "bassprog" | "chordprog" |
"controlcombo" | "temperamentnormal" | "gchord" | "ptstress" | "beatmod" | "deltaloudness" | "drumbars" | "pitchbend" |

@@ -176,2 +176,28 @@ "gracedivider" | "makechordchannels" | "randomchordattack" | "chordattack" | "stressmodel" | "transpose" |

export interface RelativeElement {
x: number;
c: string;
dx: number;
w: number;
pitch: number;
pitch2?: number;
scaleX: number;
scaleY: number;
type: string;
name: string;
linewidth?: number;
klass?: string;
anchor?: "start" | "middle" | "end";
top: number;
bottom: number;
dim?: number;
position?: number;
realWidth?: number;
partHeightAbove?: number;
chordHeightAbove?: number;
chordHeightBelow?: number;
lyricHeightAbove?: number;
lyricHeightBelow?: number;
}
export interface AbsoluteElement {

@@ -238,7 +264,9 @@ abcelem : AbcElem;

foregroundColor?: string;
format?: { [attr: FormatAttributes]: any };
format?: { [attr in FormatAttributes]: any };
header_only?: boolean;
initialClef?: boolean;
jazzchords?: boolean;
germanAlphabet?: boolean;
lineBreaks?: Array<number>;
lineThickness?: number;
minPadding?: number;

@@ -803,3 +831,3 @@ oneSvgPerLine?: boolean;

getElementFromChar: (charPos: number) => VoiceItem | null;
millisecondsPerMeasure: NumberFunction;
millisecondsPerMeasure: (bpm?: number) => number;
setTiming: (bpm?: number, measuresOfDelay? : number) => void;

@@ -920,3 +948,3 @@ setUpAudio: (options: SynthOptions) => AudioTracks;

offMs: number;
offPs: number;
offPx: number;
gapMs: number;

@@ -1143,3 +1171,3 @@ gapPx: number;

setTune(visualObj: TuneObject, userAction: boolean, audioParams?: SynthOptions): Promise<SynthInitResponse>
load(selector: string, cursorControl?: CursorControl | null, visualOptions?: SynthVisualOptions): void
load(selector: Selector, cursorControl?: CursorControl | null, visualOptions?: SynthVisualOptions): void
play(): void

@@ -1150,4 +1178,5 @@ pause(): void

setProgress(ev: number): void
setWarp(percent: number): void
setWarp(percent: number): Promise<void>
download(fName: string): void
getAudioBuffer(): AudioBuffer | undefined
}

@@ -1173,3 +1202,3 @@

export function getMidiFile(source: string | TuneObject, options?: MidiFileOptions): MidiFile;
export function playEvent(pitches: MidiPitches, graceNotes: MidiGracePitches, milliSecondsPerMeasure: number): Promise<void>;
export function playEvent(pitches: MidiPitches, graceNotes: MidiGracePitches | undefined, milliSecondsPerMeasure: number): Promise<void>;
export function sequence(visualObj: TuneObject, options: AbcVisualParams): AudioSequence

@@ -1176,0 +1205,0 @@ }

@@ -1,3 +0,3 @@

var version = '6.1.9';
var version = '6.2.0';
module.exports = version;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc