@ugfoundation/swaralipi-js 0.4.0 → 0.6.0
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/README.md +8 -8
- package/dist/{batch-V4X3GN4N.js → batch-RUZGM2NR.js} +4 -4
- package/dist/{batch-V4X3GN4N.js.map → batch-RUZGM2NR.js.map} +1 -1
- package/dist/{chunk-6QW7MSJO.js → chunk-GHWURC4U.js} +98 -6
- package/dist/chunk-GHWURC4U.js.map +1 -0
- package/dist/{chunk-RTKWFJFI.js → chunk-ULK7NVKH.js} +8 -6
- package/dist/chunk-ULK7NVKH.js.map +1 -0
- package/dist/{chunk-ZS43BDP7.js → chunk-ZNVTOY7J.js} +7 -6
- package/dist/chunk-ZNVTOY7J.js.map +1 -0
- package/dist/cli.cjs +11 -8
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/convert/index.cjs +10 -7
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.d.cts +4 -3
- package/dist/convert/index.d.ts +4 -3
- package/dist/convert/index.js +2 -2
- package/dist/index.cjs +6 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/player/index.cjs +222 -23
- package/dist/player/index.cjs.map +1 -1
- package/dist/player/index.d.cts +16 -4
- package/dist/player/index.d.ts +16 -4
- package/dist/player/index.js +120 -22
- package/dist/player/index.js.map +1 -1
- package/dist/{schedule-CAns78TD.d.ts → schedule-8WFUBJqB.d.ts} +82 -7
- package/dist/{schedule-D3JyEhuO.d.cts → schedule-CjPcD-Hf.d.cts} +82 -7
- package/dist/{schema-D3wyNRqM.d.ts → schema-D_86x4oV.d.cts} +21 -6
- package/dist/{schema-D3wyNRqM.d.cts → schema-D_86x4oV.d.ts} +21 -6
- package/dist/spec/index.cjs +6 -4
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +3 -3
- package/dist/spec/index.d.ts +3 -3
- package/dist/spec/index.js +1 -1
- package/dist/viewer/index.cjs +253 -172
- package/dist/viewer/index.cjs.map +1 -1
- package/dist/viewer/index.d.cts +16 -23
- package/dist/viewer/index.d.ts +16 -23
- package/dist/viewer/index.js +88 -47
- package/dist/viewer/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6QW7MSJO.js.map +0 -1
- package/dist/chunk-RTKWFJFI.js.map +0 -1
- package/dist/chunk-ZS43BDP7.js.map +0 -1
package/dist/viewer/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as Octave, a as SvaraLetter, N as Note, M as Meta, S as Swaralipi, T as Taal } from '../schema-
|
|
2
|
-
import { D as DrumVoice, S as Schedule, P as PlayEvent } from '../schedule-
|
|
1
|
+
import { O as Octave, a as SvaraLetter, N as Note, M as Meta, S as Swaralipi, T as Taal } from '../schema-D_86x4oV.cjs';
|
|
2
|
+
import { D as DrumVoice, S as Schedule, P as PlayEvent } from '../schedule-CjPcD-Hf.cjs';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import 'tone';
|
|
5
5
|
import '../taals-CjzBuZ35.cjs';
|
|
@@ -77,25 +77,6 @@ declare function composeCluster(letter: SvaraLetter, opts: ComposeOptions): Clus
|
|
|
77
77
|
/** Map ASCII digits in `s` to the target script's digits. */
|
|
78
78
|
declare function localizeDigits(s: string, lang: GridLang): string;
|
|
79
79
|
|
|
80
|
-
/**
|
|
81
|
-
* Pure spec-JSON → HTML renderer. No DOM, no side effects: usable for SSR
|
|
82
|
-
* (Astro/static sites emit `renderToHtml(doc)` next to a
|
|
83
|
-
* `<style>${SWARALIPI_CSS}</style>`) and unit-testable in plain Node.
|
|
84
|
-
*
|
|
85
|
-
* Layout model (mirrors NLTR's 4-row systems): each spec `Row` becomes one
|
|
86
|
-
* CSS grid with **one column per top-level note** and four grid rows —
|
|
87
|
-
* above-annotations / notation / below (slur arcs, marks) / lyric. Source
|
|
88
|
-
* cells (groups of sub-notes sharing one matra) become column *spans*, so
|
|
89
|
-
* per-sub-note lyric alignment and P2.3's per-note highlight targets fall
|
|
90
|
-
* out of the column model for free.
|
|
91
|
-
*
|
|
92
|
-
* Rendering is spec-driven (semantics, not `raw`): grouping derives from
|
|
93
|
-
* `durationMatra` accumulation so hand-authored documents without `raw`
|
|
94
|
-
* render identically. `raw` is consulted only for (a) raw-only fallback
|
|
95
|
-
* notes (never dropped — dimmed, in Swarabitan when loaded), (b) the ছেদ
|
|
96
|
-
* cut mark and beat labels, whose grammar lives in raw (see codec.ts).
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
80
|
interface RenderOptions {
|
|
100
81
|
/** Notation + UI language. Default `bn`. */
|
|
101
82
|
lang?: ViewerLang;
|
|
@@ -119,7 +100,9 @@ interface Cell {
|
|
|
119
100
|
* - bar / raw-only / carrier notes force-close and form singleton cells;
|
|
120
101
|
* - full-matra notes are singleton groups;
|
|
121
102
|
* - fractional notes accumulate until the sum reaches an integer matra
|
|
122
|
-
* boundary (epsilon for 1/3, 0.2 chains), then the group closes
|
|
103
|
+
* boundary (epsilon for 1/3, 0.2 chains), then the group closes;
|
|
104
|
+
* - `halfMatra` (the অর্ধমাত্রা ঃ) closes the cell on a half boundary — the
|
|
105
|
+
* only case durations alone cannot resolve (`সঃ গঃ` vs `সরা`).
|
|
123
106
|
* The converter emits k notes × 1/k per source cell, so groups coincide
|
|
124
107
|
* with source cells; an incomplete trailing group still closes at row end
|
|
125
108
|
* (the matra carrier lands on its last note).
|
|
@@ -147,6 +130,16 @@ interface Arc {
|
|
|
147
130
|
* A row with fill segments but no ends at all renders one straight line.
|
|
148
131
|
*/
|
|
149
132
|
declare function resolveArcs(cells: Cell[], noteCount: number): Arc[];
|
|
133
|
+
/**
|
|
134
|
+
* The matra marks a cell's final note carries: its total duration as whole
|
|
135
|
+
* আ-কার matras plus an optional অর্ধমাত্রা ঃ (legend `রাঃ` = 1½, `সঃ` = ½).
|
|
136
|
+
* Only a `halfMatra` cell may show zero matras — every other cell keeps at
|
|
137
|
+
* least one, so an incomplete trailing group still gets its carrier.
|
|
138
|
+
*/
|
|
139
|
+
declare function cellMatra(cell: Cell): {
|
|
140
|
+
matras: number;
|
|
141
|
+
half: boolean;
|
|
142
|
+
};
|
|
150
143
|
/**
|
|
151
144
|
* The নাম / তাল / রাগ / আবর্তন / স্বরলিপিকার header block, shared by the
|
|
152
145
|
* akarmatrik grid and the staff view so both show the same metadata (localized
|
|
@@ -467,4 +460,4 @@ type Transliterator = (bengaliText: string) => string;
|
|
|
467
460
|
*/
|
|
468
461
|
declare function loadLyricTransliterator(lang: ViewerLang): Promise<Transliterator | undefined>;
|
|
469
462
|
|
|
470
|
-
export { type Arc, type Cell, type Cluster, type ComposeOptions, DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, type GridLang, LABELS, MARKS, NOTATION_FONT_URLS, type PrintOptions, type RenderOptions, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, type StaffOptions, type SwaralipiSheetElement, type TaalStaffOptions, type Transliterator, type ViewerLang, abcDuration, abcToSvg, buildAbc, buildTaalAbc, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
|
463
|
+
export { type Arc, type Cell, type Cluster, type ComposeOptions, DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, type GridLang, LABELS, MARKS, NOTATION_FONT_URLS, type PrintOptions, type RenderOptions, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, type StaffOptions, type SwaralipiSheetElement, type TaalStaffOptions, type Transliterator, type ViewerLang, abcDuration, abcToSvg, buildAbc, buildTaalAbc, cellMatra, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
package/dist/viewer/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as Octave, a as SvaraLetter, N as Note, M as Meta, S as Swaralipi, T as Taal } from '../schema-
|
|
2
|
-
import { D as DrumVoice, S as Schedule, P as PlayEvent } from '../schedule-
|
|
1
|
+
import { O as Octave, a as SvaraLetter, N as Note, M as Meta, S as Swaralipi, T as Taal } from '../schema-D_86x4oV.js';
|
|
2
|
+
import { D as DrumVoice, S as Schedule, P as PlayEvent } from '../schedule-8WFUBJqB.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import 'tone';
|
|
5
5
|
import '../taals-CjzBuZ35.js';
|
|
@@ -77,25 +77,6 @@ declare function composeCluster(letter: SvaraLetter, opts: ComposeOptions): Clus
|
|
|
77
77
|
/** Map ASCII digits in `s` to the target script's digits. */
|
|
78
78
|
declare function localizeDigits(s: string, lang: GridLang): string;
|
|
79
79
|
|
|
80
|
-
/**
|
|
81
|
-
* Pure spec-JSON → HTML renderer. No DOM, no side effects: usable for SSR
|
|
82
|
-
* (Astro/static sites emit `renderToHtml(doc)` next to a
|
|
83
|
-
* `<style>${SWARALIPI_CSS}</style>`) and unit-testable in plain Node.
|
|
84
|
-
*
|
|
85
|
-
* Layout model (mirrors NLTR's 4-row systems): each spec `Row` becomes one
|
|
86
|
-
* CSS grid with **one column per top-level note** and four grid rows —
|
|
87
|
-
* above-annotations / notation / below (slur arcs, marks) / lyric. Source
|
|
88
|
-
* cells (groups of sub-notes sharing one matra) become column *spans*, so
|
|
89
|
-
* per-sub-note lyric alignment and P2.3's per-note highlight targets fall
|
|
90
|
-
* out of the column model for free.
|
|
91
|
-
*
|
|
92
|
-
* Rendering is spec-driven (semantics, not `raw`): grouping derives from
|
|
93
|
-
* `durationMatra` accumulation so hand-authored documents without `raw`
|
|
94
|
-
* render identically. `raw` is consulted only for (a) raw-only fallback
|
|
95
|
-
* notes (never dropped — dimmed, in Swarabitan when loaded), (b) the ছেদ
|
|
96
|
-
* cut mark and beat labels, whose grammar lives in raw (see codec.ts).
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
80
|
interface RenderOptions {
|
|
100
81
|
/** Notation + UI language. Default `bn`. */
|
|
101
82
|
lang?: ViewerLang;
|
|
@@ -119,7 +100,9 @@ interface Cell {
|
|
|
119
100
|
* - bar / raw-only / carrier notes force-close and form singleton cells;
|
|
120
101
|
* - full-matra notes are singleton groups;
|
|
121
102
|
* - fractional notes accumulate until the sum reaches an integer matra
|
|
122
|
-
* boundary (epsilon for 1/3, 0.2 chains), then the group closes
|
|
103
|
+
* boundary (epsilon for 1/3, 0.2 chains), then the group closes;
|
|
104
|
+
* - `halfMatra` (the অর্ধমাত্রা ঃ) closes the cell on a half boundary — the
|
|
105
|
+
* only case durations alone cannot resolve (`সঃ গঃ` vs `সরা`).
|
|
123
106
|
* The converter emits k notes × 1/k per source cell, so groups coincide
|
|
124
107
|
* with source cells; an incomplete trailing group still closes at row end
|
|
125
108
|
* (the matra carrier lands on its last note).
|
|
@@ -147,6 +130,16 @@ interface Arc {
|
|
|
147
130
|
* A row with fill segments but no ends at all renders one straight line.
|
|
148
131
|
*/
|
|
149
132
|
declare function resolveArcs(cells: Cell[], noteCount: number): Arc[];
|
|
133
|
+
/**
|
|
134
|
+
* The matra marks a cell's final note carries: its total duration as whole
|
|
135
|
+
* আ-কার matras plus an optional অর্ধমাত্রা ঃ (legend `রাঃ` = 1½, `সঃ` = ½).
|
|
136
|
+
* Only a `halfMatra` cell may show zero matras — every other cell keeps at
|
|
137
|
+
* least one, so an incomplete trailing group still gets its carrier.
|
|
138
|
+
*/
|
|
139
|
+
declare function cellMatra(cell: Cell): {
|
|
140
|
+
matras: number;
|
|
141
|
+
half: boolean;
|
|
142
|
+
};
|
|
150
143
|
/**
|
|
151
144
|
* The নাম / তাল / রাগ / আবর্তন / স্বরলিপিকার header block, shared by the
|
|
152
145
|
* akarmatrik grid and the staff view so both show the same metadata (localized
|
|
@@ -467,4 +460,4 @@ type Transliterator = (bengaliText: string) => string;
|
|
|
467
460
|
*/
|
|
468
461
|
declare function loadLyricTransliterator(lang: ViewerLang): Promise<Transliterator | undefined>;
|
|
469
462
|
|
|
470
|
-
export { type Arc, type Cell, type Cluster, type ComposeOptions, DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, type GridLang, LABELS, MARKS, NOTATION_FONT_URLS, type PrintOptions, type RenderOptions, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, type StaffOptions, type SwaralipiSheetElement, type TaalStaffOptions, type Transliterator, type ViewerLang, abcDuration, abcToSvg, buildAbc, buildTaalAbc, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
|
463
|
+
export { type Arc, type Cell, type Cluster, type ComposeOptions, DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, type GridLang, LABELS, MARKS, NOTATION_FONT_URLS, type PrintOptions, type RenderOptions, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, type StaffOptions, type SwaralipiSheetElement, type TaalStaffOptions, type Transliterator, type ViewerLang, abcDuration, abcToSvg, buildAbc, buildTaalAbc, cellMatra, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
package/dist/viewer/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildSchedule, drumPattern } from '../chunk-
|
|
1
|
+
import { isArcRaw, glideTargets, buildSchedule, drumPattern } from '../chunk-GHWURC4U.js';
|
|
2
2
|
import { TAALS } from '../chunk-6ETPFHZ6.js';
|
|
3
3
|
|
|
4
4
|
// src/viewer/glyphs.ts
|
|
@@ -41,7 +41,9 @@ var MARKS = {
|
|
|
41
41
|
var LABELS = {
|
|
42
42
|
bn: { title: "\u09A8\u09BE\u09AE", taal: "\u09A4\u09BE\u09B2", raag: "\u09B0\u09BE\u0997", avartan: "\u0986\u09AC\u09B0\u09CD\u09A4\u09A8", notationBy: "\u09B8\u09CD\u09AC\u09B0\u09B2\u09BF\u09AA\u09BF\u0995\u09BE\u09B0" },
|
|
43
43
|
hi: { title: "\u0928\u093E\u092E", taal: "\u0924\u093E\u0932", raag: "\u0930\u093E\u0917", avartan: "\u0906\u0935\u0930\u094D\u0924\u0928", notationBy: "\u0938\u094D\u0935\u0930\u0932\u093F\u092A\u093F\u0915\u093E\u0930" },
|
|
44
|
-
|
|
44
|
+
// "Cycle", not "Avartan": the English sheet is read by people who do not know the word, and
|
|
45
|
+
// one taal cycle is exactly what the number counts.
|
|
46
|
+
en: { title: "Song", taal: "Taal", raag: "Raag", avartan: "Cycles", notationBy: "Notator" }
|
|
45
47
|
};
|
|
46
48
|
function composeCluster(letter, opts) {
|
|
47
49
|
const classes = [];
|
|
@@ -65,7 +67,6 @@ function localizeDigits(s, lang) {
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
// src/viewer/render.ts
|
|
68
|
-
var NBSP = "\xA0";
|
|
69
70
|
var EPS = 1e-6;
|
|
70
71
|
var isIntegral = (x) => Math.abs(x - Math.round(x)) < EPS;
|
|
71
72
|
function escapeHtml(s) {
|
|
@@ -100,7 +101,7 @@ function groupRowIntoCells(notes) {
|
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
103
|
const d = note.durationMatra ?? 1;
|
|
103
|
-
if (isIntegral(d)) {
|
|
104
|
+
if (isIntegral(d) && note.halfMatra !== true) {
|
|
104
105
|
close();
|
|
105
106
|
cells.push({ kind: "group", start: i, notes: [note] });
|
|
106
107
|
return;
|
|
@@ -108,13 +109,11 @@ function groupRowIntoCells(notes) {
|
|
|
108
109
|
cur ??= { kind: "group", start: i, notes: [] };
|
|
109
110
|
cur.notes.push(note);
|
|
110
111
|
acc += d;
|
|
111
|
-
if (acc > EPS && isIntegral(acc)) close();
|
|
112
|
+
if (note.halfMatra === true || acc > EPS && isIntegral(acc)) close();
|
|
112
113
|
});
|
|
113
114
|
close();
|
|
114
115
|
return cells;
|
|
115
116
|
}
|
|
116
|
-
var ARC_RAW_RE = /^[wWxXyYjJeEzZ$=_<>`\\]+$/;
|
|
117
|
-
var isArcRaw = (raw) => raw !== void 0 && ARC_RAW_RE.test(raw);
|
|
118
117
|
function resolveArcs(cells, noteCount) {
|
|
119
118
|
const arcs = [];
|
|
120
119
|
let openStart;
|
|
@@ -183,15 +182,21 @@ function bracketGlyphs(note, edge) {
|
|
|
183
182
|
function matraGlyph(ctx) {
|
|
184
183
|
return ctx.lang === "bn" ? '<span class="sw-cl">a</span>' : '<span class="sw-iso">\u2013</span>';
|
|
185
184
|
}
|
|
186
|
-
function
|
|
187
|
-
if (
|
|
188
|
-
const [octave, letter] =
|
|
185
|
+
function renderGrace(svara, cls, ctx) {
|
|
186
|
+
if (svara === void 0) return "";
|
|
187
|
+
const [octave, letter] = svara;
|
|
189
188
|
const c = composeCluster(letter, { octave, withMatra: false, lang: ctx.lang });
|
|
190
|
-
return `<span class="${[
|
|
189
|
+
return `<span class="${[cls, ...c.classes].join(" ")}">${c.text}</span>`;
|
|
190
|
+
}
|
|
191
|
+
function cellMatra(cell) {
|
|
192
|
+
const total = cell.notes.reduce((a, n) => a + (n.durationMatra ?? 1), 0);
|
|
193
|
+
const half = cell.notes.some((n) => n.halfMatra === true);
|
|
194
|
+
const whole = Math.floor(total + EPS);
|
|
195
|
+
return { matras: half ? whole : Math.max(1, whole), half };
|
|
191
196
|
}
|
|
192
197
|
function renderPitchedInner(note, opts, ctx) {
|
|
193
198
|
let inner = bracketGlyphs(note, "open");
|
|
194
|
-
inner +=
|
|
199
|
+
inner += renderGrace(note.kan, "sw-kan", ctx);
|
|
195
200
|
if (note.sustain === true) inner += `<span class="sw-hy">${ctx.marks.hyphen}</span>`;
|
|
196
201
|
if (note.svara !== void 0) {
|
|
197
202
|
const [octave, letter] = note.svara;
|
|
@@ -199,22 +204,27 @@ function renderPitchedInner(note, opts, ctx) {
|
|
|
199
204
|
komal: note.komal,
|
|
200
205
|
tivra: note.tivra,
|
|
201
206
|
octave,
|
|
202
|
-
|
|
207
|
+
// The first matra is composed into the cluster itself (bn: the font's
|
|
208
|
+
// trailing `a`); any further ones are separate glyphs below.
|
|
209
|
+
withMatra: opts.matras >= 1,
|
|
203
210
|
lang: ctx.lang
|
|
204
211
|
});
|
|
205
212
|
inner += `<span class="${["sw-cl", ...c.classes].join(" ")}">${c.text}</span>`;
|
|
206
213
|
} else if (note.rest === true) {
|
|
207
|
-
inner += matraGlyph(ctx);
|
|
208
|
-
} else if (note.sustain === true
|
|
209
|
-
inner += matraGlyph(ctx);
|
|
214
|
+
inner += matraGlyph(ctx).repeat(Math.max(1, opts.matras));
|
|
215
|
+
} else if (note.sustain === true) {
|
|
216
|
+
inner += matraGlyph(ctx).repeat(opts.matras);
|
|
210
217
|
}
|
|
211
218
|
if (note.microtone !== void 0) {
|
|
212
219
|
const mark = localizeDigits(note.microtone === "atikomal" ? "2" : "1", ctx.lang);
|
|
213
220
|
inner += `<span class="sw-micro" title="${note.microtone}">${mark}</span>`;
|
|
214
221
|
}
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
|
|
222
|
+
inner += renderGrace(note.resh, "sw-resh", ctx);
|
|
223
|
+
if (note.svara !== void 0 && opts.matras > 1) {
|
|
224
|
+
inner += matraGlyph(ctx).repeat(opts.matras - 1);
|
|
225
|
+
}
|
|
226
|
+
if (opts.half) inner += `<span class="sw-half" title="${ctx.marks.cut}"></span>`;
|
|
227
|
+
if (opts.cuts > 0) inner += `<span class="sw-cut" title="${ctx.marks.cut}"></span>`.repeat(opts.cuts);
|
|
218
228
|
inner += bracketGlyphs(note, "close");
|
|
219
229
|
return inner;
|
|
220
230
|
}
|
|
@@ -231,12 +241,12 @@ function renderAnnotation(notes, ctx) {
|
|
|
231
241
|
continue;
|
|
232
242
|
}
|
|
233
243
|
if (cell.kind === "group") {
|
|
234
|
-
const
|
|
244
|
+
const { matras, half } = cellMatra(cell);
|
|
245
|
+
const cuts = half ? 0 : cutMarkCount(cell.notes[0].raw);
|
|
235
246
|
cell.notes.forEach((note2, j) => {
|
|
236
247
|
const last = j === cell.notes.length - 1;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
);
|
|
248
|
+
const opts = last ? { matras, half, cuts } : { matras: 0, half: false, cuts: 0 };
|
|
249
|
+
parts.push(`<span class="sw-n">${renderPitchedInner(note2, opts, ctx)}</span>`);
|
|
240
250
|
});
|
|
241
251
|
continue;
|
|
242
252
|
}
|
|
@@ -274,7 +284,8 @@ function renderRow(row, partIdx, rowIdx, ctx) {
|
|
|
274
284
|
const firstCol = cell.start + 1;
|
|
275
285
|
const lastCol = cell.start + cell.notes.length;
|
|
276
286
|
const cellSpan = lastCol > firstCol ? `grid-column:${firstCol} / ${lastCol + 1}` : `grid-column:${firstCol}`;
|
|
277
|
-
const
|
|
287
|
+
const { matras, half } = cellMatra(cell);
|
|
288
|
+
const cuts = cell.kind === "group" && !half ? cutMarkCount(cell.notes[0].raw) : 0;
|
|
278
289
|
cell.notes.forEach((note, j) => {
|
|
279
290
|
const col = cell.start + j + 1;
|
|
280
291
|
const path = `${partIdx}.${rowIdx}.${cell.start + j}`;
|
|
@@ -285,8 +296,9 @@ function renderRow(row, partIdx, rowIdx, ctx) {
|
|
|
285
296
|
);
|
|
286
297
|
} else if (cell.kind === "group") {
|
|
287
298
|
const last = j === cell.notes.length - 1;
|
|
299
|
+
const pOpts = last ? { matras, half, cuts } : { matras: 0, half: false, cuts: 0 };
|
|
288
300
|
notation.push(
|
|
289
|
-
`<span class="sw-n${cellEdges}" data-note="${path}" style="grid-column:${col}">${renderPitchedInner(note,
|
|
301
|
+
`<span class="sw-n${cellEdges}" data-note="${path}" style="grid-column:${col}">${renderPitchedInner(note, pOpts, ctx)}</span>`
|
|
290
302
|
);
|
|
291
303
|
} else {
|
|
292
304
|
const raw = rawDisplay(note);
|
|
@@ -359,9 +371,9 @@ function renderToHtml(doc, opts = {}) {
|
|
|
359
371
|
|
|
360
372
|
// src/viewer/styles.ts
|
|
361
373
|
var NOTATION_FONT_URLS = {
|
|
362
|
-
Swarabitan: "https://
|
|
363
|
-
ome_bhatkhande_hindi: "https://
|
|
364
|
-
ome_bhatkhande_english: "https://
|
|
374
|
+
Swarabitan: "https://lipighor.pages.dev/swarabitan/Swarabitan.ttf",
|
|
375
|
+
ome_bhatkhande_hindi: "https://lipighor.pages.dev/ome-bhatkhande/OmeBhatkhandeHindi.ttf",
|
|
376
|
+
ome_bhatkhande_english: "https://lipighor.pages.dev/ome-bhatkhande/OmeBhatkhandeEnglish.ttf"
|
|
365
377
|
};
|
|
366
378
|
NOTATION_FONT_URLS.Swarabitan;
|
|
367
379
|
var FONT_FACES = Object.entries(NOTATION_FONT_URLS).map(
|
|
@@ -377,9 +389,9 @@ ${FONT_FACES}
|
|
|
377
389
|
}
|
|
378
390
|
|
|
379
391
|
/* ---- notation font, per language (the note clusters + grace notes) ---- */
|
|
380
|
-
.sw-sheet[lang="bn"] .sw-cl, .sw-
|
|
381
|
-
.sw-sheet[lang="hi"] .sw-cl, .sw-
|
|
382
|
-
.sw-sheet[lang="en"] .sw-cl, .sw-
|
|
392
|
+
.sw-sheet[lang="bn"] :is(.sw-cl, .sw-kan, .sw-resh) { font-family: Swarabitan, var(--sw-font, sans-serif); }
|
|
393
|
+
.sw-sheet[lang="hi"] :is(.sw-cl, .sw-kan, .sw-resh) { font-family: ome_bhatkhande_hindi, var(--sw-font, sans-serif); }
|
|
394
|
+
.sw-sheet[lang="en"] :is(.sw-cl, .sw-kan, .sw-resh) { font-family: ome_bhatkhande_english, var(--sw-font, sans-serif); }
|
|
383
395
|
|
|
384
396
|
/* ---- header ---- */
|
|
385
397
|
.sw-header {
|
|
@@ -438,18 +450,44 @@ ${FONT_FACES}
|
|
|
438
450
|
.sw-ati-taar::before { top: -0.3em; }
|
|
439
451
|
.sw-ati-mandra::before { bottom: -0.35em; }
|
|
440
452
|
|
|
441
|
-
/*
|
|
442
|
-
.sw-kan
|
|
453
|
+
/* grace notes: small raised clusters \u2014 \u0995\u09A3 before the note, \u09B0\u09C7\u09B6 after it */
|
|
454
|
+
.sw-kan,
|
|
455
|
+
.sw-resh {
|
|
443
456
|
position: relative;
|
|
444
457
|
display: inline-block;
|
|
445
458
|
font-size: 0.58em;
|
|
446
459
|
vertical-align: 0.75em;
|
|
447
|
-
margin-right: 0.08em;
|
|
448
460
|
}
|
|
461
|
+
.sw-kan { margin-right: 0.08em; }
|
|
462
|
+
.sw-resh { margin-left: 0.08em; }
|
|
449
463
|
|
|
450
464
|
.sw-hy { padding-right: 0.02em; }
|
|
451
465
|
.sw-iso { display: inline-block; margin-left: -0.18em; }
|
|
452
|
-
|
|
466
|
+
/* The \u0985\u09B0\u09CD\u09A7\u09AE\u09BE\u09A4\u09CD\u09B0\u09BE / \u099B\u09C7\u09A6 mark: two stacked rings (legend p. \u09E7\u09E9\u09EB), drawn rather
|
|
467
|
+
* than typed \u2014 an isolated \u0983 has no base, so every Bengali font shapes it with
|
|
468
|
+
* a dotted circle (an NBSP carrier does not help). sw-half = semantic
|
|
469
|
+
* (halfMatra), sw-cut = decoded from a source cell's raw: one look, two
|
|
470
|
+
* provenances. */
|
|
471
|
+
.sw-cut,
|
|
472
|
+
.sw-half {
|
|
473
|
+
position: relative;
|
|
474
|
+
display: inline-block;
|
|
475
|
+
width: 0.3em;
|
|
476
|
+
height: 1em;
|
|
477
|
+
vertical-align: baseline;
|
|
478
|
+
}
|
|
479
|
+
.sw-cut::before, .sw-cut::after,
|
|
480
|
+
.sw-half::before, .sw-half::after {
|
|
481
|
+
content: '';
|
|
482
|
+
position: absolute;
|
|
483
|
+
left: 0.08em;
|
|
484
|
+
width: 0.15em;
|
|
485
|
+
height: 0.15em;
|
|
486
|
+
border-radius: 50%;
|
|
487
|
+
background: currentColor;
|
|
488
|
+
}
|
|
489
|
+
.sw-cut::before, .sw-half::before { top: 0.2em; }
|
|
490
|
+
.sw-cut::after, .sw-half::after { top: 0.55em; }
|
|
453
491
|
.sw-br { opacity: 0.8; padding: 0 0.06em; }
|
|
454
492
|
.sw-micro { font-size: 0.6em; vertical-align: super; opacity: 0.8; }
|
|
455
493
|
|
|
@@ -606,20 +644,23 @@ function buildAbc(schedule, lyricOf, opts) {
|
|
|
606
644
|
barPos -= beatsPerBar;
|
|
607
645
|
}
|
|
608
646
|
};
|
|
609
|
-
|
|
647
|
+
schedule.events.forEach((ev, i) => {
|
|
610
648
|
if (ev.midi === null) {
|
|
611
649
|
if (ev.kind === "rest") {
|
|
612
650
|
tokens.push(`z${abcDuration(ev.durationBeats)}`);
|
|
613
651
|
words.push("*");
|
|
614
652
|
advance(ev.durationBeats);
|
|
615
653
|
}
|
|
616
|
-
|
|
654
|
+
return;
|
|
617
655
|
}
|
|
618
|
-
|
|
656
|
+
const more = glideTargets(schedule.events, i).length > 0;
|
|
657
|
+
const slurOpen = ev.glide !== true && more ? "(" : "";
|
|
658
|
+
const slurClose = ev.glide === true && !more ? ")" : "";
|
|
659
|
+
tokens.push(`${slurOpen}${abcNote(ev)}${slurClose}`);
|
|
619
660
|
const lyr = lyricOf(ev);
|
|
620
661
|
words.push(lyr ? abcText(lyr).replace(/\s+/g, "~") : "*");
|
|
621
662
|
advance(ev.durationBeats);
|
|
622
|
-
}
|
|
663
|
+
});
|
|
623
664
|
if (tokens.length && tokens[tokens.length - 1] !== "|") tokens.push("|]");
|
|
624
665
|
else if (tokens.length) tokens[tokens.length - 1] = "|]";
|
|
625
666
|
const meter = ratioMeter(beatsPerBar);
|
|
@@ -790,26 +831,26 @@ function escapeHtml2(s) {
|
|
|
790
831
|
}
|
|
791
832
|
function watermarkCss(text) {
|
|
792
833
|
if (!text) return "";
|
|
834
|
+
const span = 92;
|
|
835
|
+
const size = Math.min(18, span / (0.62 * text.length));
|
|
836
|
+
const len = Math.min(span, 0.62 * text.length * size);
|
|
837
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"><text x="50" y="50" dy=".35em" text-anchor="middle" font-family="sans-serif" font-weight="700" fill="rgba(0,0,0,0.07)" font-size="${size.toFixed(2)}" textLength="${len.toFixed(2)}" lengthAdjust="spacingAndGlyphs" transform="rotate(-35 50 50)">${escapeHtml2(text)}</text></svg>`;
|
|
793
838
|
return `
|
|
794
839
|
.sw-watermark {
|
|
795
840
|
position: fixed; inset: 0; z-index: 0; pointer-events: none;
|
|
796
|
-
|
|
797
|
-
overflow: hidden;
|
|
841
|
+
background: url("data:image/svg+xml,${encodeURIComponent(svg)}") center / contain no-repeat;
|
|
798
842
|
-webkit-print-color-adjust: exact; print-color-adjust: exact;
|
|
799
843
|
}
|
|
800
|
-
.sw-watermark span {
|
|
801
|
-
font-size: 11vw; font-weight: 700; letter-spacing: .08em;
|
|
802
|
-
color: rgba(0,0,0,0.07); transform: rotate(-35deg); white-space: nowrap;
|
|
803
|
-
}
|
|
804
844
|
body > .sw-sheet, body > .sw-footer { position: relative; z-index: 1; }
|
|
805
845
|
`;
|
|
806
846
|
}
|
|
807
847
|
function chrome(text, notator) {
|
|
808
|
-
const top = text ?
|
|
848
|
+
const top = text ? '<div class="sw-watermark" aria-hidden="true"></div>' : "";
|
|
809
849
|
const bottom = notator ? `<footer class="sw-footer">${escapeHtml2(notator)}</footer>` : "";
|
|
810
850
|
return { top, bottom };
|
|
811
851
|
}
|
|
812
852
|
function resolveNotator(doc, opts) {
|
|
853
|
+
if (opts.notator === "") return "";
|
|
813
854
|
return doc.meta.notationBy ?? opts.notator ?? DEFAULT_NOTATOR;
|
|
814
855
|
}
|
|
815
856
|
function pageHtml(lang, title, bodyHtml, opts, doc) {
|
|
@@ -1075,6 +1116,6 @@ function defineSwaralipiSheet(tagName = "swaralipi-sheet") {
|
|
|
1075
1116
|
return ctor;
|
|
1076
1117
|
}
|
|
1077
1118
|
|
|
1078
|
-
export { DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, LABELS, MARKS, NOTATION_FONT_URLS, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, abcDuration, abcToSvg, buildAbc, buildTaalAbc, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
|
1119
|
+
export { DEFAULT_NOTATOR, DEFAULT_WATERMARK, DIGITS, LABELS, MARKS, NOTATION_FONT_URLS, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS, abcDuration, abcToSvg, buildAbc, buildTaalAbc, cellMatra, composeCluster, defineSwaralipiSheet, docToAbc, groupRowIntoCells, loadLyricTransliterator, localizeDigits, midiToAbc, printSwaralipi, renderMetaHeader, renderPrintDocument, renderStaffHtml, renderStaffPrintDocument, renderTaalStaffHtml, renderToHtml, resolveArcs };
|
|
1079
1120
|
//# sourceMappingURL=index.js.map
|
|
1080
1121
|
//# sourceMappingURL=index.js.map
|