diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f87924609be4c18d591c480fcd1396a538200efc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+smarty/templates_c/*
+*~
\ No newline at end of file
diff --git a/empty_sheet.php b/empty_sheet.php
index b7688ed4454f0e621638ca1a97ce478e9fb2caee..4a997c69b6f1eb1ce83c881b1aee495d2b93dc70 100644
--- a/empty_sheet.php
+++ b/empty_sheet.php
@@ -1,6 +1,6 @@
 <?php
 
-umask (0644)
+umask (0001);
 $basedir=dirname(__FILE__);
 
 $user = "lilyjail";
@@ -8,14 +8,15 @@ $lilymnt = "/home/lilyjail/lilymnt";
 $lilyhome = "/lilyhome";
 $lilyworkdir = "$lilyhome/empty_sheet";
 
-$ly_cmd = "/usr/bin/sudo /opt/lily2.14/bin/lilypond -j$user,$user,$lilymnt,$lilyhome ";
+$ly_cmd = "/usr/bin/sudo /opt/lily2.14/bin/lilypond -j$user,$user,$lilymnt,$lilyhome --png --pdf -dpixmap-format=pngalpha -dresolution=20 ";
 // print "<p>basedir: $basedir</p>";
 // print "<p>ly_cmd: $ly_cmd</p>";
 
 include('smarty3/Smarty.class.php');
 $smarty = new Smarty();
 
-$smarty->setTemplateDir($basedir.'/smarty/templates');
+// $smarty->setTemplateDir($basedir.'/smarty/templates');
+// $smarty->setTemplateDir($basedir.'/smarty/templates');
 $smarty->setCompileDir($basedir.'/smarty/templates_c');
 $smarty->setCacheDir($basedir.'/smarty/cache');
 $smarty->setConfigDir($basedir.'/smarty/configs');
@@ -23,51 +24,181 @@ $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])) {
+    // remove all problematic characters (\ and "):
+    $val = $_REQUEST[$parm];
+    $val = str_replace ('"', '', $val);
+    $val = str_replace ('\\', '', $val);
+    return $val;
+  } else {
+    return $default;
+  }
+}
+function robust_request_number ($parm, $default, $min, $max) {
+  if (isset ($_REQUEST[$parm]) && is_numeric ($_REQUEST[$parm])) {
+    $val = $_REQUEST[$parm];
+    // Ensure the value is inside the given range:
+    return min (max ($val, $min), $max);
+  } else {
+    return $default;
+  }
+}
 
-//////// Sanity checks for the URL parameters:
-// TODO: Escape all values (i.e. make sure they are within the range, don't contain ", etc.
-$paper_size = $_REQUEST["paper_size"];
-$staff_size = $_REQUEST["staff_size"];
-$systems = $_REQUEST["systems"];
-$pages = $_REQUEST["pages"];
-$title = $_REQUEST["title"];
-$subtitle = $_REQUEST["subtitle"];
-$composer = $_REQUEST["composer"];
-$instrument = $_REQUEST["instrument"];
-$metainfo = $title . $subtitle . $composer . $instrument;
-$metahash = md5( $metainfo );
 
+// Score type: 
+// Syntax: new Staff/Group indicated by capital letter
+// S0, S, Sa, St, S8, Sb ... Staff w/o clef, w/ treble, alto, tenor, treble_8, bass clef
+// Ch2, Ch4 ... Choir staff with 2/4 staves
+// P, O ... Piano / Organ staff
+// Rh ... Rhythmic staff
+// Tab ... Tab staff
+// [...] ... StaffGroup
+// {...} ... GrandStaff
+// (...) ... <<..>>
+
+$known_staff_types = array ("S0", "S", "S8", "Sa", "St", "Sb", "O", "P", "Ch2", "Ch4", "Rh", "Tab");
+$known_group_types = array ("{" => "GrandStaff", "(" => "", "[" => "StaffGroup");
+$known_group_endings = array ("{" => "}", "(" => ")", "[" => "]");
+
+// Get the next entry (single staff or group), will be called recursively.
+// Return (next-elm, remaining), where next-elm is either a string 
+// describing the next staff or an array describing a group (keys "type" and
+// "contents").
+function get_next_group_staff ($remaining)
+{
+  global $known_staff_types;
+  global $known_group_types;
+  global $known_group_endings;
+
+  if (empty($remaining)) {
+    return NULL;
+  }
+  $l = array_shift($remaining);
+  if (in_array ($l, $known_staff_types)) {
+    return array ($l, $remaining);
+  } elseif (isset ($known_group_types[$l])) {
+    $ending = $known_group_endings[$l];
+    $grp["type"] = $known_group_types[$l];
+    $contents = array ();
+    while ($remaining && reset($remaining) != $ending) {
+      list ($elt, $remaining) = get_next_group_staff ($remaining);
+      if ($elt)
+        $contents[] = $elt;
+    }
+    if (reset($remaining) == $ending)
+      array_shift ($remaining);
+    $grp["contents"] = $contents;
+    return array ($grp, $remaining);
+  } elseif (in_array ($l, $known_group_endings)) {
+    // Somehow we missed a closing bracket, or the staff type definition is messed up.
+    return array (NULL, $remaining);
+  } else {
+    die ("Unknown type `$l' in Staff type definition.");
+  }
+  
+}
+
+function parse_score_type ($type) {
+  // First, split the type into its components, i.e. strings of the form 
+  // "Xxxx" or any bracket.
+  $elements = preg_split ("/([{}\[\]\(\)]|[A-Z][a-z0-9]*)/", $type, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+  $result = array();
+  while ($elements) {
+    list ($thiselt, $elements) = get_next_group_staff ($elements);
+    if ($thiselt)
+      $result[] = $thiselt;
+  }
+  return $result;
+}
 
-$score_type=$_REQUEST["score_type"];
 
+//////// Sanity checks for the URL parameters:
+// Escape all values, i.e. make sure they are within the range, don't contain ", etc.
+// $type = strtr (robust_request_string ("score_type", NULL), "{}[]()", "E3LJ");
+$type = robust_request_string ("score_type", NULL);
+
+$psz = explode (" ", robust_request_string ("paper_size", "a4"), 2);
+$paper_size = array_shift ($psz);
+if ($psz) {
+  $orientation = array_shift($psz);
+}
+
+$staff_size = robust_request_number ("staff_size", 20, 3, 100);
+$systems = robust_request_number ("systems", 10, 1, 30);
+$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);
+$instrument = robust_request_string ("instrument", NULL);
+$metainfo = $title . $subtitle . $composer . $instrument;
+$metahash = md5( $metainfo );
 
 //////// Use cache file name composed from the arguments
-$out_file_basename = "Score_${score_type}_${paper_size}_${staff_size}pt_${systems}Systems_${pages}Pages";
+$out_file_basename = "Score_${type}_${paper_size}${orientation}_${staff_size}pt_${systems}Systems_${pages}Pages";
 if ($metainfo != "")
   $out_file_basename .= "_${metahash}";
+  
+// Create file names
+$base_file = $lilyworkdir . "/" . $out_file_basename;
+$ly_file = $base_file . ".ly";
+$pdf_file = $base_file . ".pdf";
+if ($pages > 1) {
+  $png_file = $base_file . "-page1.png";
+} else {
+  $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);
+  }
+} 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);
+  exit (0);
+}
+
+
+
+// Parse the score type:
+if (isset ($_REQUEST["score_type"])) {
+  $score_type = parse_score_type ($_REQUEST["score_type"]);
+} else {
+  $score_type = array ('S0');
+}
+
+
+
 
 /////// Output variables for the template
 $smarty->assign('paper_size', $paper_size);
+$smarty->assign('orientation', $orientation);
 $smarty->assign('staff_size', $staff_size);
 $smarty->assign('systems', $systems);
 $smarty->assign('pages', $pages);
 
-if ($_REQUEST["title_check"])
-  $smarty->assign('title', $title);
-if ($_REQUEST["subtitle_check"])
-  $smarty->assign('subtitle', $subtitle) ;
-if ($_REQUEST["composer_check"]) 
-  $smarty->assign('composer', $composer);
-if ($_REQUEST["instrument_check"])
-  $smarty->assign('instrument', $instrument);
+$smarty->assign('title', $title);
+$smarty->assign('subtitle', $subtitle) ;
+$smarty->assign('composer', $composer);
+$smarty->assign('instrument', $instrument);
 
+$smarty->assign('indent', '');
+$smarty->assign('contents', $score_type);
+
+$smarty->allow_php_tag = true;
 
 //////// Check for the pdf file, create it if needed and return it:
 $lycode = $smarty->fetch('empty_sheet.tpl.ly');
 
-$base_file = $lilyworkdir . "/" . $out_file_basename;
-$ly_file = $base_file . ".ly";
-$pdf_file = $base_file . ".pdf";
 
 if (!file_exists ($pdf_file)) {
   // Create the lilypond file
@@ -79,19 +210,30 @@ if (!file_exists ($pdf_file)) {
 
   // 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";
+  $cmd = "$ly_cmd -o $base_file $ly_file 2>&1";
   $lily_result = exec($cmd, $output, $retval);
 }
 
-if (file_exists ($lilymnt.$pdf_file)) {
+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-Type: application/pdf');
   header('Content-Length: ' . filesize($lilymnt.$pdf_file));
   header('Content-Disposition: inline; filename=' . basename($lilymnt.$pdf_file));
   readfile($lilymnt.$pdf_file);
 } else {
-  die ("Unable to create the score file. Wrong input or server error encountered.");
+  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");
+//   die ("Unable to create the score file. Wrong input or server error encountered.");
 }
 
 ?>
diff --git a/empty_sheet_form.html b/empty_sheet_form.html
index a9894657150d3e6a3205fb18af5f6fbbcfbbebe7..e3b766c4c14d4225536ff938e11cea64fd7c46da 100644
--- a/empty_sheet_form.html
+++ b/empty_sheet_form.html
@@ -1,33 +1,77 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
-  <head>
-<style>
-.vsep {
-  background: darkgray;
-}
+<head>
+  <style>
+    #preview { border: 1px solid black; }
+    .vsep { background: darkgray; }
+    #previewdiv {
+      position: relative;
+    }
+    #loadingOverlay {
+      background-image: url('loading.gif');
+      position: absolute;
+      z-index: 1;
+      top: 40%;
+      left: 35%;
+      width: 32px;
+      height: 32px;
+    }
 
-</style>
-  </head>
-<body>
-  <FORM action="empty_sheet.php" name="score_form">
+  </style>
+  <script type="text/javascript">
+  <!--
+    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";
+      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);
+        }
+      }
+      document.getElementById("preview").src = src;
+    }
+  //-->
+  </script>
+</head>
+<body onLoad="javascript:loadPreview();">
+  <FORM action="empty_sheet.php" name="score_form" onreset="javascript:loadPreview();">
   <table>
   <TR>
     <td><label for="paper_size">Paper size:</label></td>
-    <td><select name="paper_size" id="paper_size">
+    <td><select name="paper_size" id="paper_size" onchange="javascript:loadPreview();">
         <option value="a4" selected="selected">A4</option>
         <option value="a5">A5</option>
         <option value="a6">A6</option>
         <option value="letter">US letter</option>
         <option value="legal">Legal</option>
         <option value="11x17">Ledger</option>
+        <option value="a4 landscape">A4 (landscape)</option>
+        <option value="a5 landscape">A5 (landscape)</option>
+        <option value="a6 landscape">A6 (landscape)</option>
+        <option value="letter landscape">US letter (landscape)</option>
+        <option value="legal landscape">Legal (landscape)</option>
+        <option value="11x17 landscape">Ledger (landscape)</option>
       </select></td>
-    <td rowspan=4 class="vsep"></td>
-    <td><INPUT type="checkbox" name="title_check" size="15" accesskey="t" onchange="document.score_form.title.disabled = !this.checked" id="title_check"><label for="title_check" >Title: </label></td>
-    <td><INPUT type="text" checked name="title" size="25" maxlength="100" id="title" disabled="true"></td>
+    <td rowspan=5 class="vsep"></td>
+    <td rowspan=5 colspan=2 align=center>
+      <div id=previewdiv class="foo">
+        <div id="loadingOverlay"></div>
+        <img id=preview onLoad="javascript:document.getElementById('loadingOverlay').style.visibility = 'hidden';"/>
+      </div>
+    </td>
+
+<!--     <td><INPUT type="checkbox" name="title_check" size="15" accesskey="t" onchange="document.score_form.title.disabled = !this.checked" id="title_check"><label for="title_check" >Title: </label></td> -->
+<!--     <td><INPUT type="text" checked name="title" size="25" maxlength="100" id="title" disabled="true"></td> -->
   </tr>
   <tr>
     <td><label for="staff_size">Staff size:</label></td>
-    <td><select name="staff_size" id="staff_size">
+    <td><select name="staff_size" id="staff_size" onchange="javascript:loadPreview();">
         <option value="11">11pt (Pocket scores)</option>
         <option value="12.5">12.5pt</option>
         <option value="14">14pt</option>
@@ -40,12 +84,12 @@
         <option value="22">22</option>
         <option></option>
       </select></td>
-    <td><INPUT type="checkbox" name="subtitle_check" size="15" accesskey="c" onchange="document.score_form.subtitle.disabled = !this.checked" id="subtitle_check"><label for="subtitle_check" >Subtitle: </label></td>
-    <td><INPUT type="text" checked name="subtitle" size="25" maxlength="100" id="subtitle" disabled="true"></td>
+<!--     <td><INPUT type="checkbox" name="subtitle_check" size="15" accesskey="c" onchange="document.score_form.subtitle.disabled = !this.checked" id="subtitle_check"><label for="subtitle_check" >Subtitle: </label></td> -->
+<!--     <td><INPUT type="text" checked name="subtitle" size="25" maxlength="100" id="subtitle" disabled="true"></td> -->
   </tr>
   <tr>
     <td><label for="systems">Systems/page:</label></td>
-    <td><select name="systems" id="systems">
+    <td><select name="systems" id="systems" onchange="javascript:loadPreview();">
         <option value="1">1</option>
         <option value="2">2</option>
         <option value="3">3</option>
@@ -62,12 +106,12 @@
         <option value="14">14</option>
         <option value="15">15</option>
       </select></td>
-    <td><INPUT type="checkbox" name="composer_check" size="15" accesskey="c" onchange="document.score_form.composer.disabled = !this.checked" id="composer_check"><label for="composer_check" >Composer: </label></td>
-    <td><INPUT type="text" checked name="composer" size="25" maxlength="100" id="composer" disabled="true"></td>
+<!--     <td><INPUT type="checkbox" name="composer_check" size="15" accesskey="c" onchange="document.score_form.composer.disabled = !this.checked" id="composer_check"><label for="composer_check" >Composer: </label></td> -->
+<!--     <td><INPUT type="text" checked name="composer" size="25" maxlength="100" id="composer" disabled="true"></td> -->
   </tr>
   <tr>
     <td><label for="pages">Pages:</label></td>
-    <td><select name="pages" id="pages">
+    <td><select name="pages" id="pages" onchange="javascript:loadPreview();">
         <option value="1">1</option>
         <option value="2" selected="selected">2</option>
         <option value="3">3</option>
@@ -84,8 +128,13 @@
         <option value="14">14</option>
         <option value="15">15</option>
       </select></td>
-    <td><INPUT type="checkbox" name="instrument_check" size="15" accesskey="i" onchange="document.score_form.instrument.disabled = !this.checked" id="instrument_check"><label for="instrument_check" >Instrument: </label></td>
-    <td><INPUT type="text" checked name="instrument" size="25" maxlength="100" id="instrument" disabled="true"></td>
+<!--     <td><INPUT type="checkbox" name="instrument_check" size="15" accesskey="i" onchange="document.score_form.instrument.disabled = !this.checked" id="instrument_check"><label for="instrument_check" >Instrument: </label></td> -->
+<!--     <td><INPUT type="text" checked name="instrument" size="25" maxlength="100" id="instrument" disabled="true"></td> -->
+  </tr>
+  <tr>
+    <td colspan=2>
+      <INPUT type="checkbox" name="header_check" id="header_check"><label for="header_check" >Reserve space for title</label>
+    </td>
   </tr>
 
   <tr><TD colspan=5><hr></TD></tr>
@@ -93,31 +142,31 @@
   <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">
-        <option value="1" selected="selected">Single staff, no clef</option>
-        <option value="2">Single staff, treble clef</option>
-        <option value="3">Single staff, bass clef</option>
-        <option value="4">Single staff, tenor clef</option>
-        <option value="5">Single staff, alto clef</option>
+      <SELECT name="score_type" id="score_type" style='width: 100%' size="20" onchange="javascript:loadPreview();">
+        <option value="S0" selected="selected">Single staff, no clef</option>
+        <option value="S">Single staff, treble clef</option>
+        <option value="Sb">Single staff, bass clef</option>
+        <option value="St">Single staff, tenor clef</option>
+        <option value="Sa">Single staff, alto clef</option>
         <option disabled="disabled">---------</option>
-        <option value="6">Piano staff</option>
-        <option value="7">Organ staff</option>
+        <option value="P">Piano staff</option>
+        <option value="O">Organ staff</option>
         <option disabled="disabled">---------</option>
-        <option value="8">Choir, 2 staves (SA + TB)</option>
-        <option value="9">Choir, 4 staves (S, A, T, B)</option>
+        <option value="Ch2">Choir, 2 staves (SA + TB)</option>
+        <option value="Ch4">Choir, 4 staves (S, A, T, B)</option>
         <option disabled="disabled">---------</option>
-        <option value="10">Piano reduction for choir</option>
-        <option value="11">Piano reduction for single soloist</option>
+        <option value="Ch4P">Piano reduction for choir</option>
+        <option value="S0P">Piano reduction for single soloist</option>
         <option disabled="disabled">---------</option>
-        <option value="12">String Trio</option>
-        <option value="13">String Quartett</option>
-        <option value="14">Piano Trio</option>
-        <option value="15">Piano Quartett</option>
+        <option value="[StSaSb]">String Trio</option>
+        <option value="[StStSaSb]">String Quartett</option>
+        <option value="[StSbP]">Piano Trio</option>
+        <option value="[StSaSbP]">Piano Quartett</option>
         <option disabled="disabled">---------</option>
-        <option value="16">Full Score, Chamber Orchestra</option>
-        <option value="17">Full Score, Symphonic Orchestra</option>
+        <option value="">Full Score, Chamber Orchestra</option>
+        <option value="[SSb][SS][Sb][{SS}SaSb]">Full Score, Symphonic Orchestra</option>
         <option value="18">Full Score, Chamber Orchestra + Choir</option>
-        <option value="19">Full Score, Symphonic Orchestra + Choir</option>
+        <option value="[SSb][SS][Sb][{SS}Sa]Ch4[Sb]">Full Score, Symphonic Orchestra + Choir</option>
       </SELECT>
     </td>
   </tr>
diff --git a/loading.gif b/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b15321949c8f49673463a3cca3d15c1bd5988439
Binary files /dev/null and b/loading.gif differ
diff --git a/templates/Ch2.tpl.ly b/templates/Ch2.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..85a009c74cd24e6f0626039de2673f3137e73a50
--- /dev/null
+++ b/templates/Ch2.tpl.ly
@@ -0,0 +1,4 @@
+{{$indent}}\new ChoirStaff <<
+{{$indent}}  \new Staff \new Voice { \clef "treble" \emptymusic }
+{{$indent}}  \new Staff \new Voice { \clef "bass" \emptymusic }
+{{$indent}}>>
\ No newline at end of file
diff --git a/templates/Ch4.tpl.ly b/templates/Ch4.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..aac65897f05c8846706f342b2208ed0179a4e489
--- /dev/null
+++ b/templates/Ch4.tpl.ly
@@ -0,0 +1,6 @@
+{{$indent}}\new ChoirStaff <<
+{{$indent}}  \new Staff \new Voice { \clef "treble" \emptymusic }
+{{$indent}}  \new Staff \new Voice { \clef "treble" \emptymusic }
+{{$indent}}  \new Staff \new Voice { \clef "treble_8" \emptymusic }
+{{$indent}}  \new Staff \new Voice { \clef "bass" \emptymusic }
+{{$indent}}>>
\ No newline at end of file
diff --git a/templates/Group.tpl.ly b/templates/Group.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..cda959998a052dc82de29b173b194b760c65ce4c
--- /dev/null
+++ b/templates/Group.tpl.ly
@@ -0,0 +1,9 @@
+{{$indent}}{{if $type}}\new {{$type}} {{/if}}<<
+{{foreach $contents as $c}}
+{{if is_array($c)}}
+{{include file='Group.tpl.ly' indent="$indent  " type=$c.type contents=$c.contents}}
+{{else}}
+{{include file="$c.tpl.ly" indent="$indent  "}}
+{{/if}}
+{{/foreach}}
+{{$indent}}>>
diff --git a/templates/O.tpl.ly b/templates/O.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..20026c62092c575b651b72cb34fbac0a76c29d47
--- /dev/null
+++ b/templates/O.tpl.ly
@@ -0,0 +1,4 @@
+{{$indent}}<<
+{{include file='P.tpl.ly' indent="$indent  "}}
+{{$indent}}  \new Staff \new Voice { \clef "bass" \emptymusic }
+{{$indent}}>>
\ No newline at end of file
diff --git a/templates/P.tpl.ly b/templates/P.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..df3fc7b12fb06d813c42ae1dae7e9ba85bb21bdf
--- /dev/null
+++ b/templates/P.tpl.ly
@@ -0,0 +1,4 @@
+{{$indent}}\new PianoStaff <<
+{{$indent}}  \new Staff \new Voice { \clef "treble" \emptymusic }
+{{$indent}}  \new Staff \new Voice { \clef "bass" \emptymusic }
+{{$indent}}>>
\ No newline at end of file
diff --git a/templates/Rh.tpl.ly b/templates/Rh.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..dba2ffc5d59d45282248ab1fcc7e8debd1e00ba1
--- /dev/null
+++ b/templates/Rh.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new RhythmicStaff \new Voice { \emptymusic }
\ No newline at end of file
diff --git a/templates/S.tpl.ly b/templates/S.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..09744580032f460cf764f0751f75c937ec9073ee
--- /dev/null
+++ b/templates/S.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \new Voice { \clef "treble" \emptymusic }
\ No newline at end of file
diff --git a/templates/S0.tpl.ly b/templates/S0.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..a17e9e5fc7f56b2aecb4caf00f406f9247f2f40f
--- /dev/null
+++ b/templates/S0.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \with {\remove "Clef_engraver"} \new Voice { \emptymusic }
\ No newline at end of file
diff --git a/templates/S8.tpl.ly b/templates/S8.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..c7c8b3fbb04d82d88b55f6cca27d8dd3140d7985
--- /dev/null
+++ b/templates/S8.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \new Voice { \clef "treble_8" \emptymusic }
\ No newline at end of file
diff --git a/templates/Sa.tpl.ly b/templates/Sa.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..add01bd7c23a3d02846df6a3dc6734158e0c420d
--- /dev/null
+++ b/templates/Sa.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \new Voice { \clef "alto" \emptymusic }
\ No newline at end of file
diff --git a/templates/Sb.tpl.ly b/templates/Sb.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..e8122974d0bab42268a4ba5df564c4518ad2ed75
--- /dev/null
+++ b/templates/Sb.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \new Voice { \clef "bass" \emptymusic }
\ No newline at end of file
diff --git a/templates/St.tpl.ly b/templates/St.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..e44f56d3714aa479e27a353cc9908a4bd47a9fe3
--- /dev/null
+++ b/templates/St.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new Staff \new Voice { \clef "tenor" \emptymusic }
\ No newline at end of file
diff --git a/templates/Tab.tpl.ly b/templates/Tab.tpl.ly
new file mode 100644
index 0000000000000000000000000000000000000000..9a0e7eb9afcd19acd7cd118bbe31c6aa74876f8a
--- /dev/null
+++ b/templates/Tab.tpl.ly
@@ -0,0 +1 @@
+{{$indent}}\new TabStaff \new TabVoice { \emptymusic }
\ No newline at end of file
diff --git a/empty_sheet.tpl.ly b/templates/empty_sheet.tpl.ly
similarity index 58%
rename from empty_sheet.tpl.ly
rename to templates/empty_sheet.tpl.ly
index 2b0c8de0635e7c1d28fe3f096992df1992150a21..1c364140305aa47932ef13238f0c25b90d9e96df 100644
--- a/empty_sheet.tpl.ly
+++ b/templates/empty_sheet.tpl.ly
@@ -1,7 +1,7 @@
 \version "2.12.3"
 
 #(set-global-staff-size {{$staff_size}})
-#(set-default-paper-size "{{$paper_size}}")
+#(set-default-paper-size "{{$paper_size}}"{{if $orientation}} '{{$orientation}}{{/if}})
 \header { 
 {{if $title}}  title="{{$title}}"
 {{/if}}
@@ -20,27 +20,29 @@
   ragged-last-bottom=##f
   ragged-last=##f
   ragged-right=##f
+  #(set-paper-size "{{$paper_size}}"{{if $orientation}} '{{$orientation}}{{/if}})
+}
+
+\layout {
+  \context { \StaffGroup
+    \override SystemStartBracket #'collapse-height = #1
+  }
+%   \context { \Score
+%     \override SystemStartBar #'collapse-height = #1
+%   }
+  \context { \PianoStaff 
+    \override SystemStartBrace #'collapse-height = #1
+  }
 }
 
 emptymusic = {
   \repeat unfold {{$systems*$pages}} { s1\break }
 }
 
+
 \new Score \with {
   \override TimeSignature #'transparent = ##t
   defaultBarType = #""
   \remove Bar_number_engraver
-} <<
-  \context ChoirStaff <<
-    \context Staff = women <<
-      \context Voice = sopranos { \emptymusic }
-      \context Voice = altos { \emptymusic }
-    >>
-    
-    \context Staff = men <<
-      \clef bass
-      \context Voice = tenors { \voiceOne <<\emptymusic >> }
-      \context Voice = basses { \voiceTwo <<\emptymusic >> }
-    >>
-  >>
->>
+}
+{{include file='Group.tpl.ly' indent='' contents=$contents}}