@k-l-lambda/lilylet 0.1.64 → 0.1.66

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.
@@ -205,16 +205,7 @@ case 44:
205
205
  this.$ = markupEvent($$[$0].slice(1, -1));
206
206
  break;
207
207
  case 45:
208
-
209
- // On newline, reset ottava to 0 if it's non-zero (like pitch base resets)
210
- if (currentOttava !== 0) {
211
- const ottavaReset = contextChange({ ottava: 0 });
212
- currentOttava = 0;
213
- this.$ = [ottavaReset, { type: 'pitchReset' }];
214
- } else {
215
- this.$ = { type: 'pitchReset' };
216
- }
217
-
208
+ this.$ = { type: 'pitchReset' };
218
209
  break;
219
210
  case 46: case 47:
220
211
  currentDuration = $$[$0-1]; this.$ = noteEvent($$[$0-2], $$[$0-1], $$[$0]);
@@ -128,7 +128,9 @@ const encodePitch = (pitch, keyFifths = 0, ottavaShift = 0, measureAccidentals)
128
128
  // Lilylet octave: 0 = middle C octave (C4), positive = higher, negative = lower
129
129
  // When ottava is active, the source pitch is the sounding pitch, but we need to output the written pitch
130
130
  // For 8va up (ottavaShift=1), written pitch is one octave lower than sounding
131
- const oct = 4 + pitch.octave - ottavaShift;
131
+ const soundingOct = 4 + pitch.octave;
132
+ const oct = soundingOct - ottavaShift;
133
+ const octGes = ottavaShift !== 0 ? soundingOct : undefined;
132
134
  // Get the accidental implied by the key signature for this note
133
135
  const keyAccidentals = getKeyAccidentals(keyFifths);
134
136
  const keyAccid = keyAccidentals[pitch.phonet];
@@ -189,7 +191,7 @@ const encodePitch = (pitch, keyFifths = 0, ottavaShift = 0, measureAccidentals)
189
191
  measureAccidentals.set(pitchKey, 'n');
190
192
  }
191
193
  }
192
- return { pname: pitch.phonet, oct, accid, accidGes };
194
+ return { pname: pitch.phonet, oct, octGes, accid, accidGes };
193
195
  };
194
196
  // Convert tremolo division to stem.mod value
195
197
  const tremoloToStemMod = (division) => {
@@ -209,6 +211,8 @@ const buildNoteElement = (pitch, dur, dots, indent, inChord, options = {}, noteI
209
211
  }
210
212
  if (pitch.accid)
211
213
  attrs += ` accid="${pitch.accid}"`;
214
+ if (pitch.octGes !== undefined)
215
+ attrs += ` oct.ges="${pitch.octGes}"`;
212
216
  if (pitch.accidGes)
213
217
  attrs += ` accid.ges="${pitch.accidGes}"`;
214
218
  if (!inChord && dots > 0)
@@ -655,6 +659,8 @@ const tremoloEventToMEI = (event, indent, keyFifths = 0, ottavaShift = 0, measur
655
659
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}" dur="${noteDur}"`;
656
660
  if (pitch.accid)
657
661
  attrs += ` accid="${pitch.accid}"`;
662
+ if (pitch.octGes !== undefined)
663
+ attrs += ` oct.ges="${pitch.octGes}"`;
658
664
  if (pitch.accidGes)
659
665
  attrs += ` accid.ges="${pitch.accidGes}"`;
660
666
  result += `${indent} <note ${attrs} />\n`;
@@ -666,6 +672,8 @@ const tremoloEventToMEI = (event, indent, keyFifths = 0, ottavaShift = 0, measur
666
672
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}"`;
667
673
  if (pitch.accid)
668
674
  attrs += ` accid="${pitch.accid}"`;
675
+ if (pitch.octGes !== undefined)
676
+ attrs += ` oct.ges="${pitch.octGes}"`;
669
677
  if (pitch.accidGes)
670
678
  attrs += ` accid.ges="${pitch.accidGes}"`;
671
679
  result += `${indent} <note ${attrs} />\n`;
@@ -678,6 +686,8 @@ const tremoloEventToMEI = (event, indent, keyFifths = 0, ottavaShift = 0, measur
678
686
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}" dur="${noteDur}"`;
679
687
  if (pitch.accid)
680
688
  attrs += ` accid="${pitch.accid}"`;
689
+ if (pitch.octGes !== undefined)
690
+ attrs += ` oct.ges="${pitch.octGes}"`;
681
691
  if (pitch.accidGes)
682
692
  attrs += ` accid.ges="${pitch.accidGes}"`;
683
693
  result += `${indent} <note ${attrs} />\n`;
@@ -689,6 +699,8 @@ const tremoloEventToMEI = (event, indent, keyFifths = 0, ottavaShift = 0, measur
689
699
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}"`;
690
700
  if (pitch.accid)
691
701
  attrs += ` accid="${pitch.accid}"`;
702
+ if (pitch.octGes !== undefined)
703
+ attrs += ` oct.ges="${pitch.octGes}"`;
692
704
  if (pitch.accidGes)
693
705
  attrs += ` accid.ges="${pitch.accidGes}"`;
694
706
  result += `${indent} <note ${attrs} />\n`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k-l-lambda/lilylet",
3
- "version": "0.1.64",
3
+ "version": "0.1.66",
4
4
  "description": "Lilylet is a lilyopnd-like sheet music language designed for Markdown rendering and symbolic music representation in AIGC applications.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -205,16 +205,7 @@ case 44:
205
205
  this.$ = markupEvent($$[$0].slice(1, -1));
206
206
  break;
207
207
  case 45:
208
-
209
- // On newline, reset ottava to 0 if it's non-zero (like pitch base resets)
210
- if (currentOttava !== 0) {
211
- const ottavaReset = contextChange({ ottava: 0 });
212
- currentOttava = 0;
213
- this.$ = [ottavaReset, { type: 'pitchReset' }];
214
- } else {
215
- this.$ = { type: 'pitchReset' };
216
- }
217
-
208
+ this.$ = { type: 'pitchReset' };
218
209
  break;
219
210
  case 46: case 47:
220
211
  currentDuration = $$[$0-1]; this.$ = noteEvent($$[$0-2], $$[$0-1], $$[$0]);
@@ -460,16 +460,7 @@ markup_event
460
460
  ;
461
461
 
462
462
  pitch_reset_event
463
- : NEWLINE %{
464
- // On newline, reset ottava to 0 if it's non-zero (like pitch base resets)
465
- if (currentOttava !== 0) {
466
- const ottavaReset = contextChange({ ottava: 0 });
467
- currentOttava = 0;
468
- $$ = [ottavaReset, { type: 'pitchReset' }];
469
- } else {
470
- $$ = { type: 'pitchReset' };
471
- }
472
- %}
463
+ : NEWLINE -> { type: 'pitchReset' }
473
464
  ;
474
465
 
475
466
  note_event
@@ -178,11 +178,13 @@ const getKeyAccidentals = (fifths: number): Record<string, string> => {
178
178
  // The written pitch should be adjusted by subtracting the ottava shift
179
179
  // measureAccidentals: tracks accidentals used earlier in the same measure (keyed by "pname-oct")
180
180
  // - mutated to record new accidentals; used to add cancellation naturals
181
- const encodePitch = (pitch: Pitch, keyFifths: number = 0, ottavaShift: number = 0, measureAccidentals?: Map<string, string>): { pname: string; oct: number; accid?: string; accidGes?: string } => {
181
+ const encodePitch = (pitch: Pitch, keyFifths: number = 0, ottavaShift: number = 0, measureAccidentals?: Map<string, string>): { pname: string; oct: number; octGes?: number; accid?: string; accidGes?: string } => {
182
182
  // Lilylet octave: 0 = middle C octave (C4), positive = higher, negative = lower
183
183
  // When ottava is active, the source pitch is the sounding pitch, but we need to output the written pitch
184
184
  // For 8va up (ottavaShift=1), written pitch is one octave lower than sounding
185
- const oct = 4 + pitch.octave - ottavaShift;
185
+ const soundingOct = 4 + pitch.octave;
186
+ const oct = soundingOct - ottavaShift;
187
+ const octGes = ottavaShift !== 0 ? soundingOct : undefined;
186
188
 
187
189
  // Get the accidental implied by the key signature for this note
188
190
  const keyAccidentals = getKeyAccidentals(keyFifths);
@@ -239,7 +241,7 @@ const encodePitch = (pitch: Pitch, keyFifths: number = 0, ottavaShift: number =
239
241
  }
240
242
  }
241
243
 
242
- return { pname: pitch.phonet, oct, accid, accidGes };
244
+ return { pname: pitch.phonet, oct, octGes, accid, accidGes };
243
245
  };
244
246
 
245
247
 
@@ -255,7 +257,7 @@ const tremoloToStemMod = (division: number): string | undefined => {
255
257
 
256
258
  // Build note element
257
259
  const buildNoteElement = (
258
- pitch: { pname: string; oct: number; accid?: string; accidGes?: string },
260
+ pitch: { pname: string; oct: number; octGes?: number; accid?: string; accidGes?: string },
259
261
  dur: string,
260
262
  dots: number,
261
263
  indent: string,
@@ -278,6 +280,7 @@ const buildNoteElement = (
278
280
  attrs += ` dur="${dur}"`;
279
281
  }
280
282
  if (pitch.accid) attrs += ` accid="${pitch.accid}"`;
283
+ if (pitch.octGes !== undefined) attrs += ` oct.ges="${pitch.octGes}"`;
281
284
  if (pitch.accidGes) attrs += ` accid.ges="${pitch.accidGes}"`;
282
285
  if (!inChord && dots > 0) attrs += ` dots="${dots}"`;
283
286
  if (!inChord && options.grace) attrs += ` grace="unacc"`;
@@ -801,6 +804,7 @@ const tremoloEventToMEI = (event: TremoloEvent, indent: string, keyFifths: numbe
801
804
  const pitch = encodePitch(event.pitchA[0], keyFifths, ottavaShift, measureAccidentals);
802
805
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}" dur="${noteDur}"`;
803
806
  if (pitch.accid) attrs += ` accid="${pitch.accid}"`;
807
+ if (pitch.octGes !== undefined) attrs += ` oct.ges="${pitch.octGes}"`;
804
808
  if (pitch.accidGes) attrs += ` accid.ges="${pitch.accidGes}"`;
805
809
  result += `${indent} <note ${attrs} />\n`;
806
810
  } else if (event.pitchA.length > 1) {
@@ -809,6 +813,7 @@ const tremoloEventToMEI = (event: TremoloEvent, indent: string, keyFifths: numbe
809
813
  const pitch = encodePitch(p, keyFifths, ottavaShift, measureAccidentals);
810
814
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}"`;
811
815
  if (pitch.accid) attrs += ` accid="${pitch.accid}"`;
816
+ if (pitch.octGes !== undefined) attrs += ` oct.ges="${pitch.octGes}"`;
812
817
  if (pitch.accidGes) attrs += ` accid.ges="${pitch.accidGes}"`;
813
818
  result += `${indent} <note ${attrs} />\n`;
814
819
  }
@@ -820,6 +825,7 @@ const tremoloEventToMEI = (event: TremoloEvent, indent: string, keyFifths: numbe
820
825
  const pitch = encodePitch(event.pitchB[0], keyFifths, ottavaShift, measureAccidentals);
821
826
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}" dur="${noteDur}"`;
822
827
  if (pitch.accid) attrs += ` accid="${pitch.accid}"`;
828
+ if (pitch.octGes !== undefined) attrs += ` oct.ges="${pitch.octGes}"`;
823
829
  if (pitch.accidGes) attrs += ` accid.ges="${pitch.accidGes}"`;
824
830
  result += `${indent} <note ${attrs} />\n`;
825
831
  } else if (event.pitchB.length > 1) {
@@ -828,6 +834,7 @@ const tremoloEventToMEI = (event: TremoloEvent, indent: string, keyFifths: numbe
828
834
  const pitch = encodePitch(p, keyFifths, ottavaShift, measureAccidentals);
829
835
  let attrs = `xml:id="${generateId('note')}" pname="${pitch.pname}" oct="${pitch.oct}"`;
830
836
  if (pitch.accid) attrs += ` accid="${pitch.accid}"`;
837
+ if (pitch.octGes !== undefined) attrs += ` oct.ges="${pitch.octGes}"`;
831
838
  if (pitch.accidGes) attrs += ` accid.ges="${pitch.accidGes}"`;
832
839
  result += `${indent} <note ${attrs} />\n`;
833
840
  }