From b4478f4011bbcb995c9706926a13e9feab9430b1 Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Wed, 7 Sep 2011 18:34:03 +0200
Subject: [PATCH] Implement max staff number, other improvements

-) Calculate good max nr of staves per page
-) Staff size given in mm rather than pt
-) add 2-staff choir, tab staff, drum staff, etc.
-) typos
-) Add empty header fields for title etc.
-) good-looking footer line with links to Edition Kainhofer & LilyPond
-) no page numbers
-) Create 3 pages (1 title, 2 normal), page number not selectable by more
-) Add proper absolute pathes to the images and scripts, so the php code
   can be included in any page and will still access the correct files
	 in the source dir
-) Create .ly file only if needed, create smarty object only when needed
-) Disable access to the templates and other code via .htaccess
---
 .htaccess                    |  16 ++-
 empty_sheet.php              | 138 +++++++++++++----------
 empty_sheet_form.php         | 212 ++++++++++++++++++++++++-----------
 preview.png                  | Bin 0 -> 7472 bytes
 templates/Dr.tpl.ly          |   1 +
 templates/empty_sheet.tpl.ly |  37 +++---
 6 files changed, 261 insertions(+), 143 deletions(-)
 create mode 100644 preview.png
 create mode 100644 templates/Dr.tpl.ly

diff --git a/.htaccess b/.htaccess
index ec3ea62..b89142f 100644
--- a/.htaccess
+++ b/.htaccess
@@ -1,3 +1,13 @@
-order deny,allow
-deny from all
-allow from 127.0.0.1
+# disable everything, except empty_sheet.php and the images
+Order allow,deny
+Deny from all
+
+<Files index.php>
+  Allow from all
+</Files>
+<Files empty_sheet.php>
+  Allow from all
+</Files>
+<FilesMatch \.(?i:gif|png)$>
+  Allow from all
+</FilesMatch>
diff --git a/empty_sheet.php b/empty_sheet.php
index 1c6c37d..0d2c35f 100644
--- a/empty_sheet.php
+++ b/empty_sheet.php
@@ -1,6 +1,6 @@
 <?php
 
-umask (0001);
+umask (0000);
 $basedir=dirname(__FILE__);
 
 $user = "lilyjail";
@@ -10,15 +10,17 @@ $lilyworkdir = "$lilyhome/empty_sheet";
 
 $ly_cmd = "/usr/bin/sudo /opt/lily2.14/bin/lilypond -j$user,$user,$lilymnt,$lilyhome --png --pdf -dpixmap-format=pngalpha -dresolution=20 ";
 
-include('smarty3/Smarty.class.php');
-$smarty = new Smarty();
+$format="pdf";
+if (isset ($_REQUEST["preview"]))
+  $format="png";
+elseif (isset ($_REQUEST["create_lily"]))
+  $format="ly";
+else
+  $format="pdf";
+
+
 
-$smarty->setCompileDir($basedir.'/smarty/templates_c');
-$smarty->setCacheDir($basedir.'/smarty/cache');
-$smarty->setConfigDir($basedir.'/smarty/configs');
 
-$smarty->left_delimiter = '{{';
-$smarty->right_delimiter = '}}';
 
 function robust_request_string ($parm, $default) {
   if (isset ($_REQUEST[$parm]) && is_string ($_REQUEST[$parm])) {
@@ -60,7 +62,7 @@ function robust_request_bool ($parm, $default) {
 // {...} ... GrandStaff
 // (...) ... <<..>>
 
-$known_staff_types = array ("S0", "S", "S8", "Sa", "St", "Sb", "O", "P", "Ch2", "Ch4", "Rh", "Tab");
+$known_staff_types = array ("S0", "S", "S8", "Sa", "St", "Sb", "O", "P", "Ch2", "Ch4", "Rh", "Tab", "Dr");
 $known_group_types = array ("{" => "GrandStaff", "(" => "", "[" => "StaffGroup");
 $known_group_endings = array ("{" => "}", "(" => ")", "[" => "]");
 
@@ -134,7 +136,7 @@ $pages = robust_request_number ("pages", 2, 1, 20);
 $title = robust_request_string ("title", NULL);
 $subtitle = robust_request_string ("subtitle", NULL);
 $composer = robust_request_string ("composer", NULL);
-$arranger = robust_request_string ("composer", NULL);
+$arranger = robust_request_string ("arranger", NULL);
 $instrument = robust_request_string ("instrument", NULL);
 $header_space = robust_request_bool ("header_space", false);
 $metainfo = $title . $subtitle . $composer . $instrument.$header_space;
@@ -157,26 +159,49 @@ if ($pages > 1) {
   $png_file = $base_file . ".png";
 }
 
-// If the file exists, return it now.
-if (isset ($_REQUEST["preview"])) {
-  if (file_exists ($lilymnt.$png_file)) {
-    header('Content-type: image/png');
-    header('Content-Description: Empty Music Score Preview');
-    header('Content-Length: ' . filesize($lilymnt.$png_file));
-    readfile($lilymnt.$png_file);
-    exit (0);
+function send_file_if_exists ()
+{
+  global $format, $lilymnt, $png_file, $ly_file, $pdf_file;
+  if ($format == "png") {
+    if (file_exists ($lilymnt.$png_file)) {
+      header('Content-type: image/png');
+      header('Content-Description: Empty Music Score Preview');
+      header('Content-Length: ' . filesize($lilymnt.$png_file));
+      readfile($lilymnt.$png_file);
+      return TRUE;
+    }
+  } elseif ($format == "ly") {
+    if (file_exists ($lilymnt.$ly_file)) {
+      header('Content-type: text/plain');
+      header('Content-Description: Empty Music Score Sheets - provided by Edition Kainhofer');
+      header('Content-Length: ' . filesize($lilymnt.$ly_file));
+      header('Content-Disposition: attachment; filename=' . basename($lilymnt.$ly_file));
+      readfile($lilymnt.$ly_file);
+      return TRUE;
+    }
+  } elseif ($format == "pdf") {
+    if (file_exists ($lilymnt.$pdf_file)) {
+      header('Content-type: application/pdf');
+      header('Content-Description: Empty Music Score Sheets - provided by Edition Kainhofer');
+      header('Content-Length: ' . filesize($lilymnt.$pdf_file));
+      header('Content-Disposition: attachment; filename=' . basename($lilymnt.$pdf_file));
+      readfile($lilymnt.$pdf_file);
+      return TRUE;
+    }
   }
-} elseif (file_exists ($lilymnt.$pdf_file)) {
-  header('Content-type: application/pdf');
-  header('Content-Description: Empty Music Score Sheets - provided by Edition Kainhofer');
-  header('Content-Length: ' . filesize($lilymnt.$pdf_file));
-  header('Content-Disposition: inline; filename=' . basename($lilymnt.$pdf_file));
-  readfile($lilymnt.$pdf_file);
+}
+
+// If the file already exists, simply send it
+if (send_file_if_exists ()) {
   exit (0);
 }
 
 
 
+///////////////////////////////////////////////////////////////////////////
+//  Create the .ly file
+///////////////////////////////////////////////////////////////////////////
+
 // Parse the score type:
 if (isset ($_REQUEST["score_type"])) {
   $score_type = parse_score_type ($_REQUEST["score_type"]);
@@ -185,7 +210,14 @@ if (isset ($_REQUEST["score_type"])) {
 }
 
 
-
+/////// Smarty setup
+include('smarty3/Smarty.class.php');
+$smarty = new Smarty();
+$smarty->setCompileDir($basedir.'/smarty/templates_c');
+$smarty->setCacheDir($basedir.'/smarty/cache');
+$smarty->setConfigDir($basedir.'/smarty/configs');
+$smarty->left_delimiter = '{{';
+$smarty->right_delimiter = '}}';
 
 /////// Output variables for the template
 $smarty->assign('paper_size', $paper_size);
@@ -206,44 +238,36 @@ $smarty->assign('contents', $score_type);
 
 $smarty->allow_php_tag = true;
 
-//////// Check for the pdf file, create it if needed and return it:
+///// Create the lilypond file
 $lycode = $smarty->fetch('empty_sheet.tpl.ly');
+$fh = fopen($lilymnt.$ly_file, 'w') or die("can't open file $lilymnt$ly_file for writing");
+fwrite($fh, $lycode);
+fclose($fh);
+// Make sure jailed lilypond running as user lilyjail can read it:
+chmod ($lilymnt.$ly_file, 0644);
+
+// If .ly file was requested, send it without running lilypond
+if ($format == "ly" && send_file_if_exists ()) {
+  exit (0);
+}
 
 
-if (!file_exists ($pdf_file)) {
-  // Create the lilypond file
-  $fh = fopen($lilymnt.$ly_file, 'w') or die("can't open file $lilymnt$ly_file for writing");
-  fwrite($fh, $lycode);
-  fclose($fh);
-  // Make sure jailed lilypond running as user lilyjail can read it:
-  chmod ($lilymnt.$ly_file, 0644);
+///////////////////////////////////////////////////////////////////////////
+//  Run LilyPond on the .ly and return the result
+///////////////////////////////////////////////////////////////////////////
 
-  // run it through lilypond to create the pdf
-  // As we are running inside the jail, we don't include $lilymnt in the pathes!
-  $cmd = "$ly_cmd -o $base_file $ly_file 2>&1";
-// print "<p>Command: <pre>$cmd</pre></p>";
-  $lily_result = exec($cmd, $output, $retval);
-}
+// run it through lilypond to create the pdf
+// As we are running inside the jail, we don't include $lilymnt in the pathes!
+$cmd = "$ly_cmd -o $base_file $ly_file 2>&1";
+$lily_result = exec($cmd, $output, $retval);
 
-if (isset ($_REQUEST["preview"])) {
-  if (file_exists ($lilymnt.$png_file)) {
-    header('Content-type: image/png');
-    header('Content-Description: Empty Music Score Preview');
-    header('Content-Length: ' . filesize($lilymnt.$png_file));
-//     header('Content-Disposition: inline; filename=' . basename($lilymnt.$png_file));
-    readfile($lilymnt.$png_file);
-  }
-} elseif (file_exists ($lilymnt.$pdf_file)) {
-  header('Content-type: application/pdf');
-  header('Content-Description: Empty Music Score Sheets - provided by Edition Kainhofer');
-  header('Content-Length: ' . filesize($lilymnt.$pdf_file));
-  header('Content-Disposition: inline; filename=' . basename($lilymnt.$pdf_file));
-  readfile($lilymnt.$pdf_file);
-} else {
+if (!send_file_if_exists ()) {
   print ("Unable to create the score file. Wrong input or server error encountered.");
-  print ("The output from running lilypond is:\n<pre>");
-  print_r ($output);
-  print ("</pre>\n");
+  if ($output) {
+    print ("The output from running lilypond is:\n<pre>");
+    print_r ($output);
+    print ("</pre>\n");
+  }
 }
 
 ?>
diff --git a/empty_sheet_form.php b/empty_sheet_form.php
index 002128c..8455ebe 100644
--- a/empty_sheet_form.php
+++ b/empty_sheet_form.php
@@ -1,13 +1,29 @@
+<?php
+  $full = array_key_exists ("full", $_REQUEST);
+  $debug = array_key_exists ("debug", $_REQUEST);
+  if ($debug) {
+    echo "<p id=debug></p>";
+  }
+?>
+<?php
+// The absolute URL to the current script, needed for all references
+// to scripts in this directoty!
+$abs_path = substr (dirname(__FILE__), strlen($_SERVER["DOCUMENT_ROOT"]));
+?>
 <div id="music_score_form">
 
   <style type="text/css" >
+    table.music_score_settings_table td.submit_button_cell {
+      text-align: center;
+    }
     #preview { border: 1px solid black; }
     .vsep { background: darkgray; }
     #previewdiv {
       position: relative;
+      background: white;
     }
     #loadingOverlay {
-      background-image: url('loading.gif');
+      background-image: url('<?php echo $abs_path ?>/loading.gif');
       position: absolute;
       z-index: 1;
       top: 40%;
@@ -22,49 +38,102 @@
   function loadPreview () {
     // Show loading overlay, will be hidden in onLoad handler of the image!
     document.getElementById("loadingOverlay").style.visibility = "visible";
-    // Add all non-button form elements:      
-    var src = "empty_sheet.php?preview=True";
+    // Add all non-button form elements:
+    var src = "<?php echo $abs_path ?>/empty_sheet.php?preview=True";
     var elt = document.score_form.elements;
-    for(var i=0; i < elt.length; i++){
-      if (elt[i].type != 'submit' && elt[i].type != 'reset') {
-        src += "&" + encodeURIComponent (elt[i].name) + "=" + 
-               encodeURIComponent (elt[i].value);
+    for(var i=0; i < elt.length; i++) {
+      var type = elt[i].type;
+      if (type != 'submit' && type != 'reset' && !elt[i].disabled) {
+        if (( type === "radio" || type === "checkbox") && !elt[i].checked) {
+          // do nothing for unchecked checkboxes
+        } else {
+          src += "&" + encodeURIComponent (elt[i].name) + "=" + encodeURIComponent (elt[i].value);
+        }
       }
     }
     document.getElementById("preview").src = src;
+    <?php if ($debug) { ?>
+      document.getElementById("debug").innerHTML = src;
+    <?php } ?>
+  }
+
+  var staff_numbers = {"S0":1, "S":1, "S8":1, "Sa":1, "St":1, "Sb":1, "O":3, "P":2, "Ch2":2, "Ch4":4, "Rh":0.5, "Tab":1.35, "Dr":1};
+  var page_height = {"a4":297, "a5":210, "a6":148, "a4 landscape":210, "a5 landscape":148, "a6 landscape":105,
+     "letter":279, "legal":356, "11x17":432,
+     "letter landscape":216, "legal landscape":216, "11x17 landscape":279}
+  function checkStaffCount () {
+    // Staff type, without group structure
+    var type = document.getElementById("score_type").value.replace(/[{}\(\)\[\]]/g, "");
+    // Split into individual staves, sum up their count
+    staves = type.match(/[A-Z][^A-Z]*/g);
+    var count=0;
+    for (var i = 0; i < staves.length; ++i) {
+      count += staff_numbers[staves[i]];
+    }
+    // Check how many staves could fit on one page
+    var staffsize = document.getElementById("staff_size").value;
+    // Assume 1 staff height min spacing; extent in mm per staff:
+    var min_space_per_system = 2*staffsize*count/72*25.4;
+    var paper_size = document.getElementById("paper_size").value;
+    var available_space = page_height[paper_size] - 20;  // paper height
+    if (document.getElementById("header_space") && document.getElementById("header_space").checked) {
+      available_space -= 35;   // minus 30mm for header + padding
+    }
+    var max_staves = Math.floor (available_space / min_space_per_system);
+    max_staves = Math.max (1, max_staves); // Show at least one staff
+    // only allow max_staves in the combobox, disable all higher values:
+    var sys_page_opt = document.getElementById("systems").options;
+    for (var i = 0; i< sys_page_opt.length; ++i) {
+      sys_page_opt[i].disabled = (i>=max_staves);
+    }
+    if (document.getElementById("systems").selectedIndex >= max_staves) {
+      document.getElementById("systems").selectedIndex = max_staves-1;
+    }
+<?php if ($debug) { ?>
+    alert ("We have " + count + " staves in score with structure " + staves.join("/")+ ", max_staves: " + max_staves);
+<?php } ?>
+  }
+
+  function controlChanged () {
+    checkStaffCount ();
+    loadPreview ();
   }
 </script>
 <?php
-  $paper_sizes = array( 
-      "a4" => "A4", 
-      "a5" => "A5", 
-      "a6" => "A6", 
-      "a4 landscape" => "A4 (landscape)", 
-      "a5 landscape" => "A5 (landscape)", 
-      "a6 landscape" => "A6 (landscape)", 
-      "letter" => "US letter", 
-      "legal" => "Legal", 
+  $paper_sizes = array(
+      "a4" => "A4",
+      "a5" => "A5",
+      "a6" => "A6",
+      "a4 landscape" => "A4 (landscape)",
+      "a5 landscape" => "A5 (landscape)",
+      "a6 landscape" => "A6 (landscape)",
+      "letter" => "US letter",
+      "legal" => "Legal",
       "11x17" => "Ledger",
-      "letter landscape" => "US letter (landscape)", 
-      "legal landscape" => "Legal (landscape)", 
+      "letter landscape" => "US letter (landscape)",
+      "legal landscape" => "Legal (landscape)",
       "11x17 landscape" => "Ledger (landscape)");
   $paper_sizes_default = "a4";
 
   $staff_sizes = array (
-      "11" => "11pt (Pocket scores)",
-      "12.5" => "12.5pt",
-      "14" => "14pt",
-      "15" => "15pt",
-      "16" => "16pt",
-      "17" => "17pt",
-      "18" => "18pt",
-      "19" => "19pt",
-      "20" => "20pt (default)",
-      "22" => "22pt");
+      "10" => "3.5mm (10pt)",
+      "11" => "4mm (11pt, pocket score)",
+      "12.5" => "4.5mm (12.5pt)",
+      "14" => "5mm (14pt)",
+      "15" => "5.3mm (15pt, vocal score)",
+      "16" => "5.6mm (16pt)",
+      "17" => "6mm (17pt)",
+      "18" => "6.3mm (18pt)",
+      "19" => "6.7mm (19pt)",
+      "20" => "7mm (20pt, default)",
+      "23" => "8mm (23pt)",
+      "26" => "9mm (26pt)",
+      "28.5" => "10mm (28.5pt, HUGE)"
+);
   $staff_sizes_default = "20";
-  
+
   $systems_max = 15;
-  $systems_default = 7;
+  $systems_default = 10;
 
   $pages_max = 15;
   $pages_default = 2;
@@ -89,25 +158,31 @@
       "Ch2" =>       "Choir, 2 staves (SA + TB)",
       "Ch4" =>       "Choir, 4 staves (S, A, T, B)",
       "sep3" =>      Null,
-      "Ch4P" =>      "Piano reduction for choir",
+      "Ch4P" =>      "Piano reduction for choir (4 staves)",
+      "Ch2P" =>      "Piano reduction for choir (2 staves)",
       "S0P" =>       "Piano reduction for single soloist",
       "sep4" =>      Null,
       "[SSSb]" =>    "String Trio (2 V, Vc)",
       "[SSaSb]" =>   "String Trio (V, Va, Vc)",
-      "[SStSaSb]" => "String Quartett",
-      "[StSbP]" =>   "Piano Trio",
-      "[StSaSbP]" => "Piano Quartett",
+      "[SSSaSb]" => "String Quartet",
+      "[SSbP]" =>   "Piano Trio",
+      "[SSaSbP]" => "Piano Quartet",
       "sep5" =>      Null,
-      "" =>                             "Full Score, Chamber Orchestra",
-      "[SSb][SS][Sb][{SS}SaSb]" =>      "Full Score, Symphonic Orchestra",
-      "" =>                             "Full Score, Chamber Orchestra + Choir",
-      "[SSb][SS][Sb][{SS}Sa]Ch4[Sb]" => "Full Score, Symphonic Orchestra + Choir",
+//       "" =>                             "Full Score, Chamber Orchestra",
+      "[SSSb][SS][Sb][{SS}SaSb]" =>      "Full Score, large Orchestra",
+//       "" =>                             "Full Score, Chamber Orchestra + Choir",
+      "[SSb][SS][Sb][{SS}Sa]Ch4[Sb]" => "Full Score, large Orchestra + Choir",
+      "sep6" =>      Null,
+      "Rh" =>        "Single staff (one line)",
+      "Dr" =>        "Single staff, drum clef",
+      "Tab" =>       "Single tab staff",
+      "[S0Tab]" =>   "Staff + Tab staff",
+
       );
   $score_types_default = "S0";
-  
-  $fullheader = array_key_exists ("full", $_REQUEST);
-  $headercount = $fullheader ? count($score_header_fields) : 1;
-  
+
+  $headercount = $full ? count($score_header_fields) : 1;
+
 function write_option ($optkey, $optlabel, $optdefault) {
   $sel = ($optkey == $optdefault) ? ' selected="selected"' : '';
   if ($optlabel) {
@@ -120,38 +195,37 @@ function write_option ($optkey, $optlabel, $optdefault) {
 function write_headerfield ($field, $label) {
 ?>
     <tr>
-    <td><INPUT type="checkbox" name="<?php echo $field ?>_check" size="15" onchange="loadPreview();document.score_form.<?php echo $field ?>.disabled = !this.checked" id="<?php echo $field ?>_check"><label for="<?php echo $field ?>_check" ><?php echo $label ?>: </label></td>
-    <td><INPUT type="text" checked name="<?php echo $field ?>" size="25" maxlength="100" id="<?php echo $field ?>" disabled="disabled" onchange="loadPreview();"></td>
+    <td><INPUT type="checkbox" name="<?php echo $field ?>_check" value="1" size="15" onchange="document.score_form.<?php echo $field ?>.disabled = !this.checked; controlChanged();" id="<?php echo $field ?>_check"><label for="<?php echo $field ?>_check" ><?php echo $label ?>: </label></td>
+    <td><INPUT type="text" name="<?php echo $field ?>" size="25" maxlength="100" id="<?php echo $field ?>" disabled="disabled" onchange="controlChanged();"></td>
   </tr>
 <?php
 }
 ?>
 
-  <FORM action="empty_sheet.php" name="score_form" onreset="loadPreview();">
+  <FORM action="<?php echo $abs_path ?>/empty_sheet.php" name="score_form" onreset="controlChanged();">
   <table class="music_score_settings_table" >
   <TR>
     <td><label for="paper_size">Paper size:</label></td>
-    <td><select name="paper_size" id="paper_size" onchange="loadPreview();">
+    <td><select name="paper_size" id="paper_size" onchange="controlChanged();">
       <?php
-        foreach ($paper_sizes as $i => $value) { 
+        foreach ($paper_sizes as $i => $value) {
           write_option ($i, $value, $paper_sizes_default);
         }
       ?>
       </select></td>
-    <td rowspan="<?php echo 4+$headercount?>" class="vsep"></td>
     <td rowspan="<?php echo 4+$headercount?>" colspan=2 align=center class="previewcell">
       <div id=previewdiv class="foo">
         <div id="loadingOverlay"></div>
-        <img id=preview src="" onLoad="document.getElementById('loadingOverlay').style.visibility = 'hidden';" alt="PREVIEW">
+        <img id=preview src="<?php echo $abs_path; ?>/preview.png" onLoad="document.getElementById('loadingOverlay').style.visibility = 'hidden';" alt="PREVIEW">
       </div>
     </td>
 
   </tr>
   <tr>
     <td><label for="staff_size">Staff size:</label></td>
-    <td><select name="staff_size" id="staff_size" onchange="loadPreview();">
+    <td><select name="staff_size" id="staff_size" onchange="controlChanged();">
       <?php
-        foreach ($staff_sizes as $i => $value) { 
+        foreach ($staff_sizes as $i => $value) {
           write_option ($i, $value, $staff_sizes_default);
         }
       ?>
@@ -159,7 +233,7 @@ function write_headerfield ($field, $label) {
   </tr>
   <tr>
     <td><label for="systems">Systems/page:</label></td>
-    <td><select name="systems" id="systems" onchange="loadPreview();">
+    <td><select name="systems" id="systems" onchange="controlChanged();">
       <?php
         for ($i = 1; $i <= $systems_max; $i++) {
           write_option ($i, $i, $systems_default);
@@ -168,53 +242,55 @@ function write_headerfield ($field, $label) {
     </select></td>
   </tr>
   <tr>
-    <td><label for="pages">Pages:</label></td>
-    <td><select name="pages" id="pages" onchange="loadPreview();">
+    <td><?php if ($full) { ?><label for="pages">Pages:</label><?php } ?></td>
+    <td><?php if ($full) { ?><select name="pages" id="pages" onchange="controlChanged();">
       <?php
         for ($i = 1; $i <= $pages_max; $i++) {
           write_option ($i, $i, $pages_default);
         }
       ?>
-      </select></td>
+      </select>
+      <?php } else { ?>
+      <input type="hidden" name="pages" id="pages" value="3">
+      <?php } ?>
+    </td>
   </tr>
-  
-<?php 
-if ($fullheader) {
+
+<?php
+if ($full) {
   foreach ($score_header_fields as $i => $value) {
     write_headerfield ($i, $value);
   }
 } else {
-?> 
+?>
   <tr>
     <td colspan="2">
-      <INPUT type="checkbox" name="header_space" id="header_space" onchange="loadPreview();"><label for="header_space" >Reserve space for title</label>
+      <INPUT type="checkbox" checked value="1" name="header_space" id="header_space" onchange="controlChanged();"><label for="header_space" >Reserve space for title</label>
     </td>
   </tr>
 <?php } ?>
 
-<!--   <tr><TD colspan=5><hr></TD></tr> -->
-
   <tr>
     <td valign=top><label for="score_type">Score type:</label></td>
     <td colspan=4>
-      <SELECT name="score_type" id="score_type" style='width: 100%' size="20" onchange="loadPreview();">
+      <SELECT name="score_type" id="score_type" style='width: 100%' size="20" onchange="controlChanged();">
         <?php
-          foreach ($score_types as $i => $value) { 
+          foreach ($score_types as $i => $value) {
             write_option ($i, $value, $score_types_default);
           }
         ?>
       </SELECT>
     </td>
   </tr>
-  <tr><TD colspan=5 align=center>
-     <INPUT type="submit" name="create_score" value="Create Score"><INPUT type="reset" value="Reset Values">
+  <tr><TD colspan=5 class="submit_button_cell">
+     <INPUT type="submit" name="create_score" value="Download PDF"><INPUT type="submit" name="create_lily" value="Download LilyPond"><INPUT type="reset" value="Reset Values">
   </TD></tr>
 </table>
 
   </FORM>
 
 <script type="text/javascript">
-loadPreview ();
-// document.getElementById('loadingOverlay').style.visibility = 'hidden';
+controlChanged ();
 </script>
+
 </div>
\ No newline at end of file
diff --git a/preview.png b/preview.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6a1f2664b196ff46e00ff750d510cdc4fdd96b4
GIT binary patch
literal 7472
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
SS~4&&FnGH9xvX<aXaWFpRzSZ1

literal 0
HcmV?d00001

diff --git a/templates/Dr.tpl.ly b/templates/Dr.tpl.ly
new file mode 100644
index 0000000..8899dea
--- /dev/null
+++ b/templates/Dr.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new DrumStaff \new DrumVoice { \emptymusic }
\ No newline at end of file
diff --git a/templates/empty_sheet.tpl.ly b/templates/empty_sheet.tpl.ly
index 44f5f61..4feef05 100644
--- a/templates/empty_sheet.tpl.ly
+++ b/templates/empty_sheet.tpl.ly
@@ -2,20 +2,23 @@
 
 #(set-global-staff-size {{$staff_size}})
 #(set-default-paper-size "{{$paper_size}}"{{if $orientation}} '{{$orientation}}{{/if}})
+#(ly:set-option 'point-and-click #f)
+
 \header { 
-{{if $title}}  title="{{$title}}"
-{{/if}}
-{{if $subtitle}}  subtitle="{{$subtitle}}"
-{{/if}}
-{{if $composer}}  composer="{{$composer}}"
-{{/if}}
-{{if $instrument}}  instrument="{{$instrument}}"
-{{/if}}
-{{if $arranger}}  arranger="{{$arranger}}"
-{{/if}}
-  copyright="Created by Edition Kainhofer, http://www.edition-kainhofer.com/, using LilyPond 2.14"
+  title="{{if $title}}{{$title}}{{/if}}"
+  subtitle="{{if $subtitle}}{{$subtitle}}{{/if}}"
+  composer="{{if $composer}}{{$composer}}{{/if}}"
+  instrument="{{if $instrument}}{{$instrument}}{{/if}}"
+  arranger="{{if $arranger}}{{$arranger}}{{/if}}"
+  tagline = ##f
 }
 \paper {
+  oddHeaderMarkup = ##f
+  evenHeaderMarkup = ##f
+  oddFooterMarkup = \markup \abs-fontsize #8 \with-color #(x11-color 'gray65) \fill-line {
+    \with-url #"http://www.edition-kainhofer.com/" {"Edition Kainhofer"}
+    \with-url #"http://www.lilypond.org/" {"LilyPond - Music typesetting for everyone"}
+  }
   pages={{$pages}}
   systems-per-page={{$systems}}
   ragged-bottom=##f
@@ -23,9 +26,16 @@
   ragged-last=##f
   ragged-right=##f
   #(set-paper-size "{{$paper_size}}"{{if $orientation}} '{{$orientation}}{{/if}})
+  top-system-spacing #'basic-distance = #7
+  top-markup-spacing #'basic-distance = #5
+  last-bottom-spacing #'basic-distance = #10
+  markup-system-spacing #'basic-distance = #15
+
   top-system-spacing #'stretchability = #60
-  top-markup-spacing #'stretchability = #60
+  top-markup-spacing #'stretchability = #40
   last-bottom-spacing #'stretchability = #60
+
+  markup-system-spacing #'stretchability = #60
   system-system-spacing #'stretchability = #40
 {{if $header_space}}  bookTitleMarkup = \markup { \vspace #5 }
 {{/if}}
@@ -35,9 +45,6 @@
   \context { \StaffGroup
     \override SystemStartBracket #'collapse-height = #1
   }
-%   \context { \Score
-%     \override SystemStartBar #'collapse-height = #1
-%   }
   \context { \PianoStaff 
     \override SystemStartBrace #'collapse-height = #1
   }
-- 
GitLab