forked from magic-akari/lrc-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlrc-parser.js
106 lines (106 loc) · 3.25 KB
/
lrc-parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
export const parser = (lrcString, option = {}) => {
const { trimStart = false, trimEnd = false } = option;
const lines = lrcString.split(/\r\n|\n|\r/u);
const timeTag = /\[\s*(\d{1,3}):(\d{1,2}(?:[:.]\d{1,3})?)\s*]/g;
const infoTag = /\[\s*(\w{1,6})\s*:(.*?)]/;
const info = new Map();
const lyric = [];
for (const line of lines) {
if (line[0] !== "[") {
lyric.push({
text: line,
});
continue;
}
timeTag.lastIndex = 0;
const rTimeTag = timeTag.exec(line);
if (rTimeTag !== null) {
const mm = Number.parseInt(rTimeTag[1], 10);
const ss = Number.parseFloat(rTimeTag[2].replace(":", "."));
const text = line.slice(timeTag.lastIndex);
lyric.push({
time: mm * 60 + ss,
text,
});
continue;
}
const rInfoTag = infoTag.exec(line);
if (rInfoTag !== null) {
const value = rInfoTag[2].trim();
if (value === "") {
continue;
}
info.set(rInfoTag[1], value);
continue;
}
lyric.push({
text: line,
});
}
if (trimStart && trimEnd) {
lyric.forEach((line) => {
line.text = line.text.trim();
});
}
else if (trimStart) {
lyric.forEach((line) => {
line.text = line.text.trimStart();
});
}
else if (trimEnd) {
lyric.forEach((line) => {
line.text = line.text.trimEnd();
});
}
return { info, lyric };
};
const storedFormatter = new Map();
const getFormatter = (fixed) => {
if (storedFormatter.has(fixed)) {
return storedFormatter.get(fixed);
}
const newFormatter = new Intl.NumberFormat("en", {
minimumIntegerDigits: 2,
minimumFractionDigits: fixed,
maximumFractionDigits: fixed,
useGrouping: false,
});
storedFormatter.set(fixed, newFormatter);
return newFormatter;
};
export const convertTimeToTag = (time, fixed, withBrackets = true) => {
if (time === undefined) {
return "";
}
const formatter = getFormatter(fixed);
const mm = Math.floor(time / 60)
.toString()
.padStart(2, "0");
const ss = formatter.format(time % 60);
return withBrackets ? `[${mm}:${ss}]` : `${mm}:${ss}`;
};
export const formatText = (text, spaceStart, spaceEnd) => {
let newText = text;
if (spaceStart >= 0) {
newText = " ".repeat(spaceStart) + newText.trimStart();
}
if (spaceEnd >= 0) {
newText = newText.trimEnd() + " ".repeat(spaceEnd);
}
return newText;
};
export const stringify = (state, option) => {
const { spaceStart, spaceEnd, fixed, endOfLine = "\r\n" } = option;
const infos = Array.from(state.info.entries()).map(([name, value]) => {
return `[${name}: ${value}]`;
});
const lines = state.lyric.map((line) => {
if (line.time === undefined) {
return line.text;
}
const text = formatText(line.text, spaceStart, spaceEnd);
return `${convertTimeToTag(line.time, fixed)}${text}`;
});
return infos.concat(lines).join(endOfLine);
};
//# sourceMappingURL=lrc-parser.js.map