abcjs 6.0.0-beta.7 → 6.0.0

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 (204) hide show
  1. package/.github/workflows/tests.yml +29 -0
  2. package/CODE_OF_CONDUCT.md +76 -0
  3. package/CONTRIBUTING.md +1 -0
  4. package/LICENSE.md +1 -1
  5. package/README.md +92 -3
  6. package/RELEASE.md +957 -1
  7. package/abcjs-audio.css +14 -5
  8. package/dist/.gitignore +1 -2
  9. package/dist/abcjs-basic-min.js +3 -0
  10. package/dist/abcjs-basic-min.js.LICENSE +23 -0
  11. package/dist/abcjs-basic.js +28231 -0
  12. package/dist/abcjs-basic.js.map +1 -0
  13. package/dist/abcjs-plugin-min.js +3 -0
  14. package/dist/abcjs-plugin-min.js.LICENSE +23 -0
  15. package/dist/report-basic.html +37 -0
  16. package/dist/report-before-glyph-compress.html +37 -0
  17. package/dist/report-brown-ts-target-es5.html +37 -0
  18. package/dist/report-dev-orig-no-babel.html +37 -0
  19. package/dist/report-synth.html +37 -0
  20. package/docker-build.sh +1 -0
  21. package/glyphs.json +1 -0
  22. package/index.js +27 -2
  23. package/{static-wrappers/license.js → license.js} +1 -1
  24. package/package.json +26 -29
  25. package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
  26. package/src/api/abc_animation.js +1 -17
  27. package/src/api/abc_tablatures.js +144 -0
  28. package/src/api/abc_timing_callbacks.js +234 -116
  29. package/src/api/abc_tunebook.js +18 -67
  30. package/src/api/abc_tunebook_svg.js +38 -46
  31. package/src/data/abc_tune.js +232 -972
  32. package/src/data/deline-tune.js +199 -0
  33. package/src/edit/abc_editarea.js +112 -0
  34. package/src/edit/abc_editor.js +95 -221
  35. package/src/midi/abc_midi_create.js +48 -50
  36. package/src/parse/abc_common.js +0 -14
  37. package/src/parse/abc_parse.js +167 -1321
  38. package/src/parse/abc_parse_book.js +62 -0
  39. package/src/parse/abc_parse_directive.js +164 -41
  40. package/src/parse/abc_parse_header.js +116 -145
  41. package/src/parse/abc_parse_key_voice.js +26 -20
  42. package/src/parse/abc_parse_music.js +1337 -0
  43. package/src/parse/abc_tokenizer.js +21 -15
  44. package/src/parse/abc_transpose.js +3 -15
  45. package/src/parse/tune-builder.js +896 -0
  46. package/src/parse/wrap_lines.js +205 -453
  47. package/src/synth/abc_midi_flattener.js +1292 -0
  48. package/src/{midi → synth}/abc_midi_renderer.js +44 -17
  49. package/src/synth/abc_midi_sequencer.js +648 -0
  50. package/src/synth/active-audio-context.js +3 -14
  51. package/src/synth/cents-to-factor.js +10 -0
  52. package/src/synth/create-note-map.js +21 -32
  53. package/src/synth/create-synth-control.js +20 -103
  54. package/src/synth/create-synth.js +185 -77
  55. package/src/synth/download-buffer.js +7 -21
  56. package/src/synth/get-midi-file.js +13 -20
  57. package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
  58. package/src/synth/images/loop.svg.js +65 -0
  59. package/src/synth/images/pause.svg.js +10 -0
  60. package/src/synth/images/play.svg.js +9 -0
  61. package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
  62. package/src/synth/instrument-index-to-name.js +1 -16
  63. package/src/synth/load-note.js +37 -76
  64. package/src/synth/pitch-to-note-name.js +0 -15
  65. package/src/synth/pitches-to-perc.js +64 -0
  66. package/src/synth/place-note.js +78 -68
  67. package/src/synth/play-event.js +17 -18
  68. package/src/synth/register-audio-context.js +11 -23
  69. package/src/synth/sounds-cache.js +0 -15
  70. package/src/synth/supports-audio.js +9 -23
  71. package/src/synth/synth-controller.js +80 -49
  72. package/src/synth/synth-sequence.js +20 -34
  73. package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
  74. package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
  75. package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
  76. package/src/tablatures/instruments/string-patterns.js +277 -0
  77. package/src/tablatures/instruments/string-tablature.js +56 -0
  78. package/src/tablatures/instruments/tab-note.js +282 -0
  79. package/src/tablatures/instruments/tab-notes.js +41 -0
  80. package/src/tablatures/instruments/violin/tab-violin.js +47 -0
  81. package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
  82. package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
  83. package/src/tablatures/tab-absolute-elements.js +310 -0
  84. package/src/tablatures/tab-common.js +29 -0
  85. package/src/tablatures/tab-renderer.js +243 -0
  86. package/src/tablatures/transposer.js +110 -0
  87. package/src/test/abc_midi_lint.js +5 -22
  88. package/src/test/abc_midi_sequencer_lint.js +11 -14
  89. package/src/test/abc_parser_lint.js +136 -32
  90. package/src/test/abc_vertical_lint.js +94 -32
  91. package/src/test/rendering-lint.js +38 -5
  92. package/src/write/abc_absolute_element.js +112 -120
  93. package/src/write/abc_abstract_engraver.js +102 -253
  94. package/src/write/abc_beam_element.js +30 -290
  95. package/src/write/abc_brace_element.js +12 -121
  96. package/src/write/abc_create_clef.js +21 -32
  97. package/src/write/abc_create_key_signature.js +8 -26
  98. package/src/write/abc_create_note_head.js +107 -0
  99. package/src/write/abc_create_time_signature.js +2 -21
  100. package/src/write/abc_crescendo_element.js +3 -50
  101. package/src/write/abc_decoration.js +7 -30
  102. package/src/write/abc_dynamic_decoration.js +3 -37
  103. package/src/write/abc_ending_element.js +1 -57
  104. package/src/write/abc_engraver_controller.js +111 -234
  105. package/src/write/abc_glyphs.js +9 -19
  106. package/src/write/abc_relative_element.js +57 -97
  107. package/src/write/abc_renderer.js +10 -832
  108. package/src/write/abc_spacing.js +0 -15
  109. package/src/write/abc_staff_group_element.js +14 -349
  110. package/src/write/abc_tempo_element.js +9 -117
  111. package/src/write/abc_tie_element.js +5 -68
  112. package/src/write/abc_triplet_element.js +6 -124
  113. package/src/write/abc_voice_element.js +7 -222
  114. package/src/write/add-chord.js +103 -0
  115. package/src/write/add-text-if.js +33 -0
  116. package/src/write/bottom-text.js +79 -0
  117. package/src/write/calcHeight.js +17 -0
  118. package/src/write/classes.js +100 -0
  119. package/src/write/draw/absolute.js +68 -0
  120. package/src/write/draw/beam.js +56 -0
  121. package/src/write/draw/brace.js +106 -0
  122. package/src/write/draw/crescendo.js +38 -0
  123. package/src/write/draw/debug-box.js +8 -0
  124. package/src/write/draw/draw.js +56 -0
  125. package/src/write/draw/dynamics.js +20 -0
  126. package/src/write/draw/ending.js +46 -0
  127. package/src/write/draw/group-elements.js +66 -0
  128. package/src/write/draw/horizontal-line.js +25 -0
  129. package/src/write/draw/non-music.js +50 -0
  130. package/src/write/draw/print-line.js +24 -0
  131. package/src/write/draw/print-path.js +7 -0
  132. package/src/write/draw/print-stem.js +30 -0
  133. package/src/write/draw/print-symbol.js +59 -0
  134. package/src/write/draw/print-vertical-line.js +18 -0
  135. package/src/write/draw/relative.js +77 -0
  136. package/src/write/draw/round-number.js +5 -0
  137. package/src/write/draw/selectables.js +59 -0
  138. package/src/write/draw/separator.js +16 -0
  139. package/src/write/draw/set-paper-size.js +45 -0
  140. package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
  141. package/src/write/draw/staff-group.js +226 -0
  142. package/src/write/draw/staff-line.js +9 -0
  143. package/src/write/draw/staff.js +33 -0
  144. package/src/write/draw/tab-line.js +40 -0
  145. package/src/write/draw/tempo.js +45 -0
  146. package/src/write/draw/text.js +71 -0
  147. package/src/write/draw/tie.js +97 -0
  148. package/src/write/draw/triplet.js +46 -0
  149. package/src/write/draw/voice.js +102 -0
  150. package/src/write/format-jazz-chord.js +15 -0
  151. package/src/write/free-text.js +41 -0
  152. package/src/write/get-font-and-attr.js +37 -0
  153. package/src/write/get-text-size.js +56 -0
  154. package/src/write/highlight.js +11 -0
  155. package/src/write/layout/VoiceElements.js +121 -0
  156. package/src/write/layout/beam.js +213 -0
  157. package/src/write/layout/get-left-edge-of-staff.js +56 -0
  158. package/src/write/layout/getBarYAt.js +6 -0
  159. package/src/write/layout/layout.js +94 -0
  160. package/src/write/layout/setUpperAndLowerElements.js +232 -0
  161. package/src/write/layout/staffGroup.js +146 -0
  162. package/src/write/layout/triplet.js +75 -0
  163. package/src/write/layout/voice.js +137 -0
  164. package/src/write/selection.js +188 -70
  165. package/src/write/separator.js +10 -0
  166. package/src/write/set-class.js +21 -0
  167. package/src/write/subtitle.js +12 -0
  168. package/src/write/svg.js +95 -43
  169. package/src/write/top-text.js +54 -0
  170. package/src/write/unhighlight.js +11 -0
  171. package/temp.txt +17 -0
  172. package/test.js +27 -64
  173. package/types/index.d.ts +1095 -0
  174. package/version.js +1 -1
  175. package/.babelrc +0 -5
  176. package/.eslintrc +0 -3
  177. package/.gitmodules +0 -3
  178. package/abcjs-midi.css +0 -166
  179. package/build-utils/loadPresets.js +0 -14
  180. package/build-utils/presets/webpack.analyze.js +0 -6
  181. package/build-utils/presets/webpack.optimize.js +0 -30
  182. package/build-utils/webpack.development.js +0 -14
  183. package/build-utils/webpack.production.js +0 -35
  184. package/deploy-docs.sh +0 -25
  185. package/docs/README.md +0 -33
  186. package/fix-versions.sh +0 -23
  187. package/mei.js +0 -43
  188. package/midi.js +0 -62
  189. package/src/api/abc_tunebook_midi.js +0 -116
  190. package/src/midi/abc_midi_controls.js +0 -701
  191. package/src/midi/abc_midi_flattener.js +0 -1119
  192. package/src/midi/abc_midi_js_preparer.js +0 -243
  193. package/src/midi/abc_midi_sequencer.js +0 -401
  194. package/src/midi/abc_midi_ui_generator.js +0 -86
  195. package/src/plugin/abc_plugin_midi.js +0 -220
  196. package/src/synth/images/loop.svg +0 -61
  197. package/src/synth/images/pause.svg +0 -6
  198. package/src/synth/images/play.svg +0 -5
  199. package/src/transform/abc2abc_write.js +0 -395
  200. package/static-wrappers/basic.js +0 -2
  201. package/static-wrappers/midi.js +0 -2
  202. package/static-wrappers/plugin-midi.js +0 -6
  203. package/static-wrappers/plugin.js +0 -6
  204. package/webpack.config.js +0 -29
@@ -1,119 +1,161 @@
1
1
  // wrap_lines.js: does line wrap on an already parsed tune.
2
- // Copyright (C) 2018-2020 Paul Rosen (paul at paulrosen dot net)
3
- //
4
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
6
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
7
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
- //
9
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
- //
11
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
12
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
14
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
2
 
17
- function wrapLines(tune, lineBreaks) {
3
+ function wrapLines(tune, lineBreaks, barNumbers) {
18
4
  if (!lineBreaks || tune.lines.length === 0)
19
5
  return;
20
6
 
21
7
  // tune.lines contains nested arrays: there is an array of lines (that's the part this function rewrites),
22
8
  // there is an array of staffs per line (for instance, piano will have 2, orchestra will have many)
23
9
  // there is an array of voices per staff (for instance, 4-part harmony might have bass and tenor on a single staff)
24
- // The measure numbers start at zero for each staff, but on the succeeding lines, the measure numbers are reset to the beginning of the line.
25
- var newLines = [];
26
- // keep track of our counters for each staff and voice
27
- var startNewLine = [];
28
- var currentLine = [];
29
- var measureNumber = [];
30
- var measureMarker = [];
31
- var lastMeter = '';
32
- var voiceStart = {};
33
- var linesWithoutStaff = 0;
10
+ var lines = tune.deline({lineBreaks: false});
11
+ var linesBreakElements = findLineBreaks(lines, lineBreaks);
12
+ //console.log(JSON.stringify(linesBreakElements))
13
+ tune.lines = addLineBreaks(lines, linesBreakElements, barNumbers);
14
+ tune.lineBreaks = linesBreakElements;
15
+ }
34
16
 
35
- for (var i = 0; i < tune.lines.length; i++) {
36
- var line = tune.lines[i];
37
- if (line.staff) {
38
- var staffs = line.staff;
39
- for (var j = 0; j < staffs.length; j++) {
40
- if (startNewLine[j] === undefined) {
41
- startNewLine[j] = [];
42
- currentLine[j] = [];
43
- measureNumber[j] = [];
44
- measureMarker[j] = [];
17
+ function addLineBreaks(lines, linesBreakElements, barNumbers) {
18
+ // linesBreakElements is an array of all of the elements that break for a new line
19
+ // The objects in the array look like:
20
+ // {"ogLine":0,"line":0,"staff":0,"voice":0,"start":0, "end":21}
21
+ // ogLine is the original line that it came from,
22
+ // line is the target line.
23
+ // then copy all the elements from start to end for the staff and voice specified.
24
+ // If the item doesn't contain "staff" then it is a non music line and should just be copied.
25
+ var outputLines = [];
26
+ var lastKeySig = []; // This is per staff - if the key changed then this will be populated.
27
+ var lastStem = [];
28
+ var currentBarNumber = 1;
29
+ for (var i = 0; i < linesBreakElements.length; i++) {
30
+ var action = linesBreakElements[i];
31
+ if (lines[action.ogLine].staff) {
32
+ var inputStaff = lines[action.ogLine].staff[action.staff];
33
+ if (!outputLines[action.line]) {
34
+ outputLines[action.line] = {staff: []}
35
+ }
36
+ if (!outputLines[action.line].staff[action.staff]) {
37
+ outputLines[action.line].staff[action.staff] = {voices: []};
38
+ if (barNumbers !== undefined && action.staff === 0 && action.line > 0) {
39
+ outputLines[action.line].staff[action.staff].barNumber = currentBarNumber;
45
40
  }
46
- var staff = staffs[j];
47
- var voices = staff.voices;
48
- for (var k = 0; k < voices.length; k++) {
49
- if (startNewLine[j][k] === undefined) {
50
- startNewLine[j][k] = true;
51
- currentLine[j][k] = 0;
52
- measureNumber[j][k] = 0;
53
- measureMarker[j][k] = 0;
41
+ var keys = Object.keys(inputStaff)
42
+ for (var k = 0; k < keys.length; k++) {
43
+ var skip = keys[k] === "voices";
44
+ if (keys[k] === "meter" && action.line !== 0)
45
+ skip = true;
46
+ if (!skip)
47
+ outputLines[action.line].staff[action.staff][keys[k]] = inputStaff[keys[k]];
48
+ }
49
+ if (lastKeySig[action.staff])
50
+ outputLines[action.line].staff[action.staff].key = lastKeySig[action.staff];
51
+
52
+ }
53
+ if (!outputLines[action.line].staff[action.staff].voices[action.voice]) {
54
+ outputLines[action.line].staff[action.staff].voices[action.voice] = [];
55
+ }
56
+ outputLines[action.line].staff[action.staff].voices[action.voice] =
57
+ lines[action.ogLine].staff[action.staff].voices[action.voice].slice(action.start, action.end+1);
58
+ if (lastStem[action.staff*10+action.voice])
59
+ outputLines[action.line].staff[action.staff].voices[action.voice].unshift({el_type: "stem", direction: lastStem[action.staff*10+action.voice].direction})
60
+ var currVoice = outputLines[action.line].staff[action.staff].voices[action.voice];
61
+ for (var kk = currVoice.length-1; kk >= 0; kk--) {
62
+ if (currVoice[kk].el_type === "key") {
63
+ lastKeySig[action.staff] = {
64
+ root: currVoice[kk].root,
65
+ acc: currVoice[kk].acc,
66
+ mode: currVoice[kk].mode,
67
+ accidentals: currVoice[kk].accidentals.filter(function (acc) { return acc.acc !== 'natural' })
68
+ };
69
+ break;
70
+ }
71
+ }
72
+ for (kk = currVoice.length-1; kk >= 0; kk--) {
73
+ if (currVoice[kk].el_type === "stem") {
74
+ lastStem[action.staff*10+action.voice] = {
75
+ direction: currVoice[kk].direction,
76
+ };
77
+ break;
78
+ }
79
+ }
80
+ if (barNumbers !== undefined && action.staff === 0 && action.voice === 0) {
81
+ for (kk = 0; kk < currVoice.length; kk++) {
82
+ if (currVoice[kk].el_type === 'bar') {
83
+ currentBarNumber++
84
+ if (kk === currVoice.length-1)
85
+ delete currVoice[kk].barNumber
86
+ else
87
+ currVoice[kk].barNumber = currentBarNumber
54
88
  }
55
- if (linesWithoutStaff > 0) currentLine[j][k] += linesWithoutStaff;
56
- var voice = voices[k];
89
+ }
90
+ }
91
+ } else {
92
+ outputLines[action.line] = lines[action.ogLine];
93
+ }
94
+ }
95
+ // There could be some missing info - if the tune passed in was incomplete or had different lengths for different voices or was missing a voice altogether - just fill in the gaps.
96
+ for (var ii = 0; ii < outputLines.length; ii++) {
97
+ if (outputLines[ii].staff) {
98
+ outputLines[ii].staff = outputLines[ii].staff.filter(function (el) {
99
+ return el != null;
100
+ });
101
+ }
102
+ }
103
+ return outputLines;
104
+ }
105
+
106
+
107
+ function findLineBreaks(lines, lineBreakArray) {
108
+ // lineBreakArray is an array of all of the sections of the tune - often there will just be one
109
+ // section unless there is a subtitle or other non-music lines. Each of the elements of
110
+ // Each element of lineBreakArray is an array of the zero-based last measure of the line.
111
+ var lineBreakIndexes = [];
112
+ var lbai = 0;
113
+ var lineCounter = 0;
114
+ var outputLine = 0;
115
+ for (var i = 0; i < lines.length; i++) {
116
+ var line = lines[i];
117
+ if (line.staff) {
118
+ var lineStart = lineCounter;
119
+ var lineBreaks = lineBreakArray[lbai];
120
+ lbai++;
121
+ for (var j = 0; j < line.staff.length; j++) {
122
+ var staff = line.staff[j];
123
+ for (var k = 0; k < staff.voices.length; k++) {
124
+ outputLine = lineStart;
125
+ var measureNumber = 0;
126
+ var lbi = 0;
127
+ var voice = staff.voices[k];
128
+ var start = 0;
57
129
  for (var e = 0; e < voice.length; e++) {
58
- if (startNewLine[j][k]) {
59
- if (!newLines[currentLine[j][k]])
60
- newLines[currentLine[j][k]] = { staff: [] };
61
- if (!newLines[currentLine[j][k]].staff[j]) {
62
- newLines[currentLine[j][k]].staff[j] = {voices: []};
63
- for (var key in staff) {
64
- if (staff.hasOwnProperty(key)) {
65
- if (key === 'meter') {
66
- if (currentLine[j][k] === 0 || lastMeter !== JSON.stringify(staff[key])) {
67
- lastMeter = JSON.stringify(staff[key]);
68
- newLines[currentLine[j][k]].staff[j][key] = staff[key];
69
- }
70
- } else if (key !== 'voices') {
71
- newLines[currentLine[j][k]].staff[j][key] = staff[key];
72
- }
73
- }
74
- }
75
- }
76
- if (measureMarker[j][k])
77
- newLines[currentLine[j][k]].staff[j].barNumber = measureMarker[j][k];
78
- startNewLine[j][k] = false;
79
- }
80
- var element = voice[e];
81
- if (!newLines[currentLine[j][k]].staff[j].voices[k]) {
82
- newLines[currentLine[j][k]].staff[j].voices[k] = [];
83
- for (var startItem in voiceStart) {
84
- if (voiceStart.hasOwnProperty(startItem)) {
85
- newLines[currentLine[j][k]].staff[j].voices[k].push(voiceStart[startItem])
86
- }
130
+ var el = voice[e];
131
+
132
+ if (el.el_type === 'bar') {
133
+ if (lineBreaks[lbi] === measureNumber) {
134
+ lineBreakIndexes.push({ ogLine: i, line: outputLine, staff: j, voice: k, start: start, end: e})
135
+ start = e + 1;
136
+ outputLine++;
137
+ lineCounter = Math.max(lineCounter, outputLine)
138
+ lbi++;
87
139
  }
88
- }
89
- newLines[currentLine[j][k]].staff[j].voices[k].push(element);
90
- if (element.el_type === 'stem') {
91
- // This is a nice trick to just pay attention to the last setting of each type.
92
- voiceStart[element.el_type] = element;
93
- }
140
+ measureNumber++;
94
141
 
95
- if (element.el_type === 'bar') {
96
- measureNumber[j][k]++;
97
- if (lineBreaks[measureNumber[j][k]]) {
98
- startNewLine[j][k] = true;
99
- currentLine[j][k]++;
100
- measureMarker[j][k] = element.barNumber;
101
- delete element.barNumber;
102
- }
103
142
  }
104
143
  }
105
-
144
+ lineBreakIndexes.push({ ogLine: i, line: outputLine, staff: j, voice: k, start: start, end: voice.length})
145
+ outputLine++;
146
+ lineCounter = Math.max(lineCounter, outputLine)
106
147
  }
107
148
  }
108
- linesWithoutStaff = 0;
109
149
  } else {
110
- newLines.push(line);
111
- linesWithoutStaff++;
150
+ lineBreakIndexes.push({ ogLine: i, line: outputLine })
151
+ outputLine++;
152
+ lineCounter = Math.max(lineCounter, outputLine)
112
153
  }
113
154
  }
114
- tune.lines = newLines;
155
+ return lineBreakIndexes;
115
156
  }
116
157
 
158
+
117
159
  function freeFormLineBreaks(widths, lineBreakPoint) {
118
160
  var lineBreaks = [];
119
161
  var totals = [];
@@ -146,159 +188,6 @@ function freeFormLineBreaks(widths, lineBreakPoint) {
146
188
  return { lineBreaks: lineBreaks, totals: totals };
147
189
  }
148
190
 
149
- // function createLineTestArray(numLines, numMeasures, maxMeasuresPerLine, minMeasuresPerLine) {
150
- // var tries = [];
151
- // // To get all the iterations, it is every digit in a particular base-numbering system.
152
- // // That is, we want to generate every number that is (numLines-1) digits, in base (max-min+1)
153
- // // For instance, for 5 lines where the min is 6 and max is 8, we want ever combination of 4 digits in base 3.
154
- // var base = maxMeasuresPerLine - minMeasuresPerLine + 1;
155
- // var digits = numLines - 1; // The last digit is fixed: it is what ever is needed to sum up to the total number of measures.
156
- // var done = false;
157
- // var iter = 0;
158
- // while (!done) {
159
- // var attempt = [];
160
- // var num = iter;
161
- // var total = 0;
162
- // for (var d = digits - 1; d >= 0; d--) {
163
- // attempt[d] = (num % base) + minMeasuresPerLine;
164
- // num = Math.floor(num / base);
165
- // total += attempt[d];
166
- // }
167
- // if (num > 0)
168
- // done = true; // continue until we exceed the greatest number. We know because there is a remainer.
169
- // else {
170
- // var lastLine = numMeasures - total;
171
- // if (lastLine >= minMeasuresPerLine && lastLine <= maxMeasuresPerLine) {
172
- // attempt[digits] = lastLine;
173
- // tries.push(attempt);
174
- // }
175
- // iter++;
176
- // }
177
- // }
178
- // return tries;
179
- // }
180
-
181
- // function getVariance(attempt, idealLineBreak, widths, allowableOverage) {
182
- // var measureNumber = 0;
183
- // var thisWorstVariance = 0;
184
- // for (var j = 0; j < attempt.length; j++) {
185
- // var lineWidth = 0;
186
- // var measuresThisLine = attempt[j];
187
- // for (var k = 0; k < measuresThisLine; k++) {
188
- // lineWidth += widths[measureNumber++];
189
- // }
190
- // if (lineWidth > allowableOverage)
191
- // return null;
192
- // var variance = Math.abs(lineWidth - idealLineBreak);
193
- // if (variance > thisWorstVariance)
194
- // thisWorstVariance = variance;
195
- // }
196
- // return thisWorstVariance;
197
- // }
198
-
199
- // function getMaxVariance(widths, lineBreakPoint, lineBreaks) {
200
- // var maxVariance = 0;
201
- // var numLines = lineBreaks.length + 1; // the last line doesn't have an explicit break
202
- // var measureNumber = 0;
203
- // var totals = [];
204
- // for (var i = 0; i <= lineBreaks.length; i++) {
205
- // var breakMeasure = (i === lineBreaks.length) ? widths.length : lineBreaks[i];
206
- // var thisTotal = 0;
207
- // for (var j = measureNumber; j < breakMeasure; j++) {
208
- // thisTotal += widths[j];
209
- // }
210
- // measureNumber = breakMeasure;
211
- // var thisVariance = thisTotal <= lineBreakPoint ? lineBreakPoint - thisTotal : 1000000;
212
- // totals.push({total: thisTotal, variance: thisVariance})
213
- // maxVariance = Math.max(maxVariance, thisVariance);
214
- // }
215
- //
216
- // console.log(lineBreakPoint, totals)
217
- // return maxVariance;
218
- // }
219
-
220
- function getVariance(widths, lineBreaks) {
221
- var numLines = lineBreaks.length + 1; // the last line doesn't have an explicit break
222
- var avg = widths.total / numLines;
223
- var largestVariance = 0;
224
- var measureNumber = 0;
225
- for (var i = 0; i <= lineBreaks.length; i++) {
226
- var breakMeasure = (i === lineBreaks.length) ? widths.measureWidths.length-1 : lineBreaks[i];
227
- var thisVariance = lineVariance(widths.measureWidths, measureNumber, breakMeasure, avg);
228
- measureNumber = breakMeasure+1;
229
- largestVariance = Math.max(largestVariance, thisVariance);
230
- }
231
-
232
- return largestVariance;
233
- }
234
-
235
- // function getAvgVariance(widths, lineBreakPoint, lineBreaks) {
236
- // var totalVariance = 0;
237
- // var numLines = lineBreaks.length + 1; // the last line doesn't have an explicit break
238
- // var measureNumber = 0;
239
- // for (var i = 0; i <= lineBreaks.length; i++) {
240
- // var breakMeasure = (i === lineBreaks.length) ? widths.length : lineBreaks[i];
241
- // var thisTotal = 0;
242
- // for (var j = measureNumber; j < breakMeasure; j++) {
243
- // thisTotal += widths[j];
244
- // }
245
- // measureNumber = breakMeasure;
246
- // var thisVariance = Math.abs(lineBreakPoint - thisTotal);
247
- // totalVariance += thisVariance;
248
- // }
249
- //
250
- // return totalVariance / numLines;
251
- // }
252
-
253
- function lineVariance(widths, start, end, avg) {
254
- var thisTotal = lineWidth(widths, start, end);
255
- var thisVariance = Math.abs(avg - thisTotal);
256
- return thisVariance;
257
- }
258
-
259
- function lineWidth(widths, start, end) {
260
- var thisTotal = 0;
261
- for (var j = start; j <= end; j++)
262
- thisTotal += widths[j];
263
- return thisTotal;
264
- }
265
-
266
- // TODO-PER: For long pieces of music, this can get long, so stop finding the combinations at an arbitrary place.
267
- function getAttempts(widths, start, linesLeft, min, max, lastLines) {
268
- var MAX_COMBINATIONS = 1200;
269
- var acc = 0;
270
- var attempts = [];
271
- for (var i = start; i < widths.length && acc < max; i++) {
272
- acc += widths[i];
273
- if (acc > max)
274
- break;
275
- if (acc > min) {
276
- if (linesLeft > 0 && attempts.length < MAX_COMBINATIONS) {
277
- var nextLines = getAttempts(widths, i + 1, linesLeft - 1, min, max, lastLines);
278
- for (var j = 0; j < nextLines.length; j++)
279
- attempts.push([i].concat(nextLines[j]));
280
- }
281
- if (linesLeft === 1 && lastLines.indexOf(i) >= 0)
282
- attempts.push([i]);
283
- }
284
- }
285
- return attempts;
286
- }
287
-
288
- function lastLinePossibilities(widths, start, min, max) {
289
- var acc = 0;
290
- var possibilities = [];
291
- for (var i = widths.length-1; i >= 0; i--) {
292
- acc += widths[i];
293
- if (acc > max)
294
- break;
295
- if (acc > min && i < start) {
296
- possibilities.push(i-1);
297
- }
298
- }
299
- return possibilities;
300
- }
301
-
302
191
  function clone(arr) {
303
192
  var newArr = [];
304
193
  for (var i = 0; i < arr.length; i++)
@@ -361,8 +250,8 @@ function oneTry(measureWidths, idealWidths, accumulator, lineAccumulator, lineWi
361
250
  }
362
251
 
363
252
  function optimizeLineWidths(widths, lineBreakPoint, lineBreaks, explanation) {
364
- // figure out how many lines - That's one more than was tried before.
365
- var numLines = Math.ceil(widths.total / lineBreakPoint) + 1;
253
+ // figure out how many lines
254
+ var numLines = Math.ceil(widths.total / lineBreakPoint); // + 1 TODO-PER: this used to be plus one - not sure why
366
255
 
367
256
  // get the ideal width for a line (cumulative width / num lines) - approx the same as lineBreakPoint except for rounding
368
257
  var idealWidth = Math.floor(widths.total / numLines);
@@ -424,135 +313,6 @@ function optimizeLineWidths(widths, lineBreakPoint, lineBreaks, explanation) {
424
313
  }
425
314
  return { failed: false, lineBreaks: otherTries[smallestIndex].lineBreaks, variance: otherTries[smallestIndex].highestVariance };
426
315
  }
427
- // // Instead of having to try all the different combinations to find the best, we start with an important piece of knowledge about the lineBreaks we are given:
428
- // // If there is a line too short, it is the last one.
429
- // // So, let's just do a couple of tweaks to see how it works to add one or two measures to the last line.
430
- // var avg = widths.total / (lineBreaks.length + 1);
431
- // var variance = getVariance(widths, lineBreaks);
432
- // var variancePct = variance/lineBreakPoint*100;
433
- //
434
- // if (lineBreaks.length === 0)
435
- // return { failed: true, reason: "Only one line." };
436
- //
437
- // var lastLineStart = lineBreaks[lineBreaks.length-1]+1;
438
- // var lastLineVariance = lineVariance(widths.measureWidths, lastLineStart, widths.measureWidths.length, avg);
439
- // if (variance > lastLineVariance)
440
- // return { failed: true, reason: "Last line is not too short." };
441
- //
442
- // // Let's get a list of all combinations that have a possibility of working. That is, all combinations where no line has a variance larger than "variance".
443
- // var lastLines = lastLinePossibilities(widths.measureWidths, lastLineStart, avg - variance, avg + variance);
444
- // var attempts = getAttempts(widths.measureWidths, 0, lineBreaks.length, avg - variance, avg + variance, lastLines);
445
- // //console.log(attempts, avg - variance, avg + variance);
446
- //
447
- // var failed = true;
448
- // for (var i = 0; i < attempts.length; i++) {
449
- // var newVariance = getVariance(widths, attempts[i]);
450
- // if (newVariance < variance) {
451
- // explanation.attempts.push({
452
- // type: "Optimize try", lineBreaks: attempts[i],
453
- // variance: Math.round(variance), newVariance: Math.round(newVariance),
454
- // totalAttempts: attempts.length
455
- // });
456
- // variance = newVariance;
457
- // lineBreaks = attempts[i];
458
- // failed = false;
459
- // }
460
- // }
461
- // if (failed) {
462
- // explanation.attempts.push({ type: "Optimize try", lineBreaks: lineBreaks, variance: variance, reason: "None of the " + attempts.length + " attempts were better." });
463
- // // TODO-PER: This shouldn't be necessary, but just try to move one measure down and see if it helps.
464
- // if (lineBreaks.length > 0) {
465
- // var attempt = [].concat(lineBreaks);
466
- // attempt[attempt.length - 1]--;
467
- // newVariance = getVariance(widths, attempt);
468
- // explanation.attempts.push({
469
- // type: "Optimize last try", lineBreaks: attempts[i],
470
- // variance: Math.round(variance), newVariance: Math.round(newVariance),
471
- // totalAttempts: attempts.length
472
- // });
473
- // if (newVariance < variance) {
474
- // variance = newVariance;
475
- // lineBreaks = attempt;
476
- // failed = false;
477
- // }
478
- // }
479
- // }
480
- // // Let's squeeze the line successively until it spills onto an extra line, then take the option with the lowest variance
481
- // // var targetNumLines = lineBreaks.length;
482
- // // var newNumLines = targetNumLines;
483
- // // var TRY_INCREMENT = 1;
484
- // // var tryBreakPoint = lineBreakPoint - TRY_INCREMENT;
485
- // // var failed = true;
486
- // // while (targetNumLines === newNumLines && tryBreakPoint > 50) {
487
- // // var ff = freeFormLineBreaks(widths.measureWidths, tryBreakPoint);
488
- // // newNumLines = ff.lineBreaks.length;
489
- // // if (newNumLines === targetNumLines) {
490
- // // var newVariance = getVariance(widths, ff.lineBreaks);
491
- // // var newVariancePct = newVariance/tryBreakPoint*100;
492
- // // explanation.attempts.push({type: "Optimize try", tryBreakPoint: Math.round(tryBreakPoint), lineBreaks: ff.lineBreaks, totals: ff.totals,
493
- // // variance: Math.round(variance), newVariance: Math.round(newVariance), variancePct: Math.round(variancePct), newVariancePct: Math.round(newVariancePct)
494
- // // });
495
- // // if (newVariancePct < variancePct) {
496
- // // variancePct = newVariancePct;
497
- // // lineBreaks = ff.lineBreaks;
498
- // // failed = false;
499
- // // }
500
- // // } else {
501
- // // explanation.attempts.push({type: "Optimize try", explanation: "Exceeded number of lines." , tryBreakPoint: Math.round(tryBreakPoint), lineBreaks: ff.lineBreaks, totals: ff.totals, variance: variance, avg: avg, variancePct: variancePct});
502
- // // }
503
- // // tryBreakPoint -= TRY_INCREMENT;
504
- // // }
505
- //
506
- // return { failed: failed, lineBreaks: lineBreaks, variance: variance };
507
- // }
508
-
509
- // function fixedNumLinesBreaks(widths, numLines, allowOver, allowableVariance) {
510
- // var idealLineBreak = widths.total / numLines;
511
- // // If all the measures had the same amount of stuff, then the ave would be correct.
512
- // // We will test all the combinations from one less to one more than the average.
513
- // var averageMeasuresPerLine = Math.round(widths.measureWidths.length / numLines);
514
- // var minMeasuresPerLine = Math.max(averageMeasuresPerLine - 1, 1);
515
- // var maxMeasuresPerLine = averageMeasuresPerLine + 1;
516
- // var tries = createLineTestArray(numLines, widths.measureWidths.length, maxMeasuresPerLine, minMeasuresPerLine);
517
- // console.log("fixedNumLinesBreaks tests ("+minMeasuresPerLine+'-'+maxMeasuresPerLine+")", numLines, tries.length)
518
- //
519
- // // For each possible number of measures per line, see which has the closest spacing to the ideal.
520
- // var bestCase = -1;
521
- // var bestCaseVariance = 1000000;
522
- // for (var i = 0 ; i < tries.length; i++) {
523
- // var attempt = tries[i];
524
- // var variance = getVariance(attempt, idealLineBreak, widths.measureWidths, allowOver ? allowableVariance : 0);
525
- // if (variance !== null) {
526
- // if (variance < bestCaseVariance) {
527
- // bestCaseVariance = variance;
528
- // bestCase = i;
529
- // }
530
- // }
531
- // }
532
- // var failed = true;
533
- // // For debugging, recreate the line widths
534
- // var totals = [];
535
- // if (bestCase >= 0) {
536
- // failed = false;
537
- // var index = 0;
538
- // for (i = 0; i < tries[bestCase].length; i++) {
539
- // var total = 0;
540
- // for (var j = 0; j < tries[bestCase][i]; j++) {
541
- // total += widths.measureWidths[index++];
542
- // }
543
- // totals.push(Math.round(total));
544
- // }
545
- // // We now have an array that contains the number of measures per line, but we want to return the absolute measure number to break on.
546
- // if (tries[bestCase].length > 0) {
547
- // tries[bestCase][0]--; // The results should contain the last measure number on the line, zero-based.
548
- // for (i = 1; i < tries[bestCase].length; i++)
549
- // tries[bestCase][i] += tries[bestCase][i - 1]; // This sets the zero-based measure number
550
- // // The last line is implied and we don't need to return it
551
- // tries[bestCase].pop();
552
- // }
553
- // }
554
- // return { failed: failed, lineBreaks: tries[bestCase], bestCaseVariance: Math.round(bestCaseVariance), totals: totals };
555
- // }
556
316
 
557
317
  function fixedMeasureLineBreaks(widths, lineBreakPoint, preferredMeasuresPerLine) {
558
318
  var lineBreaks = [];
@@ -574,8 +334,8 @@ function fixedMeasureLineBreaks(widths, lineBreakPoint, preferredMeasuresPerLine
574
334
  return { failed: failed, totals: totals, lineBreaks: lineBreaks };
575
335
  }
576
336
 
577
- function getRevisedTune(lineBreaks, staffWidth, abcString, params, Parse) {
578
- var abcParser = new Parse();
337
+ function getRevisedTuneParams(lineBreaks, staffWidth, params) {
338
+
579
339
  var revisedParams = {
580
340
  lineBreaks: lineBreaks,
581
341
  staffwidth: staffWidth
@@ -586,21 +346,21 @@ function getRevisedTune(lineBreaks, staffWidth, abcString, params, Parse) {
586
346
  }
587
347
  }
588
348
 
589
- abcParser.parse(abcString, revisedParams);
590
- return { tune: abcParser.getTune(), revisedParams: revisedParams };
349
+ return { revisedParams: revisedParams };
591
350
  }
592
351
 
593
- function calcLineWraps(tune, widths, abcString, params, Parse, engraver_controller) {
352
+ function calcLineWraps(tune, widths, params) {
594
353
  // For calculating how much can go on the line, it depends on the width of the line. It is a convenience to just divide it here
595
354
  // by the minimum spacing instead of multiplying the min spacing later.
596
355
  // The scaling works differently: this is done by changing the scaling of the outer SVG, so the scaling needs to be compensated
597
356
  // for here, because the actual width will be different from the calculated numbers.
598
357
 
599
358
  // If the desired width is less than the margin, just punt and return the original tune
600
- if (params.staffwidth < widths.left) {
359
+ //console.log(widths)
360
+ if (widths.length === 0 || params.staffwidth < widths[0].left) {
601
361
  return {
602
- explanation: "Staffwidth is narrower than the margin",
603
- tune: tune,
362
+ reParse: false,
363
+ explanation: "Staff width is narrower than the margin",
604
364
  revisedParams: params
605
365
  };
606
366
  }
@@ -610,80 +370,72 @@ function calcLineWraps(tune, widths, abcString, params, Parse, engraver_controll
610
370
  var maxSpacing = params.wrap.maxSpacing ? Math.max(parseFloat(params.wrap.maxSpacing), 1) : undefined;
611
371
  if (params.wrap.lastLineLimit && !maxSpacing)
612
372
  maxSpacing = Math.max(parseFloat(params.wrap.lastLineLimit), 1);
613
- var targetHeight = params.wrap.targetHeight ? Math.max(parseInt(params.wrap.targetHeight, 10), 100) : undefined;
614
- var preferredMeasuresPerLine = params.wrap.preferredMeasuresPerLine ? Math.max(parseInt(params.wrap.preferredMeasuresPerLine, 10), 1) : undefined;
615
-
616
- var lineBreakPoint = (params.staffwidth - widths.left) / minSpacing / scale;
617
- var minLineSize = (params.staffwidth - widths.left) / maxSpacing / scale;
618
- var allowableVariance = (params.staffwidth - widths.left) / minSpacingLimit / scale;
619
- var explanation = { widths: widths, lineBreakPoint: lineBreakPoint, minLineSize: minLineSize, attempts: [], staffWidth: params.staffwidth, minWidth: Math.round(allowableVariance) };
620
-
621
- // If there is a preferred number of measures per line, test that first. If none of the lines is too long, then we're finished.
622
- var lineBreaks = null;
623
- if (preferredMeasuresPerLine) {
624
- var f = fixedMeasureLineBreaks(widths.measureWidths, lineBreakPoint, preferredMeasuresPerLine);
625
- explanation.attempts.push({ type: "Fixed Measures Per Line", preferredMeasuresPerLine: preferredMeasuresPerLine, lineBreaks: f.lineBreaks, failed: f.failed, totals: f.totals });
626
- if (!f.failed)
627
- lineBreaks = f.lineBreaks;
628
- }
373
+ // var targetHeight = params.wrap.targetHeight ? Math.max(parseInt(params.wrap.targetHeight, 10), 100) : undefined;
374
+ var preferredMeasuresPerLine = params.wrap.preferredMeasuresPerLine ? Math.max(parseInt(params.wrap.preferredMeasuresPerLine, 10), 0) : undefined;
375
+
376
+ var accumulatedLineBreaks = [];
377
+ var explanations = [];
378
+ for (var s = 0; s < widths.length; s++) {
379
+ var section = widths[s];
380
+ var usableWidth = params.staffwidth - section.left;
381
+ var lineBreakPoint = usableWidth / minSpacing / scale;
382
+ var minLineSize = usableWidth / maxSpacing / scale;
383
+ var allowableVariance = usableWidth / minSpacingLimit / scale;
384
+ var explanation = {
385
+ widths: section,
386
+ lineBreakPoint: lineBreakPoint,
387
+ minLineSize: minLineSize,
388
+ attempts: [],
389
+ staffWidth: params.staffwidth,
390
+ minWidth: Math.round(allowableVariance)
391
+ };
629
392
 
630
- // If we don't have lineBreaks yet, use the free form method of line breaks.
631
- // This will be called either if Preferred Measures is not used, or if the music is just weird - like a single measure is way too crowded.
632
- if (!lineBreaks) {
633
- var ff = freeFormLineBreaks(widths.measureWidths, lineBreakPoint);
634
- explanation.attempts.push({ type: "Free Form", lineBreaks: ff.lineBreaks, totals: ff.totals });
635
- lineBreaks = ff.lineBreaks;
393
+ // If there is a preferred number of measures per line, test that first. If none of the lines is too long, then we're finished.
394
+ var lineBreaks = null;
395
+ if (preferredMeasuresPerLine) {
396
+ var f = fixedMeasureLineBreaks(section.measureWidths, lineBreakPoint, preferredMeasuresPerLine);
397
+ explanation.attempts.push({
398
+ type: "Fixed Measures Per Line",
399
+ preferredMeasuresPerLine: preferredMeasuresPerLine,
400
+ lineBreaks: f.lineBreaks,
401
+ failed: f.failed,
402
+ totals: f.totals
403
+ });
404
+ if (!f.failed)
405
+ lineBreaks = f.lineBreaks;
406
+ }
636
407
 
637
- // We now have an acceptable number of lines, but the measures may not be optimally distributed. See if there is a better distribution.
638
- ff = optimizeLineWidths(widths, lineBreakPoint, lineBreaks, explanation);
639
- explanation.attempts.push({ type: "Optimize", failed: ff.failed, reason: ff.reason, lineBreaks: ff.lineBreaks, totals: ff.totals });
640
- if (!ff.failed)
408
+ // If we don't have lineBreaks yet, use the free form method of line breaks.
409
+ // This will be called either if Preferred Measures is not used, or if the music is just weird - like a single measure is way too crowded.
410
+ if (!lineBreaks) {
411
+ var ff = freeFormLineBreaks(section.measureWidths, lineBreakPoint);
412
+ explanation.attempts.push({type: "Free Form", lineBreaks: ff.lineBreaks, totals: ff.totals});
641
413
  lineBreaks = ff.lineBreaks;
642
- }
643
414
 
415
+ // We now have an acceptable number of lines, but the measures may not be optimally distributed. See if there is a better distribution.
416
+ if (lineBreaks.length > 0 && section.measureWidths.length < 25) {
417
+ // Only do this if everything doesn't fit on one line.
418
+ // This is an intensive operation and it is optional so just do it for shorter music.
419
+ ff = optimizeLineWidths(section, lineBreakPoint, lineBreaks, explanation);
420
+ explanation.attempts.push({
421
+ type: "Optimize",
422
+ failed: ff.failed,
423
+ reason: ff.reason,
424
+ lineBreaks: ff.lineBreaks,
425
+ totals: ff.totals
426
+ });
427
+ if (!ff.failed)
428
+ lineBreaks = ff.lineBreaks;
429
+ }
430
+ }
431
+ accumulatedLineBreaks.push(lineBreaks);
432
+ explanations.push(explanation);
433
+ }
644
434
  // If the vertical space exceeds targetHeight, remove a line and try again. If that is too crowded, then don't use it.
645
435
  var staffWidth = params.staffwidth;
646
- var ret = getRevisedTune(lineBreaks, staffWidth, abcString, params, Parse);
647
- var newWidths = engraver_controller.getMeasureWidths(ret.tune);
648
- var gotTune = true; // If we adjust the num lines, set this to false
649
- explanation.attempts.push({type: "heightCheck", height: newWidths.height });
650
-
651
- // if all of the lines are too sparse, make the width narrower.
652
- // TODO-PER: implement this case.
653
-
654
- // If one line and the spacing is > maxSpacing, make the width narrower.
655
- if (lineBreaks.length === 0 && minLineSize > widths.total) {
656
- staffWidth = (widths.total * maxSpacing * scale) + widths.left;
657
- explanation.attempts.push({type: "too sparse", newWidth: Math.round(staffWidth)})
658
- gotTune = false;
659
- }
660
-
661
- // if (ret.lineBreaks.length === 0) {
662
- // // Everything fits on one line, so see if there is TOO much space and the staff width needs to be shortened.
663
- // if (minLineSize > 0 && ret.totalThisLine > 0 && ret.totalThisLine < minLineSize)
664
- // staffWidth = staffWidth / (minLineSize / ret.totalThisLine);
665
- // } else if (ret.totalThisLine < minLineSize) {
666
- // // the last line is too short, so attempt to redistribute by changing the min.
667
- // // We will try more and less space alternatively. The space can't be less than 1.0, and we'll try in 0.1 increments.
668
- // var minTrys = [];
669
- // if (minSpacing > 1.1)
670
- // minTrys.push(minSpacing - 0.1);
671
- // minTrys.push(minSpacing + 0.1);
672
- // if (minSpacing > 1.2)
673
- // minTrys.push(minSpacing - 0.2);
674
- // minTrys.push(minSpacing + 0.2);
675
- // if (minSpacing > 1.3)
676
- // minTrys.push(minSpacing - 0.3);
677
- // minTrys.push(minSpacing + 0.3);
678
- // for (var i = 0; i < minTrys.length && ret.totalThisLine < minLineSize; i++) {
679
- // lineBreakPoint = (params.staffwidth - widths.left) / minTrys[i] / scale;
680
- // ret = calcLineBreaks(widths.measureWidths, lineBreakPoint);
681
- // }
682
- // }
683
-
684
- if (!gotTune)
685
- ret = getRevisedTune(lineBreaks, staffWidth, abcString, params, Parse);
686
- ret.explanation = explanation;
436
+ var ret = getRevisedTuneParams(accumulatedLineBreaks, staffWidth, params);
437
+ ret.explanation = explanations;
438
+ ret.reParse = true;
687
439
  return ret;
688
440
  }
689
441