Major fixes for Song page
authorAndrew DeFaria <Andrew@DeFaria.com>
Mon, 13 Nov 2017 02:29:47 +0000 (18:29 -0800)
committerAndrew DeFaria <Andrew@DeFaria.com>
Mon, 13 Nov 2017 02:29:47 +0000 (18:29 -0800)
. Changed history link to point to github.
. On the song page, the heading is now fixed to the top part of the page.
  Included in the heading is the home button, the title of the song and
  artist (not linked to show all of the artist's songs) and the HTML5 Audio
  player.
. The bottom part contains the song itself as before. I may add an auto
  scroll option later. It'd be really cool if I could tag the various lines
  and chorus such that the playback syncs with the words but I'm not sure I
  can do that.
. I've added JavaScript to allow the space bar to play/pause playback.
. Added additional keyboard shortcuts for:
  . r - return to start (initially start is 0 but can be set by the "a"
        command)
  . b - rewind back 10 seconds. I choose 10 because that seemed to be a
        good amount to rew/ff. Hit b or f multiple times to go forward or
        backward by 10 secs increments.
  . f - Fast forward 10 seconds.
  . a - Mark start. Say you are listening and playing/singing along with a
        song and you want to practice that part just before the second
        chorus. Well mark that spot with the "a" key. Then play/sing along.
        Didn't get it right? Hit either "r" or the space bar to start at the
        marked position again.
  . c - Clear start. If you don't want that start position anymore clear it
        with "c". Then "r" or space bar will start from 0.
  . ? - Hit "?" to see the keyboard short cuts.

web/index.php
web/question.mark.css [new file with mode: 0644]
web/question.mark.html [new file with mode: 0644]
web/question.mark.js [new file with mode: 0644]
web/songbook.css [new file with mode: 0644]
web/songbook.js [new file with mode: 0644]
web/webchord.cgi

index 43742c7..bd5ede6 100644 (file)
@@ -21,7 +21,7 @@ include_once "songbook.php";
   <tbody>
     <tr>
       <td align="left"><a href="news.html"><img src="/Icons/news.png"></a></td>
-      <td align="right"><a href="/gitweb/?p=songbook.git"><img src="/Icons/history.png"></a></td>
+      <td align="right"><a href="https://github.com/adefaria/songbook"><img src="/Icons/history.png"></a></td>
     </tr>
   </tbody>
 </table>
diff --git a/web/question.mark.css b/web/question.mark.css
new file mode 100644 (file)
index 0000000..37b5663
--- /dev/null
@@ -0,0 +1,155 @@
+.help-underlay * {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+.help-underlay {
+  position: absolute;
+  background: #555;
+  background: rgba(0,0,0,0.5);
+  visibility: hidden;
+  opacity: 0;
+  -webkit-transition: opacity .2s linear;
+  -moz-transition: opacity .2s linear;
+  -o-transition: opacity .2s linear;
+  transition: opacity .2s linear;
+  left: 0; right: 0; top: 0; bottom: 0;
+}
+
+.ie8 .help-underlay {
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=95)"; /* for IE8 in IE7 mode */
+  filter: alpha(opacity=95); /* for IE8 */
+  visibility: hidden;
+}
+
+.help-modal {
+  position: fixed;
+  z-index: 99999;
+  left: 0; right: 0; top: 0; bottom: 0;
+  width: 80%;
+  margin: auto;
+  background: #fff;
+  color: #676767;
+  max-height: 80%;
+  overflow: auto;
+  font-family: Arial, sans-serif;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-box-shadow: 0 4px 12px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.5);
+  box-shadow: 0 4px 12px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.5);
+  -webkit-transition: width .2s linear;
+  -moz-transition: width .2s linear;
+  -o-transition: width .2s linear;
+  transition: width .2s linear;
+}
+
+  .help-modal-content {
+    padding: 0 20px;
+  }
+
+  .help-close {
+    position: absolute;
+    top: .4em;
+    right: .5em;
+    font-size: 1.8em;
+    cursor: pointer;
+    -webkit-transition: color .2s linear;
+    -moz-transition: color .2s linear;
+    -o-transition: color .2s linear;
+    transition: color .2s linear;
+  }
+
+    .help-close:hover {
+      color: #000;
+    }
+
+.help-modal h1 {
+  text-align: center;
+  margin: .5em;
+  font-size: 1.5em;
+  padding-bottom: .4em;
+  border-bottom: solid 2px #ccc;
+  font-weight: normal;
+}
+
+  .help-modal h1 .help-key {
+    float: none;
+    line-height: 1.5;
+    position: relative;
+    bottom: 4px;
+  }
+
+.help-isVisible {
+  opacity: 1;
+  visibility: visible;
+  height: auto;
+  z-index: 8888;
+}
+
+.ie8 .help-underlay.help-isVisible {
+  visibility: visible;
+}
+
+.help-list-wrap {
+  overflow: hidden;
+  margin: 0 auto;
+  -webkit-transition: width .2s linear;
+  -moz-transition: width .2s linear;
+  -o-transition: width .2s linear;
+  transition: width .2s linear;
+}
+
+.help-list {
+  list-style: none;
+  margin: 0;
+  padding: 0 0 10px 0;
+  overflow: hidden;
+  float: left;
+  width: 280px;
+}
+
+  .help-list li {
+    margin-right: 40px;
+  }
+
+.help-key-unit {
+  line-height: 1.8;
+  margin-right: 2em;
+  padding: 5px 0;
+}
+
+.help-key {
+  min-width: 60px;
+  float: left;
+  clear: left;
+  position: relative;
+  bottom: 2px;
+}
+
+.help-key span {
+  font-size: 15px;
+  color: #555;
+  display: inline-block;
+  padding: 0 8px;
+  text-align: center;
+  background-color: #eee;
+  background-repeat: repeat-x;
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#eee));
+  background-image: -webkit-linear-gradient(#f5f5f5 0%, #eee 100%);
+  background-image: -moz-linear-gradient(#f5f5f5 0%, #eee 100%);
+  background-image: -o-linear-gradient(#f5f5f5 0%, #eee 100%);
+  background-image: linear-gradient(#f5f5f5 0%, #eee 100%);
+  border: 1px solid #ccc;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 0 #ccc;
+  box-shadow: inset 0 1px 0 #fff, 0 1px 0 #ccc;
+}
+
+.help-key-def {
+  display: inline-block;
+  margin-left: 1em;
+}
\ No newline at end of file
diff --git a/web/question.mark.html b/web/question.mark.html
new file mode 100644 (file)
index 0000000..3e2b4aa
--- /dev/null
@@ -0,0 +1,51 @@
+<div id="helpUnderlay" class="help-underlay">
+  <div id="helpModal" class="help-modal">
+  <h1>Keyboard Shortcuts <kbd class="help-key"><span>?</span></kbd></h1>
+    <div id="helpClose" class="help-close">&times;</div><!-- .help-close -->
+    
+    <div id="helpModalContent" class="help-modal-content">
+      
+      <div id="helpListWrap" class="help-list-wrap">
+
+        <!--
+             Each <ul> below creates a column, as long as each has a class of
+             "help-list". Each <li> is a single key/definition pair.
+             The extra nested <span> is to help keep the definitions lined up
+             vertically, for aesthetic reasons.
+             If you hate the extra <span>, just remove it from each key/def pair.
+        -->
+
+        <ul class="help-list">
+
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>space</span></kbd>
+            <span class="help-key-def">Pause/Play</span>
+          </li>
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>r</span></kbd>
+            <span class="help-key-def">Return to start</span>
+          </li>
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>b</span></kbd>
+            <span class="help-key-def">Rewind 10 secs</span>
+          </li>
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>f</span></kbd>
+            <span class="help-key-def">Fast forward 10 secs</span>
+          </li>
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>a</span></kbd>
+            <span class="help-key-def">Mark start</span>
+          </li>
+          <li class="help-key-unit">
+            <kbd class="help-key"><span>c</span></kbd>
+            <span class="help-key-def">Clear start</span>
+          </li>
+
+        </ul><!-- .help-list -->
+
+      </div><!-- .help-list-wrap -->
+
+    </div><!-- .help-modal-content -->
+  </div><!-- .help-modal -->
+</div><!-- .help-underlay -->
\ No newline at end of file
diff --git a/web/question.mark.js b/web/question.mark.js
new file mode 100644 (file)
index 0000000..0c9dcd1
--- /dev/null
@@ -0,0 +1 @@
+(function(){"use strict";function e(e){e.className=e.className.replace(/help-isVisible*/g,"");e.className=e.className.trim()}function t(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName("body")[0],i=e.innerWidth||n.clientWidth||r.clientWidth;return i}function n(){var e=document;return Math.max(e.body.scrollHeight,e.documentElement.scrollHeight,e.body.offsetHeight,e.documentElement.offsetHeight,e.body.clientHeight,e.documentElement.clientHeight)}function r(e){e.helpColsTotal=0;for(e.i=0;e.i<e.helpLists.length;e.i+=1){if(e.helpLists[e.i].className.indexOf("help-list")!==-1){e.helpColsTotal+=1}e.helpListsHeights[e.i]=e.helpLists[e.i].offsetHeight}e.maxHeight=Math.max.apply(Math,e.helpListsHeights);if(t()<=1180&&t()>630&&e.helpColsTotal>2){e.helpColsTotal=2;e.maxHeight=e.maxHeight*e.helpColsTotal}if(t()<=630){e.maxHeight=e.maxHeight*e.helpColsTotal;e.helpColsTotal=1}e.helpListWrap.style.offsetWidth=e.helpList.offsetWidth*e.helpColsTotal+"px";e.helpListWrap.style.height=e.maxHeight+"px";e.helpModal.style.width=e.helpList.offsetWidth*e.helpColsTotal+60+"px";e.helpModal.style.height=e.maxHeight+100+"px"}function i(e){e=e||window.event;var t=e.keyCode||e.which;return t}function s(){var t=document.getElementById("helpUnderlay"),s=document.getElementById("helpModal"),o=document.getElementById("helpClose"),u=null,a={i:null,maxHeight:null,helpListWrap:document.getElementById("helpListWrap"),helpList:document.querySelector(".help-list"),helpLists:document.querySelectorAll(".help-list"),helpModal:s,helpColsTotal:null,helpListsHeights:[]},f;r(a);document.addEventListener("keypress",function(e){if(i(e)===63){f=document.getElementById("helpUnderlay").className;if(f.indexOf("help-isVisible")===-1){document.getElementById("helpUnderlay").className+=" help-isVisible"}}t.style.height=n()+"px"},false);document.addEventListener("keyup",function(n){if(i(n)===27){e(t)}},false);t.addEventListener("click",function(){e(t)},false);s.addEventListener("click",function(e){e.stopPropagation()},false);o.addEventListener("click",function(){e(t)},false);window.onresize=function(){if(u!==null){clearTimeout(u)}u=setTimeout(function(){r(a)},100)}}function o(){var e=false;if(window.XMLHttpRequest){e=new XMLHttpRequest}return e}function u(e,t){if(!document.getElementById("helpUnderlay")){document.getElementsByTagName("body")[0].innerHTML+=e;t()}}function a(e){if(e.readyState===4){if(e.status===200||e.status===304){var t=e.responseText;u(t,function(){s()})}}}function f(){var e=o();if(e){e.onreadystatechange=function(){a(e)};e.open("POST","question.mark.html",true);e.setRequestHeader("Content-Type","application/x-www-form-urlencoded");e.send(null)}else{document.getElementsByTagName("body")[0].innerHTML+="Error: Your browser does not support Ajax"}}f()})()
\ No newline at end of file
diff --git a/web/songbook.css b/web/songbook.css
new file mode 100644 (file)
index 0000000..5335352
--- /dev/null
@@ -0,0 +1,58 @@
+body {
+  background-image: url('/songbook/background.jpg');
+  padding: 0px;
+  border: 0px;
+  margin: 0px;
+}
+#title {
+  text-align: center;
+  font-family: Arial, Helvetica;
+  font-size: 28pt;
+}
+#artist {
+  text-align: center;
+  font-family: Arial, Helvetica;
+  font-size: 22pt;
+}
+#song {
+  padding-top: 100px;
+  padding-left: 20px;
+}
+#heading {
+  border: 0;
+  border-bottom: 1px solid black;
+  position: fixed;
+  margin: 0;
+  padding: 0;
+  background-color: #ddd;
+  width: 100%;
+}
+.lyrics, .lyrics_chorus {
+  font-size: 22pt;
+}
+.lyrics_tab, .lyrics_chorus_tab {
+  font-family: "Courier New", Courier;
+  font-size: 18pt;
+}
+.lyrics_chorus, .lyrics_chorus_tab, .chords_chorus, .chords_chorus_tab {
+  font-weight: bold;
+}
+.chords, .chords_chorus, .chords_tab, .chords_chorus_tab {
+  font-size: 18pt;
+  color: blue;
+  padding-right: 4pt;
+}
+.comment, .comment_italic {
+  color: #999;
+  font-size: 18pt;
+}
+.comment_box {
+  background-color: #ffbbaa;
+  text-align: center;
+}
+.comment_italic {
+  font-style: italic;
+}
+.comment_box {
+  border: solid;
+}
diff --git a/web/songbook.js b/web/songbook.js
new file mode 100644 (file)
index 0000000..85a4b18
--- /dev/null
@@ -0,0 +1,72 @@
+// Javascript functions for controling audio
+starttime = null;
+endtime   = null;
+
+spacebar       = 32;
+return2start   = 82;
+backfewsecs    = 66;
+forwardfewsecs = 70;
+seta           = 65;
+cleara         = 67;
+howmanysecs    = 10;
+
+window.onload = function() {
+  song = document.getElementById('song');
+
+  starttime = song.currentTime;
+  endtime   = song.duration;
+  body      = document.getElementsByTagName('body')[0]
+
+  body.onkeydown = 
+    function(e) {
+      var ev = e || event;
+      if (ev.keyCode == spacebar) {
+        if (song.paused) {
+          playing = false;
+        } else {
+          playing = true;
+        } // if
+
+        if (playing) {
+          song.pause();
+          playing = false;
+        } else {
+          if (starttime != 0) {
+            song.currentTime = starttime
+          } // if
+
+          song.play();
+          playing = true;
+        } // if
+
+        e.preventDefault();
+        return;
+      } else if (ev.keyCode == return2start) {
+        if (starttime != null) {
+          song.currentTime = starttime;
+        } else {
+          song.currentTime = 0;
+        } // if
+
+        return;
+      } else if (ev.keyCode == backfewsecs) {
+        song.currentTime -= howmanysecs;
+        song.play()
+
+        return;
+      } else if (ev.keyCode == forwardfewsecs) {
+        song.currentTime += howmanysecs;
+        song.play();
+
+        return;
+      } else if (ev.keyCode == seta) {
+        starttime = song.currentTime;
+
+        return;
+      } else if (ev.keyCode == cleara) {
+        starttime = 0;
+
+        return;
+      } // if
+    } // function
+  }  // getElementByTagName
\ No newline at end of file
index 15a3186..a64b4c1 100755 (executable)
@@ -12,7 +12,6 @@
 # 2003-08-03 Version 1.1 Uses stylesheets
 # 2014-02-05 Added things particular to my implementation of Songbook at
 #            http://defaria.com/songbook
-
 use strict;
 use warnings;
 
@@ -41,31 +40,31 @@ unless (-f $infile) {
 
 sub debug ($) {
   my ($msg) = @_;
-  
+
   return unless $debug;
-  
+
   print "<font color=red><b>Debug:</b></font> $msg<br>";  
-  
+
   return;
 } # debug
 
-sub warning ($) {\r
+sub warning ($) {
   my ($msg) = @_;
 
   debug "warning";
 
   print "<font color=orange><b>Warning</b></font> $msg<br>";
 
-  return;  
+  return;
 } # warning
 
 sub error {
   my ($msg) = @_;
-  
+
   print "<html><head><title>Web Chord: Error</title></head>" .
     "<body><h1>Error</h1><p>\n$msg\n</p>" .
     "</body></html>";
-  
+
   exit;
 } # error
 
@@ -73,17 +72,17 @@ sub musicFileExists ($) {
   my ($song) = @_;
 
   debug "ENTER musicFileExists ($song)";
-  
+
   my $title     = fileparse ($song, qr/\.pro/);
   my $musicfile = "/opt/media/$title.mp3";
 
   if (-r $musicfile) {
     debug "Exists!";
-    
+
     return $title;
   } else {
     debug "Could not find $musicfile";
-    
+
     return undef;
   } # if
 } # musicFileExists
@@ -92,10 +91,10 @@ sub updateMusicpath ($$) {
   my ($chopro, $song) = @_;
 
   my $title = musicFileExists $song;
-  
+
   # If there's no corresponding music file then do nothing
   return unless $title;
-  
+
   # If the .pro file already has musicpath then do nothing
   if ($chopro =~ /\{musicpath:.*\}/) {
     debug "$song already has musicpath";
@@ -105,26 +104,26 @@ sub updateMusicpath ($$) {
 
   # Otherwise append the musicpath
   my $songfile;
-  
+
   open $songfile, '>>', $song
     or undef $songfile;
-  
+
   unless (defined $songfile) {
     my $msg  = "Unable to open $song for append - $!<br>";
        $msg .= "<br>Please notify <a href=\"mailto:adefaria\@gmail.com?subject=Please chmod 666 $song\">Andrew DeFaria</a> so this can be corrected.<br>";
        $msg .= "<br>Thanks"; 
     warning $msg;
-    
+
     return;
   } # unless
 
   my $songbase = '/sdcard';
-  
+
   print $songfile "{musicpath:$songbase/SongBook/Media/$title.mp3}\n";
-  
+
   close $songfile;
 
-  return;  
+  return;
 } # updateMusicPath
 
 # Outputs the HTML code of the chordpro file in the first parameter
@@ -135,95 +134,53 @@ sub chopro2html ($$) {
   $chopro =~ s/\>/\&gt;/g; # replace > with &gt;
   $chopro =~ s/\&/\&amp;/g; # replace & with &amp;
 
-  my $title;
-  
-  if(($chopro =~ /^{title:(.*)}/mi) || ($chopro =~ /^{t:(.*)}/mi)) {
+  my $title = "ChordPro Song";
+  my $artist = "Unknown";
+
+  if (($chopro =~ /^{title:(.*)}/mi) || ($chopro =~ /^{t:(.*)}/mi)) {
     $title = $1;
-  } else {
-    $title = "ChordPro song";
-  }
+  } # if
+
+  if (($chopro =~ /^{subtitle:(.*)}/mi) || ($chopro =~ /^{st:(.*)}/mi)) {
+    $artist = $1;
+  } # if
+  
   print <<END;
 <html>
 <head>
 <title>$title</title>
-<style type="text/css">
-body {
-  background-image: url('/songbook/background.jpg');
-  padding-left: 100px;
-}
-h1 {
-  text-align: center;
-  font-family: Arial, Helvetica;
-  font-size: 28pt;
-  line-height: 10%;
-}
-h2 {
-  text-align: center;
-  font-family: Arial, Helvetica;
-  font-size: 22pt;
-  line-height: 50%;
-}
-.lyrics, .lyrics_chorus {
-  font-size: 22pt;
-}
-.lyrics_tab, .lyrics_chorus_tab {
-  font-family: "Courier New", Courier;
-  font-size: 18pt;
-}
-.lyrics_chorus, .lyrics_chorus_tab, .chords_chorus, .chords_chorus_tab {
-  font-weight: bold;
-}
-.chords, .chords_chorus, .chords_tab, .chords_chorus_tab {
-  font-size: 18pt;
-  color: blue;
-  padding-right: 4pt;
-}
-.comment, .comment_italic {
-  color: #999;
-  font-size: 18pt;
-}
-.comment_box {
-  background-color: #ffbbaa;
-  text-align: center;
-}
-.comment_italic {
-  font-style: italic;
-}
-.comment_box {
-  border: solid;
-}
-</style>
+<link rel="stylesheet" type="text/css" href="songbook.css">
+<link rel="stylesheet" type="text/css" href="question.mark.css">
+<script src="songbook.js"></script>
+<script src="question.mark.js"></script>
 </head>
+
 <body>
 END
 
       $title = musicFileExists $song;
-      
+
       if ($title) {
         updateMusicpath $chopro, $song;
       } # if
-      
+
       print << "END";
-<table border="0" width="100%">
+<table id="heading">
   <tbody>
     <tr>
       <td align="left"><a href="/songbook"><img src="/Icons/Home.png" alt="Home"></a></td>
-END
-      
-      if ($title) {
-        print <<"END";
-<td align="right">
-<audio controls autoplay>
- <source src="http://defaria.com/Media/$title.mp3" type='audio/mp3'>
- <p>Your user agent does not support the HTML5 Audio element.</p>
-</audio>
-</td>
-END
-      } # if
-print <<"END";
+      <td><div id="title">$title</div>
+          <div id="artist"><a href="/songbook/displayartist.php?artist=$artist">$artist</a></div></td>
+      <td align="right" width="300px">
+        <audio id="song" controls autoplay style="padding:0; margin:0">
+          <source src="http://defaria.com/Media/$title.mp3" style="padding:0; margin:0" type='audio/mp3'>
+          Your user agent does not support the HTML5 Audio element.
+        </audio>
+      </td>
     </tr>
   </tbody>
 </table>
+<div id="song">
 END
   my $mode = 0; # mode defines which class to use
 
@@ -237,27 +194,23 @@ END
     $_ = $1;
     chomp;
 
-    if(/^#(.*)/) {                                # a line starting with # is a comment
-      print "<!--$1-->\n";                        # insert as HTML comment
-    } elsif(/{(.*)}/) {                           # this is a command
+    if (/^#(.*)/) {                                # a line starting with # is a comment
+      print "<!--$1-->\n";                         # insert as HTML comment
+    } elsif (/{(.*)}/) {                           # this is a command
       $_ = $1;
-      if(/^title:/i || /^t:/i) {                  # title
-        print "<H1>$'</H1>\n";
-      } elsif(/^subtitle:/i || /^st:/i) {         # subtitle
-        print "<H2>$'</H2>\n";
-      } elsif(/^start_of_chorus/i || /^soc/i) {   # start_of_chorus
+      if (/^start_of_chorus/i || /^soc/i) {        # start_of_chorus
         $mode |= 1;
-      } elsif(/^end_of_chorus/i || /^eoc/i) {     # end_of_chorus
+      } elsif (/^end_of_chorus/i || /^eoc/i) {     # end_of_chorus
         $mode &= ~1;
-      } elsif(/^comment:/i || /^c:/i) {           # comment
+      } elsif (/^comment:/i || /^c:/i) {           # comment
         print "<span class=\"comment\">($')</span>\n";
-      } elsif(/^comment_italic:/i || /^ci:/i) {   # comment_italic
+      } elsif (/^comment_italic:/i || /^ci:/i) {   # comment_italic
         print "<span class=\"comment_italic\">($')</span>\n";
-      } elsif(/^comment_box:/i || /^cb:/i) {      # comment_box
+      } elsif (/^comment_box:/i || /^cb:/i) {      # comment_box
         print "<P class=\"comment_box\">$'</P>\n";
-      } elsif(/^start_of_tab/i || /^sot/i) {      # start_of_tab
+      } elsif (/^start_of_tab/i || /^sot/i) {      # start_of_tab
         $mode |= 2;
-      } elsif(/^end_of_tab/i || /^eot/i) {        # end_of_tab
+      } elsif (/^end_of_tab/i || /^eot/i) {        # end_of_tab
         $mode &= ~2;
       } else {
         print "<!--Unsupported command: $_-->\n";
@@ -273,37 +226,39 @@ END
       }
       push(@lyrics,$_);       # rest of line (after last chord) into @lyrics
 
-      if($lyrics[0] eq "") {  # line began with a chord
+      if ($lyrics[0] eq "") {  # line began with a chord
         shift(@chords);       # remove first item
         shift(@lyrics);       # (they are both empty)
       }
 
-      if(@lyrics==0) {  # empty line?
+      if (@lyrics==0) {  # empty line?
         print "<BR>\n";
-      } elsif(@lyrics==1 && $chords[0] eq "") { # line without chords
-        print "<DIV class=\"$lClasses[$mode]\">$lyrics[0]</DIV>\n";
+      } elsif (@lyrics==1 && $chords[0] eq "") { # line without chords
+        print "<div class=\"$lClasses[$mode]\">$lyrics[0]</div>\n";
       } else {
-        print "<TABLE cellpadding=0 cellspacing=0>";
-        print "<TR>\n";
+        print "<table cellpadding=0 cellspacing=0>";
+        print "<tr>\n";
         my($i);
         for($i = 0; $i < @chords; $i++) {
-          print "<TD class=\"$cClasses[$mode]\">$chords[$i]</TD>";
+          print "<td class=\"$cClasses[$mode]\">$chords[$i]</td>";
         }
-        print "</TR>\n<TR>\n";
+        print "</tr>\n<tr>\n";
         for($i = 0; $i < @lyrics; $i++) {
-          print "<TD class=\"$lClasses[$mode]\">$lyrics[$i]</TD>";
+          print "<td class=\"$lClasses[$mode]\">$lyrics[$i]</td>";
         }
-        print "</TR></TABLE>\n";
+        print "</tr></table>\n";
       } # if
     } # if
   } # while
+  
+  print "</div>";
 } # chordpro2html
 
 ## Main
 print header;
 
 unless ($infile) {
-       error "No chordpro parameter";
+  error "No chordpro parameter";
 } # unless
 
 open my $file, '<', $infile
@@ -318,6 +273,4 @@ chopro2html ($chopro, $infile);
 
 print end_html();
 
-exit;
-
-
+exit;
\ No newline at end of file