musicxml-io 0.2.11 → 0.3.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.
- package/README.md +44 -0
- package/dist/{index-2mOfy1m5.d.ts → index-BTs3ZCQC.d.ts} +1 -1
- package/dist/{index-C9zaOJxW.d.mts → index-Dw7hpp4y.d.mts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +424 -145
- package/dist/index.mjs +424 -145
- package/dist/operations/index.d.mts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +11 -8
- package/dist/operations/index.mjs +11 -8
- package/dist/query/index.d.mts +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +7 -6
- package/dist/query/index.mjs +7 -6
- package/dist/{types-Bpq2o5JS.d.mts → types-Csxc_VGi.d.mts} +63 -9
- package/dist/{types-Bpq2o5JS.d.ts → types-Csxc_VGi.d.ts} +63 -9
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -241,9 +241,11 @@ function parseDefaults(elements) {
|
|
|
241
241
|
const lineWidths = collectElements(appContent, "line-width", (c, a) => ({ type: a["type"] || "", value: parseFloat(extractText(c)) || 0 }));
|
|
242
242
|
const noteSizes = collectElements(appContent, "note-size", (c, a) => ({ type: a["type"] || "", value: parseFloat(extractText(c)) || 0 }));
|
|
243
243
|
const distances = collectElements(appContent, "distance", (c, a) => ({ type: a["type"] || "", value: parseFloat(extractText(c)) || 0 }));
|
|
244
|
+
const glyphs = collectElements(appContent, "glyph", (c, a) => ({ type: a["type"] || "", value: extractText(c) }));
|
|
244
245
|
if (lineWidths.length > 0) appearance["line-widths"] = lineWidths;
|
|
245
246
|
if (noteSizes.length > 0) appearance["note-sizes"] = noteSizes;
|
|
246
247
|
if (distances.length > 0) appearance["distances"] = distances;
|
|
248
|
+
if (glyphs.length > 0) appearance["glyphs"] = glyphs;
|
|
247
249
|
return Object.keys(appearance).length > 0 ? appearance : void 0;
|
|
248
250
|
});
|
|
249
251
|
if (appResult) defaults.appearance = appResult;
|
|
@@ -265,13 +267,25 @@ function parsePageLayout(elements) {
|
|
|
265
267
|
m.type = attrs["type"];
|
|
266
268
|
}
|
|
267
269
|
const left = getElementText(content, "left-margin");
|
|
268
|
-
if (left)
|
|
270
|
+
if (left) {
|
|
271
|
+
m.leftMargin = parseFloat(left);
|
|
272
|
+
m.leftMarginRaw = left;
|
|
273
|
+
}
|
|
269
274
|
const right = getElementText(content, "right-margin");
|
|
270
|
-
if (right)
|
|
275
|
+
if (right) {
|
|
276
|
+
m.rightMargin = parseFloat(right);
|
|
277
|
+
m.rightMarginRaw = right;
|
|
278
|
+
}
|
|
271
279
|
const top = getElementText(content, "top-margin");
|
|
272
|
-
if (top)
|
|
280
|
+
if (top) {
|
|
281
|
+
m.topMargin = parseFloat(top);
|
|
282
|
+
m.topMarginRaw = top;
|
|
283
|
+
}
|
|
273
284
|
const bottom = getElementText(content, "bottom-margin");
|
|
274
|
-
if (bottom)
|
|
285
|
+
if (bottom) {
|
|
286
|
+
m.bottomMargin = parseFloat(bottom);
|
|
287
|
+
m.bottomMarginRaw = bottom;
|
|
288
|
+
}
|
|
275
289
|
margins.push(m);
|
|
276
290
|
}
|
|
277
291
|
}
|
|
@@ -284,14 +298,48 @@ function parseSystemLayout(elements) {
|
|
|
284
298
|
if (margins) {
|
|
285
299
|
layout.systemMargins = {};
|
|
286
300
|
const left = getElementText(margins, "left-margin");
|
|
287
|
-
if (left)
|
|
301
|
+
if (left) {
|
|
302
|
+
layout.systemMargins.leftMargin = parseFloat(left);
|
|
303
|
+
layout.systemMargins.leftMarginRaw = left;
|
|
304
|
+
}
|
|
288
305
|
const right = getElementText(margins, "right-margin");
|
|
289
|
-
if (right)
|
|
306
|
+
if (right) {
|
|
307
|
+
layout.systemMargins.rightMargin = parseFloat(right);
|
|
308
|
+
layout.systemMargins.rightMarginRaw = right;
|
|
309
|
+
}
|
|
290
310
|
}
|
|
291
311
|
const dist = getElementText(elements, "system-distance");
|
|
292
|
-
if (dist)
|
|
312
|
+
if (dist) {
|
|
313
|
+
layout.systemDistance = parseFloat(dist);
|
|
314
|
+
layout.systemDistanceRaw = dist;
|
|
315
|
+
}
|
|
293
316
|
const topDist = getElementText(elements, "top-system-distance");
|
|
294
|
-
if (topDist)
|
|
317
|
+
if (topDist) {
|
|
318
|
+
layout.topSystemDistance = parseFloat(topDist);
|
|
319
|
+
layout.topSystemDistanceRaw = topDist;
|
|
320
|
+
}
|
|
321
|
+
const dividers = getElementContent(elements, "system-dividers");
|
|
322
|
+
if (dividers) {
|
|
323
|
+
layout.systemDividers = {};
|
|
324
|
+
for (const el of dividers) {
|
|
325
|
+
if (el["left-divider"]) {
|
|
326
|
+
const attrs = getAttributes(el);
|
|
327
|
+
layout.systemDividers.leftDivider = {
|
|
328
|
+
printObject: attrs["print-object"] === "yes" ? true : attrs["print-object"] === "no" ? false : void 0,
|
|
329
|
+
halign: attrs["halign"],
|
|
330
|
+
valign: attrs["valign"]
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
if (el["right-divider"]) {
|
|
334
|
+
const attrs = getAttributes(el);
|
|
335
|
+
layout.systemDividers.rightDivider = {
|
|
336
|
+
printObject: attrs["print-object"] === "yes" ? true : attrs["print-object"] === "no" ? false : void 0,
|
|
337
|
+
halign: attrs["halign"],
|
|
338
|
+
valign: attrs["valign"]
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
295
343
|
return layout;
|
|
296
344
|
}
|
|
297
345
|
function parseCredits(elements) {
|
|
@@ -303,6 +351,7 @@ function parseCredits(elements) {
|
|
|
303
351
|
const cw = { text: extractText(c) };
|
|
304
352
|
if (a["default-x"]) cw.defaultX = parseFloat(a["default-x"]);
|
|
305
353
|
if (a["default-y"]) cw.defaultY = parseFloat(a["default-y"]);
|
|
354
|
+
if (a["font-family"]) cw.fontFamily = a["font-family"];
|
|
306
355
|
if (a["font-size"]) cw.fontSize = a["font-size"];
|
|
307
356
|
if (a["font-weight"]) cw.fontWeight = a["font-weight"];
|
|
308
357
|
if (a["font-style"]) cw.fontStyle = a["font-style"];
|
|
@@ -526,6 +575,15 @@ function parseMeasure(elements, attrs) {
|
|
|
526
575
|
measure.entries.push(parseFiguredBass(el["figured-bass"], getAttributes(el)));
|
|
527
576
|
} else if (el["sound"]) {
|
|
528
577
|
measure.entries.push(parseSound(el["sound"], getAttributes(el)));
|
|
578
|
+
} else if (el["grouping"] !== void 0) {
|
|
579
|
+
const grpAttrs = getAttributes(el);
|
|
580
|
+
const grouping = {
|
|
581
|
+
_id: generateId(),
|
|
582
|
+
type: "grouping",
|
|
583
|
+
groupingType: grpAttrs["type"] || "start"
|
|
584
|
+
};
|
|
585
|
+
if (grpAttrs["number"]) grouping.number = grpAttrs["number"];
|
|
586
|
+
measure.entries.push(grouping);
|
|
529
587
|
}
|
|
530
588
|
}
|
|
531
589
|
if (barlines.length > 0) measure.barlines = barlines;
|
|
@@ -592,6 +650,7 @@ function parseAttributes(elements) {
|
|
|
592
650
|
const key = parseKeySignature(keyContent);
|
|
593
651
|
if (keyAttrs["number"]) key.number = parseInt(keyAttrs["number"], 10);
|
|
594
652
|
if (keyAttrs["print-object"] === "no") key.printObject = false;
|
|
653
|
+
else if (keyAttrs["print-object"] === "yes") key.printObject = true;
|
|
595
654
|
keys.push(key);
|
|
596
655
|
}
|
|
597
656
|
}
|
|
@@ -643,14 +702,15 @@ function parseTimeSignature(elements, parentElements) {
|
|
|
643
702
|
return time2;
|
|
644
703
|
}
|
|
645
704
|
}
|
|
646
|
-
const
|
|
705
|
+
const beatsStrList = collectElements(elements, "beats", (c) => extractText(c));
|
|
647
706
|
const beatTypeList = collectElements(elements, "beat-type", (c) => parseInt(extractText(c), 10));
|
|
648
707
|
const time = {
|
|
649
|
-
beats:
|
|
708
|
+
beats: beatsStrList.length > 0 ? beatsStrList[0] : "4",
|
|
650
709
|
beatType: beatTypeList.length > 0 ? beatTypeList[0] : 4
|
|
651
710
|
};
|
|
652
|
-
if (
|
|
653
|
-
time.beatsList =
|
|
711
|
+
if (beatsStrList.length > 1 || beatTypeList.length > 1) {
|
|
712
|
+
time.beatsList = beatsStrList.map((b) => parseInt(b, 10));
|
|
713
|
+
time.beatsStrList = beatsStrList;
|
|
654
714
|
time.beatTypeList = beatTypeList;
|
|
655
715
|
}
|
|
656
716
|
for (const el of parentElements) {
|
|
@@ -689,6 +749,7 @@ function parseKeySignature(elements) {
|
|
|
689
749
|
const keyOctaves = collectElements(elements, "key-octave", (c, a) => {
|
|
690
750
|
const ko = { number: parseInt(a["number"] || "1", 10), octave: parseInt(extractText(c), 10) };
|
|
691
751
|
if (a["cancel"] === "yes") ko.cancel = true;
|
|
752
|
+
else if (a["cancel"] === "no") ko.cancel = false;
|
|
692
753
|
return ko;
|
|
693
754
|
});
|
|
694
755
|
if (keySteps.length > 0) key.keySteps = keySteps;
|
|
@@ -698,8 +759,11 @@ function parseKeySignature(elements) {
|
|
|
698
759
|
}
|
|
699
760
|
function parseClef(elements, attrs) {
|
|
700
761
|
const sign = getElementText(elements, "sign") || "G";
|
|
701
|
-
const
|
|
702
|
-
const clef = { sign
|
|
762
|
+
const lineText = getElementText(elements, "line");
|
|
763
|
+
const clef = { sign };
|
|
764
|
+
if (lineText) {
|
|
765
|
+
clef.line = parseInt(lineText, 10);
|
|
766
|
+
}
|
|
703
767
|
if (attrs["number"]) {
|
|
704
768
|
clef.staff = parseInt(attrs["number"], 10);
|
|
705
769
|
}
|
|
@@ -709,6 +773,8 @@ function parseClef(elements, attrs) {
|
|
|
709
773
|
}
|
|
710
774
|
if (attrs["print-object"] === "no") {
|
|
711
775
|
clef.printObject = false;
|
|
776
|
+
} else if (attrs["print-object"] === "yes") {
|
|
777
|
+
clef.printObject = true;
|
|
712
778
|
}
|
|
713
779
|
if (attrs["after-barline"] === "yes") {
|
|
714
780
|
clef.afterBarline = true;
|
|
@@ -730,15 +796,20 @@ function parseNote(elements, attrs) {
|
|
|
730
796
|
const note = {
|
|
731
797
|
_id: generateId(),
|
|
732
798
|
type: "note",
|
|
733
|
-
duration: getElementTextAsInt(elements, "duration", 0)
|
|
734
|
-
voice: getElementTextAsInt(elements, "voice", 1)
|
|
799
|
+
duration: getElementTextAsInt(elements, "duration", 0)
|
|
735
800
|
};
|
|
801
|
+
const voiceValue = getElementTextAsInt(elements, "voice");
|
|
802
|
+
if (voiceValue !== void 0) {
|
|
803
|
+
note.voice = voiceValue;
|
|
804
|
+
}
|
|
736
805
|
if (attrs["default-x"]) note.defaultX = parseFloat(attrs["default-x"]);
|
|
737
806
|
if (attrs["default-y"]) note.defaultY = parseFloat(attrs["default-y"]);
|
|
738
807
|
if (attrs["relative-x"]) note.relativeX = parseFloat(attrs["relative-x"]);
|
|
739
808
|
if (attrs["relative-y"]) note.relativeY = parseFloat(attrs["relative-y"]);
|
|
740
809
|
if (attrs["dynamics"]) note.dynamics = parseFloat(attrs["dynamics"]);
|
|
741
810
|
if (attrs["print-object"] === "no") note.printObject = false;
|
|
811
|
+
if (attrs["print-dot"] === "no") note.printDot = false;
|
|
812
|
+
if (attrs["print-dot"] === "yes") note.printDot = true;
|
|
742
813
|
if (attrs["print-spacing"] === "yes") note.printSpacing = true;
|
|
743
814
|
if (attrs["print-spacing"] === "no") note.printSpacing = false;
|
|
744
815
|
if (hasElement(elements, "cue")) {
|
|
@@ -851,6 +922,7 @@ function parseNote(elements, attrs) {
|
|
|
851
922
|
const graceAttrs = getAttributes(el);
|
|
852
923
|
note.grace = {};
|
|
853
924
|
if (graceAttrs["slash"] === "yes") note.grace.slash = true;
|
|
925
|
+
else if (graceAttrs["slash"] === "no") note.grace.slash = false;
|
|
854
926
|
if (graceAttrs["steal-time-previous"]) {
|
|
855
927
|
note.grace.stealTimePrevious = parseFloat(graceAttrs["steal-time-previous"]);
|
|
856
928
|
}
|
|
@@ -1096,6 +1168,14 @@ function parseNotations(elements, notationsIndex = 0) {
|
|
|
1096
1168
|
notations.push(tremNotation);
|
|
1097
1169
|
}
|
|
1098
1170
|
}
|
|
1171
|
+
const ornamentNotationsAdded = notations.filter((n) => n.type === "ornament" && n.notationsIndex === notationsIndex);
|
|
1172
|
+
if (ornamentNotationsAdded.length === 0) {
|
|
1173
|
+
notations.push({
|
|
1174
|
+
type: "ornament",
|
|
1175
|
+
ornament: "empty",
|
|
1176
|
+
notationsIndex
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1099
1179
|
} else if (el["technical"]) {
|
|
1100
1180
|
const techContent = el["technical"];
|
|
1101
1181
|
const technicalWithText = ["hammer-on", "pull-off", "tap", "pluck", "fingering", "other-technical"];
|
|
@@ -1145,8 +1225,7 @@ function parseNotations(elements, notationsIndex = 0) {
|
|
|
1145
1225
|
if (bendAlter) techNotation.bendAlter = parseFloat(bendAlter);
|
|
1146
1226
|
if (hasElement(bendContent, "pre-bend")) techNotation.preBend = true;
|
|
1147
1227
|
if (hasElement(bendContent, "release")) techNotation.release = true;
|
|
1148
|
-
|
|
1149
|
-
if (withBar) techNotation.withBar = parseFloat(withBar);
|
|
1228
|
+
if (hasElement(bendContent, "with-bar")) techNotation.withBar = true;
|
|
1150
1229
|
notations.push(techNotation);
|
|
1151
1230
|
}
|
|
1152
1231
|
for (const techType of technicalTypes) {
|
|
@@ -1183,6 +1262,7 @@ function parseNotations(elements, notationsIndex = 0) {
|
|
|
1183
1262
|
if (typeAttr === "start" || typeAttr === "stop") {
|
|
1184
1263
|
notation.startStop = typeAttr;
|
|
1185
1264
|
}
|
|
1265
|
+
if (techAttrs["number"]) notation.number = parseInt(techAttrs["number"], 10);
|
|
1186
1266
|
}
|
|
1187
1267
|
if (techType === "fingering") {
|
|
1188
1268
|
if (techAttrs["substitution"] === "yes") notation.fingeringSubstitution = true;
|
|
@@ -1265,11 +1345,33 @@ function parseNotations(elements, notationsIndex = 0) {
|
|
|
1265
1345
|
notations.push(fermataNotation);
|
|
1266
1346
|
} else if (el["arpeggiate"] !== void 0) {
|
|
1267
1347
|
const arpAttrs = getAttributes(el);
|
|
1268
|
-
|
|
1348
|
+
const arpNotation = {
|
|
1269
1349
|
type: "arpeggiate",
|
|
1270
1350
|
direction: arpAttrs["direction"],
|
|
1271
1351
|
number: arpAttrs["number"] ? parseInt(arpAttrs["number"], 10) : void 0,
|
|
1272
1352
|
notationsIndex
|
|
1353
|
+
};
|
|
1354
|
+
if (arpAttrs["default-x"]) arpNotation.defaultX = parseFloat(arpAttrs["default-x"]);
|
|
1355
|
+
if (arpAttrs["default-y"]) arpNotation.defaultY = parseFloat(arpAttrs["default-y"]);
|
|
1356
|
+
notations.push(arpNotation);
|
|
1357
|
+
} else if (el["non-arpeggiate"] !== void 0) {
|
|
1358
|
+
const nonArpAttrs = getAttributes(el);
|
|
1359
|
+
notations.push({
|
|
1360
|
+
type: "non-arpeggiate",
|
|
1361
|
+
nonArpeggiateType: nonArpAttrs["type"],
|
|
1362
|
+
number: nonArpAttrs["number"] ? parseInt(nonArpAttrs["number"], 10) : void 0,
|
|
1363
|
+
placement: nonArpAttrs["placement"],
|
|
1364
|
+
notationsIndex
|
|
1365
|
+
});
|
|
1366
|
+
} else if (el["accidental-mark"]) {
|
|
1367
|
+
const amAttrs = getAttributes(el);
|
|
1368
|
+
const amContent = el["accidental-mark"];
|
|
1369
|
+
const value = extractText(amContent);
|
|
1370
|
+
notations.push({
|
|
1371
|
+
type: "accidental-mark",
|
|
1372
|
+
value,
|
|
1373
|
+
placement: amAttrs["placement"],
|
|
1374
|
+
notationsIndex
|
|
1273
1375
|
});
|
|
1274
1376
|
} else if (el["glissando"]) {
|
|
1275
1377
|
const glissAttrs = getAttributes(el);
|
|
@@ -1291,13 +1393,17 @@ function parseNotations(elements, notationsIndex = 0) {
|
|
|
1291
1393
|
});
|
|
1292
1394
|
} else if (el["slide"]) {
|
|
1293
1395
|
const slideAttrs = getAttributes(el);
|
|
1294
|
-
|
|
1396
|
+
const slideContent = el["slide"];
|
|
1397
|
+
const slideText = extractText(slideContent);
|
|
1398
|
+
const slideNotation = {
|
|
1295
1399
|
type: "slide",
|
|
1296
1400
|
slideType: slideAttrs["type"] === "stop" ? "stop" : "start",
|
|
1297
1401
|
number: slideAttrs["number"] ? parseInt(slideAttrs["number"], 10) : void 0,
|
|
1298
1402
|
lineType: slideAttrs["line-type"],
|
|
1299
1403
|
notationsIndex
|
|
1300
|
-
}
|
|
1404
|
+
};
|
|
1405
|
+
if (slideText) slideNotation.text = slideText;
|
|
1406
|
+
notations.push(slideNotation);
|
|
1301
1407
|
}
|
|
1302
1408
|
}
|
|
1303
1409
|
return notations;
|
|
@@ -1318,8 +1424,9 @@ function parseLyric(elements, attrs) {
|
|
|
1318
1424
|
break;
|
|
1319
1425
|
}
|
|
1320
1426
|
}
|
|
1321
|
-
} else if (el["text"]) {
|
|
1427
|
+
} else if (el["text"] !== void 0) {
|
|
1322
1428
|
const content = el["text"];
|
|
1429
|
+
let foundText = false;
|
|
1323
1430
|
for (const item of content) {
|
|
1324
1431
|
if (item["#text"] !== void 0) {
|
|
1325
1432
|
textElements.push({
|
|
@@ -1327,9 +1434,17 @@ function parseLyric(elements, attrs) {
|
|
|
1327
1434
|
syllabic: currentSyllabic
|
|
1328
1435
|
});
|
|
1329
1436
|
currentSyllabic = void 0;
|
|
1437
|
+
foundText = true;
|
|
1330
1438
|
break;
|
|
1331
1439
|
}
|
|
1332
1440
|
}
|
|
1441
|
+
if (!foundText) {
|
|
1442
|
+
textElements.push({
|
|
1443
|
+
text: "",
|
|
1444
|
+
syllabic: currentSyllabic
|
|
1445
|
+
});
|
|
1446
|
+
currentSyllabic = void 0;
|
|
1447
|
+
}
|
|
1333
1448
|
} else if (el["elision"] !== void 0) {
|
|
1334
1449
|
hasElision = true;
|
|
1335
1450
|
}
|
|
@@ -1426,8 +1541,8 @@ function parseDirection(elements, attrs) {
|
|
|
1426
1541
|
});
|
|
1427
1542
|
for (const el of elements) {
|
|
1428
1543
|
if (el["direction-type"]) {
|
|
1429
|
-
const
|
|
1430
|
-
|
|
1544
|
+
const parsedTypes = parseDirectionTypes(el["direction-type"]);
|
|
1545
|
+
for (const parsed of parsedTypes) {
|
|
1431
1546
|
direction.directionTypes.push(parsed);
|
|
1432
1547
|
}
|
|
1433
1548
|
}
|
|
@@ -1464,7 +1579,8 @@ function parseDirection(elements, attrs) {
|
|
|
1464
1579
|
}
|
|
1465
1580
|
return direction;
|
|
1466
1581
|
}
|
|
1467
|
-
function
|
|
1582
|
+
function parseDirectionTypes(elements) {
|
|
1583
|
+
const results = [];
|
|
1468
1584
|
for (const el of elements) {
|
|
1469
1585
|
if (el["dynamics"]) {
|
|
1470
1586
|
const dynAttrs = getAttributes(el);
|
|
@@ -1497,6 +1613,7 @@ function parseDirectionType(elements) {
|
|
|
1497
1613
|
"pf"
|
|
1498
1614
|
];
|
|
1499
1615
|
for (const dyn of dynContent) {
|
|
1616
|
+
let foundStandard = false;
|
|
1500
1617
|
for (const dv of dynamicsValues) {
|
|
1501
1618
|
if (dyn[dv] !== void 0) {
|
|
1502
1619
|
const result = { kind: "dynamics", value: dv };
|
|
@@ -1504,10 +1621,25 @@ function parseDirectionType(elements) {
|
|
|
1504
1621
|
if (dynAttrs["default-y"]) result.defaultY = parseFloat(dynAttrs["default-y"]);
|
|
1505
1622
|
if (dynAttrs["relative-x"]) result.relativeX = parseFloat(dynAttrs["relative-x"]);
|
|
1506
1623
|
if (dynAttrs["halign"]) result.halign = dynAttrs["halign"];
|
|
1507
|
-
|
|
1624
|
+
results.push(result);
|
|
1625
|
+
foundStandard = true;
|
|
1626
|
+
break;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
if (!foundStandard && dyn["other-dynamics"] !== void 0) {
|
|
1630
|
+
const otherDynContent = dyn["other-dynamics"];
|
|
1631
|
+
const otherDynText = extractText(otherDynContent);
|
|
1632
|
+
if (otherDynText) {
|
|
1633
|
+
const result = { kind: "dynamics", otherDynamics: otherDynText };
|
|
1634
|
+
if (dynAttrs["default-x"]) result.defaultX = parseFloat(dynAttrs["default-x"]);
|
|
1635
|
+
if (dynAttrs["default-y"]) result.defaultY = parseFloat(dynAttrs["default-y"]);
|
|
1636
|
+
if (dynAttrs["relative-x"]) result.relativeX = parseFloat(dynAttrs["relative-x"]);
|
|
1637
|
+
if (dynAttrs["halign"]) result.halign = dynAttrs["halign"];
|
|
1638
|
+
results.push(result);
|
|
1508
1639
|
}
|
|
1509
1640
|
}
|
|
1510
1641
|
}
|
|
1642
|
+
continue;
|
|
1511
1643
|
}
|
|
1512
1644
|
if (el["wedge"]) {
|
|
1513
1645
|
const wedgeAttrs = getAttributes(el);
|
|
@@ -1517,8 +1649,9 @@ function parseDirectionType(elements) {
|
|
|
1517
1649
|
if (wedgeAttrs["spread"]) result.spread = parseFloat(wedgeAttrs["spread"]);
|
|
1518
1650
|
if (wedgeAttrs["default-y"]) result.defaultY = parseFloat(wedgeAttrs["default-y"]);
|
|
1519
1651
|
if (wedgeAttrs["relative-x"]) result.relativeX = parseFloat(wedgeAttrs["relative-x"]);
|
|
1520
|
-
|
|
1652
|
+
results.push(result);
|
|
1521
1653
|
}
|
|
1654
|
+
continue;
|
|
1522
1655
|
}
|
|
1523
1656
|
if (el["metronome"]) {
|
|
1524
1657
|
const metAttrs = getAttributes(el);
|
|
@@ -1558,28 +1691,29 @@ function parseDirectionType(elements) {
|
|
|
1558
1691
|
if (metAttrs["default-y"]) result.defaultY = parseFloat(metAttrs["default-y"]);
|
|
1559
1692
|
if (metAttrs["font-family"]) result.fontFamily = metAttrs["font-family"];
|
|
1560
1693
|
if (metAttrs["font-size"]) result.fontSize = metAttrs["font-size"];
|
|
1561
|
-
|
|
1694
|
+
results.push(result);
|
|
1562
1695
|
}
|
|
1696
|
+
continue;
|
|
1563
1697
|
}
|
|
1564
1698
|
if (el["words"]) {
|
|
1565
1699
|
const a = getAttributes(el);
|
|
1566
1700
|
const text = extractText(el["words"]);
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1701
|
+
const result = { kind: "words", text: text || "" };
|
|
1702
|
+
if (a["default-x"]) result.defaultX = parseFloat(a["default-x"]);
|
|
1703
|
+
if (a["default-y"]) result.defaultY = parseFloat(a["default-y"]);
|
|
1704
|
+
if (a["relative-x"]) result.relativeX = parseFloat(a["relative-x"]);
|
|
1705
|
+
if (a["relative-y"]) result.relativeY = parseFloat(a["relative-y"]);
|
|
1706
|
+
if (a["font-family"]) result.fontFamily = a["font-family"];
|
|
1707
|
+
if (a["font-size"]) result.fontSize = a["font-size"];
|
|
1708
|
+
if (a["font-style"]) result.fontStyle = a["font-style"];
|
|
1709
|
+
if (a["font-weight"]) result.fontWeight = a["font-weight"];
|
|
1710
|
+
if (a["xml:lang"]) result.xmlLang = a["xml:lang"];
|
|
1711
|
+
if (a["justify"]) result.justify = a["justify"];
|
|
1712
|
+
if (a["color"]) result.color = a["color"];
|
|
1713
|
+
if (a["xml:space"]) result.xmlSpace = a["xml:space"];
|
|
1714
|
+
if (a["halign"]) result.halign = a["halign"];
|
|
1715
|
+
results.push(result);
|
|
1716
|
+
continue;
|
|
1583
1717
|
}
|
|
1584
1718
|
if (el["rehearsal"]) {
|
|
1585
1719
|
const a = getAttributes(el);
|
|
@@ -1591,8 +1725,9 @@ function parseDirectionType(elements) {
|
|
|
1591
1725
|
if (a["default-y"]) result.defaultY = parseFloat(a["default-y"]);
|
|
1592
1726
|
if (a["font-size"]) result.fontSize = a["font-size"];
|
|
1593
1727
|
if (a["font-weight"]) result.fontWeight = a["font-weight"];
|
|
1594
|
-
|
|
1728
|
+
results.push(result);
|
|
1595
1729
|
}
|
|
1730
|
+
continue;
|
|
1596
1731
|
}
|
|
1597
1732
|
if (el["bracket"]) {
|
|
1598
1733
|
const bracketAttrs = getAttributes(el);
|
|
@@ -1604,8 +1739,9 @@ function parseDirectionType(elements) {
|
|
|
1604
1739
|
if (bracketAttrs["line-type"]) result.lineType = bracketAttrs["line-type"];
|
|
1605
1740
|
if (bracketAttrs["default-y"]) result.defaultY = parseFloat(bracketAttrs["default-y"]);
|
|
1606
1741
|
if (bracketAttrs["relative-x"]) result.relativeX = parseFloat(bracketAttrs["relative-x"]);
|
|
1607
|
-
|
|
1742
|
+
results.push(result);
|
|
1608
1743
|
}
|
|
1744
|
+
continue;
|
|
1609
1745
|
}
|
|
1610
1746
|
if (el["dashes"]) {
|
|
1611
1747
|
const dashAttrs = getAttributes(el);
|
|
@@ -1616,8 +1752,9 @@ function parseDirectionType(elements) {
|
|
|
1616
1752
|
if (dashAttrs["dash-length"]) result.dashLength = parseFloat(dashAttrs["dash-length"]);
|
|
1617
1753
|
if (dashAttrs["default-y"]) result.defaultY = parseFloat(dashAttrs["default-y"]);
|
|
1618
1754
|
if (dashAttrs["space-length"]) result.spaceLength = parseFloat(dashAttrs["space-length"]);
|
|
1619
|
-
|
|
1755
|
+
results.push(result);
|
|
1620
1756
|
}
|
|
1757
|
+
continue;
|
|
1621
1758
|
}
|
|
1622
1759
|
if (el["accordion-registration"]) {
|
|
1623
1760
|
const accContent = el["accordion-registration"];
|
|
@@ -1625,11 +1762,14 @@ function parseDirectionType(elements) {
|
|
|
1625
1762
|
for (const acc of accContent) {
|
|
1626
1763
|
if (acc["accordion-high"] !== void 0) {
|
|
1627
1764
|
result.high = true;
|
|
1628
|
-
} else if (acc["accordion-middle"]) {
|
|
1765
|
+
} else if (acc["accordion-middle"] !== void 0) {
|
|
1766
|
+
result.middlePresent = true;
|
|
1629
1767
|
const midContent = acc["accordion-middle"];
|
|
1630
1768
|
for (const item of midContent) {
|
|
1631
1769
|
if (item["#text"] !== void 0) {
|
|
1632
|
-
|
|
1770
|
+
const textValue = String(item["#text"]);
|
|
1771
|
+
const numValue = parseInt(textValue, 10);
|
|
1772
|
+
result.middle = !isNaN(numValue) ? numValue : textValue;
|
|
1633
1773
|
break;
|
|
1634
1774
|
}
|
|
1635
1775
|
}
|
|
@@ -1637,7 +1777,8 @@ function parseDirectionType(elements) {
|
|
|
1637
1777
|
result.low = true;
|
|
1638
1778
|
}
|
|
1639
1779
|
}
|
|
1640
|
-
|
|
1780
|
+
results.push(result);
|
|
1781
|
+
continue;
|
|
1641
1782
|
}
|
|
1642
1783
|
if (el["other-direction"]) {
|
|
1643
1784
|
const otherAttrs = getAttributes(el);
|
|
@@ -1649,24 +1790,31 @@ function parseDirectionType(elements) {
|
|
|
1649
1790
|
if (otherAttrs["default-y"]) result.defaultY = parseFloat(otherAttrs["default-y"]);
|
|
1650
1791
|
if (otherAttrs["halign"]) result.halign = otherAttrs["halign"];
|
|
1651
1792
|
if (otherAttrs["print-object"] === "no") result.printObject = false;
|
|
1652
|
-
|
|
1793
|
+
results.push(result);
|
|
1794
|
+
break;
|
|
1653
1795
|
}
|
|
1654
1796
|
}
|
|
1797
|
+
continue;
|
|
1655
1798
|
}
|
|
1656
1799
|
if (el["segno"] !== void 0) {
|
|
1657
|
-
|
|
1800
|
+
results.push({ kind: "segno" });
|
|
1801
|
+
continue;
|
|
1658
1802
|
}
|
|
1659
1803
|
if (el["coda"] !== void 0) {
|
|
1660
|
-
|
|
1804
|
+
results.push({ kind: "coda" });
|
|
1805
|
+
continue;
|
|
1661
1806
|
}
|
|
1662
1807
|
if (el["eyeglasses"] !== void 0) {
|
|
1663
|
-
|
|
1808
|
+
results.push({ kind: "eyeglasses" });
|
|
1809
|
+
continue;
|
|
1664
1810
|
}
|
|
1665
1811
|
if (el["damp"] !== void 0) {
|
|
1666
|
-
|
|
1812
|
+
results.push({ kind: "damp" });
|
|
1813
|
+
continue;
|
|
1667
1814
|
}
|
|
1668
1815
|
if (el["damp-all"] !== void 0) {
|
|
1669
|
-
|
|
1816
|
+
results.push({ kind: "damp-all" });
|
|
1817
|
+
continue;
|
|
1670
1818
|
}
|
|
1671
1819
|
if (el["scordatura"] !== void 0) {
|
|
1672
1820
|
const scordContent = el["scordatura"];
|
|
@@ -1689,7 +1837,8 @@ function parseDirectionType(elements) {
|
|
|
1689
1837
|
}
|
|
1690
1838
|
}
|
|
1691
1839
|
}
|
|
1692
|
-
|
|
1840
|
+
results.push({ kind: "scordatura", accords: accords.length > 0 ? accords : void 0 });
|
|
1841
|
+
continue;
|
|
1693
1842
|
}
|
|
1694
1843
|
if (el["harp-pedals"] !== void 0) {
|
|
1695
1844
|
const harpContent = el["harp-pedals"];
|
|
@@ -1707,15 +1856,17 @@ function parseDirectionType(elements) {
|
|
|
1707
1856
|
}
|
|
1708
1857
|
}
|
|
1709
1858
|
}
|
|
1710
|
-
|
|
1859
|
+
results.push({ kind: "harp-pedals", pedalTunings: pedalTunings.length > 0 ? pedalTunings : void 0 });
|
|
1860
|
+
continue;
|
|
1711
1861
|
}
|
|
1712
1862
|
if (el["image"] !== void 0) {
|
|
1713
1863
|
const imgAttrs = getAttributes(el);
|
|
1714
|
-
|
|
1864
|
+
results.push({
|
|
1715
1865
|
kind: "image",
|
|
1716
1866
|
source: imgAttrs["source"],
|
|
1717
1867
|
type: imgAttrs["type"]
|
|
1718
|
-
};
|
|
1868
|
+
});
|
|
1869
|
+
continue;
|
|
1719
1870
|
}
|
|
1720
1871
|
if (el["pedal"]) {
|
|
1721
1872
|
const pedalAttrs = getAttributes(el);
|
|
@@ -1727,8 +1878,9 @@ function parseDirectionType(elements) {
|
|
|
1727
1878
|
if (pedalAttrs["default-y"]) result.defaultY = parseFloat(pedalAttrs["default-y"]);
|
|
1728
1879
|
if (pedalAttrs["relative-x"]) result.relativeX = parseFloat(pedalAttrs["relative-x"]);
|
|
1729
1880
|
if (pedalAttrs["halign"]) result.halign = pedalAttrs["halign"];
|
|
1730
|
-
|
|
1881
|
+
results.push(result);
|
|
1731
1882
|
}
|
|
1883
|
+
continue;
|
|
1732
1884
|
}
|
|
1733
1885
|
if (el["octave-shift"]) {
|
|
1734
1886
|
const shiftAttrs = getAttributes(el);
|
|
@@ -1736,8 +1888,9 @@ function parseDirectionType(elements) {
|
|
|
1736
1888
|
if (shiftType === "up" || shiftType === "down" || shiftType === "stop") {
|
|
1737
1889
|
const result = { kind: "octave-shift", type: shiftType };
|
|
1738
1890
|
if (shiftAttrs["size"]) result.size = parseInt(shiftAttrs["size"], 10);
|
|
1739
|
-
|
|
1891
|
+
results.push(result);
|
|
1740
1892
|
}
|
|
1893
|
+
continue;
|
|
1741
1894
|
}
|
|
1742
1895
|
if (el["swing"]) {
|
|
1743
1896
|
const swingContent = el["swing"];
|
|
@@ -1771,10 +1924,11 @@ function parseDirectionType(elements) {
|
|
|
1771
1924
|
}
|
|
1772
1925
|
}
|
|
1773
1926
|
}
|
|
1774
|
-
|
|
1927
|
+
results.push(result);
|
|
1928
|
+
continue;
|
|
1775
1929
|
}
|
|
1776
1930
|
}
|
|
1777
|
-
return
|
|
1931
|
+
return results;
|
|
1778
1932
|
}
|
|
1779
1933
|
function parseBarline(elements, attrs) {
|
|
1780
1934
|
const location = attrs["location"] || "right";
|
|
@@ -1792,6 +1946,9 @@ function parseBarline(elements, attrs) {
|
|
|
1792
1946
|
if (repeatAttrs["times"]) {
|
|
1793
1947
|
barline.repeat.times = parseInt(repeatAttrs["times"], 10);
|
|
1794
1948
|
}
|
|
1949
|
+
if (repeatAttrs["winged"]) {
|
|
1950
|
+
barline.repeat.winged = repeatAttrs["winged"];
|
|
1951
|
+
}
|
|
1795
1952
|
}
|
|
1796
1953
|
} else if (el["ending"]) {
|
|
1797
1954
|
const endingAttrs = getAttributes(el);
|
|
@@ -1799,6 +1956,11 @@ function parseBarline(elements, attrs) {
|
|
|
1799
1956
|
const type = endingAttrs["type"];
|
|
1800
1957
|
if (number && (type === "start" || type === "stop" || type === "discontinue")) {
|
|
1801
1958
|
barline.ending = { number, type };
|
|
1959
|
+
const endingContent = el["ending"];
|
|
1960
|
+
const endingText = extractText(endingContent);
|
|
1961
|
+
if (endingText) barline.ending.text = endingText;
|
|
1962
|
+
if (endingAttrs["default-y"]) barline.ending.defaultY = parseFloat(endingAttrs["default-y"]);
|
|
1963
|
+
if (endingAttrs["end-length"]) barline.ending.endLength = parseFloat(endingAttrs["end-length"]);
|
|
1802
1964
|
}
|
|
1803
1965
|
}
|
|
1804
1966
|
}
|
|
@@ -1924,6 +2086,8 @@ function parseStaffDetails(elements, attrs) {
|
|
|
1924
2086
|
if (attrs["number"]) sd.number = parseInt(attrs["number"], 10);
|
|
1925
2087
|
if (attrs["print-object"] === "no") sd.printObject = false;
|
|
1926
2088
|
else if (attrs["print-object"] === "yes") sd.printObject = true;
|
|
2089
|
+
if (attrs["print-spacing"] === "yes") sd.printSpacing = true;
|
|
2090
|
+
else if (attrs["print-spacing"] === "no") sd.printSpacing = false;
|
|
1927
2091
|
const staffType = getElementText(elements, "staff-type");
|
|
1928
2092
|
if (staffType && ["ossia", "cue", "editorial", "regular", "alternate"].includes(staffType)) {
|
|
1929
2093
|
sd.staffType = staffType;
|
|
@@ -1987,7 +2151,9 @@ function parseMeasureStyle(elements, attrs) {
|
|
|
1987
2151
|
const slAttrs = getAttributes(el);
|
|
1988
2152
|
ms.slash = { type: slAttrs["type"] === "stop" ? "stop" : "start" };
|
|
1989
2153
|
if (slAttrs["use-dots"] === "yes") ms.slash.useDots = true;
|
|
2154
|
+
else if (slAttrs["use-dots"] === "no") ms.slash.useDots = false;
|
|
1990
2155
|
if (slAttrs["use-stems"] === "yes") ms.slash.useStems = true;
|
|
2156
|
+
else if (slAttrs["use-stems"] === "no") ms.slash.useStems = false;
|
|
1991
2157
|
}
|
|
1992
2158
|
}
|
|
1993
2159
|
return ms;
|
|
@@ -2027,19 +2193,29 @@ function parseHarmony(elements, attrs) {
|
|
|
2027
2193
|
break;
|
|
2028
2194
|
}
|
|
2029
2195
|
}
|
|
2030
|
-
if (kindAttrs["text"]) harmony.kindText = kindAttrs["text"];
|
|
2196
|
+
if (kindAttrs["text"] !== void 0) harmony.kindText = kindAttrs["text"];
|
|
2197
|
+
if (kindAttrs["halign"]) harmony.kindHalign = kindAttrs["halign"];
|
|
2031
2198
|
break;
|
|
2032
2199
|
}
|
|
2033
2200
|
}
|
|
2034
|
-
const
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2201
|
+
for (const el of elements) {
|
|
2202
|
+
if (el["bass"]) {
|
|
2203
|
+
const bassAttrs = getAttributes(el);
|
|
2204
|
+
const bassContent = el["bass"];
|
|
2205
|
+
const bassStep = getElementText(bassContent, "bass-step");
|
|
2206
|
+
if (bassStep) {
|
|
2207
|
+
harmony.bass = { bassStep };
|
|
2208
|
+
const bassAlter = getElementText(bassContent, "bass-alter");
|
|
2209
|
+
if (bassAlter) harmony.bass.bassAlter = parseFloat(bassAlter);
|
|
2210
|
+
if (bassAttrs["arrangement"]) harmony.bass.arrangement = bassAttrs["arrangement"];
|
|
2211
|
+
}
|
|
2212
|
+
break;
|
|
2041
2213
|
}
|
|
2042
2214
|
}
|
|
2215
|
+
const inversionText = getElementText(elements, "inversion");
|
|
2216
|
+
if (inversionText) {
|
|
2217
|
+
harmony.inversion = parseInt(inversionText, 10);
|
|
2218
|
+
}
|
|
2043
2219
|
const degrees = [];
|
|
2044
2220
|
for (const el of elements) {
|
|
2045
2221
|
if (el["degree"]) {
|
|
@@ -2655,7 +2831,7 @@ function validateBeams(measure, location) {
|
|
|
2655
2831
|
const entry = measure.entries[entryIndex];
|
|
2656
2832
|
if (entry.type !== "note" || !entry.beam) continue;
|
|
2657
2833
|
for (const beam of entry.beam) {
|
|
2658
|
-
const beamKey = `${beam.number}-${entry.voice}
|
|
2834
|
+
const beamKey = `${beam.number}-${entry.voice}`;
|
|
2659
2835
|
if (beam.type === "begin") {
|
|
2660
2836
|
if (openBeams.has(beamKey)) {
|
|
2661
2837
|
errors.push({
|
|
@@ -2666,7 +2842,7 @@ function validateBeams(measure, location) {
|
|
|
2666
2842
|
details: { beamNumber: beam.number }
|
|
2667
2843
|
});
|
|
2668
2844
|
}
|
|
2669
|
-
openBeams.set(beamKey, entryIndex);
|
|
2845
|
+
openBeams.set(beamKey, { entryIndex, staff: entry.staff ?? 1 });
|
|
2670
2846
|
} else if (beam.type === "end") {
|
|
2671
2847
|
if (!openBeams.has(beamKey)) {
|
|
2672
2848
|
errors.push({
|
|
@@ -2682,8 +2858,8 @@ function validateBeams(measure, location) {
|
|
|
2682
2858
|
}
|
|
2683
2859
|
}
|
|
2684
2860
|
}
|
|
2685
|
-
for (const [beamKey, startIndex] of openBeams.entries()) {
|
|
2686
|
-
const [beamNumber, voice
|
|
2861
|
+
for (const [beamKey, { entryIndex: startIndex, staff }] of openBeams.entries()) {
|
|
2862
|
+
const [beamNumber, voice] = beamKey.split("-").map(Number);
|
|
2687
2863
|
errors.push({
|
|
2688
2864
|
code: "BEAM_BEGIN_WITHOUT_END",
|
|
2689
2865
|
level: "error",
|
|
@@ -2806,7 +2982,7 @@ function validateVoiceStaff(measure, staves, location) {
|
|
|
2806
2982
|
for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
|
|
2807
2983
|
const entry = measure.entries[entryIndex];
|
|
2808
2984
|
if (entry.type !== "note") continue;
|
|
2809
|
-
if (entry.voice <= 0) {
|
|
2985
|
+
if (entry.voice !== void 0 && entry.voice <= 0) {
|
|
2810
2986
|
errors.push({
|
|
2811
2987
|
code: "INVALID_VOICE_NUMBER",
|
|
2812
2988
|
level: "error",
|
|
@@ -3455,6 +3631,11 @@ function serializeDefaults(defaults, indent) {
|
|
|
3455
3631
|
lines.push(`${indent}${indent}${indent}<distance type="${escapeXml(d.type)}">${d.value}</distance>`);
|
|
3456
3632
|
}
|
|
3457
3633
|
}
|
|
3634
|
+
if (app["glyphs"]) {
|
|
3635
|
+
for (const g of app["glyphs"]) {
|
|
3636
|
+
lines.push(`${indent}${indent}${indent}<glyph type="${escapeXml(g.type)}">${escapeXml(g.value)}</glyph>`);
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3458
3639
|
lines.push(`${indent}${indent}</appearance>`);
|
|
3459
3640
|
}
|
|
3460
3641
|
if (defaults.musicFont) {
|
|
@@ -3511,16 +3692,16 @@ function serializePageLayout(layout, indent) {
|
|
|
3511
3692
|
const typeAttr = m.type ? ` type="${m.type}"` : "";
|
|
3512
3693
|
lines.push(`${indent} <page-margins${typeAttr}>`);
|
|
3513
3694
|
if (m.leftMargin !== void 0) {
|
|
3514
|
-
lines.push(`${indent} <left-margin>${m.leftMargin}</left-margin>`);
|
|
3695
|
+
lines.push(`${indent} <left-margin>${m.leftMarginRaw ?? m.leftMargin}</left-margin>`);
|
|
3515
3696
|
}
|
|
3516
3697
|
if (m.rightMargin !== void 0) {
|
|
3517
|
-
lines.push(`${indent} <right-margin>${m.rightMargin}</right-margin>`);
|
|
3698
|
+
lines.push(`${indent} <right-margin>${m.rightMarginRaw ?? m.rightMargin}</right-margin>`);
|
|
3518
3699
|
}
|
|
3519
3700
|
if (m.topMargin !== void 0) {
|
|
3520
|
-
lines.push(`${indent} <top-margin>${m.topMargin}</top-margin>`);
|
|
3701
|
+
lines.push(`${indent} <top-margin>${m.topMarginRaw ?? m.topMargin}</top-margin>`);
|
|
3521
3702
|
}
|
|
3522
3703
|
if (m.bottomMargin !== void 0) {
|
|
3523
|
-
lines.push(`${indent} <bottom-margin>${m.bottomMargin}</bottom-margin>`);
|
|
3704
|
+
lines.push(`${indent} <bottom-margin>${m.bottomMarginRaw ?? m.bottomMargin}</bottom-margin>`);
|
|
3524
3705
|
}
|
|
3525
3706
|
lines.push(`${indent} </page-margins>`);
|
|
3526
3707
|
}
|
|
@@ -3534,18 +3715,48 @@ function serializeSystemLayout(layout, indent) {
|
|
|
3534
3715
|
if (layout.systemMargins) {
|
|
3535
3716
|
lines.push(`${indent} <system-margins>`);
|
|
3536
3717
|
if (layout.systemMargins.leftMargin !== void 0) {
|
|
3537
|
-
lines.push(`${indent} <left-margin>${layout.systemMargins.leftMargin}</left-margin>`);
|
|
3718
|
+
lines.push(`${indent} <left-margin>${layout.systemMargins.leftMarginRaw ?? layout.systemMargins.leftMargin}</left-margin>`);
|
|
3538
3719
|
}
|
|
3539
3720
|
if (layout.systemMargins.rightMargin !== void 0) {
|
|
3540
|
-
lines.push(`${indent} <right-margin>${layout.systemMargins.rightMargin}</right-margin>`);
|
|
3721
|
+
lines.push(`${indent} <right-margin>${layout.systemMargins.rightMarginRaw ?? layout.systemMargins.rightMargin}</right-margin>`);
|
|
3541
3722
|
}
|
|
3542
3723
|
lines.push(`${indent} </system-margins>`);
|
|
3543
3724
|
}
|
|
3544
3725
|
if (layout.systemDistance !== void 0) {
|
|
3545
|
-
lines.push(`${indent} <system-distance>${layout.systemDistance}</system-distance>`);
|
|
3726
|
+
lines.push(`${indent} <system-distance>${layout.systemDistanceRaw ?? layout.systemDistance}</system-distance>`);
|
|
3546
3727
|
}
|
|
3547
3728
|
if (layout.topSystemDistance !== void 0) {
|
|
3548
|
-
lines.push(`${indent} <top-system-distance>${layout.topSystemDistance}</top-system-distance>`);
|
|
3729
|
+
lines.push(`${indent} <top-system-distance>${layout.topSystemDistanceRaw ?? layout.topSystemDistance}</top-system-distance>`);
|
|
3730
|
+
}
|
|
3731
|
+
if (layout.systemDividers) {
|
|
3732
|
+
lines.push(`${indent} <system-dividers>`);
|
|
3733
|
+
if (layout.systemDividers.leftDivider) {
|
|
3734
|
+
let attrs = "";
|
|
3735
|
+
if (layout.systemDividers.leftDivider.printObject !== void 0) {
|
|
3736
|
+
attrs += ` print-object="${layout.systemDividers.leftDivider.printObject ? "yes" : "no"}"`;
|
|
3737
|
+
}
|
|
3738
|
+
if (layout.systemDividers.leftDivider.halign) {
|
|
3739
|
+
attrs += ` halign="${layout.systemDividers.leftDivider.halign}"`;
|
|
3740
|
+
}
|
|
3741
|
+
if (layout.systemDividers.leftDivider.valign) {
|
|
3742
|
+
attrs += ` valign="${layout.systemDividers.leftDivider.valign}"`;
|
|
3743
|
+
}
|
|
3744
|
+
lines.push(`${indent} <left-divider${attrs}/>`);
|
|
3745
|
+
}
|
|
3746
|
+
if (layout.systemDividers.rightDivider) {
|
|
3747
|
+
let attrs = "";
|
|
3748
|
+
if (layout.systemDividers.rightDivider.printObject !== void 0) {
|
|
3749
|
+
attrs += ` print-object="${layout.systemDividers.rightDivider.printObject ? "yes" : "no"}"`;
|
|
3750
|
+
}
|
|
3751
|
+
if (layout.systemDividers.rightDivider.halign) {
|
|
3752
|
+
attrs += ` halign="${layout.systemDividers.rightDivider.halign}"`;
|
|
3753
|
+
}
|
|
3754
|
+
if (layout.systemDividers.rightDivider.valign) {
|
|
3755
|
+
attrs += ` valign="${layout.systemDividers.rightDivider.valign}"`;
|
|
3756
|
+
}
|
|
3757
|
+
lines.push(`${indent} <right-divider${attrs}/>`);
|
|
3758
|
+
}
|
|
3759
|
+
lines.push(`${indent} </system-dividers>`);
|
|
3549
3760
|
}
|
|
3550
3761
|
lines.push(`${indent}</system-layout>`);
|
|
3551
3762
|
return lines;
|
|
@@ -3566,6 +3777,7 @@ function serializeCredit(credit, indent) {
|
|
|
3566
3777
|
let attrs2 = "";
|
|
3567
3778
|
if (cw.defaultX !== void 0) attrs2 += ` default-x="${cw.defaultX}"`;
|
|
3568
3779
|
if (cw.defaultY !== void 0) attrs2 += ` default-y="${cw.defaultY}"`;
|
|
3780
|
+
if (cw.fontFamily) attrs2 += ` font-family="${escapeXml(cw.fontFamily)}"`;
|
|
3569
3781
|
if (cw.fontSize) attrs2 += ` font-size="${escapeXml(cw.fontSize)}"`;
|
|
3570
3782
|
if (cw.fontWeight) attrs2 += ` font-weight="${escapeXml(cw.fontWeight)}"`;
|
|
3571
3783
|
if (cw.fontStyle) attrs2 += ` font-style="${escapeXml(cw.fontStyle)}"`;
|
|
@@ -3860,6 +4072,7 @@ function serializeKey(key, indent) {
|
|
|
3860
4072
|
let keyAttrs = "";
|
|
3861
4073
|
if (key.number !== void 0) keyAttrs += ` number="${key.number}"`;
|
|
3862
4074
|
if (key.printObject === false) keyAttrs += ' print-object="no"';
|
|
4075
|
+
else if (key.printObject === true) keyAttrs += ' print-object="yes"';
|
|
3863
4076
|
lines.push(`${indent}<key${keyAttrs}>`);
|
|
3864
4077
|
if (key.cancel !== void 0) {
|
|
3865
4078
|
const locationAttr = key.cancelLocation ? ` location="${key.cancelLocation}"` : "";
|
|
@@ -3907,7 +4120,8 @@ function serializeTime(time, indent) {
|
|
|
3907
4120
|
const maxLen = Math.max(time.beatsList.length, time.beatTypeList.length);
|
|
3908
4121
|
for (let i = 0; i < maxLen; i++) {
|
|
3909
4122
|
if (i < time.beatsList.length) {
|
|
3910
|
-
|
|
4123
|
+
const beatsValue = time.beatsStrList && i < time.beatsStrList.length ? time.beatsStrList[i] : time.beatsList[i];
|
|
4124
|
+
lines.push(`${indent} <beats>${beatsValue}</beats>`);
|
|
3911
4125
|
}
|
|
3912
4126
|
if (i < time.beatTypeList.length) {
|
|
3913
4127
|
lines.push(`${indent} <beat-type>${time.beatTypeList[i]}</beat-type>`);
|
|
@@ -3924,10 +4138,13 @@ function serializeClef(clef, indent) {
|
|
|
3924
4138
|
const lines = [];
|
|
3925
4139
|
let attrs = clef.staff ? ` number="${clef.staff}"` : "";
|
|
3926
4140
|
if (clef.printObject === false) attrs += ' print-object="no"';
|
|
4141
|
+
else if (clef.printObject === true) attrs += ' print-object="yes"';
|
|
3927
4142
|
if (clef.afterBarline) attrs += ' after-barline="yes"';
|
|
3928
4143
|
lines.push(`${indent}<clef${attrs}>`);
|
|
3929
4144
|
lines.push(`${indent} <sign>${clef.sign}</sign>`);
|
|
3930
|
-
|
|
4145
|
+
if (clef.line !== void 0) {
|
|
4146
|
+
lines.push(`${indent} <line>${clef.line}</line>`);
|
|
4147
|
+
}
|
|
3931
4148
|
if (clef.clefOctaveChange !== void 0) {
|
|
3932
4149
|
lines.push(`${indent} <clef-octave-change>${clef.clefOctaveChange}</clef-octave-change>`);
|
|
3933
4150
|
}
|
|
@@ -3963,6 +4180,12 @@ function serializeEntry(entry, indent) {
|
|
|
3963
4180
|
return serializeSound(entry, indent);
|
|
3964
4181
|
case "attributes":
|
|
3965
4182
|
return serializeAttributes(entry.attributes, indent, entry._id);
|
|
4183
|
+
case "grouping": {
|
|
4184
|
+
const grp = entry;
|
|
4185
|
+
let grpAttrs = ` type="${grp.groupingType}"`;
|
|
4186
|
+
if (grp.number) grpAttrs += ` number="${grp.number}"`;
|
|
4187
|
+
return [`${indent}<grouping${grpAttrs}/>`];
|
|
4188
|
+
}
|
|
3966
4189
|
default:
|
|
3967
4190
|
return [];
|
|
3968
4191
|
}
|
|
@@ -3977,12 +4200,13 @@ function serializeNote(note, indent) {
|
|
|
3977
4200
|
"relative-y": note.relativeY,
|
|
3978
4201
|
"dynamics": note.dynamics,
|
|
3979
4202
|
"print-object": note.printObject === false ? false : void 0,
|
|
4203
|
+
"print-dot": note.printDot !== void 0 ? note.printDot : void 0,
|
|
3980
4204
|
"print-spacing": note.printSpacing
|
|
3981
4205
|
});
|
|
3982
4206
|
lines.push(`${indent}<note${noteAttrs}>`);
|
|
3983
4207
|
if (note.grace) {
|
|
3984
4208
|
const graceAttrs = buildAttrs({
|
|
3985
|
-
"slash": note.grace.slash
|
|
4209
|
+
"slash": note.grace.slash !== void 0 ? note.grace.slash : void 0,
|
|
3986
4210
|
"steal-time-previous": note.grace.stealTimePrevious,
|
|
3987
4211
|
"steal-time-following": note.grace.stealTimeFollowing
|
|
3988
4212
|
});
|
|
@@ -4037,7 +4261,9 @@ function serializeNote(note, indent) {
|
|
|
4037
4261
|
} else if (note.tie) {
|
|
4038
4262
|
lines.push(`${indent} <tie type="${note.tie.type}"/>`);
|
|
4039
4263
|
}
|
|
4040
|
-
|
|
4264
|
+
if (note.voice !== void 0) {
|
|
4265
|
+
lines.push(`${indent} <voice>${note.voice}</voice>`);
|
|
4266
|
+
}
|
|
4041
4267
|
if (note.noteType) {
|
|
4042
4268
|
const typeAttrs = note.noteTypeSize ? ` size="${escapeXml(note.noteTypeSize)}"` : "";
|
|
4043
4269
|
lines.push(`${indent} <type${typeAttrs}>${note.noteType}</type>`);
|
|
@@ -4254,7 +4480,18 @@ function serializeNotationsGroup(notations, indent) {
|
|
|
4254
4480
|
let attrs = "";
|
|
4255
4481
|
if (notation.direction) attrs += ` direction="${notation.direction}"`;
|
|
4256
4482
|
if (notation.number !== void 0) attrs += ` number="${notation.number}"`;
|
|
4483
|
+
if (notation.defaultX !== void 0) attrs += ` default-x="${notation.defaultX}"`;
|
|
4484
|
+
if (notation.defaultY !== void 0) attrs += ` default-y="${notation.defaultY}"`;
|
|
4257
4485
|
lines.push(`${indent} <arpeggiate${attrs}/>`);
|
|
4486
|
+
} else if (notation.type === "non-arpeggiate") {
|
|
4487
|
+
let attrs = ` type="${notation.nonArpeggiateType}"`;
|
|
4488
|
+
if (notation.number !== void 0) attrs += ` number="${notation.number}"`;
|
|
4489
|
+
if (notation.placement) attrs += ` placement="${notation.placement}"`;
|
|
4490
|
+
lines.push(`${indent} <non-arpeggiate${attrs}/>`);
|
|
4491
|
+
} else if (notation.type === "accidental-mark") {
|
|
4492
|
+
let attrs = "";
|
|
4493
|
+
if (notation.placement) attrs += ` placement="${notation.placement}"`;
|
|
4494
|
+
lines.push(`${indent} <accidental-mark${attrs}>${escapeXml(notation.value)}</accidental-mark>`);
|
|
4258
4495
|
} else if (notation.type === "glissando") {
|
|
4259
4496
|
let attrs = ` type="${notation.glissandoType}"`;
|
|
4260
4497
|
if (notation.number !== void 0) attrs += ` number="${notation.number}"`;
|
|
@@ -4268,7 +4505,11 @@ function serializeNotationsGroup(notations, indent) {
|
|
|
4268
4505
|
let attrs = ` type="${notation.slideType}"`;
|
|
4269
4506
|
if (notation.number !== void 0) attrs += ` number="${notation.number}"`;
|
|
4270
4507
|
if (notation.lineType) attrs += ` line-type="${notation.lineType}"`;
|
|
4271
|
-
|
|
4508
|
+
if (notation.text) {
|
|
4509
|
+
lines.push(`${indent} <slide${attrs}>${escapeXml(notation.text)}</slide>`);
|
|
4510
|
+
} else {
|
|
4511
|
+
lines.push(`${indent} <slide${attrs}/>`);
|
|
4512
|
+
}
|
|
4272
4513
|
}
|
|
4273
4514
|
}
|
|
4274
4515
|
const sortedArtIndices = Array.from(articulationsGroups.keys()).sort((a, b) => a - b);
|
|
@@ -4289,44 +4530,50 @@ function serializeNotationsGroup(notations, indent) {
|
|
|
4289
4530
|
lines.push(`${indent} </articulations>`);
|
|
4290
4531
|
}
|
|
4291
4532
|
if (ornaments.length > 0) {
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
if (orn.
|
|
4301
|
-
|
|
4302
|
-
if (orn.
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
if (orn.
|
|
4310
|
-
|
|
4311
|
-
|
|
4533
|
+
const hasOnlyEmptyMarker = ornaments.length === 1 && ornaments[0].type === "ornament" && ornaments[0].ornament === "empty";
|
|
4534
|
+
if (hasOnlyEmptyMarker) {
|
|
4535
|
+
lines.push(`${indent} <ornaments/>`);
|
|
4536
|
+
} else {
|
|
4537
|
+
lines.push(`${indent} <ornaments>`);
|
|
4538
|
+
const allAccidentalMarks = [];
|
|
4539
|
+
for (const orn of ornaments) {
|
|
4540
|
+
if (orn.type === "ornament") {
|
|
4541
|
+
if (orn.ornament === "empty") continue;
|
|
4542
|
+
const placementAttr = orn.placement ? ` placement="${orn.placement}"` : "";
|
|
4543
|
+
if (orn.ornament === "wavy-line") {
|
|
4544
|
+
let wlAttrs = "";
|
|
4545
|
+
if (orn.wavyLineType) wlAttrs += ` type="${orn.wavyLineType}"`;
|
|
4546
|
+
if (orn.number !== void 0) wlAttrs += ` number="${orn.number}"`;
|
|
4547
|
+
wlAttrs += placementAttr;
|
|
4548
|
+
if (orn.defaultY !== void 0) wlAttrs += ` default-y="${orn.defaultY}"`;
|
|
4549
|
+
lines.push(`${indent} <wavy-line${wlAttrs}/>`);
|
|
4550
|
+
} else if (orn.ornament === "tremolo") {
|
|
4551
|
+
let tremAttrs = "";
|
|
4552
|
+
if (orn.tremoloType) tremAttrs += ` type="${orn.tremoloType}"`;
|
|
4553
|
+
tremAttrs += placementAttr;
|
|
4554
|
+
if (orn.defaultX !== void 0) tremAttrs += ` default-x="${orn.defaultX}"`;
|
|
4555
|
+
if (orn.defaultY !== void 0) tremAttrs += ` default-y="${orn.defaultY}"`;
|
|
4556
|
+
if (orn.tremoloMarks !== void 0) {
|
|
4557
|
+
lines.push(`${indent} <tremolo${tremAttrs}>${orn.tremoloMarks}</tremolo>`);
|
|
4558
|
+
} else {
|
|
4559
|
+
lines.push(`${indent} <tremolo${tremAttrs}/>`);
|
|
4560
|
+
}
|
|
4312
4561
|
} else {
|
|
4313
|
-
|
|
4562
|
+
let ornAttrs = placementAttr;
|
|
4563
|
+
if (orn.defaultY !== void 0) ornAttrs += ` default-y="${orn.defaultY}"`;
|
|
4564
|
+
lines.push(`${indent} <${orn.ornament}${ornAttrs}/>`);
|
|
4565
|
+
}
|
|
4566
|
+
if (orn.accidentalMarks) {
|
|
4567
|
+
allAccidentalMarks.push(...orn.accidentalMarks);
|
|
4314
4568
|
}
|
|
4315
|
-
} else {
|
|
4316
|
-
let ornAttrs = placementAttr;
|
|
4317
|
-
if (orn.defaultY !== void 0) ornAttrs += ` default-y="${orn.defaultY}"`;
|
|
4318
|
-
lines.push(`${indent} <${orn.ornament}${ornAttrs}/>`);
|
|
4319
|
-
}
|
|
4320
|
-
if (orn.accidentalMarks) {
|
|
4321
|
-
allAccidentalMarks.push(...orn.accidentalMarks);
|
|
4322
4569
|
}
|
|
4323
4570
|
}
|
|
4571
|
+
for (const am of allAccidentalMarks) {
|
|
4572
|
+
const amPlacement = am.placement ? ` placement="${am.placement}"` : "";
|
|
4573
|
+
lines.push(`${indent} <accidental-mark${amPlacement}>${am.value}</accidental-mark>`);
|
|
4574
|
+
}
|
|
4575
|
+
lines.push(`${indent} </ornaments>`);
|
|
4324
4576
|
}
|
|
4325
|
-
for (const am of allAccidentalMarks) {
|
|
4326
|
-
const amPlacement = am.placement ? ` placement="${am.placement}"` : "";
|
|
4327
|
-
lines.push(`${indent} <accidental-mark${amPlacement}>${am.value}</accidental-mark>`);
|
|
4328
|
-
}
|
|
4329
|
-
lines.push(`${indent} </ornaments>`);
|
|
4330
4577
|
}
|
|
4331
4578
|
if (technicals.length > 0) {
|
|
4332
4579
|
lines.push(`${indent} <technical>`);
|
|
@@ -4347,8 +4594,8 @@ function serializeNotationsGroup(notations, indent) {
|
|
|
4347
4594
|
if (techNotation.release) {
|
|
4348
4595
|
lines.push(`${indent} <release/>`);
|
|
4349
4596
|
}
|
|
4350
|
-
if (techNotation.withBar
|
|
4351
|
-
lines.push(`${indent} <with-bar
|
|
4597
|
+
if (techNotation.withBar) {
|
|
4598
|
+
lines.push(`${indent} <with-bar/>`);
|
|
4352
4599
|
}
|
|
4353
4600
|
lines.push(`${indent} </bend>`);
|
|
4354
4601
|
} else if (tech.technical === "harmonic") {
|
|
@@ -4365,8 +4612,10 @@ function serializeNotationsGroup(notations, indent) {
|
|
|
4365
4612
|
lines.push(`${indent} <harmonic${placementAttr}/>`);
|
|
4366
4613
|
}
|
|
4367
4614
|
} else if (tech.technical === "hammer-on" || tech.technical === "pull-off") {
|
|
4368
|
-
let attrs =
|
|
4615
|
+
let attrs = "";
|
|
4616
|
+
if (techNotation.number !== void 0) attrs += ` number="${techNotation.number}"`;
|
|
4369
4617
|
if (techNotation.startStop) attrs += ` type="${techNotation.startStop}"`;
|
|
4618
|
+
attrs += placementAttr;
|
|
4370
4619
|
if (techNotation.text !== void 0) {
|
|
4371
4620
|
lines.push(`${indent} <${tech.technical}${attrs}>${escapeXml(techNotation.text)}</${tech.technical}>`);
|
|
4372
4621
|
} else {
|
|
@@ -4422,7 +4671,7 @@ function serializeLyric(lyric, indent) {
|
|
|
4422
4671
|
lines.push(`${indent} <elision/>`);
|
|
4423
4672
|
}
|
|
4424
4673
|
}
|
|
4425
|
-
} else {
|
|
4674
|
+
} else if (lyric.syllabic || lyric.text) {
|
|
4426
4675
|
if (lyric.syllabic) {
|
|
4427
4676
|
lines.push(`${indent} <syllabic>${lyric.syllabic}</syllabic>`);
|
|
4428
4677
|
}
|
|
@@ -4537,7 +4786,12 @@ function serializeDirectionType(dirType, indent) {
|
|
|
4537
4786
|
if (dirType.relativeX !== void 0) dynAttrs += ` relative-x="${dirType.relativeX}"`;
|
|
4538
4787
|
if (dirType.halign) dynAttrs += ` halign="${dirType.halign}"`;
|
|
4539
4788
|
lines.push(`${indent} <dynamics${dynAttrs}>`);
|
|
4540
|
-
|
|
4789
|
+
if (dirType.value) {
|
|
4790
|
+
lines.push(`${indent} <${dirType.value}/>`);
|
|
4791
|
+
}
|
|
4792
|
+
if (dirType.otherDynamics) {
|
|
4793
|
+
lines.push(`${indent} <other-dynamics>${escapeXml(dirType.otherDynamics)}</other-dynamics>`);
|
|
4794
|
+
}
|
|
4541
4795
|
lines.push(`${indent} </dynamics>`);
|
|
4542
4796
|
break;
|
|
4543
4797
|
}
|
|
@@ -4577,6 +4831,7 @@ function serializeDirectionType(dirType, indent) {
|
|
|
4577
4831
|
if (dirType.defaultX !== void 0) wordAttrs += ` default-x="${dirType.defaultX}"`;
|
|
4578
4832
|
if (dirType.defaultY !== void 0) wordAttrs += ` default-y="${dirType.defaultY}"`;
|
|
4579
4833
|
if (dirType.relativeX !== void 0) wordAttrs += ` relative-x="${dirType.relativeX}"`;
|
|
4834
|
+
if (dirType.relativeY !== void 0) wordAttrs += ` relative-y="${dirType.relativeY}"`;
|
|
4580
4835
|
if (dirType.fontFamily) wordAttrs += ` font-family="${escapeXml(dirType.fontFamily)}"`;
|
|
4581
4836
|
if (dirType.fontSize) wordAttrs += ` font-size="${escapeXml(dirType.fontSize)}"`;
|
|
4582
4837
|
if (dirType.fontStyle) wordAttrs += ` font-style="${escapeXml(dirType.fontStyle)}"`;
|
|
@@ -4623,8 +4878,12 @@ function serializeDirectionType(dirType, indent) {
|
|
|
4623
4878
|
if (dirType.high) {
|
|
4624
4879
|
lines.push(`${indent} <accordion-high/>`);
|
|
4625
4880
|
}
|
|
4626
|
-
if (dirType.middle !== void 0) {
|
|
4627
|
-
|
|
4881
|
+
if (dirType.middlePresent || dirType.middle !== void 0) {
|
|
4882
|
+
if (dirType.middle !== void 0) {
|
|
4883
|
+
lines.push(`${indent} <accordion-middle>${dirType.middle}</accordion-middle>`);
|
|
4884
|
+
} else {
|
|
4885
|
+
lines.push(`${indent} <accordion-middle/>`);
|
|
4886
|
+
}
|
|
4628
4887
|
}
|
|
4629
4888
|
if (dirType.low) {
|
|
4630
4889
|
lines.push(`${indent} <accordion-low/>`);
|
|
@@ -4737,11 +4996,20 @@ function serializeBarline(barline, indent) {
|
|
|
4737
4996
|
lines.push(`${indent} <bar-style>${barline.barStyle}</bar-style>`);
|
|
4738
4997
|
}
|
|
4739
4998
|
if (barline.ending) {
|
|
4740
|
-
|
|
4999
|
+
let endingAttrs = ` number="${barline.ending.number}" type="${barline.ending.type}"`;
|
|
5000
|
+
if (barline.ending.defaultY !== void 0) endingAttrs += ` default-y="${barline.ending.defaultY}"`;
|
|
5001
|
+
if (barline.ending.endLength !== void 0) endingAttrs += ` end-length="${barline.ending.endLength}"`;
|
|
5002
|
+
if (barline.ending.text) {
|
|
5003
|
+
lines.push(`${indent} <ending${endingAttrs}>${escapeXml(barline.ending.text)}</ending>`);
|
|
5004
|
+
} else {
|
|
5005
|
+
lines.push(`${indent} <ending${endingAttrs}/>`);
|
|
5006
|
+
}
|
|
4741
5007
|
}
|
|
4742
5008
|
if (barline.repeat) {
|
|
4743
|
-
|
|
4744
|
-
|
|
5009
|
+
let repeatAttrs = ` direction="${barline.repeat.direction}"`;
|
|
5010
|
+
if (barline.repeat.times !== void 0) repeatAttrs += ` times="${barline.repeat.times}"`;
|
|
5011
|
+
if (barline.repeat.winged) repeatAttrs += ` winged="${barline.repeat.winged}"`;
|
|
5012
|
+
lines.push(`${indent} <repeat${repeatAttrs}/>`);
|
|
4745
5013
|
}
|
|
4746
5014
|
lines.push(`${indent}</barline>`);
|
|
4747
5015
|
return lines;
|
|
@@ -4774,7 +5042,8 @@ function serializeStaffDetails(sd, indent) {
|
|
|
4774
5042
|
const attrs = buildAttrs({
|
|
4775
5043
|
"number": sd.number,
|
|
4776
5044
|
"show-frets": sd.showFrets,
|
|
4777
|
-
"print-object": sd.printObject
|
|
5045
|
+
"print-object": sd.printObject,
|
|
5046
|
+
"print-spacing": sd.printSpacing
|
|
4778
5047
|
});
|
|
4779
5048
|
lines.push(`${indent}<staff-details${attrs}>`);
|
|
4780
5049
|
pushOptionalElement(lines, `${indent} `, "staff-type", sd.staffType);
|
|
@@ -4840,16 +5109,22 @@ function serializeHarmony(harmony, indent) {
|
|
|
4840
5109
|
}
|
|
4841
5110
|
lines.push(`${indent} </root>`);
|
|
4842
5111
|
let kindAttrs = "";
|
|
4843
|
-
if (harmony.kindText) kindAttrs += ` text="${escapeXml(harmony.kindText)}"`;
|
|
5112
|
+
if (harmony.kindText !== void 0) kindAttrs += ` text="${escapeXml(harmony.kindText)}"`;
|
|
5113
|
+
if (harmony.kindHalign) kindAttrs += ` halign="${escapeXml(harmony.kindHalign)}"`;
|
|
4844
5114
|
lines.push(`${indent} <kind${kindAttrs}>${escapeXml(harmony.kind)}</kind>`);
|
|
4845
5115
|
if (harmony.bass) {
|
|
4846
|
-
|
|
5116
|
+
let bassAttrs = "";
|
|
5117
|
+
if (harmony.bass.arrangement) bassAttrs += ` arrangement="${escapeXml(harmony.bass.arrangement)}"`;
|
|
5118
|
+
lines.push(`${indent} <bass${bassAttrs}>`);
|
|
4847
5119
|
lines.push(`${indent} <bass-step>${harmony.bass.bassStep}</bass-step>`);
|
|
4848
5120
|
if (harmony.bass.bassAlter !== void 0) {
|
|
4849
5121
|
lines.push(`${indent} <bass-alter>${harmony.bass.bassAlter}</bass-alter>`);
|
|
4850
5122
|
}
|
|
4851
5123
|
lines.push(`${indent} </bass>`);
|
|
4852
5124
|
}
|
|
5125
|
+
if (harmony.inversion !== void 0) {
|
|
5126
|
+
lines.push(`${indent} <inversion>${harmony.inversion}</inversion>`);
|
|
5127
|
+
}
|
|
4853
5128
|
if (harmony.degrees) {
|
|
4854
5129
|
for (const deg of harmony.degrees) {
|
|
4855
5130
|
lines.push(`${indent} <degree>`);
|
|
@@ -5535,7 +5810,7 @@ function groupByVoice(measure) {
|
|
|
5535
5810
|
for (const entry of measure.entries) {
|
|
5536
5811
|
if (entry.type !== "note") continue;
|
|
5537
5812
|
const staff = entry.staff ?? 1;
|
|
5538
|
-
const voice = entry.voice;
|
|
5813
|
+
const voice = entry.voice ?? 1;
|
|
5539
5814
|
const key = `${staff}-${voice}`;
|
|
5540
5815
|
if (!groups.has(key)) {
|
|
5541
5816
|
groups.set(key, { staff, voice, notes: [] });
|
|
@@ -5629,7 +5904,7 @@ function getVoices(measure) {
|
|
|
5629
5904
|
const voices = /* @__PURE__ */ new Set();
|
|
5630
5905
|
for (const entry of measure.entries) {
|
|
5631
5906
|
if (entry.type === "note") {
|
|
5632
|
-
voices.add(entry.voice);
|
|
5907
|
+
voices.add(entry.voice ?? 1);
|
|
5633
5908
|
}
|
|
5634
5909
|
}
|
|
5635
5910
|
return Array.from(voices).sort((a, b) => a - b);
|
|
@@ -5680,7 +5955,7 @@ function buildVoiceToStaffMap(measure) {
|
|
|
5680
5955
|
const map = /* @__PURE__ */ new Map();
|
|
5681
5956
|
for (const entry of measure.entries) {
|
|
5682
5957
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
5683
|
-
const voice = entry.voice;
|
|
5958
|
+
const voice = entry.voice ?? 1;
|
|
5684
5959
|
const staff = entry.staff;
|
|
5685
5960
|
if (!map.has(voice)) {
|
|
5686
5961
|
map.set(voice, staff);
|
|
@@ -5699,7 +5974,7 @@ function buildVoiceToStaffMapForPart(part) {
|
|
|
5699
5974
|
for (const measure of part.measures) {
|
|
5700
5975
|
for (const entry of measure.entries) {
|
|
5701
5976
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
5702
|
-
const voice = entry.voice;
|
|
5977
|
+
const voice = entry.voice ?? 1;
|
|
5703
5978
|
const staff = entry.staff;
|
|
5704
5979
|
if (!map.has(voice)) {
|
|
5705
5980
|
map.set(voice, staff);
|
|
@@ -5718,7 +5993,7 @@ function inferStaff(entry, voiceToStaffMap) {
|
|
|
5718
5993
|
if (entry.staff !== void 0) {
|
|
5719
5994
|
return entry.staff;
|
|
5720
5995
|
}
|
|
5721
|
-
const inferredStaff = voiceToStaffMap.get(entry.voice);
|
|
5996
|
+
const inferredStaff = voiceToStaffMap.get(entry.voice ?? 1);
|
|
5722
5997
|
if (inferredStaff !== void 0) {
|
|
5723
5998
|
return inferredStaff;
|
|
5724
5999
|
}
|
|
@@ -5761,7 +6036,7 @@ function getVoicesForStaff(measure, staff) {
|
|
|
5761
6036
|
if (entry.type === "note") {
|
|
5762
6037
|
const entryStaff = entry.staff ?? 1;
|
|
5763
6038
|
if (entryStaff === staff) {
|
|
5764
|
-
voices.add(entry.voice);
|
|
6039
|
+
voices.add(entry.voice ?? 1);
|
|
5765
6040
|
}
|
|
5766
6041
|
}
|
|
5767
6042
|
}
|
|
@@ -6097,6 +6372,7 @@ function getDynamics(score, options) {
|
|
|
6097
6372
|
if (dirType.kind === "dynamics") {
|
|
6098
6373
|
results.push({
|
|
6099
6374
|
dynamic: dirType.value,
|
|
6375
|
+
otherDynamics: dirType.otherDynamics,
|
|
6100
6376
|
direction: entry,
|
|
6101
6377
|
part,
|
|
6102
6378
|
partIndex,
|
|
@@ -7171,14 +7447,17 @@ function hasNotesInRange(voiceEntries, startPos, endPos) {
|
|
|
7171
7447
|
return { hasNotes: conflicting.length > 0, conflictingNotes: conflicting };
|
|
7172
7448
|
}
|
|
7173
7449
|
function createRest(duration, voice, staff) {
|
|
7174
|
-
|
|
7450
|
+
const note = {
|
|
7175
7451
|
_id: generateId(),
|
|
7176
7452
|
type: "note",
|
|
7177
7453
|
rest: { displayStep: void 0, displayOctave: void 0 },
|
|
7178
7454
|
duration,
|
|
7179
|
-
voice,
|
|
7180
7455
|
staff
|
|
7181
7456
|
};
|
|
7457
|
+
if (voice !== void 0) {
|
|
7458
|
+
note.voice = voice;
|
|
7459
|
+
}
|
|
7460
|
+
return note;
|
|
7182
7461
|
}
|
|
7183
7462
|
function rebuildMeasureWithVoice(measure, voice, newEntries, measureDuration, staff) {
|
|
7184
7463
|
const otherEntries = [];
|
|
@@ -8732,7 +9011,7 @@ function autoBeam(score, options) {
|
|
|
8732
9011
|
for (const entry of measure.entries) {
|
|
8733
9012
|
if (entry.type === "note") {
|
|
8734
9013
|
if (!entry.chord && !entry.rest) {
|
|
8735
|
-
const voice = entry.voice;
|
|
9014
|
+
const voice = entry.voice ?? 1;
|
|
8736
9015
|
if (options.voice === void 0 || voice === options.voice) {
|
|
8737
9016
|
if (!notesByVoice.has(voice)) {
|
|
8738
9017
|
notesByVoice.set(voice, []);
|