--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>ChordPro Web</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="chordpro.css">
+</head>
+
+<body>
+ <h1 id="title">No file loaded</h1>
+ <h2 id="artist"></h2>
+
+ <div id="song"></div>
+
+ <hr />
+
+ <input id="open" type="file" />
+
+ <script type="module" src="chordpro-web.js"></script>
+</body>
+</html>
--- /dev/null
+import { html, render } from 'https://cdn.pika.dev/lit';
+
+const re_directive = /^{(\w+):\s*([^}]+)}$/;
+
+const el_song = document.getElementById('song');
+const song = [];
+
+const directive_handlers = {
+ title: value => {
+ document.getElementById('title').textContent = value;
+ document.title = `${value} - ChordPro Web`;
+ },
+ subtitle: value => document.getElementById('artist').textContent = value,
+ comment: value => song.push(html`<p class="comment">${value}</p>`),
+};
+
+function renderChordpro(text) {
+ let verseLines = null;
+ let verseHasChords = false;
+ song.length = 0;
+
+ for (let line of text.split('\n')) {
+ line = line.trim();
+ if (line.startsWith('#'))
+ continue;
+
+ let m;
+ if ((m = re_directive.exec(line)) !== null) {
+ const [_, directive, value] = m;
+ const handler = directive_handlers[directive];
+ if (handler)
+ handler(value);
+ else
+ console.warn('unknown directive:', line);
+ } else if (line === '') {
+ if (verseLines == null)
+ continue;
+ song.push(html`<p class="verse${verseHasChords ? ' chords' : ''}">${verseLines}</p>`);
+ verseLines = null;
+ verseHasChords = false;
+ } else {
+ if (verseLines == null)
+ verseLines = [];
+
+ // split line into parts on chords
+ const parts = [];
+ line.split(/(\[[^\]]+\])/).forEach(part => parts.push(
+ part[0] == '[' ? html`<span class="chord">${part.slice(1, -1)}</span>` : part
+ ));
+ verseHasChords ||= parts.length > 1;
+ parts.push('\n')
+ verseLines.push(parts);
+ }
+ }
+
+ render(song, el_song);
+}
+
+document.getElementById('open').addEventListener('change', async ev => renderChordpro(await ev.target.files[0].text()));
+++ /dev/null
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <title>ChordPro Proof of Concept</title>
- <meta charset="utf-8">
- <link rel="stylesheet" href="chordpro.css">
-</head>
-
-<body>
- <h1>Nine Million Bicycles</h1>
- <h2>Katie Melua</h2>
-
- <p class="verse chords">There are <span class="chord">Am</span>nine million bicycles in Bei<span class="chord">Em</span>jing
- That's a <span class="chord">Dm</span>fact, It's a <span class="chord">F</span>thing we can't deny
- Like the <span class="chord">Dm</span>fact that I will <span class="chord">G</span>love you till I <span class="chord">C</span>die.</p>
-
- <p class="verse">We are twelve billion light years from the edge,
- That's a guess, No-one can ever say it's true
- But I know that I will always be with you.</p>
-
-</body>
-</html>