@k-l-lambda/lilylet 0.1.80 → 0.1.81
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.
|
@@ -163,7 +163,11 @@ const renderRepeatSpan = (infos, lo, hi) => {
|
|
|
163
163
|
return rangeCode(lo, hi);
|
|
164
164
|
}
|
|
165
165
|
const endInfo = repeatEnds[0];
|
|
166
|
-
|
|
166
|
+
// The repeat-start for THIS end is the latest repeat-start at or before it; a
|
|
167
|
+
// repeat-start sitting AFTER the end (e.g. the second half of a ":|:"/"::" that
|
|
168
|
+
// opens the next section) belongs to a following span, not this one. Falling
|
|
169
|
+
// back to `lo` models the implicit "repeat from the start of the span".
|
|
170
|
+
const startIdx = span.filter(i => i.repeatStart && i.index <= endInfo.index).map(i => i.index).sort((a, b) => b - a)[0] ?? lo;
|
|
167
171
|
const times = endInfo.repeatTimes ?? 2;
|
|
168
172
|
const endingStarts = span.filter(i => i.endingStart !== undefined).map(i => i.index).sort((a, b) => a - b);
|
|
169
173
|
if (endingStarts.length === 0) {
|
|
@@ -301,9 +305,14 @@ const buildDaCapoABA = (infos, dcIdx) => {
|
|
|
301
305
|
const restCode = renderRepeatSections(infos, restLo, dcIdx);
|
|
302
306
|
if (mainCode === null || restCode === null)
|
|
303
307
|
return null;
|
|
304
|
-
// main
|
|
305
|
-
//
|
|
306
|
-
|
|
308
|
+
// `main` is parsed by the ABA grammar as ONE item (parseItem). It needs wrapping
|
|
309
|
+
// in [..] when it is a comma sequence ("1, 2*[..]") or a BARE range ("1..37",
|
|
310
|
+
// which parseItem stops at the first number). A lone number, or a single
|
|
311
|
+
// already-structured token ("2*[..]" / "2*[..]{..}" / "[..]"), parses as one item
|
|
312
|
+
// and needs no extra bracket. `rest` is parsed as a sequence, so it only needs
|
|
313
|
+
// bracketing to group a comma sequence — a range there is fine.
|
|
314
|
+
const isSingleToken = /^\d+$/.test(mainCode) || /^\d+\*\[/.test(mainCode) || /^\[/.test(mainCode);
|
|
315
|
+
const main = isSingleToken ? mainCode : `[${mainCode}]`;
|
|
307
316
|
const rest = /,/.test(restCode) ? `[${restCode}]` : restCode;
|
|
308
317
|
return `<${main}, ${rest}>`;
|
|
309
318
|
};
|
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.81",
|
|
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",
|
|
@@ -174,7 +174,11 @@ const renderRepeatSpan = (infos: MeasureRepeatInfo[], lo: number, hi: number): s
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
const endInfo = repeatEnds[0];
|
|
177
|
-
|
|
177
|
+
// The repeat-start for THIS end is the latest repeat-start at or before it; a
|
|
178
|
+
// repeat-start sitting AFTER the end (e.g. the second half of a ":|:"/"::" that
|
|
179
|
+
// opens the next section) belongs to a following span, not this one. Falling
|
|
180
|
+
// back to `lo` models the implicit "repeat from the start of the span".
|
|
181
|
+
const startIdx = span.filter(i => i.repeatStart && i.index <= endInfo.index).map(i => i.index).sort((a, b) => b - a)[0] ?? lo;
|
|
178
182
|
const times = endInfo.repeatTimes ?? 2;
|
|
179
183
|
const endingStarts = span.filter(i => i.endingStart !== undefined).map(i => i.index).sort((a, b) => a - b);
|
|
180
184
|
|
|
@@ -312,9 +316,14 @@ const buildDaCapoABA = (infos: MeasureRepeatInfo[], dcIdx: number): string | nul
|
|
|
312
316
|
const restCode = renderRepeatSections(infos, restLo, dcIdx);
|
|
313
317
|
if (mainCode === null || restCode === null) return null;
|
|
314
318
|
|
|
315
|
-
// main
|
|
316
|
-
//
|
|
317
|
-
|
|
319
|
+
// `main` is parsed by the ABA grammar as ONE item (parseItem). It needs wrapping
|
|
320
|
+
// in [..] when it is a comma sequence ("1, 2*[..]") or a BARE range ("1..37",
|
|
321
|
+
// which parseItem stops at the first number). A lone number, or a single
|
|
322
|
+
// already-structured token ("2*[..]" / "2*[..]{..}" / "[..]"), parses as one item
|
|
323
|
+
// and needs no extra bracket. `rest` is parsed as a sequence, so it only needs
|
|
324
|
+
// bracketing to group a comma sequence — a range there is fine.
|
|
325
|
+
const isSingleToken = /^\d+$/.test(mainCode) || /^\d+\*\[/.test(mainCode) || /^\[/.test(mainCode);
|
|
326
|
+
const main = isSingleToken ? mainCode : `[${mainCode}]`;
|
|
318
327
|
const rest = /,/.test(restCode) ? `[${restCode}]` : restCode;
|
|
319
328
|
return `<${main}, ${rest}>`;
|
|
320
329
|
};
|