add legacy lrc parse mode
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
parent
bf7f2f508b
commit
9074f800d6
@ -146,10 +146,12 @@ function tokenParserToText<K, T>(p: Parser<K, Token<T>> | Parser<K, Token<T>[]>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function lrcLine(
|
function lrcLine(
|
||||||
wordDiv = ''
|
wordDiv = ' ', legacy = false
|
||||||
): Parser<unknown, ['script_item', ScriptItem] | ['lrc_tag', IDTag] | ['comment', string] | ['empty', null]> {
|
): Parser<unknown, ['script_item', ScriptItem] | ['lrc_tag', IDTag] | ['comment', string] | ['empty', null]> {
|
||||||
return alt_sc(
|
return alt_sc(
|
||||||
apply(seq(squareTS, rep_sc(seq(opt_sc(angleTS), trimmed(rep_sc(anythingTyped(['char', '[', ']'])))))), (r) => {
|
legacy ? apply(seq(squareTS, trimmed(rep_sc(anythingTyped(['char', '[', ']', '<', '>'])))), (r) =>
|
||||||
|
['script_item', { start: r[0], text: joinTokens(r[1]) } as any as ScriptItem] // TODO: Complete this
|
||||||
|
) : apply(seq(squareTS, rep_sc(seq(opt_sc(angleTS), trimmed(rep_sc(anythingTyped(['char', '[', ']'])))))), (r) => {
|
||||||
const start = r[0];
|
const start = r[0];
|
||||||
|
|
||||||
const text = r[1]
|
const text = r[1]
|
||||||
@ -188,7 +190,7 @@ export function dumpToken<T>(t: Token<T> | undefined): string {
|
|||||||
|
|
||||||
export function parseLRC(
|
export function parseLRC(
|
||||||
input: string,
|
input: string,
|
||||||
{ wordDiv, strict }: { wordDiv?: string; strict?: boolean } = { wordDiv: ' ' }
|
{ wordDiv, strict, legacy }: { wordDiv?: string; strict?: boolean; legacy?: boolean } = {}
|
||||||
): LrcJsonData {
|
): LrcJsonData {
|
||||||
const tokenizer = buildLexer([
|
const tokenizer = buildLexer([
|
||||||
[true, /^\[/gu, '['],
|
[true, /^\[/gu, '['],
|
||||||
@ -205,7 +207,7 @@ export function parseLRC(
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
.map((line) => {
|
.map((line) => {
|
||||||
const res = expectEOF(lrcLine(wordDiv).parse(line));
|
const res = expectEOF(lrcLine(wordDiv, legacy).parse(line));
|
||||||
if (!res.successful) {
|
if (!res.successful) {
|
||||||
if (strict) {
|
if (strict) {
|
||||||
throw new Error('Failed to parse full line: ' + dumpToken(line));
|
throw new Error('Failed to parse full line: ' + dumpToken(line));
|
||||||
|
@ -22,6 +22,7 @@ describe('LRC parser test', () => {
|
|||||||
|
|
||||||
expect(result.ti).toBe("Somebody to Love");
|
expect(result.ti).toBe("Somebody to Love");
|
||||||
expect(result.ar).toBe("Jefferson Airplane");
|
expect(result.ar).toBe("Jefferson Airplane");
|
||||||
|
expect(result.scripts!!.length).toBe(3);
|
||||||
expect(result.scripts!![0].text).toBe("When the truth is found to be lies");
|
expect(result.scripts!![0].text).toBe("When the truth is found to be lies");
|
||||||
expect(result.scripts!![0].start).toBe(0);
|
expect(result.scripts!![0].start).toBe(0);
|
||||||
expect(result.scripts!![0].words!![1].beginIndex).toBe("[00:00.00] <00:00.04> When <00:00.16> the".indexOf("the"));
|
expect(result.scripts!![0].words!![1].beginIndex).toBe("[00:00.00] <00:00.04> When <00:00.16> the".indexOf("the"));
|
||||||
@ -55,4 +56,14 @@ describe('LRC parser test', () => {
|
|||||||
expect(() => parseLRC(c, { strict: false })).not.toThrow();
|
expect(() => parseLRC(c, { strict: false })).not.toThrow();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
it('Parses a legacy LRC', () => {
|
||||||
|
const result = parseLRC(test02Text, { wordDiv: ' ', strict: true, legacy: true });
|
||||||
|
|
||||||
|
expect(result.ti).toBe("Somebody to Love");
|
||||||
|
expect(result.ar).toBe("Jefferson Airplane");
|
||||||
|
expect(result.scripts!!.length).toBe(3);
|
||||||
|
expect(result.scripts!![1].text).toBe("<00:07.67> And <00:07.94> all <00:08.36> the <00:08.63> joy <00:10.28> within <00:10.53> you <00:13.09> dies");
|
||||||
|
expect(result.scripts!![1].start).toBe(6000 + 470);
|
||||||
|
result.scripts!!.forEach((s) => expect(s.words).not.toBeDefined());
|
||||||
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user