Skip to content

Commit d37fc1c

Browse files
committed
feat(test): add parse page
1 parent 8a7c906 commit d37fc1c

4 files changed

Lines changed: 292 additions & 16 deletions

File tree

pnpm-lock.yaml

Lines changed: 5 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

private/test/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717
"type": "git",
1818
"url": "https://github.com/music-lyric/music-lyric-kit-node.git",
1919
"directory": "private/test"
20+
},
21+
"dependencies": {
22+
"music-lyric-kit": "workspace:*"
2023
}
2124
}

private/test/src/index.html

Lines changed: 178 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,184 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<title>Music Lyric Kit</title>
6+
<title>Music Lyric Parser</title>
7+
<style>
8+
:root {
9+
--primary-color: #007aff;
10+
--bg-color: #f5f5f7;
11+
--card-bg: #ffffff;
12+
--text-color: #333;
13+
--border-color: #e0e0e0;
14+
}
15+
16+
body {
17+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
18+
background-color: var(--bg-color);
19+
color: var(--text-color);
20+
margin: 0;
21+
padding: 20px;
22+
min-height: 100vh;
23+
display: flex;
24+
flex-direction: column;
25+
align-items: center;
26+
}
27+
28+
h1 {
29+
text-align: center;
30+
margin-bottom: 30px;
31+
font-weight: 600;
32+
}
33+
34+
.main-container {
35+
width: 100%;
36+
max-width: 1200px;
37+
display: flex;
38+
flex-direction: column;
39+
gap: 20px;
40+
}
41+
42+
.input-grid {
43+
display: grid;
44+
grid-template-columns: repeat(2, 1fr);
45+
gap: 20px;
46+
width: 100%;
47+
}
48+
49+
@media (max-width: 768px) {
50+
.input-grid {
51+
grid-template-columns: 1fr;
52+
}
53+
}
54+
55+
.input-group {
56+
display: flex;
57+
flex-direction: column;
58+
background: var(--card-bg);
59+
padding: 15px;
60+
border-radius: 12px;
61+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
62+
}
63+
64+
.input-group label {
65+
font-weight: 600;
66+
margin-bottom: 10px;
67+
color: #666;
68+
font-size: 0.9em;
69+
text-transform: uppercase;
70+
letter-spacing: 0.5px;
71+
}
72+
73+
textarea {
74+
width: 100%;
75+
height: 200px;
76+
padding: 12px;
77+
border: 1px solid var(--border-color);
78+
border-radius: 8px;
79+
resize: vertical;
80+
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
81+
font-size: 13px;
82+
line-height: 1.4;
83+
box-sizing: border-box;
84+
outline: none;
85+
transition: border-color 0.2s;
86+
}
87+
88+
textarea:focus {
89+
border-color: var(--primary-color);
90+
}
91+
92+
.action-area {
93+
display: flex;
94+
justify-content: center;
95+
margin: 10px 0;
96+
}
97+
98+
button {
99+
background-color: var(--primary-color);
100+
color: white;
101+
border: none;
102+
padding: 12px 40px;
103+
font-size: 16px;
104+
font-weight: 600;
105+
border-radius: 25px;
106+
cursor: pointer;
107+
transition:
108+
transform 0.1s,
109+
box-shadow 0.2s;
110+
box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3);
111+
}
112+
113+
button:hover {
114+
transform: translateY(-1px);
115+
box-shadow: 0 6px 16px rgba(0, 122, 255, 0.4);
116+
}
117+
118+
button:active {
119+
transform: translateY(1px);
120+
}
121+
122+
.result-container {
123+
background: var(--card-bg);
124+
padding: 20px;
125+
border-radius: 12px;
126+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
127+
width: 100%;
128+
box-sizing: border-box;
129+
display: flex;
130+
flex-direction: column;
131+
}
132+
133+
.result-container h2 {
134+
margin-top: 0;
135+
font-size: 1.2em;
136+
color: #666;
137+
}
138+
139+
pre {
140+
background: #1e1e1e;
141+
color: #d4d4d4;
142+
padding: 20px;
143+
border-radius: 8px;
144+
overflow-x: auto;
145+
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
146+
font-size: 13px;
147+
white-space: pre-wrap;
148+
word-wrap: break-word;
149+
}
150+
</style>
7151
<script type="module" src="./index.ts"></script>
8152
</head>
9-
<body></body>
153+
<body>
154+
<div class="main-container">
155+
<h1>Music Lyric Parser</h1>
156+
157+
<div class="input-grid">
158+
<div class="input-group">
159+
<label for="input-original">Original Lyrics</label>
160+
<textarea id="input-original" placeholder="Paste original lyrics here..."></textarea>
161+
</div>
162+
<div class="input-group">
163+
<label for="input-syllable">Syllable Lyrics</label>
164+
<textarea id="input-syllable" placeholder="Paste syllable lyrics here..."></textarea>
165+
</div>
166+
<div class="input-group">
167+
<label for="input-translate">Translation</label>
168+
<textarea id="input-translate" placeholder="Paste translation here..."></textarea>
169+
</div>
170+
<div class="input-group">
171+
<label for="input-roman">Romanization</label>
172+
<textarea id="input-roman" placeholder="Paste romanization here..."></textarea>
173+
</div>
174+
</div>
175+
176+
<div class="action-area">
177+
<button id="btn-parse">Parse Lyrics</button>
178+
</div>
179+
180+
<div class="result-container">
181+
<h2>Parse Result</h2>
182+
<pre id="output-result">// Result will appear here...</pre>
183+
</div>
184+
</div>
185+
</body>
10186
</html>

private/test/src/index.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { Parser, Lrc } from 'music-lyric-kit'
2+
3+
const DEFAULT_ORIGINAL = `
4+
[ti: title]
5+
[ar: singer]
6+
[al: album]
7+
[length: 11:45]
8+
[00:00.114]This is Original
9+
`
10+
11+
const DEFAULT_SYLLABLE = `
12+
[ti: title]
13+
[ar: singer]
14+
[al: album]
15+
[length: 11:45]
16+
[00:00.114]<0,114>This <114,514>is <514,999>Syllable
17+
`
18+
19+
const DEFAULT_TRANSLATE = `
20+
[00:00.114]This is Translate
21+
`
22+
23+
const DEFAULT_ROMAN = `
24+
[00:00.114]This is Roman
25+
`
26+
27+
const STORAGE_KEYS = {
28+
ORIGINAL: 'lyric_parser_original',
29+
SYLLABLE: 'lyric_parser_syllable',
30+
TRANSLATE: 'lyric_parser_translate',
31+
ROMAN: 'lyric_parser_roman',
32+
}
33+
34+
const main = () => {
35+
const parser = new Parser.Client()
36+
const lrc = Lrc.Parser.Plugin()
37+
parser.plugin.add(lrc)
38+
39+
const inputOriginal = document.getElementById('input-original') as HTMLTextAreaElement
40+
const inputSyllable = document.getElementById('input-syllable') as HTMLTextAreaElement
41+
const inputTranslate = document.getElementById('input-translate') as HTMLTextAreaElement
42+
const inputRoman = document.getElementById('input-roman') as HTMLTextAreaElement
43+
const btnParse = document.getElementById('btn-parse') as HTMLButtonElement
44+
const outputResult = document.getElementById('output-result') as HTMLPreElement
45+
46+
const handleParse = () => {
47+
const original = inputOriginal.value
48+
const syllable = inputSyllable.value
49+
const translate = inputTranslate.value
50+
const roman = inputRoman.value
51+
52+
localStorage.setItem(STORAGE_KEYS.ORIGINAL, original)
53+
localStorage.setItem(STORAGE_KEYS.SYLLABLE, syllable)
54+
localStorage.setItem(STORAGE_KEYS.TRANSLATE, translate)
55+
localStorage.setItem(STORAGE_KEYS.ROMAN, roman)
56+
57+
outputResult.textContent = 'Parsing...'
58+
59+
try {
60+
const format = parser.infer({
61+
content: original,
62+
})
63+
64+
if (format) {
65+
console.log(`Inferred format: ${format}`)
66+
const start = performance.now()
67+
const result = parser.parse(format, {
68+
content: {
69+
original,
70+
syllable,
71+
translate,
72+
roman,
73+
},
74+
})
75+
const end = performance.now()
76+
77+
if (result) {
78+
const content = JSON.stringify(result, null, 2)
79+
console.log(`Parser result: `, JSON.parse(content))
80+
outputResult.textContent = content
81+
} else {
82+
console.log('Parser result is null')
83+
outputResult.textContent = 'Parser returned null result.'
84+
}
85+
86+
console.log(`Parser use time: ${end - start}ms`)
87+
} else {
88+
outputResult.textContent = 'Could not infer lyric format from "Original Lyrics".'
89+
}
90+
} catch (error: any) {
91+
console.error(error)
92+
outputResult.textContent = `Error during parsing:\n${error.message || error}`
93+
}
94+
}
95+
96+
inputOriginal.value = localStorage.getItem(STORAGE_KEYS.ORIGINAL) ?? DEFAULT_ORIGINAL
97+
inputSyllable.value = localStorage.getItem(STORAGE_KEYS.SYLLABLE) ?? DEFAULT_SYLLABLE
98+
inputTranslate.value = localStorage.getItem(STORAGE_KEYS.TRANSLATE) ?? DEFAULT_TRANSLATE
99+
inputRoman.value = localStorage.getItem(STORAGE_KEYS.ROMAN) ?? DEFAULT_ROMAN
100+
101+
btnParse.addEventListener('click', handleParse)
102+
103+
handleParse()
104+
}
105+
106+
document.addEventListener('DOMContentLoaded', main)

0 commit comments

Comments
 (0)