@k-l-lambda/lilylet 0.1.54 → 0.1.55
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.
|
@@ -941,9 +941,13 @@ const encodeLayer = (voice, layerN, indent, initialTiePitches = [], keyFifths =
|
|
|
941
941
|
case 'context': {
|
|
942
942
|
const ctx = event;
|
|
943
943
|
// Check for clef changes - emit <clef> element only if different from current
|
|
944
|
+
// and only when on the home staff (don't emit cross-staff clefs into this layer)
|
|
944
945
|
if (ctx.clef && ctx.clef !== currentClef) {
|
|
945
|
-
const
|
|
946
|
-
|
|
946
|
+
const layerStaff = voice.staff || 1;
|
|
947
|
+
if (currentStaff === layerStaff) {
|
|
948
|
+
const clefInfo = CLEF_SHAPES[ctx.clef] || CLEF_SHAPES.treble;
|
|
949
|
+
xml += `${currentIndent}<clef xml:id="${generateId('clef')}" shape="${clefInfo.shape}" line="${clefInfo.line}" />\n`;
|
|
950
|
+
}
|
|
947
951
|
currentClef = ctx.clef;
|
|
948
952
|
}
|
|
949
953
|
// Check for ottava changes
|
|
@@ -1466,15 +1470,19 @@ const analyzePartStructure = (doc) => {
|
|
|
1466
1470
|
for (let pi = 0; pi < measure.parts.length; pi++) {
|
|
1467
1471
|
const part = measure.parts[pi];
|
|
1468
1472
|
for (const voice of part.voices) {
|
|
1469
|
-
|
|
1470
|
-
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff,
|
|
1471
|
-
//
|
|
1473
|
+
let currentStaff = voice.staff || 1;
|
|
1474
|
+
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff, currentStaff);
|
|
1475
|
+
// Scan context changes for staff switches and clefs
|
|
1472
1476
|
for (const event of voice.events) {
|
|
1473
1477
|
if (event.type === 'context') {
|
|
1474
1478
|
const ctx = event;
|
|
1475
|
-
if (ctx.
|
|
1476
|
-
|
|
1477
|
-
partInfos[pi].
|
|
1479
|
+
if (ctx.staff !== undefined) {
|
|
1480
|
+
currentStaff = ctx.staff;
|
|
1481
|
+
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff, currentStaff);
|
|
1482
|
+
}
|
|
1483
|
+
if (ctx.clef && !partInfos[pi].clefs[currentStaff]) {
|
|
1484
|
+
// Only set if not already set - take the FIRST clef per staff
|
|
1485
|
+
partInfos[pi].clefs[currentStaff] = ctx.clef;
|
|
1478
1486
|
}
|
|
1479
1487
|
}
|
|
1480
1488
|
}
|
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.55",
|
|
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",
|
|
@@ -1236,9 +1236,13 @@ const encodeLayer = (voice: Voice, layerN: number, indent: string, initialTiePit
|
|
|
1236
1236
|
case 'context': {
|
|
1237
1237
|
const ctx = event as ContextChange;
|
|
1238
1238
|
// Check for clef changes - emit <clef> element only if different from current
|
|
1239
|
+
// and only when on the home staff (don't emit cross-staff clefs into this layer)
|
|
1239
1240
|
if (ctx.clef && ctx.clef !== currentClef) {
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1241
|
+
const layerStaff = voice.staff || 1;
|
|
1242
|
+
if (currentStaff === layerStaff) {
|
|
1243
|
+
const clefInfo = CLEF_SHAPES[ctx.clef] || CLEF_SHAPES.treble;
|
|
1244
|
+
xml += `${currentIndent}<clef xml:id="${generateId('clef')}" shape="${clefInfo.shape}" line="${clefInfo.line}" />\n`;
|
|
1245
|
+
}
|
|
1242
1246
|
currentClef = ctx.clef;
|
|
1243
1247
|
}
|
|
1244
1248
|
// Check for ottava changes
|
|
@@ -1832,16 +1836,20 @@ const analyzePartStructure = (doc: LilyletDoc): PartInfo[] => {
|
|
|
1832
1836
|
for (let pi = 0; pi < measure.parts.length; pi++) {
|
|
1833
1837
|
const part = measure.parts[pi];
|
|
1834
1838
|
for (const voice of part.voices) {
|
|
1835
|
-
|
|
1836
|
-
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff,
|
|
1839
|
+
let currentStaff = voice.staff || 1;
|
|
1840
|
+
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff, currentStaff);
|
|
1837
1841
|
|
|
1838
|
-
//
|
|
1842
|
+
// Scan context changes for staff switches and clefs
|
|
1839
1843
|
for (const event of voice.events) {
|
|
1840
1844
|
if (event.type === 'context') {
|
|
1841
1845
|
const ctx = event as ContextChange;
|
|
1842
|
-
if (ctx.
|
|
1843
|
-
|
|
1844
|
-
partInfos[pi].
|
|
1846
|
+
if (ctx.staff !== undefined) {
|
|
1847
|
+
currentStaff = ctx.staff;
|
|
1848
|
+
partInfos[pi].maxStaff = Math.max(partInfos[pi].maxStaff, currentStaff);
|
|
1849
|
+
}
|
|
1850
|
+
if (ctx.clef && !partInfos[pi].clefs[currentStaff]) {
|
|
1851
|
+
// Only set if not already set - take the FIRST clef per staff
|
|
1852
|
+
partInfos[pi].clefs[currentStaff] = ctx.clef;
|
|
1845
1853
|
}
|
|
1846
1854
|
}
|
|
1847
1855
|
}
|