]> piware.de Git - chordpro-web.git/commitdiff
Flush open verse on directives and at end of file
authorMartin Pitt <martin@piware.de>
Wed, 23 Sep 2026 20:44:59 +0000 (22:44 +0200)
committerMartin Pitt <martin@piware.de>
Wed, 23 Sep 2026 20:45:31 +0000 (22:45 +0200)
Verses were only emitted on a blank line. A directive directly after a
lyrics line, such as {comment: Chorus}, thus appeared before that verse,
and a file without a trailing newline lost its last verse.

chordpro-web.js

index abbf4045fe1d4752dc09a19dbd69c30bf8f972d4..0d54e55c3f2b53edd2e661d72e7e46369a75c5f9 100644 (file)
@@ -19,10 +19,18 @@ const directive_handlers = {
 };
 
 function renderChordpro(text) {
-    let verseLines = null;
+    let verseLines = [];
     let verseHasChords = false;
     song.length = 0;
 
+    const flushVerse = () => {
+        if (verseLines.length === 0)
+            return;
+        song.push(html`<p class="verse${verseHasChords ? ' chords' : ''}">${verseLines}</p>`);
+        verseLines = [];
+        verseHasChords = false;
+    };
+
     for (let line of text.split('\n')) {
         line = line.trim();
         if (line.startsWith('#'))
@@ -30,6 +38,7 @@ function renderChordpro(text) {
 
         let m;
         if ((m = re_directive.exec(line)) !== null) {
+            flushVerse();
             const [_, directive, value] = m;
             const handler = directive_handlers[directive];
             if (handler)
@@ -37,15 +46,8 @@ function renderChordpro(text) {
             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;
+            flushVerse();
         } else {
-            if (verseLines == null)
-                verseLines = [];
-
             // split line into segments of one chord plus the lyrics up to the
             // next chord; the first element is the lyrics before the first chord
             const [lead, ...rest] = line.split(/\[([^\]]+)\]/);
@@ -65,6 +67,7 @@ function renderChordpro(text) {
             verseLines.push(segments);
         }
     }
+    flushVerse();
 
     render(song, el_song);
 }