@ugfoundation/swaralipi-js 0.1.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/LICENSE +347 -0
- package/README.md +257 -0
- package/dist/batch-NF2Q2CFS.js +47 -0
- package/dist/batch-NF2Q2CFS.js.map +1 -0
- package/dist/chunk-C6O7DYU5.js +115 -0
- package/dist/chunk-C6O7DYU5.js.map +1 -0
- package/dist/chunk-GWXI2HJA.js +14 -0
- package/dist/chunk-GWXI2HJA.js.map +1 -0
- package/dist/chunk-N3NNWAOW.js +593 -0
- package/dist/chunk-N3NNWAOW.js.map +1 -0
- package/dist/cli.cjs +913 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/convert/index.cjs +720 -0
- package/dist/convert/index.cjs.map +1 -0
- package/dist/convert/index.d.cts +270 -0
- package/dist/convert/index.d.ts +270 -0
- package/dist/convert/index.js +5 -0
- package/dist/convert/index.js.map +1 -0
- package/dist/index.cjs +143 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/player/index.cjs +775 -0
- package/dist/player/index.cjs.map +1 -0
- package/dist/player/index.d.cts +285 -0
- package/dist/player/index.d.ts +285 -0
- package/dist/player/index.js +743 -0
- package/dist/player/index.js.map +1 -0
- package/dist/schema-gxhG45OK.d.cts +467 -0
- package/dist/schema-gxhG45OK.d.ts +467 -0
- package/dist/spec/index.cjs +143 -0
- package/dist/spec/index.cjs.map +1 -0
- package/dist/spec/index.d.cts +70 -0
- package/dist/spec/index.d.ts +70 -0
- package/dist/spec/index.js +4 -0
- package/dist/spec/index.js.map +1 -0
- package/dist/taals-DguYW0wf.d.cts +60 -0
- package/dist/taals-DguYW0wf.d.ts +60 -0
- package/dist/viewer/index.cjs +998 -0
- package/dist/viewer/index.cjs.map +1 -0
- package/dist/viewer/index.d.cts +285 -0
- package/dist/viewer/index.d.ts +285 -0
- package/dist/viewer/index.js +814 -0
- package/dist/viewer/index.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { O as Octave, a as SvaraLetter, N as Note, S as Swaralipi } from '../schema-gxhG45OK.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-language glyph tables + Unicode cluster composition for the viewer.
|
|
6
|
+
*
|
|
7
|
+
* The akarmatrik system is script-portable: Bengali and Devanagari use the
|
|
8
|
+
* same letters-with-distinct-komal-forms convention (legend: কোমল র—ঋ,
|
|
9
|
+
* কোমল গ—জ্ঞ, কড়ি ম—ক্ষ, কোমল ধ—দ, কোমল ন—ণ), the same আ-কার matra carrier,
|
|
10
|
+
* the same reph-above for taar and understroke for mandra. `en` has no
|
|
11
|
+
* native convention, so it uses S R G M P D N with CSS marks (komal
|
|
12
|
+
* underline, tivra prime, octave dots) and no matra carrier.
|
|
13
|
+
*
|
|
14
|
+
* Unicode hazards owned here (see composeCluster):
|
|
15
|
+
* - mandra can NEVER be a real hasanta: letter + ্ + া is an invalid
|
|
16
|
+
* cluster (virama before vowel sign → dotted circle). It is always a
|
|
17
|
+
* CSS understroke (`sw-mandra`).
|
|
18
|
+
* - ঋ/ऋ (komal re) is an independent VOWEL letter: both র্+ঋ (reph over a
|
|
19
|
+
* vowel) and ঋ+া (vowel sign on a vowel) are invalid clusters. taar-ঋ
|
|
20
|
+
* falls back to a CSS reph (`sw-reph-css`); a matra following ঋ must be
|
|
21
|
+
* emitted as a separate isolated-matra span (`matraSeparate`).
|
|
22
|
+
* - Isolated dependent signs (া, ঃ) need a base: U+00A0 NBSP is the
|
|
23
|
+
* Unicode-sanctioned placeholder base and avoids dotted circles.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
type ViewerLang = 'bn' | 'hi' | 'en';
|
|
27
|
+
interface LetterForms {
|
|
28
|
+
shuddha: string;
|
|
29
|
+
/** Distinct komal glyph (bn/hi); absent for en (CSS underline instead). */
|
|
30
|
+
komal?: string;
|
|
31
|
+
/** Distinct tivra glyph (bn/hi ক্ষ/क्ष); absent for en (CSS prime). */
|
|
32
|
+
tivra?: string;
|
|
33
|
+
}
|
|
34
|
+
declare const LETTERS: Record<ViewerLang, Record<SvaraLetter, LetterForms>>;
|
|
35
|
+
/** Digits 0-9 in the target script (beat labels, avartan). */
|
|
36
|
+
declare const DIGITS: Record<ViewerLang, string>;
|
|
37
|
+
interface LangMarks {
|
|
38
|
+
/** আ-কার matra carrier appended to a group-final cluster ('' for en). */
|
|
39
|
+
matra: string;
|
|
40
|
+
/** Melisma / no-new-attack dash before a sustained cluster. */
|
|
41
|
+
hyphen: string;
|
|
42
|
+
/** Lyric continuation mark shown under sustains (the source uses ৹). */
|
|
43
|
+
melisma: string;
|
|
44
|
+
/** ছেদ cut/articulation mark (two stacked rings, ঃ-shaped). */
|
|
45
|
+
cut: string;
|
|
46
|
+
/** Real-text reph prefix for taar ('' for en → CSS dot instead). */
|
|
47
|
+
reph: string;
|
|
48
|
+
}
|
|
49
|
+
declare const MARKS: Record<ViewerLang, LangMarks>;
|
|
50
|
+
/** Header labels (NLTR prints নাম / তাল / আবর্তন …). */
|
|
51
|
+
declare const LABELS: Record<ViewerLang, {
|
|
52
|
+
title: string;
|
|
53
|
+
taal: string;
|
|
54
|
+
raag: string;
|
|
55
|
+
avartan: string;
|
|
56
|
+
notationBy: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** A composed notation cluster: text plus the CSS classes for marks the
|
|
59
|
+
* text itself cannot carry (mandra understroke, ati dots, en komal/tivra,
|
|
60
|
+
* CSS-reph fallback). */
|
|
61
|
+
interface Cluster {
|
|
62
|
+
text: string;
|
|
63
|
+
classes: string[];
|
|
64
|
+
/** Set when the matra could not join the cluster (ঋ/ऋ, or en where the
|
|
65
|
+
* carrier doesn't exist) and must be emitted as an isolated-matra span. */
|
|
66
|
+
matraSeparate: boolean;
|
|
67
|
+
}
|
|
68
|
+
interface ComposeOptions {
|
|
69
|
+
komal?: boolean;
|
|
70
|
+
tivra?: boolean;
|
|
71
|
+
octave: Octave;
|
|
72
|
+
/** Append the আ-কার matra carrier (group-final notes only). */
|
|
73
|
+
withMatra: boolean;
|
|
74
|
+
lang: ViewerLang;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compose one svara cluster. The single place that knows Unicode
|
|
78
|
+
* composition order: reph? + base + matra?, with the ঋ/mandra/en fallbacks
|
|
79
|
+
* documented in the file header.
|
|
80
|
+
*/
|
|
81
|
+
declare function composeCluster(letter: SvaraLetter, opts: ComposeOptions): Cluster;
|
|
82
|
+
/** Map ASCII digits in `s` to the target script's digits. */
|
|
83
|
+
declare function localizeDigits(s: string, lang: ViewerLang): string;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Pure spec-JSON → HTML renderer. No DOM, no side effects: usable for SSR
|
|
87
|
+
* (Astro/static sites emit `renderToHtml(doc)` next to a
|
|
88
|
+
* `<style>${SWARALIPI_CSS}</style>`) and unit-testable in plain Node.
|
|
89
|
+
*
|
|
90
|
+
* Layout model (mirrors NLTR's 4-row systems): each spec `Row` becomes one
|
|
91
|
+
* CSS grid with **one column per top-level note** and four grid rows —
|
|
92
|
+
* above-annotations / notation / below (slur arcs, marks) / lyric. Source
|
|
93
|
+
* cells (groups of sub-notes sharing one matra) become column *spans*, so
|
|
94
|
+
* per-sub-note lyric alignment and P2.3's per-note highlight targets fall
|
|
95
|
+
* out of the column model for free.
|
|
96
|
+
*
|
|
97
|
+
* Rendering is spec-driven (semantics, not `raw`): grouping derives from
|
|
98
|
+
* `durationMatra` accumulation so hand-authored documents without `raw`
|
|
99
|
+
* render identically. `raw` is consulted only for (a) raw-only fallback
|
|
100
|
+
* notes (never dropped — dimmed monospace), (b) the ছেদ cut mark and beat
|
|
101
|
+
* labels, whose grammar lives in raw (see src/convert/codec.ts).
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
interface RenderOptions {
|
|
105
|
+
/** Notation + UI language. Default `bn`. */
|
|
106
|
+
lang?: ViewerLang;
|
|
107
|
+
/** Render the NLTR-style নাম/তাল/আবর্তন header block. Default true. */
|
|
108
|
+
showHeader?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Lyric/title transliterator for `hi`/`en` (see loadLyricTransliterator).
|
|
111
|
+
* Without it, non-bn renders keep Bengali lyrics (graceful interim).
|
|
112
|
+
*/
|
|
113
|
+
transliterate?: (bengaliText: string) => string;
|
|
114
|
+
}
|
|
115
|
+
interface Cell {
|
|
116
|
+
kind: 'bar' | 'group' | 'raw' | 'carrier';
|
|
117
|
+
/** Index of the cell's first note within the row's notes array. */
|
|
118
|
+
start: number;
|
|
119
|
+
notes: Note[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Group a row's notes into rendered cells using a fractional-duration
|
|
123
|
+
* accumulator (raw-independent — works for hand-authored docs):
|
|
124
|
+
* - bar / raw-only / carrier notes force-close and form singleton cells;
|
|
125
|
+
* - full-matra notes are singleton groups;
|
|
126
|
+
* - fractional notes accumulate until the sum reaches an integer matra
|
|
127
|
+
* boundary (epsilon for 1/3, 0.2 chains), then the group closes.
|
|
128
|
+
* The converter emits k notes × 1/k per source cell, so groups coincide
|
|
129
|
+
* with source cells; an incomplete trailing group still closes at row end
|
|
130
|
+
* (the matra carrier lands on its last note).
|
|
131
|
+
*/
|
|
132
|
+
declare function groupRowIntoCells(notes: Note[]): Cell[];
|
|
133
|
+
interface Arc {
|
|
134
|
+
/** 1-based grid column of the arc's first / last note column. */
|
|
135
|
+
startCol: number;
|
|
136
|
+
endCol: number;
|
|
137
|
+
/** True when the matching end lies on a previous / following system. */
|
|
138
|
+
openLeft: boolean;
|
|
139
|
+
openRight: boolean;
|
|
140
|
+
/** Fill-segments-only row: render a straight underline, no curled ends. */
|
|
141
|
+
line?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Resolve under-arcs for one row. Sources, scanned left→right:
|
|
145
|
+
* - below-annotation raws: `w` opens at its cell's first column, `x`
|
|
146
|
+
* closes at its cell's last column ("xw" in one cell = close-then-open);
|
|
147
|
+
* - spec `meend: 'start' | 'end'` fields feed the same scan as synthetic
|
|
148
|
+
* w/x at the note's own column.
|
|
149
|
+
* Unmatched `x` → arc from column 1 with a squared-off (open) left end;
|
|
150
|
+
* unclosed `w` → arc to the last column with an open right end — both
|
|
151
|
+
* match the print's behavior when an arc continues across a system wrap.
|
|
152
|
+
* A row with fill segments but no ends at all renders one straight line.
|
|
153
|
+
*/
|
|
154
|
+
declare function resolveArcs(cells: Cell[], noteCount: number): Arc[];
|
|
155
|
+
/** Render a complete swaralipi document to an HTML string. Pair with
|
|
156
|
+
* SWARALIPI_CSS (shadow DOM does this automatically; SSR consumers emit a
|
|
157
|
+
* `<style>` themselves). All source text is HTML-escaped. */
|
|
158
|
+
declare function renderToHtml(doc: Swaralipi, opts?: RenderOptions): string;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Encapsulated stylesheet for the viewer. Injected into the
|
|
162
|
+
* `<swaralipi-sheet>` shadow root automatically; SSR consumers emit it
|
|
163
|
+
* themselves: `<style>${SWARALIPI_CSS}</style>` next to `renderToHtml()`.
|
|
164
|
+
*
|
|
165
|
+
* Theming hooks (CSS custom properties, all optional):
|
|
166
|
+
* --sw-font font stack (default: Noto Sans Bengali + system Bengali)
|
|
167
|
+
* --sw-size base font size
|
|
168
|
+
* --sw-cell-gap horizontal gap between source cells
|
|
169
|
+
* --sw-hl player-highlight background (P2.3)
|
|
170
|
+
* --sw-rule header rule / muted line color
|
|
171
|
+
*
|
|
172
|
+
* All ink uses `currentColor`, so the sheet follows the host's text color
|
|
173
|
+
* (dark mode included). Octave marks that Unicode cannot express in a valid
|
|
174
|
+
* cluster (mandra understroke, ati dots, ঋ-reph, en octave dots) are drawn
|
|
175
|
+
* with positioned pseudo-elements; offsets are em-based and tuned against
|
|
176
|
+
* the NLTR reference rendering of song 4270.
|
|
177
|
+
*/
|
|
178
|
+
declare const SWARALIPI_CSS = "\n.sw-sheet {\n font-family: var(--sw-font, 'Noto Sans Bengali', 'Kohinoor Bangla', 'Bangla Sangam MN', 'Nirmala UI', 'Noto Sans Devanagari', sans-serif);\n font-size: var(--sw-size, 1.125rem);\n line-height: 1.5;\n}\n\n/* ---- header ---- */\n.sw-header {\n margin: 0 0 0.75em;\n padding: 0 0 0.5em;\n border-bottom: 1px solid var(--sw-rule, rgba(128, 128, 128, 0.35));\n font-size: 0.95em;\n}\n.sw-meta-row { display: flex; gap: 0.3em; }\n.sw-meta-label { font-weight: 600; min-width: 4.5em; }\n.sw-meta-label::after { content: ':'; font-weight: 400; margin-left: 0.15em; }\n\n.sw-part-name { font-size: 0.85em; font-weight: 600; margin: 1em 0 0.2em; opacity: 0.85; }\n\n/* ---- row grid: above / notation / below(arcs) / lyric ---- */\n.sw-row {\n display: flex;\n align-items: flex-start;\n overflow-x: auto;\n padding: 0.4em 0;\n}\n.sw-label { flex: none; margin-right: 0.8em; font-weight: 600; }\n.sw-grid {\n display: grid;\n grid-template-rows: auto auto auto auto;\n grid-auto-columns: max-content;\n align-items: end;\n}\n.sw-above { grid-row: 1; font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n.sw-n { grid-row: 2; white-space: nowrap; }\n.sw-arc,\n.sw-below { grid-row: 3; }\n.sw-lyr { grid-row: 4; white-space: nowrap; padding-top: 0.3em; }\n.sw-below { font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n\n/* inter-cell gap as padding on each cell's first notation item, so arcs\n * and above-spans crossing cells stay continuous */\n.sw-cs { padding-left: var(--sw-cell-gap, 0.55em); }\n\n/* ---- notation clusters & marks ---- */\n.sw-cl { position: relative; display: inline-block; }\n\n/* mandra: hasanta-shaped understroke (a real \u09CD before \u09BE is invalid Unicode) */\n.sw-mandra::after {\n content: '';\n position: absolute;\n left: 0.1em;\n bottom: -0.08em;\n width: 0.45em;\n height: 0.09em;\n background: currentColor;\n transform: rotate(-32deg);\n}\n/* ati-mandra: an extra dot below */\n.sw-ati-mandra::before {\n content: '';\n position: absolute;\n left: 0.25em;\n bottom: -0.35em;\n width: 0.16em;\n height: 0.16em;\n border-radius: 50%;\n background: currentColor;\n}\n/* ati-taar (reph already in the text): an extra dot above */\n.sw-ati-taar::before {\n content: '';\n position: absolute;\n left: 0.25em;\n top: -0.3em;\n width: 0.16em;\n height: 0.16em;\n border-radius: 50%;\n background: currentColor;\n}\n/* CSS reph fallback for vowel letters \u098B/\u090B that reject a real reph */\n.sw-reph-css::before {\n content: '';\n position: absolute;\n top: -0.12em;\n left: 0.12em;\n width: 0.3em;\n height: 0.3em;\n border: 0.09em solid currentColor;\n border-right: none;\n border-bottom: none;\n border-top-left-radius: 0.3em;\n}\n/* en octave dots (Bhatkhande-style) */\n.sw-dot-above::before,\n.sw-dot-below::before {\n content: '';\n position: absolute;\n left: 50%;\n margin-left: -0.07em;\n width: 0.14em;\n height: 0.14em;\n border-radius: 50%;\n background: currentColor;\n}\n.sw-dot-above::before { top: -0.25em; }\n.sw-dot-below::before { bottom: -0.2em; }\n.sw-ati-taar.sw-dot-above::before,\n.sw-ati-mandra.sw-dot-below::before { box-shadow: 0.24em 0 0 currentColor; margin-left: -0.19em; }\n/* en accidentals (bn/hi use distinct letters instead) */\n.sw-komal { text-decoration: underline; text-underline-offset: 0.18em; }\n.sw-tivra::after { content: '\\2032'; font-size: 0.7em; vertical-align: super; }\n\n/* kan grace: small raised cluster left of the main note */\n.sw-kan {\n position: relative;\n display: inline-block;\n font-size: 0.58em;\n vertical-align: 0.75em;\n margin-right: 0.08em;\n}\n\n.sw-hy { padding-right: 0.02em; }\n.sw-iso { display: inline-block; margin-left: -0.18em; }\n.sw-cut { font-size: 0.8em; display: inline-block; margin-left: -0.15em; }\n.sw-br { opacity: 0.8; padding: 0 0.06em; }\n.sw-micro { font-size: 0.6em; vertical-align: super; opacity: 0.8; }\n\n/* raw fallback: never dropped, visibly non-notation */\n.sw-raw {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.72em;\n opacity: 0.55;\n}\n\n/* ---- bars: dari (thin) and danda strokes, notation-row height ---- */\n/* horizontal gap before a bar comes from its own .sw-cs padding-left \u2014\n * never reset it with a padding shorthand here */\n.sw-bar {\n grid-row: 2;\n align-self: stretch;\n display: inline-flex;\n align-items: stretch;\n gap: 0.16em;\n padding-right: 0.1em;\n}\n.sw-bar i { display: inline-block; width: 0.14em; min-height: 1.25em; background: currentColor; }\n.sw-bar--dari i { width: 0.05em; opacity: 0.9; }\n.sw-bar--quad i:nth-child(3) { margin-left: 0.18em; }\n.sw-above .sw-bar, .sw-below .sw-bar { display: inline-flex; vertical-align: baseline; }\n.sw-above .sw-bar i, .sw-below .sw-bar i { min-height: 1em; }\n\n/* ---- under-arcs (slurs decoded from w/x segments and meend) ---- */\n.sw-arc {\n align-self: start;\n height: 0.4em;\n margin: 0.05em 0.25em 0;\n border: 0.09em solid currentColor;\n border-top: none;\n border-bottom-left-radius: 0.6em;\n border-bottom-right-radius: 0.6em;\n opacity: 0.85;\n}\n.sw-arc--openl { border-left: none; border-bottom-left-radius: 0; }\n.sw-arc--openr { border-right: none; border-bottom-right-radius: 0; }\n.sw-arc--line { border-left: none; border-right: none; border-radius: 0; height: 0.22em; }\n\n/* ---- annotation content ---- */\n.sw-beat { position: relative; display: inline-block; padding: 0 0.1em; }\n.sw-sam::after {\n content: '';\n position: absolute;\n top: -0.45em;\n left: 50%;\n width: 0.1em;\n height: 0.4em;\n background: currentColor;\n transform: rotate(14deg);\n}\n.sw-stop i {\n display: inline-block;\n width: 0.07em;\n height: 1em;\n margin: 0 0.07em;\n background: currentColor;\n vertical-align: text-bottom;\n}\n\n/* ---- player sync (P2.3) ---- */\n.sw-hl { background: var(--sw-hl, rgba(255, 196, 64, 0.45)); border-radius: 0.15em; }\n\n/* ---- element error box ---- */\n.sw-error {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.85em;\n padding: 0.6em 0.8em;\n border: 1px solid rgba(200, 64, 64, 0.6);\n border-radius: 0.3em;\n color: #b33;\n background: rgba(200, 64, 64, 0.08);\n}\n";
|
|
179
|
+
/**
|
|
180
|
+
* Print stylesheet — pair with `SWARALIPI_CSS` (renderPrintDocument injects
|
|
181
|
+
* both). Gated on `@media print`, so it also works if a consumer drops it into
|
|
182
|
+
* a page and prints that page directly.
|
|
183
|
+
*
|
|
184
|
+
* - `print-color-adjust: exact` forces the marks that are drawn as tiny
|
|
185
|
+
* `background: currentColor` pseudo-elements (octave dots, arcs, danda
|
|
186
|
+
* strokes, sam tick) to actually print — browsers drop backgrounds by
|
|
187
|
+
* default, which would silently strip the notation's diacritics.
|
|
188
|
+
* - rows are un-clipped (no scrollbar on paper) and kept whole across page
|
|
189
|
+
* breaks; part headings stay with their first row.
|
|
190
|
+
*/
|
|
191
|
+
declare const SWARALIPI_PRINT_CSS = "\n@page { margin: 16mm; }\n@media print {\n .sw-sheet { -webkit-print-color-adjust: exact; print-color-adjust: exact; color: #000; }\n .sw-row { overflow: visible !important; break-inside: avoid; page-break-inside: avoid; }\n .sw-part { break-inside: auto; }\n .sw-part-name, .sw-header { break-after: avoid-page; page-break-after: avoid; }\n .sw-hl { background: none !important; }\n}\n";
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Print / "Save as PDF" support.
|
|
195
|
+
*
|
|
196
|
+
* High-fidelity PDF of আকারমাত্রিক notation can only come from the browser's
|
|
197
|
+
* own print engine — it reuses the exact HarfBuzz shaping (reph, conjuncts,
|
|
198
|
+
* matra) and the CSS-drawn marks (octave dots, slur arcs, danda strokes) that
|
|
199
|
+
* the viewer renders on screen. Rasterizers (html2canvas) and PDF-primitive
|
|
200
|
+
* libraries (jsPDF/pdfmake) have no Indic shaping and drop pseudo-element
|
|
201
|
+
* marks, so we deliberately avoid them.
|
|
202
|
+
*
|
|
203
|
+
* `renderPrintDocument` builds a self-contained HTML page from the pure
|
|
204
|
+
* `renderToHtml` + `SWARALIPI_CSS` (so it sidesteps the shadow-DOM "print drops
|
|
205
|
+
* encapsulated styles" gotcha); `printSwaralipi` prints it via a hidden iframe.
|
|
206
|
+
* Both reuse the same renderer as the viewer, so the PDF matches the screen.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
interface PrintOptions {
|
|
210
|
+
/** Notation + UI language. Default `bn`. */
|
|
211
|
+
lang?: ViewerLang;
|
|
212
|
+
/** Render the নাম/তাল header block. Default true. */
|
|
213
|
+
showHeader?: boolean;
|
|
214
|
+
/** Lyric/title transliterator for hi/en (see loadLyricTransliterator). */
|
|
215
|
+
transliterate?: (bengaliText: string) => string;
|
|
216
|
+
/** Document `<title>` — the browser's default "Save as PDF" filename.
|
|
217
|
+
* Defaults to the document's `meta.title`. */
|
|
218
|
+
title?: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Build a complete, standalone HTML document for printing a swaralipi sheet:
|
|
222
|
+
* the rendered notation plus `SWARALIPI_CSS` and the print stylesheet, on a
|
|
223
|
+
* white page. Usable for a hidden-iframe print, a new browser tab, or
|
|
224
|
+
* server-side headless-Chrome PDF generation.
|
|
225
|
+
*/
|
|
226
|
+
declare function renderPrintDocument(doc: Swaralipi, opts?: PrintOptions): string;
|
|
227
|
+
/**
|
|
228
|
+
* Open the browser print dialog for a swaralipi document (the user picks a
|
|
229
|
+
* printer or "Save as PDF"). Renders into an off-screen iframe so it prints
|
|
230
|
+
* only the sheet — independent of the host page's chrome and CSS — then cleans
|
|
231
|
+
* up. Browser-only; throws in a non-DOM environment (use renderPrintDocument
|
|
232
|
+
* for SSR / headless-Chrome instead).
|
|
233
|
+
*/
|
|
234
|
+
declare function printSwaralipi(doc: Swaralipi, opts?: PrintOptions): void;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The `<swaralipi-sheet>` custom element — a thin shadow-DOM shell around
|
|
238
|
+
* the pure renderer.
|
|
239
|
+
*
|
|
240
|
+
* The element class is created lazily inside defineSwaralipiSheet():
|
|
241
|
+
* a top-level `extends HTMLElement` would throw on import in Node, and this
|
|
242
|
+
* module must stay importable for SSR (where only renderToHtml is used).
|
|
243
|
+
* Nothing registers automatically — call defineSwaralipiSheet() once.
|
|
244
|
+
*
|
|
245
|
+
* Validation is off by default (converter output is pre-validated); setting
|
|
246
|
+
* `validate = true` parses documents against the Zod schema via a dynamic
|
|
247
|
+
* import, so the viewer bundle stays free of bare runtime imports (it can
|
|
248
|
+
* be loaded directly from dist/ in a browser without a bundler).
|
|
249
|
+
*/
|
|
250
|
+
|
|
251
|
+
interface SwaralipiSheetElement extends HTMLElement {
|
|
252
|
+
/** The document to render (property only; renders on assignment). */
|
|
253
|
+
doc: Swaralipi | undefined;
|
|
254
|
+
/** Parse documents against the spec schema before rendering. */
|
|
255
|
+
validate: boolean;
|
|
256
|
+
/** Add the player-highlight class to the note at "part.row.note". */
|
|
257
|
+
highlight(path: string): HTMLElement | null;
|
|
258
|
+
clearHighlights(): void;
|
|
259
|
+
/** Open the print dialog (→ "Save as PDF") for the current document. */
|
|
260
|
+
print(options?: PrintOptions): void;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Register `<swaralipi-sheet>` (or a custom tag name). Idempotent. Throws
|
|
264
|
+
* outside a DOM environment — use renderToHtml() for SSR.
|
|
265
|
+
*/
|
|
266
|
+
declare function defineSwaralipiSheet(tagName?: string): CustomElementConstructor;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Lazy lyric transliteration for `hi` / `en` renders.
|
|
270
|
+
*
|
|
271
|
+
* Swara glyphs come from the sync tables in glyphs.ts; only *linguistic*
|
|
272
|
+
* text (lyrics, title, names) needs transliteration, so sanscript loads via
|
|
273
|
+
* dynamic import — `bn`-only consumers (and their bundles) never touch it.
|
|
274
|
+
*/
|
|
275
|
+
|
|
276
|
+
type Transliterator = (bengaliText: string) => string;
|
|
277
|
+
/**
|
|
278
|
+
* Load a Bengali→target transliterator for the given viewer language.
|
|
279
|
+
* Returns undefined for `bn` (no work to do). Pass the result as
|
|
280
|
+
* `RenderOptions.transliterate`; the `<swaralipi-sheet>` element wires this
|
|
281
|
+
* automatically when its `lang` attribute changes.
|
|
282
|
+
*/
|
|
283
|
+
declare function loadLyricTransliterator(lang: ViewerLang): Promise<Transliterator | undefined>;
|
|
284
|
+
|
|
285
|
+
export { type Arc, type Cell, type Cluster, type ComposeOptions, DIGITS, LABELS, LETTERS, MARKS, type PrintOptions, type RenderOptions, SWARALIPI_CSS, SWARALIPI_PRINT_CSS, type SwaralipiSheetElement, type Transliterator, type ViewerLang, composeCluster, defineSwaralipiSheet, groupRowIntoCells, loadLyricTransliterator, localizeDigits, printSwaralipi, renderPrintDocument, renderToHtml, resolveArcs };
|