abcjs-rails 1.8 → 1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/javascripts/abcjs/api/abc_animation.js +224 -0
  4. data/app/assets/javascripts/abcjs/api/abc_tunebook.js +158 -154
  5. data/app/assets/javascripts/abcjs/data/abc_tune.js +35 -1
  6. data/app/assets/javascripts/abcjs/edit/abc_editor.js +18 -17
  7. data/app/assets/javascripts/abcjs/parse/abc_parse.js +23 -6
  8. data/app/assets/javascripts/abcjs/parse/abc_parse_header.js +5 -1
  9. data/app/assets/javascripts/abcjs/{write/raphael.js → raphael.js} +2562 -266
  10. data/app/assets/javascripts/abcjs/write/abc_absolute_element.js +163 -0
  11. data/app/assets/javascripts/abcjs/write/abc_beam_element.js +162 -0
  12. data/app/assets/javascripts/abcjs/write/abc_cresendo_element.js +46 -0
  13. data/app/assets/javascripts/abcjs/write/abc_dynamic_decoration.js +36 -0
  14. data/app/assets/javascripts/abcjs/write/abc_ending_element.js +53 -0
  15. data/app/assets/javascripts/abcjs/write/abc_glyphs.js +6 -3
  16. data/app/assets/javascripts/abcjs/write/abc_layout.js +84 -29
  17. data/app/assets/javascripts/abcjs/write/abc_relative_element.js +72 -0
  18. data/app/assets/javascripts/abcjs/write/abc_staff_group_element.js +225 -0
  19. data/app/assets/javascripts/abcjs/write/abc_tie_element.js +83 -0
  20. data/app/assets/javascripts/abcjs/write/abc_triplet_element.js +85 -0
  21. data/app/assets/javascripts/abcjs/write/abc_voice_element.js +177 -0
  22. data/app/assets/javascripts/abcjs/write/abc_write.js +65 -28
  23. data/lib/abcjs-rails/version.rb +1 -1
  24. metadata +24 -14
  25. 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: 7dbac8c0a5ad9f76a40c25b8c005af7e252d3511
4
- data.tar.gz: 0577ccedd11d130f22d2b6c2c3c89506f61e9dcb
3
+ metadata.gz: 69dc7543800ee59c97f476146e4d23392cf201f0
4
+ data.tar.gz: f36703aa7021da85d79ca7e8e287749f28db1b24
5
5
  SHA512:
6
- metadata.gz: ede96b70bf4fd02a9594fee34e9dae661b5fd2bb5e05dbc0770b57ae4c5e889876d70c3552b26cf956e7589ca437a46944faaaeae3c2ee6451c64ccb11e7856f
7
- data.tar.gz: 94f0fba0cab72e74cf8ab2c1e581250f334a974c19ebd9a5a0a954673b011967d509075886448132c3240e0513181784ee22566c7fcc3409f32fcfa8b7e10f99
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 http://code.google.com/p/abcjs/wiki/InstallationDocumentation?tm=6 for complete
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
- 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;
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
- 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
- };
79
-
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
- };
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.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;
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 renderEngine(callback, output, abc, parserParams, renderParams) {
97
- var isArray = function(testObject) {
98
- return testObject && !(testObject.propertyIsEnumerable('length')) && typeof testObject === 'object' && typeof testObject.length === 'number';
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
- // check and normalize input parameters
102
- if (output === undefined || abc === undefined)
103
- return;
104
- if (!isArray(output))
105
- output = [ output ];
106
- if (parserParams === undefined)
107
- parserParams = {};
108
- if (renderParams === undefined)
109
- renderParams = {};
110
- var currentTune = renderParams.startingTune ? renderParams.startingTune : 0;
111
-
112
- // parse the abc string
113
- var book = new ABCJS.TuneBook(abc);
114
- var abcParser = new window.ABCJS.parse.Parse();
115
-
116
- // output each tune, if it exists. Otherwise clear the div.
117
- for (var i = 0; i < output.length; i++) {
118
- var div = output[i];
119
- if (typeof(div) === "string")
120
- div = document.getElementById(div);
121
- if (div) {
122
- div.innerHTML = "";
123
- if (currentTune < book.tunes.length) {
124
- abcParser.parse(book.tunes[currentTune].abc, parserParams);
125
- var tune = abcParser.getTune();
126
- callback(div, tune);
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
- currentTune++;
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, printerParams, renderParams) {
151
- function callback(div, tune) {
152
- var width = renderParams ? renderParams.width ? renderParams.width : 800 : 800;
153
- var paper = Raphael(div, width, 400);
154
- if (printerParams === undefined)
155
- printerParams = {};
156
- var printer = new ABCJS.write.Printer(paper, printerParams);
157
- printer.printABC(tune);
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
- renderEngine(callback, output, abc, parserParams, renderParams);
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
- function callback(div, tune) {
181
- if (midiParams === undefined)
182
- midiParams = {};
183
- var midiwriter = new ABCJS.midi.MidiWriter(div, midiParams);
184
- midiwriter.writeABC(tune);
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
- renderEngine(callback, output, abc, parserParams, renderParams);
188
- };
191
+ return renderEngine(callback, output, abc, parserParams, renderParams);
192
+ };
189
193
  })();