native-lyrics-tools
Version:
A JavaScript library for parsing and generating various lyric formats.
106 lines (88 loc) • 2.76 kB
JavaScript
function parseTime(str) {
const match = str.match(/^\[(\d+),(\d+)\]/);
if (!match) throw new Error("Invalid time format");
const start = parseInt(match[1], 10);
const duration = parseInt(match[2], 10);
return { remaining: str.slice(match[0].length), result: [start, duration] };
}
function parseWordTime(str) {
const match = str.match(/^\((\d+),(\d+),0\)/);
if (!match) throw new Error("Invalid word time format");
const start = parseInt(match[1], 10);
const duration = parseInt(match[2], 10);
return { remaining: str.slice(match[0].length), result: [start, duration] };
}
function parseWords(str) {
const words = [];
while (str && str[0] === '(') {
const { remaining, result: [start, duration] } = parseWordTime(str);
str = remaining;
const wordMatch = str.match(/^[^(\r\n)]+/);
const word = wordMatch ? wordMatch[0] : '';
str = str.slice(word.length);
words.push({
start_time: start,
end_time: start + duration,
word
});
}
return { remaining: str, words };
}
function parseLine(line) {
let { remaining: rest, result: [start, duration] } = parseTime(line);
const lineContentMatch = rest.match(/^[^\r\n]*/);
const lineContent = lineContentMatch ? lineContentMatch[0] : '';
rest = rest.slice(lineContent.length);
const { words } = parseWords(lineContent || rest);
return {
remaining: rest,
line: {
words,
start_time: start,
duration: duration
}
};
}
function parseYRC(src) {
const result = [];
const lines = src.split(/\r?\n/);
for (const line of lines) {
try {
const { line: parsed } = parseLine(line);
if (parsed.words && parsed.words.length > 0) {
result.push(parsed);
}
} catch (e) {
continue;
}
}
// process_lyrics() stub (real implementation in utils, possibly adjusting times)
// result = processLyrics(result);
return result;
}
function stringifyYRC(lines) {
let result = '';
for (const line of lines) {
if (line.words.length === 0) continue;
const start_time = line.words[0].start_time;
const duration = line.words.reduce((acc, w) => acc + (w.end_time - w.start_time), 0);
result += `[${start_time},${duration}]`;
for (const word of line.words) {
const start = word.start_time;
const duration = word.end_time - word.start_time;
result += `(${start},${duration},0)`;
result += word.word.replace(/\(/g, '(').replace(/\)/g, ')');
}
result += '\n';
}
return result;
}
// Exporting for ES Module use
export {
parseTime,
parseWordTime,
parseWords,
parseLine,
parseYRC,
stringifyYRC
};