App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/res/abc/abc2svg/abc2svg-1.js view on Meta::CPAN
p += 19 // staff pitch from C-1
var b40 = ((p / 7) | 0) * 40 + abc2svg.p_b40[p % 7]
if (a && a != 3) // if some accidental, but not natural
b40 += a
return b40
} // pit2b40()
abc2svg.b40p = function(b) {
return ((b / 40) | 0) * 7 + abc2svg.b40_p[b % 40] - 19
} // b40p()
abc2svg.b40a = function(b) {
return abc2svg.b40_a[b % 40]
} // b40a()
abc2svg.b40m = function(b) {
return ((b / 40) | 0) * 12 + abc2svg.b40_m[b % 40]
} // b40m()
// chord table
// This table is used in various modules
// to convert the types of chord symbols to a minimum set.
// More chord types may be added by the command %%chordalias.
abc2svg.ch_alias = {
"maj": "",
"min": "m",
"-": "m",
"°": "dim",
"+": "aug",
"+5": "aug",
"maj7": "M7",
"Î7": "M7",
"Î": "M7",
"min7": "m7",
"-7": "m7",
"ø7": "m7b5",
"°7": "dim7",
"min+7": "m+7",
"aug7": "+7",
"7+5": "+7",
"7#5": "+7",
"sus": "sus4",
"7sus": "7sus4"
} // ch_alias
// global fonts
abc2svg.font_tb = [] // fonts - index = font.fid
abc2svg.font_st = {} // font style => font_tb index for incomplete user fonts
// cache for converting a duration into [head, dots, nflags]
abc2svg.hdn = {}
// font weight
// reference:
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
abc2svg.ft_w = {
thin: 100,
extralight: 200,
light: 300,
regular: 400,
medium: 500,
semi: 600,
demi: 600,
semibold: 600,
demibold: 600,
bold: 700,
extrabold: 800,
ultrabold: 800,
black: 900,
heavy: 900
}
abc2svg.ft_re = new RegExp('\
-?Thin|-?Extra Light|-?Light|-?Regular|-?Medium|\
-?[DS]emi|-?[DS]emi[ -]?Bold|\
-?Bold|-?Extra[ -]?Bold|-?Ultra[ -]?Bold|-?Black|-?Heavy/',
"i")
// lyric prefix
abc2svg.lypre = /^\d.+\.|^[\d-]+\.?|^\w+:|^\(|^\)/;
// simplify a rational number n/d
abc2svg.rat = function(n, d) {
var a, t,
n0 = 0,
d1 = 0,
n1 = 1,
d0 = 1
while (1) {
if (d == 0)
break
t = d
a = (n / d) | 0
d = n % d
n = t
t = n0 + a * n1
n0 = n1
n1 = t
t = d0 + a * d1
d0 = d1
d1 = t
}
return [n1, d1]
} // rat()
// compare pitches
// This function is used to sort the note pitches
abc2svg.pitcmp = function(n1, n2) { return n1.pit - n2.pit }
// start of the Abc object
abc2svg.Abc = function(user) {
"use strict";
// constants
var C = abc2svg.C;
// mask some unsafe functions
var require = empty_function,
system = empty_function,
write = empty_function,
XMLHttpRequest = empty_function,
std = null,
os = null
// -- constants --
// staff system
var OPEN_BRACE = 0x01,
CLOSE_BRACE = 0x02,
lib/ChordPro/res/abc/abc2svg/abc2svg-1.js view on Meta::CPAN
decoerr: true,
dynalign: true,
footerfont: { name: txt_ff, size: 16 },
fullsvg: '',
gchordfont: { name: "text,sans-serif", size: 12 },
gracespace: new Float32Array([6, 8, 11]), // left, inside, right
graceslurs: true,
headerfont: { name: txt_ff, size: 16 },
historyfont: { name: txt_ff, size: 16 },
hyphencont: true,
indent: 0,
infofont: {name: txt_ff, style: "italic", size: 14 },
infoname: 'R "Rhythm: "\n\
B "Book: "\n\
S "Source: "\n\
D "Discography: "\n\
N "Notes: "\n\
Z "Transcription: "\n\
H "History: "',
infospace: 0,
keywarn: true,
leftmargin: 1.4 * CM,
lineskipfac: 1.1,
linewarn: true,
maxshrink: .65, // nice scores
maxstaffsep: 2000,
maxsysstaffsep: 2000,
measrepnb: 1,
measurefont: {name: txt_ff, style: "italic", size: 10},
measurenb: -1,
musicfont: {name: "music", src: musicfont, size: 24},
musicspace: 6,
// notespacingfactor: "1.3, 38",
partsfont: {name: txt_ff, size: 15},
parskipfac: .4,
partsspace: 8,
// pageheight: 29.7 * CM,
pagewidth: 21 * CM,
"propagate-accidentals": "o", // octave
printmargin: 0,
rightmargin: 1.4 * CM,
rbmax: 4,
rbmin: 2,
repeatfont: {name: txt_ff, size: 9},
scale: 1,
slurheight: 1.0,
spatab: // spacing table (see "notespacingfactor" and set_space())
new Float32Array([ // default = "1.3, 38"
10.2, 13.3, 17.3, 22.48, 29.2,
38,
49.4, 64.2, 83.5, 108.5]),
staffsep: 46,
stemheight: 21, // one octave
stretchlast: .25,
stretchstaff: true,
subtitlefont: {name: txt_ff, size: 16},
subtitlespace: 3,
sysstaffsep: 34,
systnames: -1, // (for compatibility)
systvoices: 3,
tempofont: {name: txt_ff, weight: "bold", size: 12},
textfont: {name: txt_ff, size: 16},
// textoption: undefined,
textspace: 14,
tieheight: 1.0,
titlefont: {name: txt_ff, size: 20},
// titleleft: false,
titlespace: 6,
titletrim: true,
// transp: 0, // global transpose
// topmargin: .7 * IN,
topspace: 22,
tuplets: [0, 0, 0, 0],
tupletfont: {name: txt_ff, style: "italic", size: 10},
vocalfont: {name: txt_ff, weight: "bold", size: 13},
vocalspace: 10,
voicefont: {name: txt_ff, weight: "bold", size: 13},
// voicescale: 1,
writefields: "CMOPQsTWw",
wordsfont: {name: txt_ff, size: 16},
wordsspace: 5,
"writeout-accidentals": "n"
}
// parameters that are used in the symbols
var sfmt = {
bardef: true,
barsperstaff: true,
beamslope: true,
breaklimit: true,
bstemdown: true,
cancelkey: true,
dynalign: true,
flatbeams: true,
gracespace: true,
hyphencont: true,
keywarn: true,
maxshrink: true,
maxstaffsep: true,
measrepnb: true,
rbmax: true,
rbmin: true,
shiftunison: true,
slurheight: true,
squarebreve: true,
staffsep: true,
systvoices: 1, //true
stemheight: true,
stretchlast: true,
stretchstaff: true,
tieheight: true,
timewarn: true,
trimsvg: 1, //true
vocalspace: true
} // sfmt
function get_bool(param) {
return !param || !/^(0|n|f)/i.test(param) // accept void as true !
}
// %%font <font> [<encoding>] [<scale>]
function get_font_scale(param) {
var i, font,
a = info_split(param) // a[0] = font name
if (a.length <= 1)
return
var scale = +a[a.length - 1]
if (isNaN(scale) || scale <= 0.5) {
syntax(1, "Bad scale value in %%font")
return
}
font_scale_tb[a[0]] = scale
}
// set the width factor of a font
lib/ChordPro/res/abc/abc2svg/abc2svg-1.js view on Meta::CPAN
output += '"/>\n'
}
// tuplet bracket - the staves are not defined
function out_tubr(x, y, dx, dy, up) {
var h = up ? -3 : 3;
y += h;
dx /= stv_g.scale;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
output += 'v' + h.toFixed(1) +
'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed(1) + '"/>\n'
}
// tuplet bracket with number - the staves are not defined
function out_tubrn(x, y, dx, dy, up, str) {
var dxx,
sw = str.length * 10,
h = up ? -3 : 3;
set_font("tuplet")
xy_str(x + dx / 2, y + dy / 2 - gene.curfont.size * .1,
str, 'c')
dx /= stv_g.scale
if (!up)
y += 6;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
dxx = dx - sw + 1
if (dy > 0)
sw += dy / 8
else
sw -= dy / 8
output += 'v' + h.toFixed(1) +
'm' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed(1) + '"/>\n' +
'<path class="stroke" stroke-dasharray="' +
(dxx / 2).toFixed(1) + ' ' + sw.toFixed(1) +
'" d="m';
out_sxsy(x, ' ', y - h);
output += 'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) + '"/>\n'
}
// underscore line
function out_wln(x, y, w) {
out_XYAB('<path class="stroke" stroke-width="0.8" d="mX YhF"/>\n',
x, y + 1, w)
}
// decorations with string
var deco_str_style = {
crdc: { // cresc., decresc., dim., ...
dx: 0,
dy: 5,
style: 'font:italic 14px text,serif',
anchor: ' text-anchor="middle"'
},
dacs: { // long repeats (da capo, fine...)
dx: 0,
dy: 3,
style: 'font:bold 15px text,serif',
anchor: ' text-anchor="middle"'
},
pf: {
dx: 0,
dy: 5,
style: 'font:italic bold 16px text,serif',
anchor: ' text-anchor="middle"'
}
}
deco_str_style.at = deco_str_style.crdc
function out_deco_str(x, y, de) {
var name = de.dd.glyph // class
if (name == 'fng') {
out_XYAB('\
<text x="X" y="Y" style="font-size:14px">A</text>\n',
x - 2, y + 1, m_gl(de.dd.str))
return
}
if (name == '@') { // compatibility
name = 'at'
} else if (!/^[A-Za-z][A-Za-z\-_]*$/.test(name)) {
error(1, de.s, "No function for decoration '$1'", de.dd.name)
return
}
var f,
a_deco = deco_str_style[name]
if (!a_deco)
a_deco = deco_str_style.crdc // default style
else if (a_deco.style)
style += "\n." + name + "{" + a_deco.style + "}",
delete a_deco.style
x += a_deco.dx;
y += a_deco.dy;
out_XYAB('<text x="X" y="Y" class="A"B>', x, y,
name, a_deco.anchor || "");
set_font("annotation");
out_str(de.dd.str)
output += '</text>\n'
}
function out_arp(x, y, val) {
g_open(x, y, 270);
x = 0;
val = Math.ceil(val / 6)
while (--val >= 0) {
xygl(x, 6, "ltr");
x += 6
}
g_close()
}
function out_cresc(x, y, val, defl) {
x += val * stv_g.scale
val = -val;
out_XYAB('<path class="stroke"\n\
d="mX YlF ', x, y, val)
if (defl.nost)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_dim(x, y, val, defl) {
out_XYAB('<path class="stroke"\n\
d="mX YlF ', x, y, val)
if (defl.noen)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_ltr(x, y, val) {
y += 4;
val = Math.ceil(val / 6)
while (--val >= 0) {
xygl(x, y, "ltr");
x += 6
}
}
Abc.prototype.out_lped = function(x, y, val, defl) {
if (!defl.nost)
xygl(x, y, "ped");
if (!defl.noen)
xygl(x + val + 6, y, "pedoff")
}
function out_8va(x, y, val, defl) {
if (val < 18) {
val = 18
x -= 4
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">8\
<tspan dy="-4" style="font-size:10px">va</tspan></text>\n',
x - 8, y);
x += 12;
val -= 12
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_8vb(x, y, val, defl) {
if (val < 18) {
val = 18
x -= 4
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">8\
<tspan dy=".5" style="font-size:10px">vb</tspan></text>\n',
x - 8, y);
x += 10
val -= 10
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
function out_15ma(x, y, val, defl) {
if (val < 25) {
val = 25
x -= 6
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">15\
<tspan dy="-4" style="font-size:10px">ma</tspan></text>\n',
x - 10, y);
x += 20;
val -= 20
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_15mb(x, y, val, defl) {
if (val < 24) {
val = 24
x -= 5
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">15\
<tspan dy=".5" style="font-size:10px">mb</tspan></text>\n',
x - 10, y);
x += 18
val -= 18
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
var deco_val_tb = {
arp: out_arp,
cresc: out_cresc,
dim: out_dim,
ltr: out_ltr,
lped: function(x, y, val, defl) {
self.out_lped(x, y, val, defl)
},
"8va": out_8va,
"8vb": out_8vb,
"15ma": out_15ma,
"15mb": out_15mb
}
function out_deco_val(x, y, name, val, defl) {
if (deco_val_tb[name])
deco_val_tb[name](x, y, val, defl)
else
error(1, null, "No function for decoration '$1'", name)
}
function out_glisq(x2, y2, de) {
var ar, a, len,
de1 = de.start,
x1 = de1.x,
y1 = de1.y + staff_tb[de1.st].y,
dx = x2 - x1,
dy = self.sh(y1 - y2)
if (!stv_g.g)
dx /= stv_g.scale
ar = Math.atan2(dy, dx)
a = ar / Math.PI * 180
len = (dx - (de1.s.dots ? 13 + de1.s.xmx : 8)
- 8 - (de.s.notes[0].shac || 0))
/ Math.cos(ar)
g_open(x1, y1, a);
x1 = de1.s.dots ? 13 + de1.s.xmx : 8;
len = len / 6 | 0
if (len < 1)
len = 1
while (--len >= 0) {
xygl(x1, 0, "ltr");
x1 += 6
}
g_close()
}
( run in 0.432 second using v1.01-cache-2.11-cpan-524268b4103 )