handle alternative line ends

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
eternal-flame-AD 2024-07-27 16:53:05 -05:00
parent 3dd9829a43
commit 9e388b66ce
No known key found for this signature in database
2 changed files with 25 additions and 18 deletions

View File

@ -26,7 +26,7 @@ interface ParserScriptItem {
singer?: string; singer?: string;
} }
export interface ScriptItem extends ParserScriptItem{ export interface ScriptItem extends ParserScriptItem {
end: number; end: number;
chorus?: string; chorus?: string;
} }
@ -64,10 +64,10 @@ interface IDTag {
} }
function convertTimeToMs({ function convertTimeToMs({
mins, mins,
secs, secs,
decimals decimals
}: { }: {
mins?: number | string; mins?: number | string;
secs?: number | string; secs?: number | string;
decimals?: string; decimals?: string;
@ -180,11 +180,11 @@ function lrcLine(
['script_item', { start: r[0], text: joinTokens(r[1]) } as ParserScriptItem] // TODO: Complete this ['script_item', { start: r[0], text: joinTokens(r[1]) } as ParserScriptItem] // TODO: Complete this
) : apply( ) : apply(
seq( seq(
squareTS, squareTS,
opt_sc(padded(singerIndicator)), opt_sc(padded(singerIndicator)),
rep_sc( rep_sc(
seq( seq(
opt_sc(angleTS), opt_sc(angleTS),
trimmed(rep_sc(anythingTyped(['char', '[', ']']))) trimmed(rep_sc(anythingTyped(['char', '[', ']'])))
) )
), ),
@ -214,10 +214,10 @@ function lrcLine(
} }
return ret as ScriptWordsItem; // TODO: Complete this return ret as ScriptWordsItem; // TODO: Complete this
}); });
const singer = singerPart?.text; const singer = singerPart?.text;
const translation = translatePart === undefined ? undefined : joinTokens(translatePart); const translation = translatePart === undefined ? undefined : joinTokens(translatePart);
return ['script_item', { start, text, words, singer, translation } as ParserScriptItem]; return ['script_item', { start, text, words, singer, translation } as ParserScriptItem];
}), }),
apply(lrcTag, (r) => ['lrc_tag', r as IDTag]), apply(lrcTag, (r) => ['lrc_tag', r as IDTag]),
@ -247,7 +247,7 @@ export function parseLRC(
]); ]);
const lines = input const lines = input
.split('\n') .split(/\r\n|\r|\n/gu)
.filter((line) => line.trim().length > 0) .filter((line) => line.trim().length > 0)
.map((line) => tokenizer.parse(line)); .map((line) => tokenizer.parse(line));

View File

@ -9,15 +9,22 @@ describe('LRC parser test', () => {
const test02Text = test02Buffer.toString('utf-8'); const test02Text = test02Buffer.toString('utf-8');
const test03Buffer = fs.readFileSync('./src/test/resources/test-03.lrc'); const test03Buffer = fs.readFileSync('./src/test/resources/test-03.lrc');
const test03Text = test03Buffer.toString('utf-8'); const test03Text = test03Buffer.toString('utf-8');
it('Parses test-01.lrc', () => {
const result = parseLRC(test01Text, { wordDiv: '', strict: true });
expect(result.ar).toBe("洛天依"); const lf_alternatives = ['\n', '\r\n', '\r'];
expect(result.ti).toBe("中华少女·终");
expect(result.al).toBe("中华少女"); it('Parses test-01.lrc', () => {
expect(result["tool"]).toBe("歌词滚动姬 https://lrc-maker.github.io"); for (const lf of lf_alternatives) {
expect(result.scripts!![1].text).toBe("因果与恩怨牵杂等谁来诊断"); const text = test01Text.replaceAll('\n', lf);
expect(result.scripts!![1].start).toBe(49000 + 588);
const result = parseLRC(text, { wordDiv: '', strict: true });
expect(result.ar).toBe("洛天依");
expect(result.ti).toBe("中华少女·终");
expect(result.al).toBe("中华少女");
expect(result["tool"]).toBe("歌词滚动姬 https://lrc-maker.github.io");
expect(result.scripts!![1].text).toBe("因果与恩怨牵杂等谁来诊断");
expect(result.scripts!![1].start).toBe(49000 + 588);
}
}) })
it('Parses test-02.lrc', () => { it('Parses test-02.lrc', () => {
const result = parseLRC(test02Text, { wordDiv: ' ', strict: true }); const result = parseLRC(test02Text, { wordDiv: ' ', strict: true });