@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
|
|
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.
|
|
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
|
|
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
|
}
|