@k-l-lambda/lilylet 0.1.60 → 0.1.62
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.
- package/lib/lilylet/grammar.jison.js +273 -169
- package/lib/lilylet/lilypondDecoder.js +163 -39
- package/lib/lilylet/lilypondEncoder.js +117 -7
- package/lib/lilylet/musicXmlEncoder.js +1 -1
- package/lib/lilylet/parser.d.ts +12 -1
- package/lib/lilylet/parser.js +11 -1
- package/lib/lilylet/serializer.js +33 -4
- package/lib/lilylet/types.d.ts +8 -2
- package/package.json +12 -7
- package/source/abc/TODO.md +97 -0
- package/source/lilylet/grammar.jison.js +273 -169
- package/source/lilylet/lilylet.jison +114 -15
- package/source/lilylet/lilypondDecoder.ts +139 -42
- package/source/lilylet/lilypondEncoder.ts +114 -9
- package/source/lilylet/meiEncoder.ts +2 -1
- package/source/lilylet/musicXmlDecoder.ts +2 -2
- package/source/lilylet/musicXmlEncoder.ts +1 -1
- package/source/lilylet/parser.ts +20 -0
- package/source/lilylet/serializer.ts +31 -6
- package/source/lilylet/types.ts +10 -2
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.62",
|
|
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",
|
|
@@ -27,12 +27,16 @@
|
|
|
27
27
|
"build": "tsc -p tsconfig.build.json && node tools/convertGrammarToESM.cjs && node tools/fixEsmExtensions.cjs",
|
|
28
28
|
"build:grammar": "npx tsx ./tools/buildJisonParser.ts && node tools/convertGrammarToESM.cjs",
|
|
29
29
|
"prepublishOnly": "npm run build:grammar && npm run build",
|
|
30
|
-
"test": "
|
|
31
|
-
"test:mei": "
|
|
32
|
-
"test:unit": "
|
|
33
|
-
"test:
|
|
34
|
-
"test:
|
|
35
|
-
"
|
|
30
|
+
"test": "tsx ./tests/parser.ts",
|
|
31
|
+
"test:mei": "tsx ./tests/mei.ts",
|
|
32
|
+
"test:unit": "tsx ./tests/unit/encodePitch.test.ts",
|
|
33
|
+
"test:partial": "tsx ./tests/unit/partialWarning.test.ts",
|
|
34
|
+
"test:decoder": "tsx ./tests/lilypondDecoder.ts",
|
|
35
|
+
"test:abc": "tsx ./tests/abc-decoder.ts",
|
|
36
|
+
"test:roundtrip": "tsx ./tests/lilypond-roundtrip.ts",
|
|
37
|
+
"build:tests": "tsc -p tsconfig.tests.json; cp source/lilylet/grammar.jison.js lib-tests/source/lilylet/ && cp source/abc/grammar.jison.js lib-tests/source/abc/ && node tools/fixEsmExtensions.cjs lib-tests && ln -sfn ../../tests/assets lib-tests/tests/assets",
|
|
38
|
+
"test:roundtrip:compiled": "node lib-tests/tests/lilypond-roundtrip.js",
|
|
39
|
+
"ts": "tsx"
|
|
36
40
|
},
|
|
37
41
|
"repository": {
|
|
38
42
|
"type": "git",
|
|
@@ -51,6 +55,7 @@
|
|
|
51
55
|
"jison": "^0.4.18",
|
|
52
56
|
"sha1": "^1.1.1",
|
|
53
57
|
"ts-node": "^10.9.2",
|
|
58
|
+
"tsx": "^4.21.0",
|
|
54
59
|
"typescript": "^5.3.3",
|
|
55
60
|
"verovio": "^5.7.0",
|
|
56
61
|
"xmldom": "^0.6.0",
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# ABC Grammar TODO
|
|
2
|
+
|
|
3
|
+
Issues found by comparing `abc.jison` against the abcjs parser implementation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## High Priority
|
|
8
|
+
|
|
9
|
+
### 1. Church modes in key signatures
|
|
10
|
+
|
|
11
|
+
`key_mode` only distinguishes `major` / `minor`. The `NAME` fallback does a naive
|
|
12
|
+
`startsWith("ma")` check, which mis-classifies all church modes:
|
|
13
|
+
|
|
14
|
+
- Dorian (`Dor`, `dorian`)
|
|
15
|
+
- Phrygian (`Phr`, `phrygian`)
|
|
16
|
+
- Lydian (`Lyd`, `lydian`)
|
|
17
|
+
- Mixolydian (`Mix`, `mixolydian`)
|
|
18
|
+
- Aeolian (`Aeo`, `aeolian`)
|
|
19
|
+
- Locrian (`Loc`, `locrian`)
|
|
20
|
+
- Scottish bagpipe: `HP`, `Hp`
|
|
21
|
+
|
|
22
|
+
These should be recognized as distinct modes rather than silently falling back to
|
|
23
|
+
major or minor. The `abcDecoder.ts` key-mapping logic will also need updating to
|
|
24
|
+
handle these modes.
|
|
25
|
+
|
|
26
|
+
### 2. Bare-number Q: tempo (`Q:120`)
|
|
27
|
+
|
|
28
|
+
`numeric_tempo` only matches `frac '=' number` (e.g. `Q:1/4=120`). Two common
|
|
29
|
+
forms are not parsed:
|
|
30
|
+
|
|
31
|
+
- `Q:120` — plain BPM number (unit inferred from the current meter/L: value)
|
|
32
|
+
- `Q:"Allegro"` — text-only tempo marking
|
|
33
|
+
- `Q:"Allegro" 1/4=120` — combined text + numeric form
|
|
34
|
+
|
|
35
|
+
`Q:120` is the most frequently seen form in real-world ABC files.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Medium Priority
|
|
40
|
+
|
|
41
|
+
### 3. Missing rest type: `y` (spacer)
|
|
42
|
+
|
|
43
|
+
The `rest_phonet` rule covers `z`, `Z`, `x` but not `y` (an invisible spacer rest
|
|
44
|
+
used for spacing/layout). Files containing `y` currently cause a parse error.
|
|
45
|
+
|
|
46
|
+
### 4. Volta ending bracket (`endEnding`)
|
|
47
|
+
|
|
48
|
+
The `bar` rule appends the ending number directly to the bar token string
|
|
49
|
+
(`'|' + N → "|1"`). There is no representation of the *closing* bracket of a
|
|
50
|
+
first-ending, so `[1 ... [2` style repeat structures cannot be round-tripped.
|
|
51
|
+
abcjs tracks `startEnding` / `endEnding` flags on bar elements; consider a
|
|
52
|
+
similar approach.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Low Priority
|
|
57
|
+
|
|
58
|
+
### 5. `~` maps to `mordent` instead of `irishroll`
|
|
59
|
+
|
|
60
|
+
`abc.jison` line 507: `'~' → articulation("mordent")`.
|
|
61
|
+
The standard ABC specification defines `~` as an *Irish roll* ornament, not a
|
|
62
|
+
mordent. abcjs uses the name `irishroll`. The mordent is correctly represented by
|
|
63
|
+
`M`. This is a semantic mismatch that may affect downstream rendering/export.
|
|
64
|
+
|
|
65
|
+
### 6. Microtonal accidentals (`^/`, `_/`)
|
|
66
|
+
|
|
67
|
+
The `accidentals` rule does not cover quarter-tone accidentals:
|
|
68
|
+
|
|
69
|
+
- `^/` → quarter sharp
|
|
70
|
+
- `_/` → quarter flat
|
|
71
|
+
|
|
72
|
+
These are recognised by abcjs. Files using microtonal notation will silently drop
|
|
73
|
+
the accidental.
|
|
74
|
+
|
|
75
|
+
### 7. Short trill decoration `t`
|
|
76
|
+
|
|
77
|
+
The single-letter `t` (half/short trill, `trillh` in abcjs) is not handled. The
|
|
78
|
+
current `P`/`PP` lexer patterns only match uppercase ornament letters
|
|
79
|
+
(`HJLMOPRSTuv`), so lowercase `t` falls through as an unknown token.
|
|
80
|
+
|
|
81
|
+
### 8. Overlay voices (`&`)
|
|
82
|
+
|
|
83
|
+
The `&` operator (alternative voice within a single bar, same staff) is not
|
|
84
|
+
supported. abcjs resolves overlays into separate voices via `resolveOverlays()`.
|
|
85
|
+
This is a moderately common pattern in two-voice piano or lute transcriptions.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Out of Scope (noted for awareness)
|
|
90
|
+
|
|
91
|
+
- **Lyrics** (`w:` / `W:` fields): not handled at the ABC grammar level; notes
|
|
92
|
+
have no `lyric` property. Would require grammar additions and decoder support.
|
|
93
|
+
- **Extended clef types**: only `treble`, `bass`, `tenor` are recognised. abcjs
|
|
94
|
+
also handles `alto`, `baritone`, `mezzo`, `soprano`, `tab`, `perc`, etc.
|
|
95
|
+
- **Decoration name aliases**: abcjs normalises `tr`→`trill`, `emphasis`→`accent`,
|
|
96
|
+
`marcato`→`umarcato`, `<`/`>`→`accent`. The lilylet grammar passes `NAME`
|
|
97
|
+
through as-is; the decoder would need to handle the aliases explicitly.
|