abcjs-rails 1.8 → 1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/abcjs/api/abc_animation.js +224 -0
- data/app/assets/javascripts/abcjs/api/abc_tunebook.js +158 -154
- data/app/assets/javascripts/abcjs/data/abc_tune.js +35 -1
- data/app/assets/javascripts/abcjs/edit/abc_editor.js +18 -17
- data/app/assets/javascripts/abcjs/parse/abc_parse.js +23 -6
- data/app/assets/javascripts/abcjs/parse/abc_parse_header.js +5 -1
- data/app/assets/javascripts/abcjs/{write/raphael.js → raphael.js} +2562 -266
- data/app/assets/javascripts/abcjs/write/abc_absolute_element.js +163 -0
- data/app/assets/javascripts/abcjs/write/abc_beam_element.js +162 -0
- data/app/assets/javascripts/abcjs/write/abc_cresendo_element.js +46 -0
- data/app/assets/javascripts/abcjs/write/abc_dynamic_decoration.js +36 -0
- data/app/assets/javascripts/abcjs/write/abc_ending_element.js +53 -0
- data/app/assets/javascripts/abcjs/write/abc_glyphs.js +6 -3
- data/app/assets/javascripts/abcjs/write/abc_layout.js +84 -29
- data/app/assets/javascripts/abcjs/write/abc_relative_element.js +72 -0
- data/app/assets/javascripts/abcjs/write/abc_staff_group_element.js +225 -0
- data/app/assets/javascripts/abcjs/write/abc_tie_element.js +83 -0
- data/app/assets/javascripts/abcjs/write/abc_triplet_element.js +85 -0
- data/app/assets/javascripts/abcjs/write/abc_voice_element.js +177 -0
- data/app/assets/javascripts/abcjs/write/abc_write.js +65 -28
- data/lib/abcjs-rails/version.rb +1 -1
- metadata +24 -14
- data/app/assets/javascripts/abcjs/write/abc_graphelements.js +0 -790
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69dc7543800ee59c97f476146e4d23392cf201f0
|
4
|
+
data.tar.gz: f36703aa7021da85d79ca7e8e287749f28db1b24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab12f67b09329ba8245b574c226519cb6fc8e202bf8cd9b6c6323662cedbfca851e1abde4b94d8d02961dd007aa19389043a7f7ed9dd6fc92ed6cb2bd4d0e39d
|
7
|
+
data.tar.gz: 6228eac5b18e3cc8d6ce3b56545c29d8c12f741f321da6cf95a55a8e92994273dc4763931eba3836199f11b5625522c540f2211aa193151adb839cebe735f219
|
data/README.md
CHANGED
@@ -23,7 +23,7 @@ To include abcjs in your Rails app, add this line to application.js:
|
|
23
23
|
|
24
24
|
//= require abcjs-rails
|
25
25
|
|
26
|
-
See
|
26
|
+
See https://github.com/paulrosen/abcjs for complete
|
27
27
|
usage of abcjs. There is no additional functionality supplied by this gem.
|
28
28
|
|
29
29
|
Here is a cheatsheet for using the functionality:
|
@@ -0,0 +1,224 @@
|
|
1
|
+
// abc_animation.js: handles animating the music in real time.
|
2
|
+
// Copyright (C) 2014 Paul Rosen (paul at paulrosen dot net)
|
3
|
+
//
|
4
|
+
// This program is free software: you can redistribute it and/or modify
|
5
|
+
// it under the terms of the GNU General Public License as published by
|
6
|
+
// the Free Software Foundation, either version 3 of the License, or
|
7
|
+
// (at your option) any later version.
|
8
|
+
//
|
9
|
+
// This program is distributed in the hope that it will be useful,
|
10
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
// GNU General Public License for more details.
|
13
|
+
//
|
14
|
+
// You should have received a copy of the GNU General Public License
|
15
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
/*global ABCJS, console */
|
18
|
+
|
19
|
+
if (!window.ABCJS)
|
20
|
+
window.ABCJS = {};
|
21
|
+
|
22
|
+
(function() {
|
23
|
+
|
24
|
+
function hasClass(element, cls) {
|
25
|
+
var elClass = element.getAttribute("class");
|
26
|
+
var rclass = /[\t\r\n\f]/g;
|
27
|
+
var className = " " + cls + " ";
|
28
|
+
return (element.nodeType === 1 && (" " + elClass + " ").replace(rclass, " ").indexOf(className) >= 0);
|
29
|
+
}
|
30
|
+
|
31
|
+
function getAllElementsByClasses(startingEl, class1, class2) {
|
32
|
+
var els = startingEl.getElementsByClassName(class1);
|
33
|
+
var ret = [];
|
34
|
+
for (var i = 0; i < els.length; i++) {
|
35
|
+
if (hasClass(els[i], class2))
|
36
|
+
ret.push(els[i]);
|
37
|
+
}
|
38
|
+
return ret;
|
39
|
+
}
|
40
|
+
|
41
|
+
function getBeatsPerMinute(tune, options) {
|
42
|
+
// We either want to run the timer once per measure or once per beat. If we run it once per beat we need a multiplier for the measures.
|
43
|
+
// So, first we figure out the beats per minute and the beats per measure, then depending on the type of animation, we can
|
44
|
+
// calculate the desired interval (ret.tick) and the number of ticks before we want to run the measure
|
45
|
+
var bpm;
|
46
|
+
if (options.bpm)
|
47
|
+
bpm = options.bpm;
|
48
|
+
else {
|
49
|
+
if (tune && tune.metaText && tune.metaText.tempo && tune.metaText.tempo.bpm)
|
50
|
+
bpm = tune.metaText.tempo.bpm;
|
51
|
+
else
|
52
|
+
bpm = 120; // Just set it to something. The user should have set this.
|
53
|
+
}
|
54
|
+
return bpm;
|
55
|
+
}
|
56
|
+
|
57
|
+
// This is a way to manipulate the written music on a timer. Their are two ways to manipulate the music: turn off each measure as it goes by,
|
58
|
+
// and put a vertical cursor before the next note to play. The timer works at the speed of the original tempo of the music unless it is overwritten
|
59
|
+
// in the options parameter.
|
60
|
+
//
|
61
|
+
// parameters:
|
62
|
+
// paper: the output div that the music is in.
|
63
|
+
// tune: the tune object returned by renderAbc.
|
64
|
+
// options: a hash containing the following:
|
65
|
+
// hideFinishedMeasures: true or false [ false is the default ]
|
66
|
+
// showCursor: true or false [ false is the default ]
|
67
|
+
// bpm: number of beats per minute [ the default is whatever is in the Q: field ]
|
68
|
+
var stopNextTime = false;
|
69
|
+
var cursor;
|
70
|
+
ABCJS.startAnimation = function(paper, tune, options) {
|
71
|
+
if (paper.getElementsByClassName === undefined) {
|
72
|
+
console.error("ABCJS.startAnimation: The first parameter must be a regular DOM element. (Did you pass a jQuery object or an ID?)");
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
if (tune.getBeatLength === undefined) {
|
76
|
+
console.error("ABCJS.startAnimation: The second parameter must be a single tune. (Did you pass the entire array of tunes?)");
|
77
|
+
return;
|
78
|
+
}
|
79
|
+
if (options.showCursor) {
|
80
|
+
cursor = $('<div class="cursor" style="position: absolute;"></div>');
|
81
|
+
$(paper).append(cursor);
|
82
|
+
}
|
83
|
+
|
84
|
+
stopNextTime = false;
|
85
|
+
var beatsPerMinute = getBeatsPerMinute(tune, options);
|
86
|
+
var beatsPerMillisecond = beatsPerMinute / 60000;
|
87
|
+
var beatLength = tune.getBeatLength(); // This is the same units as the duration is stored in.
|
88
|
+
|
89
|
+
var startTime;
|
90
|
+
|
91
|
+
function processMeasureHider(lineNum, measureNum) {
|
92
|
+
var els = getAllElementsByClasses(paper, "l"+lineNum, "m"+measureNum);
|
93
|
+
|
94
|
+
if (els.length > 0) {
|
95
|
+
for (var i = 0; i < els.length; i++) {
|
96
|
+
var el = els[i];
|
97
|
+
if (!hasClass(el, "bar"))
|
98
|
+
el.style.display = "none";
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
function makeSortedArray(hash) {
|
104
|
+
var arr = [];
|
105
|
+
for (var k in hash) {
|
106
|
+
if (hash.hasOwnProperty(k))
|
107
|
+
arr.push(hash[k]);
|
108
|
+
}
|
109
|
+
arr = arr.sort(function(a,b) {
|
110
|
+
return a.time - b.time;
|
111
|
+
});
|
112
|
+
return arr;
|
113
|
+
}
|
114
|
+
|
115
|
+
var timingEvents = [];
|
116
|
+
function setupEvents(engraver) {
|
117
|
+
var eventHash = {};
|
118
|
+
// The time is the number of measures from the beginning of the piece.
|
119
|
+
var time = 0;
|
120
|
+
var isTiedState = false;
|
121
|
+
for (var line=0;line<engraver.staffgroups.length; line++) {
|
122
|
+
var group = engraver.staffgroups[line];
|
123
|
+
var voices = group.voices;
|
124
|
+
var top = group.y;
|
125
|
+
var height = group.height;
|
126
|
+
var maxVoiceTime = 0;
|
127
|
+
// Put in the notes for all voices, then sort them, then remove duplicates
|
128
|
+
for (var v = 0; v < voices.length; v++) {
|
129
|
+
var voiceTime = time;
|
130
|
+
var elements = voices[v].children;
|
131
|
+
for (var elem=0; elem<elements.length; elem++) {
|
132
|
+
var element = elements[elem];
|
133
|
+
if (element.duration > 0) {
|
134
|
+
// There are 3 possibilities here: the note could stand on its own, the note could be tied to the next,
|
135
|
+
// the note could be tied to the previous, and the note could be tied on both sides.
|
136
|
+
var isTiedToNext = element.startTie;
|
137
|
+
if (isTiedState) {
|
138
|
+
if (!isTiedToNext)
|
139
|
+
isTiedState = false;
|
140
|
+
// If the note is tied on both sides it can just be ignored.
|
141
|
+
} else {
|
142
|
+
// the last note wasn't tied.
|
143
|
+
eventHash["event"+voiceTime] = { type: "event", time: voiceTime, top: top, height: height, left: element.x, width: element.w };
|
144
|
+
if (isTiedToNext)
|
145
|
+
isTiedState = true;
|
146
|
+
}
|
147
|
+
voiceTime += element.duration;
|
148
|
+
}
|
149
|
+
if (element.type === 'bar') {
|
150
|
+
if (timingEvents.length === 0 || timingEvents[timingEvents.length-1] !== 'bar') {
|
151
|
+
if (element.elemset && element.elemset.length > 0 && element.elemset[0].attrs) {
|
152
|
+
var klass = element.elemset[0].attrs['class'];
|
153
|
+
var arr = klass.split(' ');
|
154
|
+
var lineNum;
|
155
|
+
var measureNum;
|
156
|
+
for (var i = 0; i < arr.length; i++) {
|
157
|
+
var match = /m(\d+)/.exec(arr[i]);
|
158
|
+
if (match)
|
159
|
+
measureNum = match[1];
|
160
|
+
match = /l(\d+)/.exec(arr[i]);
|
161
|
+
if (match)
|
162
|
+
lineNum = match[1];
|
163
|
+
}
|
164
|
+
eventHash["bar"+voiceTime] = { type: "bar", time: voiceTime, lineNum: lineNum, measureNum: measureNum };
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
maxVoiceTime = Math.max(maxVoiceTime, voiceTime);
|
170
|
+
}
|
171
|
+
time = maxVoiceTime;
|
172
|
+
}
|
173
|
+
// now we have all the events, but if there are multiple voices then there may be events out of order or duplicated, so normalize it.
|
174
|
+
timingEvents = makeSortedArray(eventHash);
|
175
|
+
}
|
176
|
+
setupEvents(tune.engraver);
|
177
|
+
|
178
|
+
function processShowCursor() {
|
179
|
+
var currentNote = timingEvents.shift();
|
180
|
+
if (!currentNote) {
|
181
|
+
stopNextTime = true;
|
182
|
+
return 0;
|
183
|
+
}
|
184
|
+
if (currentNote.type === "bar") {
|
185
|
+
if (options.hideFinishedMeasures)
|
186
|
+
processMeasureHider(currentNote.lineNum, currentNote.measureNum);
|
187
|
+
return processShowCursor();
|
188
|
+
}
|
189
|
+
if (options.showCursor)
|
190
|
+
cursor.css({ left: currentNote.left + "px", top: currentNote.top + "px", width: currentNote.width + "px", height: currentNote.height + "px" });
|
191
|
+
if (timingEvents.length > 0)
|
192
|
+
return timingEvents[0].time / beatLength;
|
193
|
+
stopNextTime = true;
|
194
|
+
return 0;
|
195
|
+
}
|
196
|
+
|
197
|
+
function processNext() {
|
198
|
+
if (stopNextTime) {
|
199
|
+
ABCJS.stopAnimation();
|
200
|
+
return;
|
201
|
+
}
|
202
|
+
var nextTimeInBeats = processShowCursor();
|
203
|
+
var nextTimeInMilliseconds = nextTimeInBeats / beatsPerMillisecond;
|
204
|
+
var currentTime = new Date();
|
205
|
+
currentTime = currentTime.getTime();
|
206
|
+
var interval = startTime + nextTimeInMilliseconds - currentTime;
|
207
|
+
if (interval <= 0)
|
208
|
+
processNext();
|
209
|
+
else
|
210
|
+
setTimeout(processNext, interval);
|
211
|
+
}
|
212
|
+
startTime = new Date();
|
213
|
+
startTime = startTime.getTime();
|
214
|
+
processNext();
|
215
|
+
};
|
216
|
+
|
217
|
+
ABCJS.stopAnimation = function() {
|
218
|
+
stopNextTime = true;
|
219
|
+
if (cursor) {
|
220
|
+
cursor.remove();
|
221
|
+
cursor = null;
|
222
|
+
}
|
223
|
+
};
|
224
|
+
})();
|
@@ -15,175 +15,179 @@
|
|
15
15
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
17
|
/*global document, Raphael */
|
18
|
-
/*global window */
|
18
|
+
/*global window, ABCJS, console */
|
19
19
|
|
20
20
|
if (!window.ABCJS)
|
21
21
|
window.ABCJS = {};
|
22
22
|
|
23
23
|
(function() {
|
24
|
-
ABCJS.numberOfTunes = function(abc) {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
};
|
30
|
-
|
31
|
-
ABCJS.TuneBook = function(book) {
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
});
|
45
|
-
if (This.tunes.length > 1 && !window.ABCJS.parse.startsWith(This.tunes[0].abc, 'X:')) { // If there is only one tune, the X: might be missing, otherwise assume the top of the file is "intertune"
|
46
|
-
// There could be file-wide directives in this, if so, we need to insert it into each tune. We can probably get away with
|
47
|
-
// just looking for file-wide directives here (before the first tune) and inserting them at the bottom of each tune, since
|
48
|
-
// the tune is parsed all at once. The directives will be seen before the printer begins processing.
|
49
|
-
var dir = This.tunes.shift();
|
50
|
-
var arrDir = dir.abc.split('\n');
|
51
|
-
window.ABCJS.parse.each(arrDir, function(line) {
|
52
|
-
if (window.ABCJS.parse.startsWith(line, '%%'))
|
53
|
-
directives += line + '\n';
|
24
|
+
ABCJS.numberOfTunes = function(abc) {
|
25
|
+
var tunes = abc.split("\nX:");
|
26
|
+
var num = tunes.length;
|
27
|
+
if (num === 0) num = 1;
|
28
|
+
return num;
|
29
|
+
};
|
30
|
+
|
31
|
+
ABCJS.TuneBook = function(book) {
|
32
|
+
var This = this;
|
33
|
+
var directives = "";
|
34
|
+
book = window.ABCJS.parse.strip(book);
|
35
|
+
var tunes = book.split("\nX:");
|
36
|
+
for (var i = 1; i < tunes.length; i++) // Put back the X: that we lost when splitting the tunes.
|
37
|
+
tunes[i] = "X:" + tunes[i];
|
38
|
+
// Keep track of the character position each tune starts with.
|
39
|
+
var pos = 0;
|
40
|
+
This.tunes = [];
|
41
|
+
window.ABCJS.parse.each(tunes, function(tune) {
|
42
|
+
This.tunes.push({ abc: tune, startPos: pos});
|
43
|
+
pos += tune.length;
|
54
44
|
});
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
45
|
+
if (This.tunes.length > 1 && !window.ABCJS.parse.startsWith(This.tunes[0].abc, 'X:')) { // If there is only one tune, the X: might be missing, otherwise assume the top of the file is "intertune"
|
46
|
+
// There could be file-wide directives in this, if so, we need to insert it into each tune. We can probably get away with
|
47
|
+
// just looking for file-wide directives here (before the first tune) and inserting them at the bottom of each tune, since
|
48
|
+
// the tune is parsed all at once. The directives will be seen before the engraver begins processing.
|
49
|
+
var dir = This.tunes.shift();
|
50
|
+
var arrDir = dir.abc.split('\n');
|
51
|
+
window.ABCJS.parse.each(arrDir, function(line) {
|
52
|
+
if (window.ABCJS.parse.startsWith(line, '%%'))
|
53
|
+
directives += line + '\n';
|
54
|
+
});
|
55
|
+
}
|
56
|
+
This.header = directives;
|
57
|
+
|
58
|
+
// Now, the tune ends at a blank line, so truncate it if needed. There may be "intertune" stuff.
|
59
|
+
window.ABCJS.parse.each(This.tunes, function(tune) {
|
60
|
+
var end = tune.abc.indexOf('\n\n');
|
61
|
+
if (end > 0)
|
62
|
+
tune.abc = tune.abc.substring(0, end);
|
63
|
+
tune.pure = tune.abc;
|
64
|
+
tune.abc = directives + tune.abc;
|
65
|
+
|
66
|
+
// for the user's convenience, parse and store the title separately. The title is between the first T: and the next \n
|
67
|
+
var title = tune.pure.split("T:");
|
68
|
+
if (title.length > 1) {
|
69
|
+
title = title[1].split("\n");
|
70
|
+
tune.title = title[0].replace(/^\s+|\s+$/g, '');
|
71
|
+
} else
|
72
|
+
tune.title = "";
|
73
|
+
|
74
|
+
// for the user's convenience, parse and store the id separately. The id is between the first X: and the next \n
|
75
|
+
var id = tune.pure.substring(2, tune.pure.indexOf("\n"));
|
76
|
+
tune.id = id.replace(/^\s+|\s+$/g, '');
|
77
|
+
});
|
78
|
+
};
|
87
79
|
|
88
|
-
ABCJS.TuneBook.prototype.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
};
|
80
|
+
ABCJS.TuneBook.prototype.getTuneById = function(id) {
|
81
|
+
for (var i = 0; i < this.tunes.length; i++) {
|
82
|
+
if (this.tunes[i].id === id)
|
83
|
+
return this.tunes[i];
|
84
|
+
}
|
85
|
+
return null;
|
86
|
+
};
|
95
87
|
|
96
|
-
function
|
97
|
-
|
98
|
-
|
88
|
+
ABCJS.TuneBook.prototype.getTuneByTitle = function(title) {
|
89
|
+
for (var i = 0; i < this.tunes.length; i++) {
|
90
|
+
if (this.tunes[i].title === title)
|
91
|
+
return this.tunes[i];
|
92
|
+
}
|
93
|
+
return null;
|
99
94
|
};
|
100
95
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
96
|
+
function renderEngine(callback, output, abc, parserParams, renderParams) {
|
97
|
+
var ret = [];
|
98
|
+
var isArray = function(testObject) {
|
99
|
+
return testObject && !(testObject.propertyIsEnumerable('length')) && typeof testObject === 'object' && typeof testObject.length === 'number';
|
100
|
+
};
|
101
|
+
|
102
|
+
// check and normalize input parameters
|
103
|
+
if (output === undefined || abc === undefined)
|
104
|
+
return;
|
105
|
+
if (!isArray(output))
|
106
|
+
output = [ output ];
|
107
|
+
if (parserParams === undefined)
|
108
|
+
parserParams = {};
|
109
|
+
if (renderParams === undefined)
|
110
|
+
renderParams = {};
|
111
|
+
var currentTune = renderParams.startingTune ? renderParams.startingTune : 0;
|
112
|
+
|
113
|
+
// parse the abc string
|
114
|
+
var book = new ABCJS.TuneBook(abc);
|
115
|
+
var abcParser = new window.ABCJS.parse.Parse();
|
116
|
+
|
117
|
+
// output each tune, if it exists. Otherwise clear the div.
|
118
|
+
for (var i = 0; i < output.length; i++) {
|
119
|
+
var div = output[i];
|
120
|
+
if (typeof(div) === "string")
|
121
|
+
div = document.getElementById(div);
|
122
|
+
if (div) {
|
123
|
+
div.innerHTML = "";
|
124
|
+
if (currentTune < book.tunes.length) {
|
125
|
+
abcParser.parse(book.tunes[currentTune].abc, parserParams);
|
126
|
+
var tune = abcParser.getTune();
|
127
|
+
ret.push(tune);
|
128
|
+
callback(div, tune);
|
129
|
+
}
|
127
130
|
}
|
131
|
+
currentTune++;
|
128
132
|
}
|
129
|
-
|
133
|
+
return ret;
|
130
134
|
}
|
131
|
-
}
|
132
135
|
|
133
|
-
// A quick way to render a tune from javascript when interactivity is not required.
|
134
|
-
// This is used when a javascript routine has some abc text that it wants to render
|
135
|
-
// in a div or collection of divs. One tune or many can be rendered.
|
136
|
-
//
|
137
|
-
// parameters:
|
138
|
-
// output: an array of divs that the individual tunes are rendered to.
|
139
|
-
// If the number of tunes exceeds the number of divs in the array, then
|
140
|
-
// only the first tunes are rendered. If the number of divs exceeds the number
|
141
|
-
// of tunes, then the unused divs are cleared. The divs can be passed as either
|
142
|
-
// elements or strings of ids. If ids are passed, then the div MUST exist already.
|
143
|
-
// (if a single element is passed, then it is an implied array of length one.)
|
144
|
-
// (if a null is passed for an element, or the element doesn't exist, then that tune is skipped.)
|
145
|
-
// abc: text representing a tune or an entire tune book in ABC notation.
|
146
|
-
// renderParams: hash of:
|
147
|
-
// startingTune: an index, starting at zero, representing which tune to start rendering at.
|
148
|
-
// (If this element is not present, then rendering starts at zero.)
|
149
|
-
// width: 800 by default. The width in pixels of the output paper
|
150
|
-
ABCJS.renderAbc = function(output, abc, parserParams,
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
136
|
+
// A quick way to render a tune from javascript when interactivity is not required.
|
137
|
+
// This is used when a javascript routine has some abc text that it wants to render
|
138
|
+
// in a div or collection of divs. One tune or many can be rendered.
|
139
|
+
//
|
140
|
+
// parameters:
|
141
|
+
// output: an array of divs that the individual tunes are rendered to.
|
142
|
+
// If the number of tunes exceeds the number of divs in the array, then
|
143
|
+
// only the first tunes are rendered. If the number of divs exceeds the number
|
144
|
+
// of tunes, then the unused divs are cleared. The divs can be passed as either
|
145
|
+
// elements or strings of ids. If ids are passed, then the div MUST exist already.
|
146
|
+
// (if a single element is passed, then it is an implied array of length one.)
|
147
|
+
// (if a null is passed for an element, or the element doesn't exist, then that tune is skipped.)
|
148
|
+
// abc: text representing a tune or an entire tune book in ABC notation.
|
149
|
+
// renderParams: hash of:
|
150
|
+
// startingTune: an index, starting at zero, representing which tune to start rendering at.
|
151
|
+
// (If this element is not present, then rendering starts at zero.)
|
152
|
+
// width: 800 by default. The width in pixels of the output paper
|
153
|
+
ABCJS.renderAbc = function(output, abc, parserParams, engraverParams, renderParams) {
|
154
|
+
function callback(div, tune) {
|
155
|
+
var width = renderParams ? renderParams.width ? renderParams.width : 800 : 800;
|
156
|
+
/* jshint -W064 */ var paper = Raphael(div, width, 400); /* jshint +W064 */
|
157
|
+
if (engraverParams === undefined)
|
158
|
+
engraverParams = {};
|
159
|
+
var engraver_controller = new ABCJS.write.Printer(paper, engraverParams);
|
160
|
+
engraver_controller.printABC(tune);
|
161
|
+
tune.engraver = engraver_controller;
|
162
|
+
}
|
159
163
|
|
160
|
-
|
161
|
-
};
|
164
|
+
return renderEngine(callback, output, abc, parserParams, renderParams);
|
165
|
+
};
|
162
166
|
|
163
|
-
// A quick way to render a tune from javascript when interactivity is not required.
|
164
|
-
// This is used when a javascript routine has some abc text that it wants to render
|
165
|
-
// in a div or collection of divs. One tune or many can be rendered.
|
166
|
-
//
|
167
|
-
// parameters:
|
168
|
-
// output: an array of divs that the individual tunes are rendered to.
|
169
|
-
// If the number of tunes exceeds the number of divs in the array, then
|
170
|
-
// only the first tunes are rendered. If the number of divs exceeds the number
|
171
|
-
// of tunes, then the unused divs are cleared. The divs can be passed as either
|
172
|
-
// elements or strings of ids. If ids are passed, then the div MUST exist already.
|
173
|
-
// (if a single element is passed, then it is an implied array of length one.)
|
174
|
-
// (if a null is passed for an element, or the element doesn't exist, then that tune is skipped.)
|
175
|
-
// abc: text representing a tune or an entire tune book in ABC notation.
|
176
|
-
// renderParams: hash of:
|
177
|
-
// startingTune: an index, starting at zero, representing which tune to start rendering at.
|
178
|
-
// (If this element is not present, then rendering starts at zero.)
|
179
|
-
ABCJS.renderMidi = function(output, abc, parserParams, midiParams, renderParams) {
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
167
|
+
// A quick way to render a tune from javascript when interactivity is not required.
|
168
|
+
// This is used when a javascript routine has some abc text that it wants to render
|
169
|
+
// in a div or collection of divs. One tune or many can be rendered.
|
170
|
+
//
|
171
|
+
// parameters:
|
172
|
+
// output: an array of divs that the individual tunes are rendered to.
|
173
|
+
// If the number of tunes exceeds the number of divs in the array, then
|
174
|
+
// only the first tunes are rendered. If the number of divs exceeds the number
|
175
|
+
// of tunes, then the unused divs are cleared. The divs can be passed as either
|
176
|
+
// elements or strings of ids. If ids are passed, then the div MUST exist already.
|
177
|
+
// (if a single element is passed, then it is an implied array of length one.)
|
178
|
+
// (if a null is passed for an element, or the element doesn't exist, then that tune is skipped.)
|
179
|
+
// abc: text representing a tune or an entire tune book in ABC notation.
|
180
|
+
// renderParams: hash of:
|
181
|
+
// startingTune: an index, starting at zero, representing which tune to start rendering at.
|
182
|
+
// (If this element is not present, then rendering starts at zero.)
|
183
|
+
ABCJS.renderMidi = function(output, abc, parserParams, midiParams, renderParams) {
|
184
|
+
function callback(div, tune) {
|
185
|
+
if (midiParams === undefined)
|
186
|
+
midiParams = {};
|
187
|
+
var midiwriter = new ABCJS.midi.MidiWriter(div, midiParams);
|
188
|
+
midiwriter.writeABC(tune);
|
189
|
+
}
|
186
190
|
|
187
|
-
|
188
|
-
};
|
191
|
+
return renderEngine(callback, output, abc, parserParams, renderParams);
|
192
|
+
};
|
189
193
|
})();
|