abcjs 6.1.9 → 6.2.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 (129) hide show
  1. package/RELEASE.md +42 -0
  2. package/dist/abcjs-basic-min.js +2 -2
  3. package/dist/abcjs-basic.js +4318 -4411
  4. package/dist/abcjs-basic.js.map +1 -1
  5. package/dist/abcjs-plugin-min.js +2 -2
  6. package/index.js +1 -1
  7. package/package.json +1 -1
  8. package/plugin.js +1 -1
  9. package/src/api/abc_timing_callbacks.js +7 -3
  10. package/src/api/abc_tunebook_svg.js +1 -2
  11. package/src/data/abc_tune.js +2 -2
  12. package/src/parse/abc_common.js +0 -47
  13. package/src/parse/abc_parse.js +16 -16
  14. package/src/parse/abc_parse_book.js +3 -3
  15. package/src/parse/abc_parse_directive.js +26 -7
  16. package/src/parse/abc_parse_header.js +11 -9
  17. package/src/parse/abc_parse_key_voice.js +17 -17
  18. package/src/parse/abc_parse_music.js +88 -105
  19. package/src/parse/abc_tokenizer.js +60 -60
  20. package/src/parse/tune-builder.js +19 -14
  21. package/src/synth/abc_midi_flattener.js +25 -9
  22. package/src/synth/create-synth.js +41 -0
  23. package/src/synth/note-to-midi.js +50 -0
  24. package/src/tablatures/instruments/guitar/tab-guitar.js +0 -2
  25. package/src/tablatures/instruments/string-patterns.js +46 -28
  26. package/src/tablatures/instruments/tab-note.js +26 -103
  27. package/src/tablatures/instruments/violin/tab-violin.js +0 -2
  28. package/src/tablatures/tab-absolute-elements.js +9 -31
  29. package/src/tablatures/tab-renderer.js +2 -2
  30. package/src/test/abc_parser_lint.js +7 -4
  31. package/src/write/README.md +31 -0
  32. package/src/write/creation/abstract-engraver.js +1036 -0
  33. package/src/write/creation/add-chord.js +102 -0
  34. package/src/write/{add-text-if.js → creation/add-text-if.js} +6 -6
  35. package/src/write/{calcHeight.js → creation/calc-height.js} +2 -2
  36. package/src/write/creation/create-clef.js +72 -0
  37. package/src/write/creation/create-key-signature.js +31 -0
  38. package/src/write/creation/create-note-head.js +107 -0
  39. package/src/write/creation/create-time-signature.js +55 -0
  40. package/src/write/creation/decoration.js +357 -0
  41. package/src/write/{abc_absolute_element.js → creation/elements/absolute-element.js} +14 -15
  42. package/src/write/creation/elements/beam-element.js +113 -0
  43. package/src/write/{bottom-text.js → creation/elements/bottom-text.js} +14 -15
  44. package/src/write/{abc_brace_element.js → creation/elements/brace-element.js} +5 -5
  45. package/src/write/creation/elements/free-text.js +41 -0
  46. package/src/write/{abc_relative_element.js → creation/elements/relative-element.js} +7 -7
  47. package/src/write/{separator.js → creation/elements/separator.js} +2 -2
  48. package/src/write/{abc_staff_group_element.js → creation/elements/staff-group-element.js} +4 -4
  49. package/src/write/{subtitle.js → creation/elements/subtitle.js} +3 -3
  50. package/src/write/creation/elements/tempo-element.js +63 -0
  51. package/src/write/{abc_tie_element.js → creation/elements/tie-element.js} +15 -11
  52. package/src/write/{top-text.js → creation/elements/top-text.js} +12 -12
  53. package/src/write/creation/elements/triplet-element.js +28 -0
  54. package/src/write/{abc_voice_element.js → creation/elements/voice-element.js} +3 -3
  55. package/src/write/creation/glyphs.js +226 -0
  56. package/src/write/creation/translate-chord.js +37 -0
  57. package/src/write/draw/absolute.js +5 -5
  58. package/src/write/draw/beam.js +8 -8
  59. package/src/write/draw/brace.js +33 -33
  60. package/src/write/draw/crescendo.js +4 -4
  61. package/src/write/draw/debug-box.js +1 -1
  62. package/src/write/draw/draw.js +7 -7
  63. package/src/write/draw/dynamics.js +2 -2
  64. package/src/write/draw/ending.js +6 -6
  65. package/src/write/draw/glissando.js +17 -17
  66. package/src/write/draw/group-elements.js +51 -51
  67. package/src/write/draw/horizontal-line.js +9 -9
  68. package/src/write/draw/non-music.js +1 -1
  69. package/src/write/draw/print-line.js +15 -16
  70. package/src/write/draw/print-stem.js +5 -5
  71. package/src/write/draw/print-symbol.js +12 -12
  72. package/src/write/draw/print-vertical-line.js +8 -8
  73. package/src/write/draw/relative.js +17 -16
  74. package/src/write/draw/selectables.js +5 -5
  75. package/src/write/draw/separator.js +4 -4
  76. package/src/write/draw/set-paper-size.js +2 -2
  77. package/src/write/draw/sprintf.js +31 -31
  78. package/src/write/draw/staff-group.js +36 -30
  79. package/src/write/draw/staff-line.js +2 -2
  80. package/src/write/draw/staff.js +4 -4
  81. package/src/write/draw/tab-line.js +26 -26
  82. package/src/write/draw/tempo.js +30 -30
  83. package/src/write/draw/text.js +5 -5
  84. package/src/write/draw/tie.js +18 -18
  85. package/src/write/draw/triplet.js +6 -6
  86. package/src/write/draw/voice.js +16 -17
  87. package/src/write/{abc_engraver_controller.js → engraver-controller.js} +58 -51
  88. package/src/write/{classes.js → helpers/classes.js} +6 -6
  89. package/src/write/{get-font-and-attr.js → helpers/get-font-and-attr.js} +9 -7
  90. package/src/write/{get-text-size.js → helpers/get-text-size.js} +5 -5
  91. package/src/write/{set-class.js → helpers/set-class.js} +1 -1
  92. package/src/write/{abc_spacing.js → helpers/spacing.js} +1 -1
  93. package/src/write/{highlight.js → interactive/highlight.js} +1 -1
  94. package/src/write/{selection.js → interactive/selection.js} +27 -27
  95. package/src/write/{unhighlight.js → interactive/unhighlight.js} +1 -1
  96. package/src/write/layout/beam.js +13 -13
  97. package/src/write/layout/get-left-edge-of-staff.js +4 -4
  98. package/src/write/layout/layout.js +74 -74
  99. package/src/write/layout/{setUpperAndLowerElements.js → set-upper-and-lower-elements.js} +8 -8
  100. package/src/write/layout/{staffGroup.js → staff-group.js} +32 -32
  101. package/src/write/layout/triplet.js +4 -4
  102. package/src/write/layout/{VoiceElements.js → voice-elements.js} +23 -23
  103. package/src/write/layout/voice.js +6 -6
  104. package/src/write/{abc_renderer.js → renderer.js} +35 -32
  105. package/src/write/svg.js +35 -35
  106. package/test.js +1 -1
  107. package/types/index.d.ts +36 -7
  108. package/version.js +1 -1
  109. package/src/tablatures/instruments/guitar/guitar-fonts.js +0 -19
  110. package/src/tablatures/instruments/violin/violin-fonts.js +0 -19
  111. package/src/tablatures/transposer.js +0 -110
  112. package/src/write/abc_abstract_engraver.js +0 -1026
  113. package/src/write/abc_beam_element.js +0 -113
  114. package/src/write/abc_create_clef.js +0 -72
  115. package/src/write/abc_create_key_signature.js +0 -33
  116. package/src/write/abc_create_note_head.js +0 -107
  117. package/src/write/abc_create_time_signature.js +0 -55
  118. package/src/write/abc_decoration.js +0 -357
  119. package/src/write/abc_glyphs.js +0 -224
  120. package/src/write/abc_tempo_element.js +0 -63
  121. package/src/write/abc_triplet_element.js +0 -28
  122. package/src/write/add-chord.js +0 -103
  123. package/src/write/format-jazz-chord.js +0 -15
  124. package/src/write/free-text.js +0 -41
  125. /package/src/write/{abc_crescendo_element.js → creation/elements/crescendo-element.js} +0 -0
  126. /package/src/write/{abc_dynamic_decoration.js → creation/elements/dynamic-decoration.js} +0 -0
  127. /package/src/write/{abc_ending_element.js → creation/elements/ending-element.js} +0 -0
  128. /package/src/write/{abc_glissando_element.js → creation/elements/glissando-element.js} +0 -0
  129. /package/src/write/layout/{getBarYAt.js → get-bar-y-at.js} +0 -0
@@ -8,37 +8,37 @@ function drawTempo(renderer, params) {
8
8
 
9
9
  //var tempoGroup;
10
10
  params.tempo.el_type = "tempo";
11
- // renderer.wrapInAbsElem(params.tempo, "abcjs-tempo", function () {
12
- //renderer.paper.openGroup({klass: renderer.controller.classes.generate("tempo wha")});
13
- // The text is aligned with extra room for descenders but numbers look like they are a little too high, so bump it a little.
11
+ // renderer.wrapInAbsElem(params.tempo, "abcjs-tempo", function () {
12
+ //renderer.paper.openGroup({klass: renderer.controller.classes.generate("tempo wha")});
13
+ // The text is aligned with extra room for descenders but numbers look like they are a little too high, so bump it a little.
14
14
  var descenderHeight = 2;
15
- var y = renderer.calcY(params.pitch) + 2;
16
- var text;
17
- var size;
18
- if (params.tempo.preString) {
19
- text = renderText(renderer, {x:x, y: y, text: params.tempo.preString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, "dominant-baseline": "ideographic", name: "pre"}, true);
20
- size = renderer.controller.getTextSize.calc(params.tempo.preString, 'tempofont', 'tempo', text);
21
- var preWidth = size.width;
22
- var charWidth = preWidth / params.tempo.preString.length; // Just get some average number to increase the spacing.
23
- x += preWidth + charWidth;
24
- }
25
- if (params.note) {
26
- params.note.setX(x);
27
- for (var i = 0; i < params.note.children.length; i++)
28
- drawRelativeElement(renderer, params.note.children[i], x);
29
- x += (params.note.w + 5);
30
- var str = "= " + params.tempo.bpm;
31
- text = renderText(renderer, {x:x, y: y, text: str, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "beats"});
32
- size = renderer.controller.getTextSize.calc(str, 'tempofont', 'tempo', text);
33
- var postWidth = size.width;
34
- var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
35
- x += postWidth + charWidth2;
36
- }
37
- if (params.tempo.postString) {
38
- renderText(renderer, {x:x, y: y, text: params.tempo.postString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "post"}, true);
39
- }
40
- //tempoGroup = renderer.paper.closeGroup();
41
- // });
15
+ var y = renderer.calcY(params.pitch) + 2;
16
+ var text;
17
+ var size;
18
+ if (params.tempo.preString) {
19
+ text = renderText(renderer, { x: x, y: y, text: params.tempo.preString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, "dominant-baseline": "ideographic", name: "pre" }, true);
20
+ size = renderer.controller.getTextSize.calc(params.tempo.preString, 'tempofont', 'tempo', text);
21
+ var preWidth = size.width;
22
+ var charWidth = preWidth / params.tempo.preString.length; // Just get some average number to increase the spacing.
23
+ x += preWidth + charWidth;
24
+ }
25
+ if (params.note) {
26
+ params.note.setX(x);
27
+ for (var i = 0; i < params.note.children.length; i++)
28
+ drawRelativeElement(renderer, params.note.children[i], x);
29
+ x += (params.note.w + 5);
30
+ var str = "= " + params.tempo.bpm;
31
+ text = renderText(renderer, { x: x, y: y, text: str, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "beats" });
32
+ size = renderer.controller.getTextSize.calc(str, 'tempofont', 'tempo', text);
33
+ var postWidth = size.width;
34
+ var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
35
+ x += postWidth + charWidth2;
36
+ }
37
+ if (params.tempo.postString) {
38
+ renderText(renderer, { x: x, y: y, text: params.tempo.postString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true, name: "post" }, true);
39
+ }
40
+ //tempoGroup = renderer.paper.closeGroup();
41
+ // });
42
42
  //return [tempoGroup];
43
43
  }
44
44
 
@@ -3,7 +3,7 @@ var roundNumber = require("./round-number");
3
3
  function renderText(renderer, params, alreadyInGroup) {
4
4
  var y = params.y;
5
5
  if (params.lane) {
6
- var laneMargin = params.dim.font.size*0.25;
6
+ var laneMargin = params.dim.font.size * 0.25;
7
7
  y += (params.dim.font.size + laneMargin) * params.lane;
8
8
  }
9
9
 
@@ -12,7 +12,7 @@ function renderText(renderer, params, alreadyInGroup) {
12
12
  hash = params.dim;
13
13
  hash.attr.class = params.klass;
14
14
  } else
15
- hash = renderer.controller.getFontAndAttr.calc(params.type, params.klass);
15
+ hash = renderer.controller.getFontAndAttr.calc(params.type, params.klass);
16
16
  if (params.anchor)
17
17
  hash.attr["text-anchor"] = params.anchor;
18
18
  hash.attr.x = params.x;
@@ -32,7 +32,7 @@ function renderText(renderer, params, alreadyInGroup) {
32
32
 
33
33
  if (hash.font.box) {
34
34
  if (!alreadyInGroup)
35
- renderer.paper.openGroup({klass: hash.attr['class'], fill: renderer.foregroundColor, "data-name": params.name});
35
+ renderer.paper.openGroup({ klass: hash.attr['class'], fill: renderer.foregroundColor, "data-name": params.name });
36
36
  if (hash.attr["text-anchor"] === "end") {
37
37
  hash.attr.x -= hash.font.padding;
38
38
  } else if (hash.attr["text-anchor"] === "start") {
@@ -53,7 +53,7 @@ function renderText(renderer, params, alreadyInGroup) {
53
53
 
54
54
  var delta = 0;
55
55
  if (hash.attr["text-anchor"] === "middle") {
56
- delta = size.width / 2 + hash.font.padding;
56
+ delta = size.width / 2 + hash.font.padding;
57
57
  } else if (hash.attr["text-anchor"] === "end") {
58
58
  delta = size.width + hash.font.padding * 2;
59
59
  }
@@ -61,7 +61,7 @@ function renderText(renderer, params, alreadyInGroup) {
61
61
  if (params.centerVertically) {
62
62
  deltaY = size.height - hash.font.padding;
63
63
  }
64
- renderer.paper.rect({ "data-name": "box", x: Math.round(params.x - delta), y: Math.round(y - deltaY), width: Math.round(size.width + hash.font.padding*2), height: Math.round(size.height + hash.font.padding*2)});
64
+ renderer.paper.rect({ "data-name": "box", x: Math.round(params.x - delta), y: Math.round(y - deltaY), width: Math.round(size.width + hash.font.padding * 2), height: Math.round(size.height + hash.font.padding * 2) });
65
65
  if (!alreadyInGroup)
66
66
  elem = renderer.paper.closeGroup();
67
67
  }
@@ -15,8 +15,8 @@ function drawTie(renderer, params, linestartx, lineendx, selectables) {
15
15
  klass += ' abcjs-end-edge';
16
16
  if (params.hint)
17
17
  klass = "abcjs-hint";
18
- var fudgeY = params.fixedY ? 1.5 : 0; // TODO-PER: This just compensates for drawArc, which contains too much knowledge of ties and slurs.
19
- var el = drawArc(renderer, params.startX, params.endX, params.startY+fudgeY, params.endY+fudgeY, params.above, klass, params.isTie, params.dotted);
18
+ var fudgeY = params.fixedY ? 1.5 : 0; // TODO-PER: This just compensates for drawArc, which contains too much knowledge of ties and slurs.
19
+ var el = drawArc(renderer, params.startX, params.endX, params.startY + fudgeY, params.endY + fudgeY, params.above, klass, params.isTie, params.dotted);
20
20
  selectables.wrapSvgEl({ el_type: "slur", startChar: -1, endChar: -1 }, el);
21
21
  return [el];
22
22
  }
@@ -46,32 +46,32 @@ var layout = function (params, lineStartX, lineEndX) {
46
46
  params.avoidCollisionAbove();
47
47
  };
48
48
 
49
- var drawArc = function(renderer, x1, x2, pitch1, pitch2, above, klass, isTie, dotted) {
49
+ var drawArc = function (renderer, x1, x2, pitch1, pitch2, above, klass, isTie, dotted) {
50
50
  // If it is a tie vs. a slur, draw it shallower.
51
51
  var spacing = isTie ? 1.2 : 1.5;
52
52
 
53
53
  x1 = roundNumber(x1 + 6);
54
54
  x2 = roundNumber(x2 + 4);
55
- pitch1 = pitch1 + ((above)?spacing:-spacing);
56
- pitch2 = pitch2 + ((above)?spacing:-spacing);
55
+ pitch1 = pitch1 + ((above) ? spacing : -spacing);
56
+ pitch2 = pitch2 + ((above) ? spacing : -spacing);
57
57
  var y1 = roundNumber(renderer.calcY(pitch1));
58
58
  var y2 = roundNumber(renderer.calcY(pitch2));
59
59
 
60
60
  //unit direction vector
61
- var dx = x2-x1;
62
- var dy = y2-y1;
63
- var norm= Math.sqrt(dx*dx+dy*dy);
64
- var ux = dx/norm;
65
- var uy = dy/norm;
61
+ var dx = x2 - x1;
62
+ var dy = y2 - y1;
63
+ var norm = Math.sqrt(dx * dx + dy * dy);
64
+ var ux = dx / norm;
65
+ var uy = dy / norm;
66
66
 
67
- var flatten = norm/3.5;
67
+ var flatten = norm / 3.5;
68
68
  var maxFlatten = isTie ? 10 : 25; // If it is a tie vs. a slur, draw it shallower.
69
- var curve = ((above)?-1:1)*Math.min(maxFlatten, Math.max(4, flatten));
69
+ var curve = ((above) ? -1 : 1) * Math.min(maxFlatten, Math.max(4, flatten));
70
70
 
71
- var controlx1 = roundNumber(x1+flatten*ux-curve*uy);
72
- var controly1 = roundNumber(y1+flatten*uy+curve*ux);
73
- var controlx2 = roundNumber(x2-flatten*ux-curve*uy);
74
- var controly2 = roundNumber(y2-flatten*uy+curve*ux);
71
+ var controlx1 = roundNumber(x1 + flatten * ux - curve * uy);
72
+ var controly1 = roundNumber(y1 + flatten * uy + curve * ux);
73
+ var controlx2 = roundNumber(x2 - flatten * ux - curve * uy);
74
+ var controly2 = roundNumber(y2 - flatten * uy + curve * ux);
75
75
  var thickness = 2;
76
76
  if (klass)
77
77
  klass += ' slur';
@@ -83,12 +83,12 @@ var drawArc = function(renderer, x1, x2, pitch1, pitch2, above, klass, isTie, do
83
83
  klass += ' dotted';
84
84
  var pathString2 = sprintf("M %f %f C %f %f %f %f %f %f", x1, y1,
85
85
  controlx1, controly1, controlx2, controly2, x2, y2);
86
- ret = renderer.paper.path({path:pathString2, stroke:renderer.foregroundColor, fill:"none", 'stroke-dasharray': "5 5", 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur"});
86
+ ret = renderer.paper.path({ path: pathString2, stroke: renderer.foregroundColor, fill: "none", 'stroke-dasharray': "5 5", 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" });
87
87
  } else {
88
88
  var pathString = sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z", x1, y1,
89
89
  controlx1, controly1, controlx2, controly2, x2, y2,
90
90
  roundNumber(controlx2 - thickness * uy), roundNumber(controly2 + thickness * ux), roundNumber(controlx1 - thickness * uy), roundNumber(controly1 + thickness * ux), x1, y1);
91
- ret = renderer.paper.path({path:pathString, stroke:"none", fill:renderer.foregroundColor, 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur"});
91
+ ret = renderer.paper.path({ path: pathString, stroke: "none", fill: renderer.foregroundColor, 'class': renderer.controller.classes.generate(klass), "data-name": isTie ? "tie" : "slur" });
92
92
  }
93
93
 
94
94
  return ret;
@@ -4,12 +4,12 @@ var printPath = require('./print-path');
4
4
  var roundNumber = require("./round-number");
5
5
 
6
6
  function drawTriplet(renderer, params, selectables) {
7
- renderer.paper.openGroup({ klass: renderer.controller.classes.generate('triplet '+params.durationClass), "data-name": "triplet"});
7
+ renderer.paper.openGroup({ klass: renderer.controller.classes.generate('triplet ' + params.durationClass), "data-name": "triplet" });
8
8
  if (!params.hasBeam) {
9
9
  drawBracket(renderer, params.anchor1.x, params.startNote, params.anchor2.x + params.anchor2.w, params.endNote);
10
10
  }
11
11
  // HACK: adjust the position of "3". It is too high in all cases so we fudge it by subtracting 1 here.
12
- renderText(renderer, {x: params.xTextPos, y: renderer.calcY(params.yTextPos - 1), text: "" + params.number, type: 'tripletfont', anchor: "middle", centerVertically: true, noClass: true, name: ""+params.number}, true);
12
+ renderText(renderer, { x: params.xTextPos, y: renderer.calcY(params.yTextPos - 1), text: "" + params.number, type: 'tripletfont', anchor: "middle", centerVertically: true, noClass: true, name: "" + params.number }, true);
13
13
  var g = renderer.paper.closeGroup();
14
14
  selectables.wrapSvgEl({ el_type: "triplet", startChar: -1, endChar: -1 }, g);
15
15
  return g;
@@ -30,17 +30,17 @@ function drawBracket(renderer, x1, y1, x2, y2) {
30
30
  pathString += drawLine(x2, y2, x2, y2 + bracketHeight);
31
31
 
32
32
  // figure out midpoints to draw the broken line.
33
- var midX = x1 + (x2-x1)/2;
33
+ var midX = x1 + (x2 - x1) / 2;
34
34
  //var midY = y1 + (y2-y1)/2;
35
35
  var gapWidth = 8;
36
36
  var slope = (y2 - y1) / (x2 - x1);
37
37
  var leftEndX = midX - gapWidth;
38
38
  var leftEndY = y1 + (leftEndX - x1) * slope;
39
- pathString += drawLine( x1, y1, leftEndX, leftEndY);
39
+ pathString += drawLine(x1, y1, leftEndX, leftEndY);
40
40
  var rightStartX = midX + gapWidth;
41
41
  var rightStartY = y1 + (rightStartX - x1) * slope;
42
- pathString += drawLine( rightStartX, rightStartY, x2, y2);
43
- printPath(renderer, {path: pathString, stroke: renderer.foregroundColor, "data-name": "triplet-bracket"});
42
+ pathString += drawLine(rightStartX, rightStartY, x2, y2);
43
+ printPath(renderer, { path: pathString, stroke: renderer.foregroundColor, "data-name": "triplet-bracket" });
44
44
  }
45
45
 
46
46
  module.exports = drawTriplet;
@@ -9,18 +9,21 @@ var renderText = require('./text');
9
9
  var drawAbsolute = require('./absolute');
10
10
 
11
11
  function drawVoice(renderer, params, bartop, selectables, staffPos) {
12
- var width = params.w-1;
12
+ var width = params.w - 1;
13
13
  renderer.staffbottom = params.staff.bottom;
14
+ var saveColor = renderer.foregroundColor
15
+ if (params.color)
16
+ renderer.foregroundColor = params.color
14
17
 
15
18
  if (params.header) { // print voice name
16
- var textEl = renderText(renderer, {x: renderer.padding.left, y: renderer.calcY(params.headerPosition), text: params.header, type: 'voicefont', klass: 'staff-extra voice-name', anchor: 'start', centerVertically: true, name: "voice-name"}, true);
19
+ var textEl = renderText(renderer, { x: renderer.padding.left, y: renderer.calcY(params.headerPosition), text: params.header, type: 'voicefont', klass: 'staff-extra voice-name', anchor: 'start', centerVertically: true, name: "voice-name" }, true);
17
20
  selectables.wrapSvgEl({ el_type: "voiceName", startChar: -1, endChar: -1, text: params.header }, textEl);
18
21
  }
19
22
 
20
23
  var i;
21
24
  var child;
22
25
  var foundNote = false;
23
- for (i=0; i < params.children.length; i++) {
26
+ for (i = 0; i < params.children.length; i++) {
24
27
  child = params.children[i];
25
28
  if (child.type === 'note' || child.type === 'rest')
26
29
  foundNote = true;
@@ -29,21 +32,16 @@ function drawVoice(renderer, params, bartop, selectables, staffPos) {
29
32
  renderer.controller.classes.startMeasure();
30
33
  justInitializedMeasureNumber = true;
31
34
  }
32
- switch (child.type) {
33
- // case "tempo":
34
- // child.elemset = drawTempo(renderer, child);
35
- // break;
36
- default:
37
- if (params.staff.isTabStaff) {
38
- child.invisible = false;
39
- if ( child.type == 'bar' ) {
40
- if (child.abcelem.lastBar) {
41
- bartop = params.topLine;
42
- }
43
- }
44
- }
45
- drawAbsolute(renderer, child,(params.barto || i === params.children.length - 1) ? bartop : 0, selectables, staffPos);
35
+ if (params.staff.isTabStaff) {
36
+ child.invisible = false;
37
+ if (child.type == 'bar') {
38
+ if (child.abcelem.lastBar) {
39
+ bartop = params.topLine;
40
+ }
41
+ }
46
42
  }
43
+ drawAbsolute(renderer, child, (params.barto || i === params.children.length - 1) ? bartop : 0, selectables, staffPos);
44
+
47
45
  if (child.type === 'note' || isNonSpacerRest(child))
48
46
  renderer.controller.classes.incrNote();
49
47
  if (child.type === 'bar' && !justInitializedMeasureNumber && foundNote) {
@@ -92,6 +90,7 @@ function drawVoice(renderer, params, bartop, selectables, staffPos) {
92
90
  }
93
91
  }
94
92
  }
93
+ renderer.foregroundColor = saveColor
95
94
 
96
95
  }
97
96
 
@@ -2,19 +2,19 @@
2
2
 
3
3
  /*global Math */
4
4
 
5
- var spacing = require('./abc_spacing');
6
- var AbstractEngraver = require('./abc_abstract_engraver');
7
- var Renderer = require('./abc_renderer');
8
- var FreeText = require('./free-text');
9
- var Separator = require('./separator');
10
- var Subtitle = require('./subtitle');
11
- var TopText = require('./top-text');
12
- var BottomText = require('./bottom-text');
13
- var setupSelection = require('./selection');
5
+ var spacing = require('./helpers/spacing');
6
+ var AbstractEngraver = require('./creation/abstract-engraver');
7
+ var Renderer = require('./renderer');
8
+ var FreeText = require('./creation/elements/free-text');
9
+ var Separator = require('./creation/elements/separator');
10
+ var Subtitle = require('./creation/elements/subtitle');
11
+ var TopText = require('./creation/elements/top-text');
12
+ var BottomText = require('./creation/elements/bottom-text');
13
+ var setupSelection = require('./interactive/selection');
14
14
  var layout = require('./layout/layout');
15
- var Classes = require('./classes');
16
- var GetFontAndAttr = require('./get-font-and-attr');
17
- var GetTextSize = require('./get-text-size');
15
+ var Classes = require('./helpers/classes');
16
+ var GetFontAndAttr = require('./helpers/get-font-and-attr');
17
+ var GetTextSize = require('./helpers/get-text-size');
18
18
  var draw = require('./draw/draw');
19
19
  var tablatures = require('../api/abc_tablatures');
20
20
 
@@ -30,20 +30,20 @@ var tablatures = require('../api/abc_tablatures');
30
30
  * in the renderer for highlighting purposes
31
31
  *
32
32
  */
33
- var EngraverController = function(paper, params) {
34
- params = params || {};
35
- this.oneSvgPerLine = params.oneSvgPerLine;
36
- this.selectionColor = params.selectionColor;
37
- this.dragColor = params.dragColor ? params.dragColor : params.selectionColor;
38
- this.dragging = !!params.dragging;
39
- this.selectTypes = params.selectTypes;
40
- this.responsive = params.responsive;
41
- this.space = 3*spacing.SPACE;
33
+ var EngraverController = function (paper, params) {
34
+ params = params || {};
35
+ this.oneSvgPerLine = params.oneSvgPerLine;
36
+ this.selectionColor = params.selectionColor;
37
+ this.dragColor = params.dragColor ? params.dragColor : params.selectionColor;
38
+ this.dragging = !!params.dragging;
39
+ this.selectTypes = params.selectTypes;
40
+ this.responsive = params.responsive;
41
+ this.space = 3 * spacing.SPACE;
42
42
  this.initialClef = params.initialClef;
43
- this.scale = params.scale ? parseFloat(params.scale) : 0;
44
- this.classes = new Classes({ shouldAddClasses: params.add_classes });
45
- if (!(this.scale > 0.1))
46
- this.scale = undefined;
43
+ this.scale = params.scale ? parseFloat(params.scale) : 0;
44
+ this.classes = new Classes({ shouldAddClasses: params.add_classes });
45
+ if (!(this.scale > 0.1))
46
+ this.scale = undefined;
47
47
 
48
48
  if (params.staffwidth) {
49
49
  // Note: Normally all measurements to the engraver are in POINTS. However, if a person is formatting for the
@@ -58,13 +58,17 @@ var EngraverController = function(paper, params) {
58
58
  if (params.clickListener)
59
59
  this.addSelectListener(params.clickListener);
60
60
 
61
- this.renderer=new Renderer(paper);
61
+ this.renderer = new Renderer(paper);
62
62
  this.renderer.setPaddingOverride(params);
63
63
  if (params.showDebug)
64
64
  this.renderer.showDebug = params.showDebug;
65
65
  if (params.jazzchords)
66
66
  this.jazzchords = params.jazzchords;
67
- this.renderer.controller = this; // TODO-GD needed for highlighting
67
+ if (params.germanAlphabet)
68
+ this.germanAlphabet = params.germanAlphabet;
69
+ if (params.lineThickness)
70
+ this.lineThickness = params.lineThickness;
71
+ this.renderer.controller = this; // TODO-GD needed for highlighting
68
72
  this.renderer.foregroundColor = params.foregroundColor ? params.foregroundColor : "currentColor";
69
73
  if (params.ariaLabel !== undefined)
70
74
  this.renderer.ariaLabel = params.ariaLabel;
@@ -73,7 +77,7 @@ var EngraverController = function(paper, params) {
73
77
  this.reset();
74
78
  };
75
79
 
76
- EngraverController.prototype.reset = function() {
80
+ EngraverController.prototype.reset = function () {
77
81
  this.selected = [];
78
82
  this.staffgroups = [];
79
83
  if (this.engraver)
@@ -84,24 +88,26 @@ EngraverController.prototype.reset = function() {
84
88
  this.dragIndex = -1;
85
89
  this.dragMouseStart = { x: -1, y: -1 };
86
90
  this.dragYStep = 0;
91
+ if (this.lineThickness)
92
+ this.renderer.setLineThickness(this.lineThickness)
87
93
  };
88
94
 
89
95
  /**
90
96
  * run the engraving process
91
97
  */
92
- EngraverController.prototype.engraveABC = function(abctunes, tuneNumber, lineOffset) {
93
- if (abctunes[0]===undefined) {
94
- abctunes = [abctunes];
95
- }
98
+ EngraverController.prototype.engraveABC = function (abctunes, tuneNumber, lineOffset) {
99
+ if (abctunes[0] === undefined) {
100
+ abctunes = [abctunes];
101
+ }
96
102
  this.reset();
97
103
 
98
- for (var i = 0; i < abctunes.length; i++) {
99
- if (tuneNumber === undefined)
100
- tuneNumber = i;
101
- this.getFontAndAttr = new GetFontAndAttr(abctunes[i].formatting, this.classes);
102
- this.getTextSize = new GetTextSize(this.getFontAndAttr, this.renderer.paper);
103
- this.engraveTune(abctunes[i], tuneNumber, lineOffset);
104
- }
104
+ for (var i = 0; i < abctunes.length; i++) {
105
+ if (tuneNumber === undefined)
106
+ tuneNumber = i;
107
+ this.getFontAndAttr = new GetFontAndAttr(abctunes[i].formatting, this.classes);
108
+ this.getTextSize = new GetTextSize(this.getFontAndAttr, this.renderer.paper);
109
+ this.engraveTune(abctunes[i], tuneNumber, lineOffset);
110
+ }
105
111
  };
106
112
 
107
113
  /**
@@ -112,7 +118,7 @@ EngraverController.prototype.adjustNonScaledItems = function (scale) {
112
118
  this.renderer.adjustNonScaledItems(scale);
113
119
  };
114
120
 
115
- EngraverController.prototype.getMeasureWidths = function(abcTune) {
121
+ EngraverController.prototype.getMeasureWidths = function (abcTune) {
116
122
  this.reset();
117
123
  this.getFontAndAttr = new GetFontAndAttr(abcTune.formatting, this.classes);
118
124
  this.getTextSize = new GetTextSize(this.getFontAndAttr, this.renderer.paper);
@@ -127,7 +133,7 @@ EngraverController.prototype.getMeasureWidths = function(abcTune) {
127
133
  var section;
128
134
 
129
135
  var needNewSection = true;
130
- for(var i=0; i<abcTune.lines.length; i++) {
136
+ for (var i = 0; i < abcTune.lines.length; i++) {
131
137
  var abcLine = abcTune.lines[i];
132
138
  if (abcLine.staff) {
133
139
  if (needNewSection) {
@@ -179,10 +185,11 @@ EngraverController.prototype.setupTune = function (abcTune, tuneNumber) {
179
185
  graceSlurs: abcTune.formatting.graceSlurs !== false, // undefined is the default, which is true
180
186
  percmap: abcTune.formatting.percmap,
181
187
  initialClef: this.initialClef,
182
- jazzchords: this.jazzchords
188
+ jazzchords: this.jazzchords,
189
+ germanAlphabet: this.germanAlphabet
183
190
  });
184
191
  this.engraver.setStemHeight(this.renderer.spacing.stemHeight);
185
- this.engraver.measureLength = abcTune.getMeterFraction().num/abcTune.getMeterFraction().den;
192
+ this.engraver.measureLength = abcTune.getMeterFraction().num / abcTune.getMeterFraction().den;
186
193
  if (abcTune.formatting.staffwidth) {
187
194
  this.width = abcTune.formatting.staffwidth * 1.33; // The width is expressed in pt; convert to px.
188
195
  } else {
@@ -205,11 +212,11 @@ EngraverController.prototype.constructTuneElements = function (abcTune) {
205
212
  var abcLine;
206
213
  var hasPrintedTempo = false;
207
214
  var hasSeenNonSubtitle = false;
208
- for(i=0; i<abcTune.lines.length; i++) {
215
+ for (i = 0; i < abcTune.lines.length; i++) {
209
216
  abcLine = abcTune.lines[i];
210
217
  if (abcLine.staff) {
211
218
  hasSeenNonSubtitle = true;
212
- abcLine.staffGroup = this.engraver.createABCLine(abcLine.staff, !hasPrintedTempo ? abcTune.metaText.tempo: null, i);
219
+ abcLine.staffGroup = this.engraver.createABCLine(abcLine.staff, !hasPrintedTempo ? abcTune.metaText.tempo : null, i);
213
220
  hasPrintedTempo = true;
214
221
  } else if (abcLine.subtitle) {
215
222
  // If the subtitle is at the top, then it was already accounted for. So skip all subtitles until the first non-subtitle line.
@@ -281,16 +288,16 @@ function splitSvgIntoLines(output, title, responsive) {
281
288
  var wrapper = document.createElement("div");
282
289
  var divStyles = "overflow: hidden;"
283
290
  if (responsive !== 'resize')
284
- divStyles += "height:"+height+"px;"
291
+ divStyles += "height:" + height + "px;"
285
292
  wrapper.setAttribute("style", divStyles)
286
293
  var svg = duplicateSvg(source)
287
- var fullTitle = "Sheet Music for \"" + title + "\" section " + (i+1)
294
+ var fullTitle = "Sheet Music for \"" + title + "\" section " + (i + 1)
288
295
  svg.setAttribute("aria-label", fullTitle)
289
296
  if (responsive !== 'resize')
290
297
  svg.setAttribute("height", height)
291
298
  if (responsive === 'resize')
292
299
  svg.style.position = ''
293
- svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + height )
300
+ svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + height)
294
301
  svg.appendChild(style.cloneNode(true))
295
302
  var titleEl = document.createElement("title")
296
303
  titleEl.innerText = fullTitle
@@ -301,7 +308,7 @@ function splitSvgIntoLines(output, title, responsive) {
301
308
  svgs.push(svg)
302
309
  output.appendChild(wrapper)
303
310
  //wrappers.push(wrapper)
304
- nextTop = box.y+box.height
311
+ nextTop = box.y + box.height
305
312
  }
306
313
  // for (i = 0; i < wrappers.length; i++)
307
314
  // output.appendChild(wrappers[i])
@@ -320,11 +327,11 @@ function duplicateSvg(source) {
320
327
  return svg;
321
328
  }
322
329
 
323
- EngraverController.prototype.getDim = function(historyEl) {
330
+ EngraverController.prototype.getDim = function (historyEl) {
324
331
  // Get the dimensions on demand because the getBBox call is expensive.
325
332
  if (!historyEl.dim) {
326
333
  var box = historyEl.svgEl.getBBox();
327
- historyEl.dim = { left: Math.round(box.x), top: Math.round(box.y), right: Math.round(box.x+box.width), bottom: Math.round(box.y+box.height) };
334
+ historyEl.dim = { left: Math.round(box.x), top: Math.round(box.y), right: Math.round(box.x + box.width), bottom: Math.round(box.y + box.height) };
328
335
  }
329
336
  return historyEl.dim;
330
337
  };
@@ -82,12 +82,12 @@ Classes.prototype.generate = function (c) {
82
82
  if (c === "tab-number") // TODO-PER-HACK! straighten out the tablature
83
83
  return ret.join(' ')
84
84
  if (c === "text instrument-name")
85
- return "abcjs-text abcjs-instrument-name"
86
- if (this.lineNumber !== null) ret.push("l"+this.lineNumber);
87
- if (this.measureNumber !== null) ret.push("m"+this.measureNumber);
88
- if (this.measureNumber !== null) ret.push("mm"+this.measureTotal()); // measureNumber is null between measures so this is still the test for measureTotal
89
- if (this.voiceNumber !== null) ret.push("v"+this.voiceNumber);
90
- if (c && (c.indexOf('note') >= 0 || c.indexOf('rest') >= 0 || c.indexOf('lyric') >= 0 ) && this.noteNumber !== null) ret.push("n"+this.noteNumber);
85
+ return "abcjs-text abcjs-instrument-name"
86
+ if (this.lineNumber !== null) ret.push("l" + this.lineNumber);
87
+ if (this.measureNumber !== null) ret.push("m" + this.measureNumber);
88
+ if (this.measureNumber !== null) ret.push("mm" + this.measureTotal()); // measureNumber is null between measures so this is still the test for measureTotal
89
+ if (this.voiceNumber !== null) ret.push("v" + this.voiceNumber);
90
+ if (c && (c.indexOf('note') >= 0 || c.indexOf('rest') >= 0 || c.indexOf('lyric') >= 0) && this.noteNumber !== null) ret.push("n" + this.noteNumber);
91
91
  // add a prefix to all classes that abcjs adds.
92
92
  if (ret.length > 0) {
93
93
  ret = ret.join(' '); // Some strings are compound classes - that is, specify more than one class in a string.
@@ -3,7 +3,7 @@ var GetFontAndAttr = function GetFontAndAttr(formatting, classes) {
3
3
  this.classes = classes;
4
4
  };
5
5
 
6
- GetFontAndAttr.prototype.updateFonts = function(fontOverrides) {
6
+ GetFontAndAttr.prototype.updateFonts = function (fontOverrides) {
7
7
  if (fontOverrides.gchordfont)
8
8
  this.formatting.gchordfont = fontOverrides.gchordfont;
9
9
  if (fontOverrides.tripletfont)
@@ -14,23 +14,25 @@ GetFontAndAttr.prototype.updateFonts = function(fontOverrides) {
14
14
  this.formatting.vocalfont = fontOverrides.vocalfont;
15
15
  };
16
16
 
17
- GetFontAndAttr.prototype.calc = function(type, klass) {
17
+ GetFontAndAttr.prototype.calc = function (type, klass) {
18
18
  var font;
19
19
  if (typeof type === 'string') {
20
20
  font = this.formatting[type];
21
21
  // Raphael deliberately changes the font units to pixels for some reason, so we need to change points to pixels here.
22
22
  if (font)
23
- font = {face: font.face, size: Math.round(font.size * 4 / 3), decoration: font.decoration, style: font.style, weight: font.weight, box: font.box};
23
+ font = { face: font.face, size: Math.round(font.size * 4 / 3), decoration: font.decoration, style: font.style, weight: font.weight, box: font.box };
24
24
  else
25
- font = {face: "Arial", size: Math.round(12 * 4 / 3), decoration: "underline", style: "normal", weight: "normal"};
25
+ font = { face: "Arial", size: Math.round(12 * 4 / 3), decoration: "underline", style: "normal", weight: "normal" };
26
26
  } else
27
- font = {face: type.face, size: Math.round(type.size * 4 / 3), decoration: type.decoration, style: type.style, weight: type.weight, box: type.box};
27
+ font = { face: type.face, size: Math.round(type.size * 4 / 3), decoration: type.decoration, style: type.style, weight: type.weight, box: type.box };
28
28
  var paddingPercent = this.formatting.fontboxpadding ? this.formatting.fontboxpadding : 0.1
29
29
  font.padding = font.size * paddingPercent;
30
30
 
31
- var attr = {"font-size": font.size, 'font-style': font.style,
31
+ var attr = {
32
+ "font-size": font.size, 'font-style': font.style,
32
33
  "font-family": font.face, 'font-weight': font.weight, 'text-decoration': font.decoration,
33
- 'class': this.classes.generate(klass) };
34
+ 'class': this.classes.generate(klass)
35
+ };
34
36
  return { font: font, attr: attr };
35
37
  };
36
38
 
@@ -3,15 +3,15 @@ var GetTextSize = function GetTextSize(getFontAndAttr, svg) {
3
3
  this.svg = svg;
4
4
  };
5
5
 
6
- GetTextSize.prototype.updateFonts = function(fontOverrides) {
6
+ GetTextSize.prototype.updateFonts = function (fontOverrides) {
7
7
  this.getFontAndAttr.updateFonts(fontOverrides);
8
8
  };
9
9
 
10
- GetTextSize.prototype.attr = function(type, klass) {
10
+ GetTextSize.prototype.attr = function (type, klass) {
11
11
  return this.getFontAndAttr.calc(type, klass);
12
12
  };
13
13
 
14
- GetTextSize.prototype.calc = function(text, type, klass, el) {
14
+ GetTextSize.prototype.calc = function (text, type, klass, el) {
15
15
  var hash;
16
16
  // This can be passed in either a string or a font. If it is a string it names one of the standard fonts.
17
17
  if (typeof type === 'string')
@@ -38,12 +38,12 @@ GetTextSize.prototype.calc = function(text, type, klass, el) {
38
38
  var size = this.svg.getTextSize(text, hash.attr, el);
39
39
  if (hash.font.box) {
40
40
  // Add padding and an equal margin to each side.
41
- return { height: size.height + hash.font.padding*4, width: size.width + hash.font.padding*4 };
41
+ return { height: size.height + hash.font.padding * 4, width: size.width + hash.font.padding * 4 };
42
42
  }
43
43
  return size;
44
44
  };
45
45
 
46
- GetTextSize.prototype.baselineToCenter = function(text, type, klass, index, total) {
46
+ GetTextSize.prototype.baselineToCenter = function (text, type, klass, index, total) {
47
47
  // This is for the case where SVG wants to use the baseline of the first line as the Y coordinate.
48
48
  // If there are multiple lines of text or there is an array of text then that will not be centered so this adjusts it.
49
49
  var height = this.calc(text, type, klass).height;
@@ -11,7 +11,7 @@ var setClass = function (elemset, addClass, removeClass, color) {
11
11
  kls = kls.replace(removeClass, "");
12
12
  kls = kls.replace(addClass, "");
13
13
  if (addClass.length > 0) {
14
- if (kls.length > 0 && kls.charAt(kls.length - 1) !== ' ') kls += " ";
14
+ if (kls.length > 0 && kls[kls.length - 1] !== ' ') kls += " ";
15
15
  kls += addClass;
16
16
  }
17
17
  el.setAttribute("class", kls);
@@ -2,7 +2,7 @@ var spacing = {};
2
2
 
3
3
  spacing.FONTEM = 360;
4
4
  spacing.FONTSIZE = 30;
5
- spacing.STEP = spacing.FONTSIZE*93/720;
5
+ spacing.STEP = spacing.FONTSIZE * 93 / 720;
6
6
  spacing.SPACE = 10;
7
7
  spacing.TOPNOTE = 15;
8
8
  spacing.STAVEHEIGHT = 100;
@@ -1,4 +1,4 @@
1
- var setClass = require('./set-class');
1
+ var setClass = require('../helpers/set-class');
2
2
 
3
3
  var highlight = function (klass, color) {
4
4
  if (klass === undefined)