musicxml-io 0.2.7 → 0.2.9

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/dist/index.js CHANGED
@@ -45,14 +45,17 @@ __export(src_exports, {
45
45
  getAbsolutePosition: () => getAbsolutePosition,
46
46
  getAdjacentNotes: () => getAdjacentNotes,
47
47
  getAllNotes: () => getAllNotes,
48
+ getAllPartInfos: () => getAllPartInfos,
48
49
  getAttributesAtMeasure: () => getAttributesAtMeasure,
49
50
  getBeamGroups: () => getBeamGroups,
50
51
  getChordProgression: () => getChordProgression,
51
52
  getChords: () => getChords,
52
53
  getClefChanges: () => getClefChanges,
53
54
  getClefForStaff: () => getClefForStaff,
55
+ getDirectionOfKind: () => getDirectionOfKind,
54
56
  getDirections: () => getDirections,
55
57
  getDirectionsAtPosition: () => getDirectionsAtPosition,
58
+ getDirectionsOfKind: () => getDirectionsOfKind,
56
59
  getDivisions: () => getDivisions,
57
60
  getDuration: () => getDuration,
58
61
  getDynamics: () => getDynamics,
@@ -79,15 +82,24 @@ __export(src_exports, {
79
82
  getNotesForVoice: () => getNotesForVoice,
80
83
  getNotesInRange: () => getNotesInRange,
81
84
  getOctaveShifts: () => getOctaveShifts,
85
+ getPartAbbreviation: () => getPartAbbreviation,
82
86
  getPartById: () => getPartById,
83
87
  getPartByIndex: () => getPartByIndex,
84
88
  getPartCount: () => getPartCount,
85
89
  getPartIds: () => getPartIds,
86
90
  getPartIndex: () => getPartIndex,
91
+ getPartInfo: () => getPartInfo,
92
+ getPartName: () => getPartName,
93
+ getPartNameMap: () => getPartNameMap,
87
94
  getPedalMarkings: () => getPedalMarkings,
88
95
  getPrevNote: () => getPrevNote,
89
96
  getRepeatStructure: () => getRepeatStructure,
90
97
  getSlurSpans: () => getSlurSpans,
98
+ getSoundDamperPedal: () => getSoundDamperPedal,
99
+ getSoundDynamics: () => getSoundDynamics,
100
+ getSoundSoftPedal: () => getSoundSoftPedal,
101
+ getSoundSostenutoPedal: () => getSoundSostenutoPedal,
102
+ getSoundTempo: () => getSoundTempo,
91
103
  getStaffRange: () => getStaffRange,
92
104
  getStaveCount: () => getStaveCount,
93
105
  getStaves: () => getStaves,
@@ -105,12 +117,27 @@ __export(src_exports, {
105
117
  getWedges: () => getWedges,
106
118
  groupByStaff: () => groupByStaff,
107
119
  groupByVoice: () => groupByVoice,
120
+ hasBeam: () => hasBeam,
121
+ hasDirectionOfKind: () => hasDirectionOfKind,
122
+ hasLyrics: () => hasLyrics,
108
123
  hasMultipleStaves: () => hasMultipleStaves,
124
+ hasNotations: () => hasNotations,
109
125
  hasNotes: () => hasNotes,
126
+ hasTie: () => hasTie,
127
+ hasTieStart: () => hasTieStart,
128
+ hasTieStop: () => hasTieStop,
129
+ hasTuplet: () => hasTuplet,
110
130
  inferStaff: () => inferStaff,
111
131
  insertMeasure: () => insertMeasure,
132
+ isChordNote: () => isChordNote,
112
133
  isCompressed: () => isCompressed,
134
+ isCueNote: () => isCueNote,
135
+ isGraceNote: () => isGraceNote,
136
+ isPartInfo: () => isPartInfo,
137
+ isPitchedNote: () => isPitchedNote,
138
+ isRest: () => isRest,
113
139
  isRestMeasure: () => isRestMeasure,
140
+ isUnpitchedNote: () => isUnpitchedNote,
114
141
  isValid: () => isValid,
115
142
  iterateEntries: () => iterateEntries,
116
143
  iterateNotes: () => iterateNotes,
@@ -3700,8 +3727,10 @@ function serializeSystemLayout(layout, indent) {
3700
3727
  }
3701
3728
  function serializeCredit(credit, indent) {
3702
3729
  const lines = [];
3703
- const pageAttr = credit.page !== void 0 ? ` page="${credit.page}"` : "";
3704
- lines.push(`${indent}<credit${pageAttr}>`);
3730
+ let attrs = "";
3731
+ if (credit._id) attrs += ` id="${escapeXml(credit._id)}"`;
3732
+ if (credit.page !== void 0) attrs += ` page="${credit.page}"`;
3733
+ lines.push(`${indent}<credit${attrs}>`);
3705
3734
  if (credit.creditType) {
3706
3735
  for (const ct of credit.creditType) {
3707
3736
  lines.push(`${indent}${indent}<credit-type>${escapeXml(ct)}</credit-type>`);
@@ -3709,19 +3738,19 @@ function serializeCredit(credit, indent) {
3709
3738
  }
3710
3739
  if (credit.creditWords) {
3711
3740
  for (const cw of credit.creditWords) {
3712
- let attrs = "";
3713
- if (cw.defaultX !== void 0) attrs += ` default-x="${cw.defaultX}"`;
3714
- if (cw.defaultY !== void 0) attrs += ` default-y="${cw.defaultY}"`;
3715
- if (cw.fontSize) attrs += ` font-size="${escapeXml(cw.fontSize)}"`;
3716
- if (cw.fontWeight) attrs += ` font-weight="${escapeXml(cw.fontWeight)}"`;
3717
- if (cw.fontStyle) attrs += ` font-style="${escapeXml(cw.fontStyle)}"`;
3718
- if (cw.justify) attrs += ` justify="${escapeXml(cw.justify)}"`;
3719
- if (cw.halign) attrs += ` halign="${escapeXml(cw.halign)}"`;
3720
- if (cw.valign) attrs += ` valign="${escapeXml(cw.valign)}"`;
3721
- if (cw.letterSpacing) attrs += ` letter-spacing="${escapeXml(cw.letterSpacing)}"`;
3722
- if (cw.xmlLang) attrs += ` xml:lang="${escapeXml(cw.xmlLang)}"`;
3723
- if (cw.xmlSpace) attrs += ` xml:space="${escapeXml(cw.xmlSpace)}"`;
3724
- lines.push(`${indent}${indent}<credit-words${attrs}>${escapeXml(cw.text)}</credit-words>`);
3741
+ let attrs2 = "";
3742
+ if (cw.defaultX !== void 0) attrs2 += ` default-x="${cw.defaultX}"`;
3743
+ if (cw.defaultY !== void 0) attrs2 += ` default-y="${cw.defaultY}"`;
3744
+ if (cw.fontSize) attrs2 += ` font-size="${escapeXml(cw.fontSize)}"`;
3745
+ if (cw.fontWeight) attrs2 += ` font-weight="${escapeXml(cw.fontWeight)}"`;
3746
+ if (cw.fontStyle) attrs2 += ` font-style="${escapeXml(cw.fontStyle)}"`;
3747
+ if (cw.justify) attrs2 += ` justify="${escapeXml(cw.justify)}"`;
3748
+ if (cw.halign) attrs2 += ` halign="${escapeXml(cw.halign)}"`;
3749
+ if (cw.valign) attrs2 += ` valign="${escapeXml(cw.valign)}"`;
3750
+ if (cw.letterSpacing) attrs2 += ` letter-spacing="${escapeXml(cw.letterSpacing)}"`;
3751
+ if (cw.xmlLang) attrs2 += ` xml:lang="${escapeXml(cw.xmlLang)}"`;
3752
+ if (cw.xmlSpace) attrs2 += ` xml:space="${escapeXml(cw.xmlSpace)}"`;
3753
+ lines.push(`${indent}${indent}<credit-words${attrs2}>${escapeXml(cw.text)}</credit-words>`);
3725
3754
  }
3726
3755
  }
3727
3756
  lines.push(`${indent}</credit>`);
@@ -3841,6 +3870,7 @@ function serializePartGroup(group, indent) {
3841
3870
  const lines = [];
3842
3871
  let attrs = ` type="${group.groupType}"`;
3843
3872
  if (group.number !== void 0) attrs += ` number="${group.number}"`;
3873
+ if (group._id) attrs += ` id="${escapeXml(group._id)}"`;
3844
3874
  lines.push(`${indent}<part-group${attrs}>`);
3845
3875
  if (group.groupName) {
3846
3876
  lines.push(`${indent} <group-name>${escapeXml(group.groupName)}</group-name>`);
@@ -3881,6 +3911,7 @@ function serializePart(part, indent) {
3881
3911
  function serializeMeasure(measure, indent) {
3882
3912
  const lines = [];
3883
3913
  let attrs = ` number="${measure.number}"`;
3914
+ if (measure._id) attrs += ` id="${escapeXml(measure._id)}"`;
3884
3915
  if (measure.width !== void 0) attrs += ` width="${measure.width}"`;
3885
3916
  if (measure.implicit) attrs += ` implicit="yes"`;
3886
3917
  lines.push(`${indent}<measure${attrs}>`);
@@ -3955,9 +3986,10 @@ function serializePrint(print, indent) {
3955
3986
  lines.push(`${indent}</print>`);
3956
3987
  return lines;
3957
3988
  }
3958
- function serializeAttributes(attrs, indent) {
3989
+ function serializeAttributes(attrs, indent, id) {
3959
3990
  const lines = [];
3960
- lines.push(`${indent}<attributes>`);
3991
+ const idAttr = id ? ` id="${escapeXml(id)}"` : "";
3992
+ lines.push(`${indent}<attributes${idAttr}>`);
3961
3993
  if (attrs.divisions !== void 0) {
3962
3994
  lines.push(`${indent} <divisions>${attrs.divisions}</divisions>`);
3963
3995
  }
@@ -4105,7 +4137,7 @@ function serializeEntry(entry, indent) {
4105
4137
  case "sound":
4106
4138
  return serializeSound(entry, indent);
4107
4139
  case "attributes":
4108
- return serializeAttributes(entry.attributes, indent);
4140
+ return serializeAttributes(entry.attributes, indent, entry._id);
4109
4141
  default:
4110
4142
  return [];
4111
4143
  }
@@ -4113,6 +4145,7 @@ function serializeEntry(entry, indent) {
4113
4145
  function serializeNote(note, indent) {
4114
4146
  const lines = [];
4115
4147
  const noteAttrs = buildAttrs({
4148
+ "id": note._id,
4116
4149
  "default-x": note.defaultX,
4117
4150
  "default-y": note.defaultY,
4118
4151
  "relative-x": note.relativeX,
@@ -4595,7 +4628,8 @@ function serializeBackup(backup, indent) {
4595
4628
  }
4596
4629
  function serializeForward(forward, indent) {
4597
4630
  const lines = [];
4598
- lines.push(`${indent}<forward>`);
4631
+ const idAttr = forward._id ? ` id="${escapeXml(forward._id)}"` : "";
4632
+ lines.push(`${indent}<forward${idAttr}>`);
4599
4633
  lines.push(`${indent} <duration>${forward.duration}</duration>`);
4600
4634
  if (forward.voice !== void 0) {
4601
4635
  lines.push(`${indent} <voice>${forward.voice}</voice>`);
@@ -4609,6 +4643,7 @@ function serializeForward(forward, indent) {
4609
4643
  function serializeDirection(direction, indent) {
4610
4644
  const lines = [];
4611
4645
  let attrs = "";
4646
+ if (direction._id) attrs += ` id="${escapeXml(direction._id)}"`;
4612
4647
  if (direction.placement) attrs += ` placement="${direction.placement}"`;
4613
4648
  if (direction.directive) attrs += ' directive="yes"';
4614
4649
  if (direction.system) attrs += ` system="${direction.system}"`;
@@ -4870,7 +4905,9 @@ function serializeDirectionType(dirType, indent) {
4870
4905
  }
4871
4906
  function serializeBarline(barline, indent) {
4872
4907
  const lines = [];
4873
- lines.push(`${indent}<barline location="${barline.location}">`);
4908
+ let attrs = ` location="${barline.location}"`;
4909
+ if (barline._id) attrs += ` id="${escapeXml(barline._id)}"`;
4910
+ lines.push(`${indent}<barline${attrs}>`);
4874
4911
  if (barline.barStyle) {
4875
4912
  lines.push(`${indent} <bar-style>${barline.barStyle}</bar-style>`);
4876
4913
  }
@@ -4963,6 +5000,7 @@ function serializeMeasureStyle(ms, indent) {
4963
5000
  function serializeHarmony(harmony, indent) {
4964
5001
  const lines = [];
4965
5002
  const attrs = buildAttrs({
5003
+ id: harmony._id,
4966
5004
  placement: harmony.placement,
4967
5005
  "print-frame": harmony.printFrame,
4968
5006
  "default-y": harmony.defaultY,
@@ -5040,6 +5078,7 @@ function serializeHarmony(harmony, indent) {
5040
5078
  function serializeFiguredBass(fb, indent) {
5041
5079
  const lines = [];
5042
5080
  let attrs = "";
5081
+ if (fb._id) attrs += ` id="${escapeXml(fb._id)}"`;
5043
5082
  if (fb.parentheses) attrs += ' parentheses="yes"';
5044
5083
  lines.push(`${indent}<figured-bass${attrs}>`);
5045
5084
  for (const fig of fb.figures) {
@@ -5071,6 +5110,7 @@ function serializeFiguredBass(fb, indent) {
5071
5110
  function serializeSound(sound, indent) {
5072
5111
  const lines = [];
5073
5112
  const attrs = [];
5113
+ if (sound._id) attrs.push(`id="${escapeXml(sound._id)}"`);
5074
5114
  if (sound.tempo !== void 0) attrs.push(`tempo="${sound.tempo}"`);
5075
5115
  if (sound.dynamics !== void 0) attrs.push(`dynamics="${sound.dynamics}"`);
5076
5116
  if (sound.dacapo) attrs.push('dacapo="yes"');
@@ -5102,7 +5142,7 @@ function serializeSound(sound, indent) {
5102
5142
  }
5103
5143
  lines.push(`${indent} </swing>`);
5104
5144
  lines.push(`${indent}</sound>`);
5105
- } else if (attrs.length === 0) {
5145
+ } else if (attrs.length === 0 && !sound._id) {
5106
5146
  lines.push(`${indent}<sound/>`);
5107
5147
  } else {
5108
5148
  lines.push(`${indent}<sound${attrStr}/>`);
@@ -5531,7 +5571,7 @@ function getMeasureEndPosition(measure) {
5531
5571
  return state.position;
5532
5572
  }
5533
5573
 
5534
- // src/accessors/index.ts
5574
+ // src/query/index.ts
5535
5575
  function getNotesForVoice(measure, filter) {
5536
5576
  return measure.entries.filter((entry) => {
5537
5577
  if (entry.type !== "note") return false;
@@ -6272,17 +6312,17 @@ function getTiedNoteGroups(score, options) {
6272
6312
  measureIndex,
6273
6313
  position
6274
6314
  };
6275
- const hasTieStart = entry.tie?.type === "start" || entry.ties?.some((t) => t.type === "start") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "start");
6276
- const hasTieStop = entry.tie?.type === "stop" || entry.ties?.some((t) => t.type === "stop") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "stop");
6277
- if (hasTieStop && pendingTies.has(pitchKey)) {
6315
+ const hasTieStart2 = entry.tie?.type === "start" || entry.ties?.some((t) => t.type === "start") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "start");
6316
+ const hasTieStop2 = entry.tie?.type === "stop" || entry.ties?.some((t) => t.type === "stop") || entry.notations?.some((n) => n.type === "tied" && n.tiedType === "stop");
6317
+ if (hasTieStop2 && pendingTies.has(pitchKey)) {
6278
6318
  const group = pendingTies.get(pitchKey);
6279
6319
  group.push(context);
6280
- if (!hasTieStart) {
6320
+ if (!hasTieStart2) {
6281
6321
  const totalDuration = group.reduce((sum, nc) => sum + nc.note.duration, 0);
6282
6322
  results.push({ notes: group, totalDuration });
6283
6323
  pendingTies.delete(pitchKey);
6284
6324
  }
6285
- } else if (hasTieStart) {
6325
+ } else if (hasTieStart2) {
6286
6326
  pendingTies.set(pitchKey, [context]);
6287
6327
  }
6288
6328
  }
@@ -6878,8 +6918,6 @@ function getPartCount(score) {
6878
6918
  function getPartIds(score) {
6879
6919
  return score.parts.map((part) => part.id);
6880
6920
  }
6881
-
6882
- // src/query/index.ts
6883
6921
  function getMeasure(score, options) {
6884
6922
  const part = score.parts[options.part];
6885
6923
  if (!part) return void 0;
@@ -6957,8 +6995,8 @@ function findNotes(score, filter) {
6957
6995
  if (filter.staff !== void 0 && (entry.staff ?? 1) !== filter.staff) continue;
6958
6996
  if (filter.noteType !== void 0 && entry.noteType !== filter.noteType) continue;
6959
6997
  if (filter.hasTie !== void 0) {
6960
- const hasTie = entry.tie !== void 0;
6961
- if (filter.hasTie !== hasTie) continue;
6998
+ const hasTie2 = entry.tie !== void 0;
6999
+ if (filter.hasTie !== hasTie2) continue;
6962
7000
  }
6963
7001
  results.push(entry);
6964
7002
  }
@@ -7710,6 +7748,97 @@ async function serializeToFile(score, filePath, options = {}) {
7710
7748
  await (0, import_promises.writeFile)(filePath, xmlString, "utf-8");
7711
7749
  }
7712
7750
  }
7751
+
7752
+ // src/entry-accessors.ts
7753
+ function getDirectionOfKind(entry, kind) {
7754
+ return entry.directionTypes.find((d) => d.kind === kind);
7755
+ }
7756
+ function getDirectionsOfKind(entry, kind) {
7757
+ return entry.directionTypes.filter((d) => d.kind === kind);
7758
+ }
7759
+ function hasDirectionOfKind(entry, kind) {
7760
+ return entry.directionTypes.some((d) => d.kind === kind);
7761
+ }
7762
+ function getSoundTempo(entry) {
7763
+ return entry.sound?.tempo;
7764
+ }
7765
+ function getSoundDynamics(entry) {
7766
+ return entry.sound?.dynamics;
7767
+ }
7768
+ function getSoundDamperPedal(entry) {
7769
+ return entry.sound?.damperPedal;
7770
+ }
7771
+ function getSoundSoftPedal(entry) {
7772
+ return entry.sound?.softPedal;
7773
+ }
7774
+ function getSoundSostenutoPedal(entry) {
7775
+ return entry.sound?.sostenutoPedal;
7776
+ }
7777
+ function isRest(entry) {
7778
+ return entry.rest !== void 0 || !entry.pitch && !entry.unpitched;
7779
+ }
7780
+ function isPitchedNote(entry) {
7781
+ return entry.pitch !== void 0;
7782
+ }
7783
+ function isUnpitchedNote(entry) {
7784
+ return entry.unpitched !== void 0;
7785
+ }
7786
+ function isChordNote(entry) {
7787
+ return entry.chord === true;
7788
+ }
7789
+ function isGraceNote(entry) {
7790
+ return entry.grace !== void 0;
7791
+ }
7792
+ function hasTie(entry) {
7793
+ return entry.tie !== void 0 || entry.ties !== void 0 && entry.ties.length > 0;
7794
+ }
7795
+ function hasTieStart(entry) {
7796
+ if (entry.tie?.type === "start") return true;
7797
+ return entry.ties?.some((t) => t.type === "start") ?? false;
7798
+ }
7799
+ function hasTieStop(entry) {
7800
+ if (entry.tie?.type === "stop") return true;
7801
+ return entry.ties?.some((t) => t.type === "stop") ?? false;
7802
+ }
7803
+ function isCueNote(entry) {
7804
+ return entry.cue === true;
7805
+ }
7806
+ function hasBeam(entry) {
7807
+ return entry.beam !== void 0 && entry.beam.length > 0;
7808
+ }
7809
+ function hasLyrics(entry) {
7810
+ return entry.lyrics !== void 0 && entry.lyrics.length > 0;
7811
+ }
7812
+ function hasNotations(entry) {
7813
+ return entry.notations !== void 0 && entry.notations.length > 0;
7814
+ }
7815
+ function hasTuplet(entry) {
7816
+ return entry.timeModification !== void 0;
7817
+ }
7818
+ function isPartInfo(entry) {
7819
+ return entry.type === "score-part";
7820
+ }
7821
+ function getPartInfo(score, partId) {
7822
+ return score.partList.find((entry) => {
7823
+ return entry.type === "score-part" && entry.id === partId;
7824
+ });
7825
+ }
7826
+ function getPartName(score, partId) {
7827
+ return getPartInfo(score, partId)?.name;
7828
+ }
7829
+ function getPartAbbreviation(score, partId) {
7830
+ return getPartInfo(score, partId)?.abbreviation;
7831
+ }
7832
+ function getAllPartInfos(score) {
7833
+ return score.partList.filter(isPartInfo);
7834
+ }
7835
+ function getPartNameMap(score) {
7836
+ const map = {};
7837
+ for (const part of getAllPartInfos(score)) {
7838
+ map[part.id] = part.name;
7839
+ }
7840
+ return map;
7841
+ }
7713
7842
  // Annotate the CommonJS export names for ESM import in node:
7714
7843
  0 && (module.exports = {
7715
7844
  STEPS,
@@ -7737,14 +7866,17 @@ async function serializeToFile(score, filePath, options = {}) {
7737
7866
  getAbsolutePosition,
7738
7867
  getAdjacentNotes,
7739
7868
  getAllNotes,
7869
+ getAllPartInfos,
7740
7870
  getAttributesAtMeasure,
7741
7871
  getBeamGroups,
7742
7872
  getChordProgression,
7743
7873
  getChords,
7744
7874
  getClefChanges,
7745
7875
  getClefForStaff,
7876
+ getDirectionOfKind,
7746
7877
  getDirections,
7747
7878
  getDirectionsAtPosition,
7879
+ getDirectionsOfKind,
7748
7880
  getDivisions,
7749
7881
  getDuration,
7750
7882
  getDynamics,
@@ -7771,15 +7903,24 @@ async function serializeToFile(score, filePath, options = {}) {
7771
7903
  getNotesForVoice,
7772
7904
  getNotesInRange,
7773
7905
  getOctaveShifts,
7906
+ getPartAbbreviation,
7774
7907
  getPartById,
7775
7908
  getPartByIndex,
7776
7909
  getPartCount,
7777
7910
  getPartIds,
7778
7911
  getPartIndex,
7912
+ getPartInfo,
7913
+ getPartName,
7914
+ getPartNameMap,
7779
7915
  getPedalMarkings,
7780
7916
  getPrevNote,
7781
7917
  getRepeatStructure,
7782
7918
  getSlurSpans,
7919
+ getSoundDamperPedal,
7920
+ getSoundDynamics,
7921
+ getSoundSoftPedal,
7922
+ getSoundSostenutoPedal,
7923
+ getSoundTempo,
7783
7924
  getStaffRange,
7784
7925
  getStaveCount,
7785
7926
  getStaves,
@@ -7797,12 +7938,27 @@ async function serializeToFile(score, filePath, options = {}) {
7797
7938
  getWedges,
7798
7939
  groupByStaff,
7799
7940
  groupByVoice,
7941
+ hasBeam,
7942
+ hasDirectionOfKind,
7943
+ hasLyrics,
7800
7944
  hasMultipleStaves,
7945
+ hasNotations,
7801
7946
  hasNotes,
7947
+ hasTie,
7948
+ hasTieStart,
7949
+ hasTieStop,
7950
+ hasTuplet,
7802
7951
  inferStaff,
7803
7952
  insertMeasure,
7953
+ isChordNote,
7804
7954
  isCompressed,
7955
+ isCueNote,
7956
+ isGraceNote,
7957
+ isPartInfo,
7958
+ isPitchedNote,
7959
+ isRest,
7805
7960
  isRestMeasure,
7961
+ isUnpitchedNote,
7806
7962
  isValid,
7807
7963
  iterateEntries,
7808
7964
  iterateNotes,