]> piware.de Git - chordpro-web.git/blob - chordpro-web.js
Initial implementation
[chordpro-web.git] / chordpro-web.js
1 import { html, render } from 'https://cdn.pika.dev/lit';
2
3 const re_directive = /^{(\w+):\s*([^}]+)}$/;
4
5 const el_song = document.getElementById('song');
6 const song = [];
7
8 const directive_handlers = {
9     title: value => {
10         document.getElementById('title').textContent = value;
11         document.title = `${value} - ChordPro Web`;
12     },
13     subtitle: value => document.getElementById('artist').textContent = value,
14     comment: value => song.push(html`<p class="comment">${value}</p>`),
15 };
16
17 function renderChordpro(text) {
18     let verseLines = null;
19     let verseHasChords = false;
20     song.length = 0;
21
22     for (let line of text.split('\n')) {
23         line = line.trim();
24         if (line.startsWith('#'))
25             continue;
26
27         let m;
28         if ((m = re_directive.exec(line)) !== null) {
29             const [_, directive, value] = m;
30             const handler = directive_handlers[directive];
31             if (handler)
32                 handler(value);
33             else
34                 console.warn('unknown directive:', line);
35         } else if (line === '') {
36             if (verseLines == null)
37                 continue;
38             song.push(html`<p class="verse${verseHasChords ? ' chords' : ''}">${verseLines}</p>`);
39             verseLines = null;
40             verseHasChords = false;
41         } else {
42             if (verseLines == null)
43                 verseLines = [];
44
45             // split line into parts on chords
46             const parts = [];
47             line.split(/(\[[^\]]+\])/).forEach(part => parts.push(
48                 part[0] == '[' ? html`<span class="chord">${part.slice(1, -1)}</span>` : part
49             ));
50             verseHasChords ||= parts.length > 1;
51             parts.push('\n')
52             verseLines.push(parts);
53         }
54     }
55
56     render(song, el_song);
57 }
58
59 document.getElementById('open').addEventListener('change', async ev => renderChordpro(await ev.target.files[0].text()));