@gondola-lyrics/kit 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/dist/formats.d.ts CHANGED
@@ -1,6 +1,20 @@
1
1
  import { Diagnostic } from '@gondola-lyrics/model/runtime';
2
+ import { Meta } from '@gondola-lyrics/model/runtime';
2
3
  import { runtime } from '@gondola-lyrics/model';
3
4
 
5
+ /**
6
+ * Attaches whole-word ruby without changing the source text, segmentation, or timing.
7
+ *
8
+ * @param lines Original timed rows before filtering or sorting.
9
+ * @param sources Readings with source coverage lengths and optional token times.
10
+ *
11
+ * @returns Annotated rows and matched source indices, preserving unchanged nodes.
12
+ */
13
+ export declare const attachRubies: (lines: runtime.Line[], sources: RubySource[]) => {
14
+ lines: runtime.Line[];
15
+ matched: Set<number>;
16
+ };
17
+
4
18
  /**
5
19
  * Recognition reads only the original text; the annotation tracks never decide the format.
6
20
  *
@@ -8,12 +22,33 @@ import { runtime } from '@gondola-lyrics/model';
8
22
  */
9
23
  export declare const detectFormat: (input: unknown) => LyricFormat | undefined;
10
24
 
25
+ /**
26
+ * Recognizes native KRC from a duration line carrying a complete three-field word tag, or from the Kugou language container.
27
+ *
28
+ * Both signals live in the original plaintext, so an auxiliary track still cannot decide the format.
29
+ *
30
+ * @returns Whether the original plaintext contains a strong KRC syntax signal.
31
+ */
32
+ export declare const detectKrc: (input: unknown) => boolean;
33
+
34
+ /**
35
+ * Recognizes octal parameters with encoded clock rows, or a complete marked bilingual sequence.
36
+ */
37
+ export declare const detectKwrc: (input: unknown) => boolean;
38
+
11
39
  /**
12
40
  * A single readable time tag is enough for recognition; metadata alone is not.
13
41
  * This is a format probe, not a validity check, so an input of another shape is simply not LRC.
14
42
  */
15
43
  export declare const detectLrc: (input: unknown) => boolean;
16
44
 
45
+ /**
46
+ * Detects QRC from the original track so annotations cannot change format selection.
47
+ *
48
+ * @returns Whether plaintext or a supported XML payload contains a timed QRC row.
49
+ */
50
+ export declare const detectQrc: (input: unknown) => boolean;
51
+
17
52
  /**
18
53
  * Recognition needs a profile hint, since plain TTML says nothing about which profile wrote it.
19
54
  *
@@ -22,18 +57,28 @@ export declare const detectLrc: (input: unknown) => boolean;
22
57
  */
23
58
  export declare const detectTtml: (input: unknown) => boolean;
24
59
 
60
+ /**
61
+ * Recognizes native word tags or a JSON display line accompanied by LRC content in the original track.
62
+ *
63
+ * @returns Whether the original plaintext carries a YRC signal stronger than its shared QRC line header.
64
+ */
65
+ export declare const detectYrc: (input: unknown) => boolean;
66
+
25
67
  /**
26
68
  * Generates text in the requested format, which need not match `lyric.format`.
27
69
  *
28
- * The writer map pairs each format's options with its result and requires a writer for every supported format.
70
+ * The writer map pairs options with results only for formats that have an implemented writer.
29
71
  * An unknown target returns `null`.
30
72
  */
31
- export declare const generate: <Target extends LyricFormat>(lyric: runtime.Lyric, target: Target, options?: GenerateOptions[Target]) => GenerateResults[Target] | null;
73
+ export declare const generate: <Target extends GenerateFormat>(lyric: runtime.Lyric, target: Target, options?: GenerateOptions[Target]) => GenerateResults[Target] | null;
74
+
75
+ export declare type GenerateFormat = keyof GenerateOptions;
32
76
 
33
77
  /**
34
78
  * Generates the LRC text plus the annotations a single file cannot hold.
35
79
  *
36
80
  * Word tags appear only for a word-timed lyric when `wordTiming` is not `none`; otherwise every line stays whole.
81
+ * Word romanizations retain token boundaries; explicit line romanizations take precedence for the same language.
37
82
  */
38
83
  export declare const generateLrc: (lyric: runtime.Lyric, options?: LrcGenerateOptions) => LrcGenerateResult;
39
84
 
@@ -52,9 +97,42 @@ declare interface GenerateResults {
52
97
  *
53
98
  * Offsets are baked into timestamps; a negative result or a missing required time throws.
54
99
  * Profile mappings retain the lead agent and first AMLL ruby, omitting unsupported fields and instrumental nodes.
100
+ * Word romanizations are emitted as line text without their token timing.
55
101
  */
56
102
  export declare const generateTtml: (lyric: runtime.Lyric, options?: TtmlGenerateOptions) => TtmlGenerateResult;
57
103
 
104
+ /**
105
+ * Kugou writes `//` where it holds no translation, in QRC source rows and in its language payload alike.
106
+ *
107
+ * @returns Whether the trimmed text is that sentinel instead of real content.
108
+ */
109
+ export declare const isPlaceholderText: (text: string) => boolean;
110
+
111
+ declare interface JsonLine {
112
+ start: number;
113
+ text: string;
114
+ complete: boolean;
115
+ credit?: {
116
+ raw: string;
117
+ names: string[];
118
+ };
119
+ }
120
+
121
+ declare interface KrcContent {
122
+ original: string;
123
+ }
124
+
125
+ export declare type KrcParseInput = KrcContent;
126
+
127
+ export declare interface KrcReadResult {
128
+ lines: runtime.Line[];
129
+ metaTags: LrcMetaTag[];
130
+ }
131
+
132
+ export declare interface KwrcParseInput {
133
+ original: string;
134
+ }
135
+
58
136
  declare interface LrcContent {
59
137
  original: string;
60
138
  translations?: string;
@@ -82,6 +160,18 @@ export declare interface LrcGenerateOptions {
82
160
 
83
161
  export declare type LrcGenerateResult = LrcContent;
84
162
 
163
+ export declare interface LrcLineTiming {
164
+ /**
165
+ * Clock timestamp precision in milliseconds; unit-suffixed timestamps use 1ms.
166
+ */
167
+ precision: number;
168
+ }
169
+
170
+ export declare interface LrcMetaTag {
171
+ key: string;
172
+ value: string;
173
+ }
174
+
85
175
  export declare type LrcParseInput = LrcContent;
86
176
 
87
177
  export declare interface LrcParseOptions {
@@ -90,28 +180,99 @@ export declare interface LrcParseOptions {
90
180
  * Defaults to `0`, which requires an exact match.
91
181
  */
92
182
  annotationTolerance?: number;
183
+ /**
184
+ * Maximum roman token drift outside a matched word, in milliseconds; matched boundaries are adjusted to that word.
185
+ * Original word timing is preserved, and incomplete word matches retain the source line romanization.
186
+ *
187
+ * @default 0
188
+ */
189
+ wordAnnotationTolerance?: number;
190
+ /**
191
+ * Recovers unmatched roman fragments from unique two-kana combination starts or equal-sized gaps between timing anchors.
192
+ * Only a base kana followed by its small kana combines; doubled consonants and long vowels retain the whole line romanization.
193
+ * Recovered token times are clipped to their original word; untimed fragments inherit its range.
194
+ *
195
+ * @default false
196
+ */
197
+ wordAnnotationFallback?: boolean;
198
+ }
199
+
200
+ export declare interface LrcReadOptions {
201
+ /**
202
+ * Reports each line with its source precision and zero-based physical row before normalization changes its identity or order.
203
+ */
204
+ onLine?: (line: runtime.Line, timing: LrcLineTiming, row: number) => void;
205
+ /**
206
+ * Reports metadata with its zero-based physical row so container fields can preserve their relative order.
207
+ */
208
+ onMeta?: (tag: LrcMetaTag, row: number) => void;
209
+ }
210
+
211
+ export declare interface LrcReadResult {
212
+ lines: runtime.Line[];
213
+ metaTags: LrcMetaTag[];
93
214
  }
94
215
 
95
216
  /**
96
217
  * Values match the lowercase format names stored in `Lyric.format`.
97
218
  */
98
- export declare type LyricFormat = 'lrc' | 'ttml';
219
+ export declare type LyricFormat = 'lrc' | 'qrc' | 'krc' | 'kwrc' | 'yrc' | 'ttml';
220
+
221
+ export declare const META_PATTERN: RegExp;
99
222
 
100
223
  /**
101
224
  * Unrecognized text returns `null`; a recognized format returns its canonical lyric and diagnostics.
102
225
  * Annotation tracks travel with the source and are attached by the format's parser.
103
226
  */
104
- export declare const parse: (input: unknown, options?: LrcParseOptions & TtmlParseOptions) => ParseResult | null;
227
+ export declare const parse: (input: unknown, options?: LrcParseOptions & QrcParseOptions & TtmlParseOptions & YrcParseOptions) => ParseResult | null;
228
+
229
+ /**
230
+ * Parses decrypted Kugou lyrics, retaining explicit durations and attaching embedded annotations by source slot.
231
+ *
232
+ * A source carrying no KRC row is read as LRC, so a platform fallback keeps its container annotations.
233
+ * Placeholder slots carry no annotation, so they never keep a credit line in the stream.
234
+ * Kana supplies whole-word ruby; type 0 language tracks retain complete line romanization.
235
+ * Incomplete metadata remains available in unknowns, and source timing violations remain visible in diagnostics.
236
+ *
237
+ * @param input Decrypted plaintext or an object containing its original text.
238
+ *
239
+ * @returns Canonical lyrics and model diagnostics; no readable timed rows yields INVALID status.
240
+ */
241
+ export declare const parseKrc: (input: string | KrcParseInput) => ParseResult;
242
+
243
+ /**
244
+ * Parses decoded KWRC with explicit word durations and structurally verified embedded translations.
245
+ *
246
+ * Missing or conflicting parameters and unsafe word calculations retain the complete row as line-level text.
247
+ * Plain LRC remains readable; offset is stored as metadata without changing source timestamps.
248
+ *
249
+ * @param input Decoded plaintext or an object containing its original text.
250
+ *
251
+ * @returns Canonical lyrics and model diagnostics; no readable timed rows yields INVALID status.
252
+ */
253
+ export declare const parseKwrc: (input: string | KwrcParseInput) => ParseResult;
105
254
 
106
255
  /**
107
256
  * Empty timed rows become instrumental lines; source order and missing word times remain for model validation.
108
257
  *
109
258
  * Annotation tracks are read as lines too and attached by timestamp, and rows that match no line are dropped.
259
+ * Complete roman tracks attach to words by timing and optional local recovery; other tracks retain their source line text.
110
260
  *
111
261
  * `INVALID` means no readable timed lines; the returned diagnostics carry whatever the canonical tree breaks.
112
262
  */
113
263
  export declare const parseLrc: (input: string | LrcParseInput, options?: LrcParseOptions) => ParseResult;
114
264
 
265
+ /**
266
+ * Parses plaintext or XML QRC, retaining explicit timing, word romanization, and ruby from kana metadata.
267
+ * Original-track kana supplies ruby and is removed from the returned metadata.
268
+ *
269
+ * @param input Original lyrics with optional translation and romanization tracks.
270
+ * @param options Independent line and word tolerances, with optional local roman recovery.
271
+ *
272
+ * @returns Canonical lyrics and source diagnostics; an empty result has INVALID status.
273
+ */
274
+ export declare const parseQrc: (input: string | QrcParseInput, options?: QrcParseOptions) => ParseResult;
275
+
115
276
  /**
116
277
  * A parsed lyric in canonical form, with every rule it breaks.
117
278
  */
@@ -128,6 +289,128 @@ export declare interface ParseResult {
128
289
  */
129
290
  export declare const parseTtml: (input: TtmlParseInput, options?: TtmlParseOptions) => ParseResult;
130
291
 
292
+ /**
293
+ * Integer tags use `offset[,duration]` in milliseconds relative to the line start.
294
+ * Clock tags are absolute and may append a duration in milliseconds, as in `<00:01.50,500>`.
295
+ * A missing or zero duration leaves the word end unspecified.
296
+ */
297
+ export declare const parseWordTime: (body: string, lineStart: number) => {
298
+ start: number;
299
+ end: number | undefined;
300
+ } | undefined;
301
+
302
+ /**
303
+ * Parses native YRC or LRC fallback, keeping JSON display rows separate from annotation matching.
304
+ * Explicit line and word durations remain unchanged, including zero durations and source timing violations.
305
+ * JSON credit content becomes separate plain-text unknown entries sharing the source label and is omitted from lyric lines.
306
+ *
307
+ * @param input Plaintext tracks on the same timeline: yrc with ytlrc/yromalrc, or lrc with tlyric/romalrc.
308
+ * @param options Independent line and word tolerances, with optional local roman recovery.
309
+ *
310
+ * @returns Canonical lyrics and model diagnostics; no readable timed rows yields INVALID status.
311
+ */
312
+ export declare const parseYrc: (input: string | YrcParseInput, options?: YrcParseOptions) => ParseResult;
313
+
314
+ declare interface QrcContent {
315
+ original: string;
316
+ translations?: string;
317
+ romans?: string;
318
+ }
319
+
320
+ export declare type QrcParseInput = QrcContent;
321
+
322
+ export declare interface QrcParseOptions {
323
+ /**
324
+ * Extra tolerance in milliseconds for line annotations left after exact time and row order matching.
325
+ *
326
+ * @default 0
327
+ */
328
+ annotationTolerance?: number;
329
+ /**
330
+ * Extra word-boundary tolerance in milliseconds; native QRC tracks allow at least 1ms for rounding.
331
+ * LRC auxiliary tracks use exact word boundaries by default, and incomplete matches retain the whole line romanization.
332
+ *
333
+ * @default 0
334
+ */
335
+ wordAnnotationTolerance?: number;
336
+ /**
337
+ * Recovers unmatched roman fragments from unique two-kana combination starts or equal-sized gaps between timing anchors.
338
+ * Only a base kana followed by its small kana combines; doubled consonants and long vowels retain the whole line romanization.
339
+ * Recovered token times are clipped to their original word; untimed fragments inherit its range.
340
+ *
341
+ * @default false
342
+ */
343
+ wordAnnotationFallback?: boolean;
344
+ }
345
+
346
+ /**
347
+ * Reads JSON display text and splits the joined credit content at slash separators.
348
+ *
349
+ * @returns A readable display line and whether all source fields are represented, or null for other JSON.
350
+ */
351
+ export declare const readJsonLine: (text: string) => JsonLine | null;
352
+
353
+ /**
354
+ * Reads native KRC rows in source order and performs no other operation: no metadata mapping, annotation attachment, sorting, or normalization.
355
+ *
356
+ * Explicit line and word durations survive unchanged; whitespace splitting never reallocates segment time.
357
+ *
358
+ * @returns Original-order model lines and metadata tags awaiting interpretation.
359
+ */
360
+ export declare const readKrc: (text: string) => KrcReadResult;
361
+
362
+ /**
363
+ * Reads one LRC track in source order and performs no other operation: no metadata mapping, annotation attachment, sorting, or normalization.
364
+ *
365
+ * @param text Original lyrics or one auxiliary track in LRC syntax.
366
+ * @param options Optional observer for source timestamp information.
367
+ *
368
+ * @returns Model lines in input order and metadata tags with lowercase keys and trimmed values.
369
+ */
370
+ export declare const readLrc: (text: string, options?: LrcReadOptions) => LrcReadResult;
371
+
372
+ /**
373
+ * Maps standard lyric metadata while preserving unmapped tags and unparseable durations in unknowns.
374
+ *
375
+ * @param tags Reader tags with lowercase keys and trimmed values.
376
+ *
377
+ * @returns Model metadata without interpreting platform-specific embedded annotations.
378
+ */
379
+ export declare const readLrcMetaTags: (tags: LrcMetaTag[]) => Meta;
380
+
381
+ /**
382
+ * Reads coverage markers and optional absolute token times without interpreting timing digits as coverage.
383
+ *
384
+ * @returns Complete ruby sources, or undefined when any source cannot be read.
385
+ */
386
+ export declare const readRubyEntries: (value: string) => RubySource[] | undefined;
387
+
388
+ /**
389
+ * One reading and the length of the source word it covers, in Unicode code points.
390
+ */
391
+ export declare interface RubySource {
392
+ length: number;
393
+ ruby: runtime.WordAnnotationRuby;
394
+ }
395
+
396
+ /**
397
+ * Splits recognized tags from their following text while preserving literal content and empty tagged segments.
398
+ *
399
+ * @param pattern A global pattern whose first capture is the tag body.
400
+ * @param accepts Optional format-specific tag validation.
401
+ *
402
+ * @returns Source pieces in their original order, including an untagged prefix when present.
403
+ */
404
+ export declare const scanWordTags: (content: string, pattern: RegExp, accepts?: (tag: string) => boolean) => WordPiece[];
405
+
406
+ /**
407
+ * Untagged leading text is preserved; empty timed pieces retain explicit segment boundaries.
408
+ * Only recognized time tags split content; other angle-bracket text remains literal.
409
+ */
410
+ export declare const splitWordTags: (content: string) => WordPiece[];
411
+
412
+ export declare const TAG_PATTERN: RegExp;
413
+
131
414
  export declare interface TtmlGenerateOptions {
132
415
  /**
133
416
  * Defaults to the source TTML profile, or `amll` when the lyric came from another format.
@@ -156,4 +439,44 @@ export declare interface TtmlParseOptions {
156
439
 
157
440
  export declare type TtmlProfile = 'amll' | 'itunes';
158
441
 
442
+ /**
443
+ * A recognized tag precedes its text; a missing tag identifies the literal prefix.
444
+ */
445
+ export declare interface WordPiece {
446
+ text: string;
447
+ tag?: string;
448
+ }
449
+
450
+ declare interface YrcContent {
451
+ original: string;
452
+ translations?: string;
453
+ romans?: string;
454
+ }
455
+
456
+ export declare type YrcParseInput = YrcContent;
457
+
458
+ export declare interface YrcParseOptions {
459
+ /**
460
+ * Extra timestamp drift allowed after exact and source-precision matching, in milliseconds.
461
+ * Tracks must share the original timeline; equal row counts never enable order matching.
462
+ *
463
+ * @default 0
464
+ */
465
+ annotationTolerance?: number;
466
+ /**
467
+ * Maximum roman token drift outside a matched word, in milliseconds; matched boundaries are adjusted to that word.
468
+ * Original word timing is preserved, and incomplete matches retain the whole line romanization.
469
+ *
470
+ * @default 0
471
+ */
472
+ wordAnnotationTolerance?: number;
473
+ /**
474
+ * Recovers roman fragments from unique two-kana combination starts or equal-sized gaps between timing anchors.
475
+ * Recovered token times are clipped to their original word; untimed fragments inherit its range.
476
+ *
477
+ * @default false
478
+ */
479
+ wordAnnotationFallback?: boolean;
480
+ }
481
+
159
482
  export { }