@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 +327 -4
- package/dist/formats.js +1991 -292
- package/dist/formats.js.map +1 -1
- package/dist/generator.d.ts +7 -3
- package/dist/index.d.ts +242 -4
- package/dist/index.js +3 -3
- package/dist/parser.d.ts +236 -2
- package/dist/parser.js +3 -3
- package/dist/rules.js +166 -0
- package/dist/rules.js.map +1 -0
- package/dist/transforms.d.ts +95 -0
- package/dist/transforms.js +2251 -32
- package/dist/transforms.js.map +1 -1
- package/package.json +1 -1
package/dist/parser.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { detectFormat, parse, parseLrc, parseTtml } from "./formats.js";
|
|
2
|
-
import { InsertSpacesRules, deriveWordEmphasis, extractBackgroundLines, insertInstrumentalLines, insertSpacesInLines, stripBackgroundBrackets } from "./transforms.js";
|
|
3
|
-
export { InsertSpacesRules, deriveWordEmphasis, detectFormat, extractBackgroundLines, insertInstrumentalLines, insertSpacesInLines, parse, parseLrc, parseTtml, stripBackgroundBrackets };
|
|
1
|
+
import { detectFormat, parse, parseKrc, parseKwrc, parseLrc, parseQrc, parseTtml, parseYrc } from "./formats.js";
|
|
2
|
+
import { DEFAULT_CREDIT_NAME_SEPARATORS, InsertSpacesRules, NON_LYRIC_CATEGORIES, deriveWordEmphasis, extractAgents, extractBackgroundLines, extractCredits, insertInstrumentalLines, insertSpacesInLines, removeNonLyricLines, stripBackgroundBrackets } from "./transforms.js";
|
|
3
|
+
export { DEFAULT_CREDIT_NAME_SEPARATORS, InsertSpacesRules, NON_LYRIC_CATEGORIES, deriveWordEmphasis, detectFormat, extractAgents, extractBackgroundLines, extractCredits, insertInstrumentalLines, insertSpacesInLines, parse, parseKrc, parseKwrc, parseLrc, parseQrc, parseTtml, parseYrc, removeNonLyricLines, stripBackgroundBrackets };
|
package/dist/rules.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
//#region src/utils/array.ts
|
|
2
|
+
/**
|
|
3
|
+
* Preserves the input array when every element keeps its identity, so unchanged parent nodes can also be reused.
|
|
4
|
+
*
|
|
5
|
+
* The callback must leave inputs untouched and return the original element when unchanged.
|
|
6
|
+
*/
|
|
7
|
+
var mapShared = (items, transform) => {
|
|
8
|
+
let result = items;
|
|
9
|
+
for (const [index, item] of items.entries()) {
|
|
10
|
+
const transformed = transform(item);
|
|
11
|
+
if (transformed !== item) {
|
|
12
|
+
if (result === items) result = [...items];
|
|
13
|
+
result[index] = transformed;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Finds the first value meeting a lower bound so range queries can skip earlier candidates.
|
|
20
|
+
*
|
|
21
|
+
* @param values Values sorted in ascending order.
|
|
22
|
+
* @param target Inclusive lower bound.
|
|
23
|
+
*
|
|
24
|
+
* @returns The first matching index, or the array length when every value is smaller.
|
|
25
|
+
*/
|
|
26
|
+
var lowerBound = (values, target) => {
|
|
27
|
+
let left = 0;
|
|
28
|
+
let right = values.length;
|
|
29
|
+
while (left < right) {
|
|
30
|
+
const middle = Math.floor((left + right) / 2);
|
|
31
|
+
if (values[middle] < target) left = middle + 1;
|
|
32
|
+
else right = middle;
|
|
33
|
+
}
|
|
34
|
+
return left;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/utils/language.ts
|
|
38
|
+
var SCRIPT_PATTERNS = [
|
|
39
|
+
[/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u, 1],
|
|
40
|
+
[/\p{Script=Latin}/u, 2],
|
|
41
|
+
[/\p{Script=Hangul}/u, 3],
|
|
42
|
+
[/\p{Script=Cyrillic}/u, 4],
|
|
43
|
+
[/\p{Script=Greek}/u, 5],
|
|
44
|
+
[/\p{Script=Arabic}/u, 6],
|
|
45
|
+
[/\p{Script=Hebrew}/u, 7],
|
|
46
|
+
[/\p{Script=Devanagari}/u, 8],
|
|
47
|
+
[/\p{Script=Thai}/u, 9]
|
|
48
|
+
];
|
|
49
|
+
var getOtherScript = (text, start, width) => {
|
|
50
|
+
const unit = text.charCodeAt(start);
|
|
51
|
+
if (unit === 12539 || unit === 12540) return 0;
|
|
52
|
+
if (unit >= 1024 && unit <= 1153 || unit >= 1162 && unit <= 1327) return 4;
|
|
53
|
+
if (unit >= 931 && unit <= 993) return 5;
|
|
54
|
+
if (unit >= 1568 && unit <= 1599 || unit >= 1601 && unit <= 1610) return 6;
|
|
55
|
+
if (unit >= 1488 && unit <= 1514) return 7;
|
|
56
|
+
if (unit >= 2304 && unit <= 2384 || unit >= 2389 && unit <= 2403 || unit >= 2406 && unit <= 2431) return 8;
|
|
57
|
+
if (unit >= 3585 && unit <= 3642 || unit >= 3648 && unit <= 3675) return 9;
|
|
58
|
+
const character = text.slice(start, start + width);
|
|
59
|
+
for (const [pattern, script] of SCRIPT_PATTERNS) if (pattern.test(character)) return script;
|
|
60
|
+
return 0;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Finds a boundary between supported scripts without allocating a segment list.
|
|
64
|
+
* Han and kana share a group so Japanese labels stay intact; Hangul, Latin, Cyrillic, Greek, Arabic, Hebrew, Devanagari and Thai remain separate.
|
|
65
|
+
* Punctuation, digits, inherited marks and unsupported scripts stay in the surrounding run.
|
|
66
|
+
*
|
|
67
|
+
* @param start A UTF-16 offset at a code-point boundary, usually the end returned by the previous call.
|
|
68
|
+
*
|
|
69
|
+
* @returns The exclusive UTF-16 end of the run, or text.length when no later boundary exists.
|
|
70
|
+
*/
|
|
71
|
+
var findScriptRunEnd = (text, start = 0) => {
|
|
72
|
+
let script = 0;
|
|
73
|
+
let index = start;
|
|
74
|
+
while (index < text.length) {
|
|
75
|
+
const unit = text.charCodeAt(index);
|
|
76
|
+
let nextScript = 0;
|
|
77
|
+
let width = 1;
|
|
78
|
+
if (unit <= 127) {
|
|
79
|
+
const letter = unit | 32;
|
|
80
|
+
if (letter >= 97 && letter <= 122) {
|
|
81
|
+
if (script !== 0 && script !== 2) return index;
|
|
82
|
+
script = 2;
|
|
83
|
+
do {
|
|
84
|
+
index += 1;
|
|
85
|
+
const nextLetter = text.charCodeAt(index) | 32;
|
|
86
|
+
if (nextLetter < 97 || nextLetter > 122) break;
|
|
87
|
+
} while (index < text.length);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
} else if (unit >= 19968 && unit <= 40959) nextScript = 1;
|
|
91
|
+
else if (unit >= 12353 && unit <= 12438 || unit >= 12449 && unit <= 12538) nextScript = 1;
|
|
92
|
+
else if (unit >= 44032 && unit <= 55203) nextScript = 3;
|
|
93
|
+
else {
|
|
94
|
+
width = unit >= 55296 && unit <= 56319 && text.codePointAt(index) > 65535 ? 2 : 1;
|
|
95
|
+
nextScript = getOtherScript(text, index, width);
|
|
96
|
+
}
|
|
97
|
+
if (nextScript !== 0) {
|
|
98
|
+
if (script !== 0 && script !== nextScript) return index;
|
|
99
|
+
script = nextScript;
|
|
100
|
+
}
|
|
101
|
+
index += width;
|
|
102
|
+
}
|
|
103
|
+
return text.length;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Returns a language tag in the canonical form the model stores, which is lower case.
|
|
107
|
+
*
|
|
108
|
+
* This mirrors the model's own helper, which it does not export.
|
|
109
|
+
* Comparing tags stays with the consumer, since BCP 47 matches by subtag prefix rather than by string equality.
|
|
110
|
+
*/
|
|
111
|
+
var lowerTag = (tag) => {
|
|
112
|
+
return tag ? tag.toLowerCase() : void 0;
|
|
113
|
+
};
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/utils/rules.ts
|
|
116
|
+
var RULE_WHITESPACE = /[\u0009-\u000D\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/g;
|
|
117
|
+
var RULE_EDGE_WHITESPACE = /^[\u0009-\u000D\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+|[\u0009-\u000D\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+$/g;
|
|
118
|
+
/**
|
|
119
|
+
* Uses the shared whitespace set and ASCII case folding to keep matching consistent across language kits.
|
|
120
|
+
*/
|
|
121
|
+
var toRuleMatchKey = (text) => {
|
|
122
|
+
return text.replace(RULE_WHITESPACE, "").replace(/[A-Z]+/g, (run) => run.toLowerCase());
|
|
123
|
+
};
|
|
124
|
+
var RULE_WHITESPACE_CHARACTER = new RegExp(RULE_WHITESPACE.source);
|
|
125
|
+
/**
|
|
126
|
+
* Finds the offsets in toRuleMatchKey(text) where the source allows a cut.
|
|
127
|
+
* A cut sits before the first kept character of a script run and after configured whitespace, so neutral punctuation never splits aliases such as A&R or Co-Producer.
|
|
128
|
+
*
|
|
129
|
+
* @param text A source label with its original spelling.
|
|
130
|
+
*
|
|
131
|
+
* @returns Ascending offsets from 0 to the key length, or undefined when the source has no inner cut.
|
|
132
|
+
*/
|
|
133
|
+
var findRuleMatchCuts = (text) => {
|
|
134
|
+
if (!RULE_WHITESPACE_CHARACTER.test(text) && findScriptRunEnd(text) === text.length) return;
|
|
135
|
+
const cuts = [0];
|
|
136
|
+
let length = 0;
|
|
137
|
+
let pendingCut = false;
|
|
138
|
+
let runStart = 0;
|
|
139
|
+
while (runStart < text.length) {
|
|
140
|
+
const runEnd = findScriptRunEnd(text, runStart);
|
|
141
|
+
if (runStart > 0) pendingCut = true;
|
|
142
|
+
for (const character of text.slice(runStart, runEnd)) {
|
|
143
|
+
if (RULE_WHITESPACE_CHARACTER.test(character)) {
|
|
144
|
+
pendingCut = true;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (pendingCut) {
|
|
148
|
+
if (length > 0) cuts.push(length);
|
|
149
|
+
pendingCut = false;
|
|
150
|
+
}
|
|
151
|
+
length += character.length;
|
|
152
|
+
}
|
|
153
|
+
runStart = runEnd;
|
|
154
|
+
}
|
|
155
|
+
if (cuts.length === 1) return;
|
|
156
|
+
cuts.push(length);
|
|
157
|
+
return cuts;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Preserves internal whitespace so source labels and credited names retain their spelling.
|
|
161
|
+
*/
|
|
162
|
+
var trimRuleWhitespace = (text) => text.replace(RULE_EDGE_WHITESPACE, "");
|
|
163
|
+
//#endregion
|
|
164
|
+
export { lowerBound as a, lowerTag as i, toRuleMatchKey as n, mapShared as o, trimRuleWhitespace as r, findRuleMatchCuts as t };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","names":[],"sources":["../src/utils/array.ts","../src/utils/language.ts","../src/utils/rules.ts"],"sourcesContent":["/**\n * Preserves the input array when every element keeps its identity, so unchanged parent nodes can also be reused.\n *\n * The callback must leave inputs untouched and return the original element when unchanged.\n */\nexport const mapShared = <T>(items: T[], transform: (item: T) => T): T[] => {\n let result = items\n for (const [index, item] of items.entries()) {\n const transformed = transform(item)\n if (transformed !== item) {\n if (result === items) {\n result = [...items]\n }\n result[index] = transformed\n }\n }\n return result\n}\n\n/**\n * Finds the first value meeting a lower bound so range queries can skip earlier candidates.\n *\n * @param values Values sorted in ascending order.\n * @param target Inclusive lower bound.\n *\n * @returns The first matching index, or the array length when every value is smaller.\n */\nexport const lowerBound = (values: readonly number[], target: number): number => {\n let left = 0\n let right = values.length\n while (left < right) {\n const middle = Math.floor((left + right) / 2)\n if (values[middle]! < target) {\n left = middle + 1\n } else {\n right = middle\n }\n }\n return left\n}\n","const enum ScriptGroup {\n NEUTRAL,\n EAST_ASIAN,\n LATIN,\n HANGUL,\n CYRILLIC,\n GREEK,\n ARABIC,\n HEBREW,\n DEVANAGARI,\n THAI,\n}\n\nconst SCRIPT_PATTERNS: readonly (readonly [RegExp, ScriptGroup])[] = [\n [/[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}]/u, ScriptGroup.EAST_ASIAN],\n [/\\p{Script=Latin}/u, ScriptGroup.LATIN],\n [/\\p{Script=Hangul}/u, ScriptGroup.HANGUL],\n [/\\p{Script=Cyrillic}/u, ScriptGroup.CYRILLIC],\n [/\\p{Script=Greek}/u, ScriptGroup.GREEK],\n [/\\p{Script=Arabic}/u, ScriptGroup.ARABIC],\n [/\\p{Script=Hebrew}/u, ScriptGroup.HEBREW],\n [/\\p{Script=Devanagari}/u, ScriptGroup.DEVANAGARI],\n [/\\p{Script=Thai}/u, ScriptGroup.THAI],\n]\n\nconst getOtherScript = (text: string, start: number, width: number): ScriptGroup => {\n const unit = text.charCodeAt(start)\n if (unit === 0x30fb || unit === 0x30fc) {\n return ScriptGroup.NEUTRAL\n }\n if ((unit >= 0x0400 && unit <= 0x0481) || (unit >= 0x048a && unit <= 0x052f)) {\n return ScriptGroup.CYRILLIC\n }\n if (unit >= 0x03a3 && unit <= 0x03e1) {\n return ScriptGroup.GREEK\n }\n if ((unit >= 0x0620 && unit <= 0x063f) || (unit >= 0x0641 && unit <= 0x064a)) {\n return ScriptGroup.ARABIC\n }\n if (unit >= 0x05d0 && unit <= 0x05ea) {\n return ScriptGroup.HEBREW\n }\n if ((unit >= 0x0900 && unit <= 0x0950) || (unit >= 0x0955 && unit <= 0x0963) || (unit >= 0x0966 && unit <= 0x097f)) {\n return ScriptGroup.DEVANAGARI\n }\n if ((unit >= 0x0e01 && unit <= 0x0e3a) || (unit >= 0x0e40 && unit <= 0x0e5b)) {\n return ScriptGroup.THAI\n }\n\n const character = text.slice(start, start + width)\n for (const [pattern, script] of SCRIPT_PATTERNS) {\n if (pattern.test(character)) {\n return script\n }\n }\n return ScriptGroup.NEUTRAL\n}\n\n/**\n * Finds a boundary between supported scripts without allocating a segment list.\n * Han and kana share a group so Japanese labels stay intact; Hangul, Latin, Cyrillic, Greek, Arabic, Hebrew, Devanagari and Thai remain separate.\n * Punctuation, digits, inherited marks and unsupported scripts stay in the surrounding run.\n *\n * @param start A UTF-16 offset at a code-point boundary, usually the end returned by the previous call.\n *\n * @returns The exclusive UTF-16 end of the run, or text.length when no later boundary exists.\n */\nexport const findScriptRunEnd = (text: string, start = 0): number => {\n let script = ScriptGroup.NEUTRAL\n let index = start\n\n while (index < text.length) {\n const unit = text.charCodeAt(index)\n let nextScript = ScriptGroup.NEUTRAL\n let width = 1\n\n if (unit <= 0x7f) {\n const letter = unit | 0x20\n if (letter >= 0x61 && letter <= 0x7a) {\n if (script !== ScriptGroup.NEUTRAL && script !== ScriptGroup.LATIN) {\n return index\n }\n script = ScriptGroup.LATIN\n do {\n index += 1\n const nextLetter = text.charCodeAt(index) | 0x20\n if (nextLetter < 0x61 || nextLetter > 0x7a) {\n break\n }\n } while (index < text.length)\n continue\n }\n } else if (unit >= 0x4e00 && unit <= 0x9fff) {\n nextScript = ScriptGroup.EAST_ASIAN\n } else if ((unit >= 0x3041 && unit <= 0x3096) || (unit >= 0x30a1 && unit <= 0x30fa)) {\n nextScript = ScriptGroup.EAST_ASIAN\n } else if (unit >= 0xac00 && unit <= 0xd7a3) {\n nextScript = ScriptGroup.HANGUL\n } else {\n width = unit >= 0xd800 && unit <= 0xdbff && text.codePointAt(index)! > 0xffff ? 2 : 1\n nextScript = getOtherScript(text, index, width)\n }\n\n if (nextScript !== ScriptGroup.NEUTRAL) {\n if (script !== ScriptGroup.NEUTRAL && script !== nextScript) {\n return index\n }\n script = nextScript\n }\n index += width\n }\n return text.length\n}\n\n/**\n * Returns a language tag in the canonical form the model stores, which is lower case.\n *\n * This mirrors the model's own helper, which it does not export.\n * Comparing tags stays with the consumer, since BCP 47 matches by subtag prefix rather than by string equality.\n */\nexport const lowerTag = (tag: string | undefined): string | undefined => {\n return tag ? tag.toLowerCase() : undefined\n}\n","import { findScriptRunEnd } from './language'\n\nconst RULE_WHITESPACE = /[\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF]/g\nconst RULE_EDGE_WHITESPACE =\n /^[\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF]+|[\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF]+$/g\n\n/**\n * Uses the shared whitespace set and ASCII case folding to keep matching consistent across language kits.\n */\nexport const toRuleMatchKey = (text: string): string => {\n return text.replace(RULE_WHITESPACE, '').replace(/[A-Z]+/g, (run) => run.toLowerCase())\n}\n\nconst RULE_WHITESPACE_CHARACTER = new RegExp(RULE_WHITESPACE.source)\n\n/**\n * Finds the offsets in toRuleMatchKey(text) where the source allows a cut.\n * A cut sits before the first kept character of a script run and after configured whitespace, so neutral punctuation never splits aliases such as A&R or Co-Producer.\n *\n * @param text A source label with its original spelling.\n *\n * @returns Ascending offsets from 0 to the key length, or undefined when the source has no inner cut.\n */\nexport const findRuleMatchCuts = (text: string): readonly number[] | undefined => {\n // Most labels are a single script run without inner whitespace, so they skip the character walk.\n if (!RULE_WHITESPACE_CHARACTER.test(text) && findScriptRunEnd(text) === text.length) {\n return undefined\n }\n\n const cuts: number[] = [0]\n let length = 0\n let pendingCut = false\n let runStart = 0\n while (runStart < text.length) {\n const runEnd = findScriptRunEnd(text, runStart)\n if (runStart > 0) {\n pendingCut = true\n }\n for (const character of text.slice(runStart, runEnd)) {\n if (RULE_WHITESPACE_CHARACTER.test(character)) {\n pendingCut = true\n continue\n }\n if (pendingCut) {\n if (length > 0) {\n cuts.push(length)\n }\n pendingCut = false\n }\n length += character.length\n }\n runStart = runEnd\n }\n if (cuts.length === 1) {\n return undefined\n }\n cuts.push(length)\n return cuts\n}\n\n/**\n * Preserves internal whitespace so source labels and credited names retain their spelling.\n */\nexport const trimRuleWhitespace = (text: string): string => text.replace(RULE_EDGE_WHITESPACE, '')\n"],"mappings":"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"}
|
package/dist/transforms.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { runtime } from '@gondola-lyrics/model';
|
|
2
2
|
|
|
3
|
+
export declare const DEFAULT_CREDIT_NAME_SEPARATORS: readonly ["+", ":", "/"];
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Derives emphasis for normal words in lead and background vocals using complete, valid word ranges.
|
|
5
7
|
* The stored word duration must strictly exceed durationThreshold; metadata offset and duration have no effect.
|
|
@@ -21,6 +23,32 @@ export declare interface DeriveWordEmphasisOptions {
|
|
|
21
23
|
durationThreshold?: number;
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Extracts colon-prefixed performers and carries them across nonempty normal lines, replacing their existing agent lists.
|
|
28
|
+
* Missing bindings enables legacy name inference; supplied bindings accept exact prefixes and reset propagation on unmatched prefixes.
|
|
29
|
+
* Removing prefixes preserves retained line and word times, but drops prefix-only lines with their attached content.
|
|
30
|
+
*
|
|
31
|
+
* @returns The input when unchanged, or a new lyric sharing all unchanged nodes.
|
|
32
|
+
*
|
|
33
|
+
* @throws {TypeError} If bindings reference an agent id absent from lyric.agents.
|
|
34
|
+
*/
|
|
35
|
+
export declare const extractAgents: (lyric: runtime.Lyric, options?: ExtractAgentsOptions) => runtime.Lyric;
|
|
36
|
+
|
|
37
|
+
export declare interface ExtractAgentsOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Maps complete, trimmed prefixes to existing agent ids, preserving array order for joint performers.
|
|
40
|
+
* Matching is case-sensitive and preserves internal whitespace; an empty object disables automatic inference.
|
|
41
|
+
* Omitting this option enables legacy name inference; explicit bindings override its clock exclusion.
|
|
42
|
+
*/
|
|
43
|
+
bindings?: Readonly<Record<string, string | readonly string[]>>;
|
|
44
|
+
/**
|
|
45
|
+
* Removes matched prefixes and drops lines left with no sung text, including their attached content.
|
|
46
|
+
*
|
|
47
|
+
* @default true
|
|
48
|
+
*/
|
|
49
|
+
removePrefixes?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
24
52
|
/**
|
|
25
53
|
* Pulls bracketed background vocals out of the sung lines and attaches them to the line they accompany.
|
|
26
54
|
*
|
|
@@ -53,6 +81,41 @@ export declare interface ExtractBackgroundLinesOptions {
|
|
|
53
81
|
crossLine?: boolean;
|
|
54
82
|
}
|
|
55
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Preserves source labels and name spelling while matching normalized credit labels in normal lead lines.
|
|
86
|
+
* Merges names by role and original label without inferring their language.
|
|
87
|
+
* Unknown metadata is processed only when matchUnknowns is enabled; consumed entries leave the unknown list.
|
|
88
|
+
*
|
|
89
|
+
* @returns The input when unchanged, or a new lyric sharing all unchanged nodes.
|
|
90
|
+
*/
|
|
91
|
+
export declare const extractCredits: (lyric: runtime.Lyric, options?: ExtractCreditsOptions) => runtime.Lyric;
|
|
92
|
+
|
|
93
|
+
export declare interface ExtractCreditsOptions {
|
|
94
|
+
/**
|
|
95
|
+
* Matches existing unknown metadata keys as credit labels and consumes fully readable matches.
|
|
96
|
+
* Values use nameSeparators; unrecognized keys and values with no readable names remain unchanged.
|
|
97
|
+
*
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
matchUnknowns?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Removes successfully extracted source lines together with their backgrounds and annotations.
|
|
103
|
+
* Extracted roles and names remain in metadata; attached content is not moved to other lines.
|
|
104
|
+
*
|
|
105
|
+
* Refreshes language usages and falls back to line timing when no word-level content remains.
|
|
106
|
+
*
|
|
107
|
+
* @default false
|
|
108
|
+
*/
|
|
109
|
+
removeSourceLines?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Splits names at literal separators and ignores empty strings; an empty list preserves the complete source name.
|
|
112
|
+
* Longer separators take precedence so overlapping delimiters remain predictable.
|
|
113
|
+
*
|
|
114
|
+
* @default DEFAULT_CREDIT_NAME_SEPARATORS
|
|
115
|
+
*/
|
|
116
|
+
nameSeparators?: readonly string[];
|
|
117
|
+
}
|
|
118
|
+
|
|
56
119
|
export declare const INSERT_SPACES_RULES: InsertSpacesRule[];
|
|
57
120
|
|
|
58
121
|
/**
|
|
@@ -157,6 +220,38 @@ export declare const InsertSpacesRules: {
|
|
|
157
220
|
readonly TRIM_INSIDE_SYMBOLS: "trimInsideSymbols";
|
|
158
221
|
};
|
|
159
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Categories the bundled filter rules identify, in rule order.
|
|
225
|
+
*/
|
|
226
|
+
export declare const NON_LYRIC_CATEGORIES: readonly string[];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Removes normal lead lines matched by the shared notice rules and, when musicInfo is provided, first-line song information.
|
|
230
|
+
* The first non-empty normal line must have one literal " - " separator and a known title and artist on opposite sides; either order and extra text such as bracketed aliases are accepted.
|
|
231
|
+
* Drops attached annotations and backgrounds, refreshes language usages, and falls back to line timing when no word-level content remains.
|
|
232
|
+
*
|
|
233
|
+
* @returns The input when unchanged, or a new lyric sharing all unchanged nodes.
|
|
234
|
+
*/
|
|
235
|
+
export declare const removeNonLyricLines: (lyric: runtime.Lyric, options?: RemoveNonLyricLinesOptions) => runtime.Lyric;
|
|
236
|
+
|
|
237
|
+
export declare interface RemoveNonLyricLinesOptions {
|
|
238
|
+
/**
|
|
239
|
+
* Removes lines identified under these categories; an empty list skips the shared rules.
|
|
240
|
+
* First-line music information is selected independently.
|
|
241
|
+
*
|
|
242
|
+
* @default NON_LYRIC_CATEGORIES
|
|
243
|
+
*/
|
|
244
|
+
categories?: readonly string[];
|
|
245
|
+
/**
|
|
246
|
+
* Enables first-line music-information matching using these known titles and artists.
|
|
247
|
+
* Omitting this option, or leaving either list empty, skips the check; lyric metadata is not inferred.
|
|
248
|
+
*/
|
|
249
|
+
musicInfo?: {
|
|
250
|
+
titles?: readonly string[];
|
|
251
|
+
artists?: readonly string[];
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
160
255
|
/**
|
|
161
256
|
* Removes the brackets some sources wrap around background vocals.
|
|
162
257
|
*
|