add legacy lrc parse mode

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
eternal-flame-AD 2024-07-26 00:05:50 -05:00
parent bf7f2f508b
commit 9074f800d6
No known key found for this signature in database
2 changed files with 17 additions and 4 deletions

View File

@ -146,10 +146,12 @@ function tokenParserToText<K, T>(p: Parser<K, Token<T>> | Parser<K, Token<T>[]>)
}
function lrcLine(
wordDiv = ''
wordDiv = ' ', legacy = false
): Parser<unknown, ['script_item', ScriptItem] | ['lrc_tag', IDTag] | ['comment', string] | ['empty', null]> {
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 text = r[1]
@ -188,7 +190,7 @@ export function dumpToken<T>(t: Token<T> | undefined): string {
export function parseLRC(
input: string,
{ wordDiv, strict }: { wordDiv?: string; strict?: boolean } = { wordDiv: ' ' }
{ wordDiv, strict, legacy }: { wordDiv?: string; strict?: boolean; legacy?: boolean } = {}
): LrcJsonData {
const tokenizer = buildLexer([
[true, /^\[/gu, '['],
@ -205,7 +207,7 @@ export function parseLRC(
return lines
.map((line) => {
const res = expectEOF(lrcLine(wordDiv).parse(line));
const res = expectEOF(lrcLine(wordDiv, legacy).parse(line));
if (!res.successful) {
if (strict) {
throw new Error('Failed to parse full line: ' + dumpToken(line));

View File

@ -22,6 +22,7 @@ describe('LRC parser test', () => {
expect(result.ti).toBe("Somebody to Love");
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].start).toBe(0);
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();
}
})
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());
});
});