@k-l-lambda/lilylet 0.1.60 → 0.1.63

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.
@@ -758,13 +758,13 @@ const convertEventTerm = (
758
758
  const firstPitch = chord.pitches[0];
759
759
 
760
760
  // Check if rest
761
- if (firstPitch.phonet === "z" || firstPitch.phonet === "Z" || firstPitch.phonet === "x") {
761
+ if (firstPitch.phonet === "z" || firstPitch.phonet === "Z" || firstPitch.phonet === "x" || firstPitch.phonet === "y") {
762
762
  const duration = convertDuration(eventData.duration, unitLength);
763
763
  const rest: RestEvent = {
764
764
  type: "rest",
765
765
  duration,
766
766
  };
767
- if (firstPitch.phonet === "x") {
767
+ if (firstPitch.phonet === "x" || firstPitch.phonet === "y") {
768
768
  rest.invisible = true;
769
769
  }
770
770
  if (firstPitch.phonet === "Z") {
@@ -779,7 +779,7 @@ const convertEventTerm = (
779
779
 
780
780
  // Note or chord
781
781
  const pitches = chord.pitches.filter(p =>
782
- p.phonet !== "z" && p.phonet !== "Z" && p.phonet !== "x"
782
+ p.phonet !== "z" && p.phonet !== "Z" && p.phonet !== "x" && p.phonet !== "y"
783
783
  ).map(convertPitch);
784
784
 
785
785
  if (pitches.length === 0) return undefined;
@@ -865,8 +865,17 @@ const decodeTune = (tune: ABC.Tune): LilyletDoc => {
865
865
  let timeSig: TimeSig | undefined;
866
866
  let keySig: KeySignature | undefined;
867
867
  let tempo: Tempo | undefined;
868
- const voiceConfigs = new Map<number, VoiceConfig>();
869
- const voiceClefs = new Map<number, Clef>();
868
+ const voiceConfigs = new Map<number | string, VoiceConfig>();
869
+ const voiceClefs = new Map<number | string, Clef>();
870
+
871
+ // Pre-scan for unit length (needed for bare Q: tempo)
872
+ for (const h of headers) {
873
+ const hdr = h as { name: string; value: any };
874
+ if (hdr.name === "L" && hdr.value?.numerator && hdr.value?.denominator) {
875
+ unitLength = hdr.value;
876
+ break;
877
+ }
878
+ }
870
879
 
871
880
  for (const h of headers) {
872
881
  if ((h as any).comment) continue;
@@ -905,24 +914,43 @@ const decodeTune = (tune: ABC.Tune): LilyletDoc => {
905
914
  const beatDuration = convertDuration(header.value.note, { numerator: 1, denominator: 1 });
906
915
  tempo = { beat: beatDuration, bpm: header.value.bpm };
907
916
  } else if (typeof header.value === "number") {
908
- tempo = { bpm: header.value };
917
+ const beat = convertDuration({ numerator: 1, denominator: 1 }, unitLength);
918
+ tempo = { beat, bpm: header.value };
909
919
  }
910
920
  break;
911
921
  case "V": {
912
922
  const voiceValue = header.value;
913
923
  if (voiceValue) {
914
- const voiceNum = typeof voiceValue === "number" ? voiceValue :
915
- (voiceValue.name || 1);
916
- const clefStr = typeof voiceValue === "string" ? voiceValue :
917
- (voiceValue.clef || undefined);
918
- voiceConfigs.set(voiceNum, {
919
- name: voiceNum,
924
+ let voiceId: number | string;
925
+ let clefStr: string | undefined;
926
+
927
+ if (typeof voiceValue === "number") {
928
+ voiceId = voiceValue;
929
+ } else if (typeof voiceValue === "string") {
930
+ voiceId = voiceValue;
931
+ } else {
932
+ const rawClef = (voiceValue.clef || "").replace(/,+$/, "").trim();
933
+ const isKnownClef = !!convertClef(rawClef);
934
+ if (isKnownClef) {
935
+ // V:1 treble → voiceId=number, clef=treble
936
+ voiceId = voiceValue.name || 1;
937
+ clefStr = rawClef;
938
+ } else {
939
+ // V:S clef=treble → voiceId=voiceName, clef from properties
940
+ voiceId = rawClef || voiceValue.name || 1;
941
+ const propClef = (voiceValue.properties?.clef || "").replace(/,+$/, "").trim();
942
+ clefStr = propClef || undefined;
943
+ }
944
+ }
945
+
946
+ voiceConfigs.set(voiceId, {
947
+ name: typeof voiceId === "number" ? voiceId : 1,
920
948
  clef: clefStr,
921
- properties: voiceValue.properties,
949
+ properties: voiceValue?.properties,
922
950
  });
923
951
  if (clefStr) {
924
952
  const clef = convertClef(clefStr);
925
- if (clef) voiceClefs.set(voiceNum, clef);
953
+ if (clef) voiceClefs.set(voiceId, clef);
926
954
  }
927
955
  }
928
956
  break;