//
// Programmer:    Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Thu Dec 27 19:33:37 PST 2001
// Last Modified: Wed Jan  2 14:25:02 PST 2002
// Last Modified: Thu Aug 15 12:21:21 PDT 2002 (added V and v marks)
// Filename:      ...sig/examples/all/koto2eps.cpp
// Web Address:   http://sig.sapp.org/examples/museinfo/humdrum/koto2eps.cpp
// Syntax:        C++; museinfo
//
// Description:   Convert Humdrum **koto representation to an EPS format
//                using arabic numerals.
//
// Todo:          
//        add V and v marks
//        add slur marks
//	  add chord marker to left of chord
//	  fix chord accidental: bottom note is getting top note accidental
//        add rotation portrait/landscape
//

#include "humdrum.h"

#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>

#ifndef OLDCPP
   #include <sstream>
   #define SSTREAM stringstream
   #define CSTRING str().c_str()
   using namespace std;
#else
   #ifdef VISUAL
      #include <strstrea.h>    /* for Windows 95 */
   #else
      #include <strstream.h>
   #endif
   #define SSTREAM strstream
   #define CSTRING str()
#endif


class StaffItem {
   public:
           StaffItem(void) { clear(); }
          ~StaffItem() { }
           void clear(void) {
              line = spine = beams = -1;
              hpos = width = height = -1.0;
              textfont = 'T';
              textface = 'R';
              textsize = 12.0;
              textjustify = 'L';
              chord = grace = 0;
              vpos = 0;
               memset(name, '\0', 32);
           }
   char    name[32];       //
   int     line;           // line in humdrum file of item
   int     spine;          // spine on line in humdrum file of item
   char    grace;          // 1 = grace note
   char    chord;          // 1 = grace note
   double  hpos;           // horizontal position of item
   double  vpos;           // horizontal position of item
   double  width;          // horizontal position of item
   double  height;         // horizontal position of item
   int     beams;          // for beaming information
   int     textfont;       // default font for text display (T, H, C)
   int     textface;       // default font for text display (R, I, B)
   double  textsize;       // default font size for text display 
   int     textjustify;    // default text justification for text (C,L,R)
   protected:
};

typedef Array<StaffItem> StaffItemArray;

// function declarations
void   checkOptions(Options& opts, int argc, char* argv[]);
void   example(void);
void   usage(const char* command);
void   storeEpsHeader(SSTREAM& out, int pagecount);
void   storeEpsFooter(SSTREAM& out);
void   generateKotoNotation(HumdrumFile& infile, SSTREAM& out);
void   storePageStart(SSTREAM& out, int pagenum);
void   calculatePageInformation(HumdrumFile& infile, 
                              Array<StaffItemArray>& systems);
void   drawPrintingMargin(SSTREAM& out);
void   setPageSize(const char* sizestring, double& width, 
                              double& height);
double getItemWidth(const char* name, double scaling);
double getItemHeight(const char* name, double scaling);
char   getStringSymbol(const char* string);
void   printSystemInformation(Array<StaffItemArray>& systems);
int    fillSystem(HumdrumFile& infile, int start, 
                              StaffItemArray& sarray, double indent);
double getKotoDuration(const char* kstring);
int    countKotoDots(const char* kstring);
void   writeStaff(SSTREAM& out, StaffItemArray& items, int staff, 
                              int page, HumdrumFile& infile);
void   printItem(SSTREAM& out, StaffItem& item, double vpos,
                              HumdrumFile& infile, StaffItemArray& items,
                              int iline);
void   storeSymbols(SSTREAM& out);
void   printTechniques(SSTREAM& out, StaffItem& item, double vpos, 
                              HumdrumFile& infile);
int    getSharpCount(const char* string);
int    getBeamCount(const char* string);
void   printBeaming(SSTREAM& out, StaffItem& item, double vpos, 
                              HumdrumFile& infile, StaffItemArray& items,
                              int iline);
void   appendSpace(StaffItemArray& sarray, StaffItem& spaceitem);
void   printTitleInformation(SSTREAM& out, HumdrumFile& infile);
int    endOfBeat(HumdrumFile& infile, int line);
int    endOfBeat2(HumdrumFile& infile, int line);
double adjustwidth(HumdrumFile& infile, StaffItemArray& items, 
                              int iline, int level);
void   processComment(const char* cstring, StaffItem& textitem, 
                              StaffItemArray& sarray, int line, int spine,
                              double& totalwidth);
void   printChord(HumdrumFile& infile, StaffItem& item, 
                              SSTREAM& out, double vpos);
void   processColor(const char* cstring, StaffItemArray& sarray, 
                              double hpos);
char   hexdigit(int number, int digit);
void   printColor(SSTREAM& out, const char* cstring, 
                              StaffItem& item, double lmargin, double vpos);
void   printText(SSTREAM& out, StaffItem& item, double vpos, 
                              HumdrumFile& infile);
const char* getTuningInfo(HumdrumFile& infile);
void  printTuningInfo(SSTREAM& out, const char* tuning);

// global variables
Options      options;            // database for command-line arguments
int          staffperpage = 8;   // max number of staves per page
int          debugQ = 0;         // for debugging lines;
int          pagecountQ = 0;     // for printing out the number of pages only
double       beambase = 10.5;    // base line for lowest beam (8th note)
double       beamsep = 0.70;     // distance between beams lines
double       beamthick = 0.35;   // thickness of beams
double       beatspace = 1.0;    // number of spaces between beats
double       pagewidth = 612.0;  // width of the page (8.5" by default)
double       pageheight = 792.0; // height of the page (11" by default)
double       lmargin = 54.0;     // left margin (0.75" by default)
double       rmargin = 54.0;     // right margin (0.75" by default)
double       bmargin = 72.0;     // bottom margin (1" by default)
double       tmargin = 108.0;    // top margin (1.5" by default)
double       indentfirst = 18.0; // indent length for first system
double       scaling = 1.25;     // scaling of items on staff
int          measurenumQ = 0;    // for measure number display
char         titlestring[1024] = {0};
char         composerstring[1024] = {0};
char         composerdatestring[1024] = {0};
int          verbosetitleQ = 1;  // for displaying title at bottom of pages
int          colorQ = 1;         // for -C option
int          textQ = 1;          // for -X option
int          justifyQ = 1;       // for -J option
const char*  tuning = "";        // for printing tuning specification

// font control variables

int          textfont = 'T';     // default font for text display (T, H, C)
int          textface = 'R';     // default font for text display (R, I, B)
double       textsize = 12.0;    // default font size for text display 
int          textjustify = 'L';  // default text justification for text (C,L,R)

///////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[]) {
   checkOptions(options, argc, argv);   // process the command-line options

   HumdrumFile infile;

   if (options.getArgCount() < 1) {
      infile.read(cin);
   } else {
      infile.read(options.getArg(1));
   }
   infile.analyzeRhythm();

   tuning = getTuningInfo(infile);

   SSTREAM epsoutput;
   generateKotoNotation(infile, epsoutput);
   epsoutput << ends;
   cout << epsoutput.str();

   return 0;
}


///////////////////////////////////////////////////////////////////////////


//////////////////////////////
//
// getTuningInfo -- read the first !!!tune: record in the file.
//

const char* getTuningInfo(HumdrumFile& infile) {
   int i;
   const char* ptr = "";
   for (i=0; i<infile.getNumLines(); i++) {
      if (infile[i].getType() == E_humrec_bibliography) {
         if (strncmp(infile[i][0], "!!!tune:", 8) == 0) {
            ptr = &(infile[i][0][8]);
            break;
         }
      }
   }
   i = 0;
   while (ptr[i] == ' ' || ptr[i] == '\t') {
      i++;
   }
   return ptr + i;
}



//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//

void checkOptions(Options& opts, int argc, char* argv[]) {
   opts.define("a|append=b",        "append analysis to data in output");   

   opts.define("debug=b",  "trace input parsing");   
   opts.define("J|no-justify=b",    "don't justify music");

   opts.define("author=b",  "author of the program");   
   opts.define("version=b", "compilation information"); 
   opts.define("example=b", "example usage"); 
   opts.define("h|help=b",  "short description"); 
  
   opts.define("pagecount=b",              "print number of pages only");

   // style options
   opts.define("M|measure-numbers=b",      "for suppressing measure numbers");
   opts.define("T|no-title-footer=b",      "suppress title at bottom of page");
   opts.define("C|ignore-color=b",         "suppress coloration markings");
   opts.define("X|ignore-text=b",          "suppress coloration markings");

   // spacing information
   opts.define("staffperpage=i:8",         "number of staves per page");
   opts.define("bs|beatspace=d:1.0",       "spaces between beats");
   opts.define("s|scale|scaling=d:1.25",   "scaling size of items in score");
   opts.define("i|indent=s:0.25 in",       "first system indentation");

   // beam information
   opts.define("base|beambase=d:10.5",     "base line for lowest beam");
   opts.define("sep|beamsep=d:0.7",        "distance between beam lines");
   opts.define("thick|beamthick=d:0.35",   "thickness of beams");

   // page size information
   opts.define("p|pagesize=s:8.5x11.0 in", "size of paper wxh");
   opts.define("l|leftmargin=s:0.75 in",   "page margin on left");
   opts.define("r|rightmargin=s:0.75 in",  "page margin on right");
   opts.define("t|topmargin=s:1.5 in",     "page margin on top");
   opts.define("b|bottommargin=s:1.0 in",  "page margin on bottom");

   opts.process(argc, argv);
   
   // handle basic options:
   if (opts.getBoolean("author")) {
      cout << "Written by Craig Stuart Sapp, "
           << "craig@ccrma.stanford.edu, Dec 2001" << endl;
      exit(0);
   } else if (opts.getBoolean("version")) {
      cout << argv[0] << ", version: 15 Aug 2001" << endl;
      cout << "compiled: " << __DATE__ << endl;
      cout << MUSEINFO_VERSION << endl;
      exit(0);
   } else if (opts.getBoolean("help")) {
      usage(opts.getCommand());
      exit(0);
   } else if (opts.getBoolean("example")) {
      example();
      exit(0);
   }

   staffperpage =  opts.getInt("staffperpage");
   debugQ       =  opts.getBoolean("debug");
   justifyQ     = !opts.getBoolean("no-justify");
   pagecountQ   =  opts.getBoolean("pagecount");
   beambase     =  opts.getDouble("beambase");
   beamsep      =  opts.getDouble("beamsep");
   beamthick    =  opts.getDouble("beamthick");
   beatspace    =  opts.getDouble("beatspace");

   measurenumQ = !opts.getBoolean("measure-numbers");
   colorQ      = !opts.getBoolean("ignore-color");
   textQ       = !opts.getBoolean("ignore-text");
   verbosetitleQ = !opts.getBoolean("no-title-footer");
   scaling = opts.getDouble("scaling");
   setPageSize(opts.getString("pagesize"), pagewidth, pageheight);

   indentfirst = opts.getDouble("indent");
   if (strstr(opts.getString("indent"), "in") != NULL) {
      indentfirst = indentfirst * 72.0;
   } else if (strstr(opts.getString("indent"), "cm") != NULL) {
      indentfirst = indentfirst / 2.54 * 72.0;
   } else if (strstr(opts.getString("indent"), "mm") != NULL) {
      indentfirst = indentfirst / 25.4 * 72.0;
   }

   lmargin = opts.getDouble("leftmargin");
   if (strstr(opts.getString("leftmargin"), "in") != NULL) {
      lmargin = lmargin * 72.0;
   } else if (strstr(opts.getString("leftmargin"), "cm") != NULL) {
      lmargin = lmargin / 2.54 * 72.0;
   } else if (strstr(opts.getString("leftmargin"), "mm") != NULL) {
      lmargin = lmargin / 25.4 * 72.0;
   }

   rmargin = opts.getDouble("rightmargin");
   if (strstr(opts.getString("rightmargin"), "in") != NULL) {
      rmargin = rmargin * 72.0;
   } else if (strstr(opts.getString("rightmargin"), "cm") != NULL) {
      rmargin = rmargin / 2.54 * 72.0;
   } else if (strstr(opts.getString("rightmargin"), "mm") != NULL) {
      rmargin = rmargin / 25.4 * 72.0;
   }

   tmargin = opts.getDouble("topmargin");
   if (strstr(opts.getString("topmargin"), "in") != NULL) {
      tmargin = tmargin * 72.0;
   } else if (strstr(opts.getString("topmargin"), "cm") != NULL) {
      tmargin = tmargin / 2.54 * 72.0;
   } else if (strstr(opts.getString("topmargin"), "mm") != NULL) {
      tmargin = tmargin / 25.4 * 72.0;
   }

   bmargin = opts.getDouble("bottommargin");
   if (strstr(opts.getString("bottommargin"), "in") != NULL) {
      bmargin = bmargin * 72.0;
   } else if (strstr(opts.getString("bottommargin"), "cm") != NULL) {
      bmargin = bmargin / 2.54 * 72.0;
   } else if (strstr(opts.getString("bottommargin"), "mm") != NULL) {
      bmargin = bmargin / 25.4 * 72.0;
   }

}



//////////////////////////////
//
// setPageSize -- read the option string for setting the page size.
//

void setPageSize(const char* sizestring, double& width, double& height) {
   int count = sscanf(sizestring, "%lfx%lf", &width, &height);
   if (count != 2) {
      return;
   }

   if (strstr(sizestring, "in") != NULL) {
      width  *= 72.0;   
      height *= 72.0;   
   } else if (strstr(sizestring, "cm") != NULL) {
      width  = width  / 2.54 * 72.0;   
      height = height / 2.54 * 72.0;   
   } else if (strstr(sizestring, "mm") != NULL) {
      width  = width  / 25.4 * 72.0;   
      height = height / 25.2 * 72.0;   
   }
}



//////////////////////////////
//
// drawPrintingMargin -- print the bounding box for the printing region
//

void drawPrintingMargin(SSTREAM& out) {
   out << " 0.0 w \n";
   out << " 1 0 0 setrgbcolor \n";
   out << lmargin << " " << bmargin << " m \n";
   out << lmargin << " " << pageheight - tmargin << " l \n";
   out << pagewidth - rmargin << " " << pageheight - tmargin << " l \n";
   out << pagewidth - rmargin << " " << bmargin << "  l \n";
   out << lmargin << " " << bmargin << " l \n";
   out << " closepath \n stroke \n";
}



//////////////////////////////
//
// generateKotoNotation --
//

void generateKotoNotation(HumdrumFile& infile, SSTREAM& out) {
   Array<StaffItemArray> systems;  
   systems.setSize(1000);
   systems.setSize(0);

   calculatePageInformation(infile, systems);

   int systemcount = systems.getSize();
   int pagecount = (int)((1.0 * systemcount) / staffperpage + 0.99999);
   int sys = 0;

   storeEpsHeader(out, pagecount);
   int i, j;
   for (i=0; i<pagecount; i++) {
      storePageStart(out, i+1);
      for (j=0; j<staffperpage; j++) {
         sys++;
         if (sys <= systemcount) {
            writeStaff(out, systems[i * staffperpage + j], j, i+1, infile);
         } else {
            break;
         }
      }
      out << " showpage \n";
   }
   storeEpsFooter(out);

//   for (i=0; i<systems.getSize(); i++) {
//      systems[i].setSize(0);
//   }
//   systems.setSize(0);
}



///////////////////////////////
//
// writeStaff --
//

void writeStaff(SSTREAM& out, StaffItemArray& items, int staff, int page, 
      HumdrumFile& infile) {
   int i;
   double height = pageheight - tmargin - bmargin;
   double spacer = height / staffperpage;
   double vpos   = (staffperpage - staff - 0.5) * spacer + bmargin;

   out << "% page = " << page << "\tstaff = " << staff+1 << "\n";
   if (page > 1 && staff == 0) {
      out << "\t" << 16 << "\t(" << page << ")" << "\t\t\t\tpagenumber\n";
      if (verbosetitleQ) {
         out << "\t" << 8 << "\t"
             << "(\\(" << titlestring << "\\))\t\ttitlefooter\n";
      }
   } else if (page == 1 && staff == 0) {
      printTitleInformation(out, infile);
      if (strcmp(tuning, "") != 0) {
         printTuningInfo(out, tuning);
      }
   }
   for (i=0; i<items.getSize(); i++) {
      printItem(out, items[i], vpos, infile, items, i);
   }
   out << "\n";
}



//////////////////////////////
//
// printTuningInformation --
//

void printTuningInfo(SSTREAM& out, const char* tuning) {
   int length = strlen(tuning);
   if (length > 0) {
      out << "\t" << 12 << "\t(" << tuning << ")"
          << "\t\t\ttuning\n";
   }
}



//////////////////////////////
//
// printTitleInformation --
//

void printTitleInformation(SSTREAM& out, HumdrumFile& infile) {
   int i;
   int j;

   for (i=0; i<infile.getNumLines(); i++) {
      if (infile[i].getType() == E_humrec_bibliography) {
         if (strncmp(infile[i][0], "!!!OTL", 6) == 0) {
            j = 6;
            while (infile[i][0][j] != '\0' && infile[i][0][j] != ':') {
               j++;
            }
            if (infile[i][0][j] == '\0') {
               break;
            }
            j++;   // skip over ':'
            while (infile[i][0][j] != '\0' && infile[i][0][j] == ' ') {
               j++;
            }
            strcpy(titlestring, &(infile[i][0][j]));
            break;
         }
      }
   }

   for (i=0; i<infile.getNumLines(); i++) {
      if (infile[i].getType() == E_humrec_bibliography) {
         if (strncmp(infile[i][0], "!!!COM", 6) == 0) {
            j = 6;
            while (infile[i][0][j] != '\0' && infile[i][0][j] != ':') {
               j++;
            }
            if (infile[i][0][j] == '\0') {
               break;
            }
            j++;   // skip over ':'
            while (infile[i][0][j] != '\0' && infile[i][0][j] == ' ') {
               j++;
            }
            strcpy(composerstring, &(infile[i][0][j]));
            break;
         }
      }
   }

   for (i=0; i<infile.getNumLines(); i++) {
      if (infile[i].getType() == E_humrec_bibliography) {
         if (strncmp(infile[i][0], "!!!CDT", 6) == 0) {
            j = 6;
            while (infile[i][0][j] != '\0' && infile[i][0][j] != ':') {
               j++;
            }
            if (infile[i][0][j] == '\0') {
               break;
            }
            j++;   // skip over ':'
            while (infile[i][0][j] != '\0' && infile[i][0][j] == ' ') {
               j++;
            }
            int byear = 0;
            int dyear = 0;
            int count = sscanf(infile[i][0], "!!!CDT: %d///-%d///", 
                  &byear, &dyear);
            if (count == 2) {
               sprintf(composerdatestring, "\\(%d\\261%d\\)", byear, dyear);
            }
            break;
         }
      }
   }



   int length = strlen(titlestring);
   if (length > 0) {
      out << "\t" << 18 << "\t(" << titlestring << ")\t\t\ttitle\n";
   }

   length = strlen(composerstring);
   if (length > 0) {
      out << "\t" << 12 << "\t(" << composerstring 
          << ")\t(" << composerdatestring << ")"
          << "\tcomposer\n";
   }

}



//////////////////////////////
//
// printItem --
//

void printItem(SSTREAM& out, StaffItem& item, double vpos, 
      HumdrumFile& infile, StaffItemArray& items, int iline) {
   if (strcmp(item.name, "doublebar") == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t"
          << scaling << "\t\t\t" << "doublebar" << "\n";
   } else if (strcmp(item.name, "finalbar") == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t"
          << scaling << "\t\t\t" << "fbar" << "\n";
   } else if (strstr(item.name, "bar") != NULL) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
          << scaling << "\t\t\t" << item.name << "\n";

   } else if (strlen(item.name) == 1 && item.name[0] - '0' < 10 &&
         item.name[0] - '0' >= 0) {
      if (item.chord) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos - 0.5 * item.height << "\t" 
             << scaling << "\t\t\t" << "string" << item.name << "\n";
      } else if (item.grace) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos + 8.0 * scaling << "\t" << scaling * 0.65
             << "\t\t\t" << "string" << item.name << "\n";

      } else {
         out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
             << scaling << "\t\t\t" << "string" << item.name << "\n";
      }
      if (textQ) {
         printText(out, item, vpos, infile);
      }
      printTechniques(out, item, vpos, infile);
      printBeaming(out, item, vpos, infile, items, iline);
      if (strchr(infile[item.line][0], ' ') != NULL) {
         printChord(infile, item, out, vpos);
      }

   } else if (strlen(item.name) == 1 && item.name[0] - 'A' < 4 &&
         item.name[0] - 'A' >= 0) {
      int digit = 10 + item.name[0] - 'A';
      if (item.chord) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos - 0.5 * item.height << "\t" 
             << scaling << "\t\t\t" << "string" << digit << "\n";
      } else if (item.grace) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos + 8.0 * scaling << "\t" << scaling * 0.65
             << "\t\t\t" << "string" << digit << "\n";
      } else {
         out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
             << scaling << "\t\t\t" << "string" << digit << "\n";
      }
      if (textQ) {
         printText(out, item, vpos, infile);
      }
      printTechniques(out, item, vpos, infile);
      printBeaming(out, item, vpos, infile, items, iline);
      if (strchr(infile[item.line][0], ' ') != NULL) {
         printChord(infile, item, out, vpos);
      }

   } else if (strcmp(item.name, "W") == 0) {
      if (item.chord) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos - 0.5 * item.height << "\t" 
             << scaling << "\t\t\t" << "wa" << "\n";
      } else if (item.grace) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos + 8.0 * scaling << "\t" << scaling * 0.65
             << "\t\t\t" << "wa" << "\n";
      } else {
         out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
             << scaling << "\t\t\t" << "wa" << "\n";
      }
      if (textQ) {
         printText(out, item, vpos, infile);
      }
      printTechniques(out, item, vpos, infile);
      printBeaming(out, item, vpos, infile, items, iline);
      if (strchr(infile[item.line][0], ' ') != NULL) {
         printChord(infile, item, out, vpos);
      }

   } else if (strcmp(item.name, "Z") == 0) {
      if (item.chord) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos - 0.5 * item.height << "\t" 
             << scaling << "\t\t\t" << "Zu" << "\n";
      } else if (item.grace) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos + 8.0 * scaling << "\t" << scaling * 0.65
             << "\t\t\t" << "Zu" << "\n";
      } else {
         out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
             << scaling << "\t\t\t" << "Zu" << "\n";
      }
      if (textQ) {
         printText(out, item, vpos, infile);
      }
      printTechniques(out, item, vpos, infile);
      printBeaming(out, item, vpos, infile, items, iline);
      if (strchr(infile[item.line][0], ' ') != NULL) {
         printChord(infile, item, out, vpos);
      }

   } else if (strcmp(item.name, "z") == 0) {
      if (item.chord) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos - 0.5 * item.height << "\t" 
             << scaling << "\t\t\t" << "zu" << "\n";
      } else if (item.grace) {
         out << "\t" << item.hpos + lmargin << "\t" 
             << vpos + 8.0 * scaling << "\t" << scaling * 0.65
             << "\t\t\t" << "zu" << "\n";
      } else {
         out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
             << scaling << "\t\t\t" << "zu" << "\n";
      }
      if (textQ) {
         printText(out, item, vpos, infile);
      }
      printTechniques(out, item, vpos, infile);
      printBeaming(out, item, vpos, infile, items, iline);
      if (strchr(infile[item.line][0], ' ') != NULL) {
         printChord(infile, item, out, vpos);
      }

   } else if (strlen(item.name) == 1 && item.name[0] == '-') {
      out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t" 
          << scaling << "\t\t\t" << "dash\n";
   } else if (strcmp(item.name, " ") == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos << "\t"
          << item.width << "\t\t\t" << "spacer\n";
   } else if (strncmp(item.name, "measno=", 7) == 0) {
      int barno = 0;
      int count = sscanf(item.name, "measno=%d", &barno);
      if (count == 1) {
         out << "\t" << item.hpos + lmargin + 
                getItemWidth("sbar", scaling) * 0.5
             << "\t" << vpos + getItemHeight("sbar", scaling) +
                 6 * scaling
             << "\t" << 10 * scaling
             << "\t(" << barno << ")\t\tbarnum\n";
      }
   } else if (strcmp(item.name, "augdot") == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos 
          << "\t" << scaling << "\t\t\taugdot\n";
   } else if (strcmp(item.name, "sha") == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos 
          << "\t" << scaling << "\t\t\tsha\n";
   } else if (strncmp(item.name, "color=", 6) == 0) {
      printColor(out, &item.name[6], item, lmargin, vpos);
   } else if (strncmp(item.name, "text", 4) == 0) {
      out << "\t" << item.hpos + lmargin << "\t" << vpos + 25 * scaling
          << "\t" << scaling << "\t"; 
      switch (item.textfont) {
         case 'C':           out << "/Courier";     break;
         case 'H':           out << "/Helvetica";   break;
         case 'T':   
         default:        out << "/Times-Roman"; break;
      }
      out << "\t" << item.textsize;
      out << "\t(" << &infile[item.line][0][5] << ")";
      out << "\t" << item.name << "\n";
   } else if (strcmp(item.name, "indent") == 0) {
      // ignore code
   } else {
      out << "% unknown item : \"" << item.name << "\"\n";
   }

}




//////////////////////////////
//
// printText -- print lyrics
//

void printText(SSTREAM& out, StaffItem& item, double vpos, 
      HumdrumFile& infile) {
   int line = item.line;
   int spine = item.spine;

   int spinecount = infile[line].getFieldCount();
   int i = spine + 1;
   int verse = 1;
   while ((i<spinecount) && 
            ((strcmp(infile[line].getExInterp(i), "**text") == 0) ||
            (strcmp(infile[line].getExInterp(i), "**silbe") == 0)) ) {
      if (strcmp(infile[line][i], ".") != 0) {
         out << "\t"  << lmargin + item.hpos + item.width / 2.0
             << "\t"  << vpos
             << "\t"  << scaling
             << "\t(" << infile[line][i] << ")"
             << "\t"  << verse
             << "\t"  << 0			// justification = center
             << "\t"  << "verse\n";
      } 
      verse++;
      i++;
   }

}



//////////////////////////////
//
// printColor --
//

void printColor(SSTREAM& out, const char* cstring, StaffItem& item, 
      double lmargin, double vpos) {

   char buffer[7] = {0};
   strncpy(buffer, cstring, 6);

   double blue  = strtol(&buffer[4], NULL, 16) / 255.0;
   buffer[4] = '\0';
   double green = strtol(&buffer[2], NULL, 16) / 255.0;
   buffer[2] = '\0';
   double red   = strtol(buffer, NULL, 16) / 255.0;

   out << "\t" << red << "\t" << green << "\t" << blue << "\t\t\tsetcolor\n";
}



//////////////////////////////
//
// printChord --
//

void printChord(HumdrumFile& infile, StaffItem& item, SSTREAM& out, 
      double vpos) {
   const char* note2 = strchr(infile[item.line][0], ' ');
   if (note2 == NULL) {
      return;
   }

   char string = getStringSymbol(note2);
   int stringnum = 0;
   char strnum[2] = {0};
   strnum[0] = string;

   if (isdigit(string)) {
      stringnum = string - '0';
   } else {
      stringnum = string - 'A' + 10;
   }
      
   out << "\t" << item.hpos + lmargin - 
                         (getItemWidth(strnum, scaling)-item.width)/2.0 << "\t" 
       << vpos + item.height / 2.0 + 1.0 * scaling 
       << "\t" << scaling << "\t\t\t" << "string" << stringnum << "\n";
}



//////////////////////////////
//
// printBeaming -- printing of beams
//

void printBeaming(SSTREAM& out, StaffItem& item, double vpos, 
      HumdrumFile& infile, StaffItemArray& items, int iline) {

   double bheight = 1.5;         // height of beams
   double bspace  = 1.0;         // spacing between beams
   int graceQ = item.grace;

   int level = item.beams;
   double newwidth = 0.0;
   double newvpos = 0.0;
   int i;

   for (i=0; i<level; i++) {
      newwidth = adjustwidth(infile, items, iline, i+1); 
      if (graceQ) {
         newvpos = vpos + 8.0 * scaling - bspace * (i+1) * scaling * 0.65 - 
               bheight * i * scaling * 0.65;
      } else {
         newvpos = vpos - bspace * (i+1) * scaling - bheight * i * scaling;
      }
      out << "\t" << item.hpos + lmargin;     // horizontal position
      out << "\t" << newvpos;                 // vertical position
      out << "\t" << newwidth;                // width
      out << "\t" << level;                   // number of lines in beaming
      if (graceQ) {
         out << "\t" << scaling * 0.65;       // size scaling
      } else {
         out << "\t" << scaling;              // size scaling
      }
      out << "\tbeam\n";
   }


   // process fingerings

   double offset = item.width / 2.0;
   if (strchr(infile[item.line][item.spine], '1') != NULL) {
      offset += item.width * 0.30;
   }
   if (strchr(infile[item.line][item.spine], 'a') != NULL) {
      out << "\t" << item.hpos + lmargin;       // hpos
      out << "\t" << vpos;                      // vpos
      out << "\t" << offset;                    // offset
      out << "\t" << level;                     // beaming level
      out << "\t" << scaling;                   // scaling
      out << "\t(1)";                           // fingering
      out << "\tfinger\n";
   } else if (strchr(infile[item.line][item.spine], 'b') != NULL) {
      out << "\t" << item.hpos + lmargin;       // hpos
      out << "\t" << vpos;                      // vpos
      out << "\t" << offset;                    // offset
      out << "\t" << level;                     // beaming level
      out << "\t" << scaling;                   // scaling
      out << "\t(2)";                           // fingering
      out << "\tfinger\n";
   } else if (strchr(infile[item.line][item.spine], 'c') != NULL) {
      out << "\t" << item.hpos + lmargin;       // hpos
      out << "\t" << vpos;                      // vpos
      out << "\t" << offset;                    // offset
      out << "\t" << level;                     // beaming level
      out << "\t" << scaling;                   // scaling
      out << "\t(3)";                           // fingering
      out << "\tfinger\n";
   } else if (strchr(infile[item.line][item.spine], 'd') != NULL) {
      out << "\t" << item.hpos + lmargin;       // hpos
      out << "\t" << vpos;                      // vpos
      out << "\t" << offset;                    // offset
      out << "\t" << level;                     // beaming level
      out << "\t" << scaling;                   // scaling
      out << "\t(4)";                           // fingering
      out << "\tfinger\n";
   }

}



//////////////////////////////
//
// adjustwidth -- extend beams if necessary
//

double adjustwidth(HumdrumFile& infile, StaffItemArray& items, int iline, 
      int level) {
   int nextitem = iline + 1;
   while (nextitem < items.getSize() && 
      (strcmp(items[nextitem].name, "sha") == 0 ||
       strcmp(items[nextitem].name, "augdot") == 0 ||
       strncmp(items[nextitem].name, "color", 5) == 0 ||
       strcmp(items[nextitem].name, " ") == 0)) {
      nextitem++;
   }

   if(items[iline].grace == 1 && items[nextitem].grace != 1) {
      return items[iline].width;
   }

   // end of the line, so don't extend beam
   if (nextitem >= items.getSize()) {
      return items[iline].width;
   }

   // some unknown object or a barline
   if (strlen(items[nextitem].name) != 1) {
      return items[iline].width;
   }


   // if at a beat boundary, do not extend beam
   int boundary = endOfBeat2(infile, items[iline].line);
   if (boundary) {
      return items[iline].width;
   }

   // now at a point where the beams continues to part of same beat.
   // decide to continue or not 
   int nextbeamlevel = items[nextitem].beams;

   if (level > nextbeamlevel) {
      return items[iline].width;
   }

 
   int i;
   double returnwidth = items[iline].width;
   for (i=iline + 1; i<nextitem; i++) {
      returnwidth += items[i].width;
   }


   return returnwidth;
}



//////////////////////////////
//
// printTechniques --
//

void printTechniques(SSTREAM& out, StaffItem& item, double vpos, 
      HumdrumFile& infile) {
   char buffer[128] = {0};
   infile[item.line].getToken(buffer, item.spine, 0);

   int sharpcount = getSharpCount(buffer);
   double hposbase = item.hpos + lmargin + item.width / 2.0;
   double vposbase = vpos + item.height + 1.0 * scaling;
   if (item.chord) {
      vposbase = vposbase - item.height/2.0;
   } 

   switch (sharpcount) {
      case 3:
         out << "\t" << hposbase - getItemWidth("triplesharp", scaling)/2.0;
         out << "\t" << vposbase;
         out << "\t" << scaling;
         out << "\t\t\ttriplesharp\n";
         break;
      case 2:
         out << "\t" << hposbase - getItemWidth("doublesharp", scaling)/2.0;
         out << "\t" << vposbase;
         out << "\t" << scaling;
         out << "\t\t\tdoublesharp\n";
         break;
      case 1:
         out << "\t" << hposbase - getItemWidth("sharp", scaling)/2.0;
         out << "\t" << vposbase;
         out << "\t" << scaling;
         out << "\t\t\tsharp\n";
         break;
      default:
         break;
   }


   if (strchr(buffer, 'o') != NULL) {
      out << "\t" << item.hpos + lmargin + item.width / 2.0 -
             getItemWidth("oshi", scaling)/2.0;
      out << "\t" << vpos + getItemHeight(item.name, scaling)+1.0 * scaling;
      out << "\t" << scaling;
      out << "\t\t\toshi\n";
   } else if (strchr(buffer, 'r') != NULL) {
      out << "\t" << item.hpos + lmargin + item.width / 2.0 -
             getItemWidth("oshith", scaling)/2.0;
      out << "\t" << vpos + getItemHeight(item.name, scaling)+1.0 * scaling;
      out << "\t" << scaling;
      out << "\t\t\toshith\n";
   } else if (strchr(buffer, 'i') != NULL) {
      out << "\t" << item.hpos + lmargin + item.width / 2.0 -
             getItemWidth("hiki", scaling)/2.0;
      out << "\t" << vpos + getItemHeight(item.name, scaling)+1.0 * scaling;
      out << "\t" << scaling;
      out << "\t\t\thiki\n";
   } else if (strchr(buffer, 'v') != NULL) {
      out << "%\t" << item.hpos + lmargin + item.width / 2.0 -
             getItemWidth("vrepeat", scaling)/2.0;
      out << "\t" << vpos + getItemHeight(item.name, scaling)+1.0 * scaling;
      out << "\t" << scaling;
      out << "\t\t\tvrepeat\n";
      
   }

}




//////////////////////////////
//
// getSharpCount -- count the number of sharps in the string
//

int getSharpCount(const char* string) {
   int length = strlen(string);
   int i;
   int count = 0;
   for (i=0; i<length; i++) {
      if (string[i] == '#') {
         count++;
      }
   }
   return count;
}



//////////////////////////////
//
// getBeamCount -- 
//

int getBeamCount(const char* string) {
   int length = strlen(string);
   int i;
   int count = 0;
   for (i=0; i<length; i++) {
      if (string[i] == '|') {
         count++;
      }
   }
   return count;
}




//////////////////////////////
//
// calculatePageInformation -- assign page, system and positions to data.
//

void calculatePageInformation(HumdrumFile& infile, 
      Array<StaffItemArray>& systems) {

   int i = 0;
   StaffItemArray temparray;
   int staff = 0;
   while (i < infile.getNumLines()) {
      temparray.setSize(0);
      if (staff == 0) { 
         i = fillSystem(infile, i, temparray, indentfirst);
      } else {
         i = fillSystem(infile, i, temparray, 0.0);
      }
      staff++;
      if (temparray.getSize() > 3) {
         systems.append(temparray);
      }
   }


   // printSystemInformation(systems);

}



//////////////////////////////
//
// printSystemInformation --
//

void printSystemInformation(Array& systems) {
   int i, j;
   for (i=0; i<systems.getSize(); i++) {
      for (j=0; j<systems[i].getSize(); j++) {
         cout << "SYSTEM " << i << "\t";
         cout << systems[i][j].name;
         cout << "\thpos = " << systems[i][j].hpos << endl;
        
      }
   }
}



//////////////////////////////
//
// fillSystem -- position data on staff line
//

int fillSystem(HumdrumFile& infile, int start, StaffItemArray& sarray, 
   double indent) {

   double totalwidth = indent;
   double targetwidth = pagewidth - lmargin - rmargin;

   StaffItem textitem;
   StaffItem shaitem;
   StaffItem spaceitem;
   spaceitem.hpos = -1;
   strcpy(spaceitem.name, " ");
   spaceitem.width = 0;

   // add the starting system staff
   StaffItem tempitem;

   if (indent > 0.0) {
      tempitem.hpos = 0;
      strcpy(tempitem.name, "indent");
      tempitem.width = indent;
      sarray.append(tempitem);
   }

   tempitem.hpos = indent;

   tempitem.clear();
   int measureno = 0;
   int count = 0;
   if (indent == 0.0 && measurenumQ) {
      count = sscanf (infile[start][0], "=%d", &measureno);
      if (count == 1) {
         sprintf(tempitem.name, "measno=%d", measureno);
         tempitem.hpos = indent;
         tempitem.width = 0;
         sarray.append(tempitem);
      }
   }

   strcpy(tempitem.name, "sbar");
   tempitem.width = getItemWidth("sbar", scaling);
   sarray.append(tempitem);
   spaceitem.width = tempitem.width * 1.5;
   spaceitem.hpos = totalwidth;
   totalwidth += spaceitem.width;
   appendSpace(sarray, spaceitem);

   double stretchfactor = 1.0;
   double lastbpos;
   double currentpos;
   char notebuffer[128] = {0};

   int datafoundQ = 0;      // suppress the first barline 
   int chordQ = 0;
   int n;
   int lastmeasure = 0;     // storage location for previous measure if too far
   int lastlastmeasure = 0; // storage location for previous measure if too far
   int i = start + 1;
   char string = '0';
   double duration = 0;
   while (i<infile.getNumLines()) { 
      tempitem.clear();
      spaceitem.hpos = -1;
      spaceitem.width = 0;
      switch (infile[i].getType()) {
         case E_humrec_none:
         case E_humrec_empty:
         case E_humrec_global_comment:
            processComment(&infile[i][0][1], textitem, sarray, i,0,totalwidth);
         case E_humrec_bibliography:
            break;
         case E_humrec_data_comment:
            processComment(infile[i][0], textitem, sarray, i, 0, totalwidth);
            break;
         case E_humrec_data_kern_measure:
            if (!datafoundQ) {
               break;
            }
            // add a little space before the barline incase of sixteenth notes
            spaceitem.width = 0.5 * getItemWidth("sbar", scaling);
            spaceitem.hpos = totalwidth;
            totalwidth += spaceitem.width;
            appendSpace(sarray, spaceitem);

            if (strstr(infile[i][0], "||") != NULL) {
               strcpy(tempitem.name, "doublebar");
               tempitem.width = getItemWidth("doublebar", scaling);
            } else if (strstr(infile[i][0], "==") != NULL) {
               strcpy(tempitem.name, "finalbar");
               tempitem.width = getItemWidth("fbar", scaling);
            } else {
               strcpy(tempitem.name, "lbar");
               tempitem.width = getItemWidth("lbar", scaling);
            }
            tempitem.line = i;
            tempitem.spine = 0;
            tempitem.hpos = totalwidth;
            sarray.append(tempitem);
            lastlastmeasure = lastmeasure;
            lastlastmeasure = sarray.getSize() - 1;
            totalwidth += tempitem.width;
            spaceitem.width = 1.5 * getItemWidth("sbar", scaling);
            spaceitem.hpos = totalwidth;
            appendSpace(sarray, spaceitem);
            totalwidth += spaceitem.width;
            if (totalwidth>targetwidth) {
               goto endofloop;
            }
            break;
         case E_humrec_interpretation:
            // ignore for now, but later handle time signatures, tempo, etc.
            break;
         case E_humrec_data:
            datafoundQ = 1;
            if (strchr(infile[i][0], ' ') != NULL) {
               chordQ = 1;
            } else {
               chordQ = 0;
            }
            infile[i].getToken(notebuffer, 0, 0);
            string = getStringSymbol(notebuffer);
            if (string == '.') {  // ignore null records
               break;
            }
            tempitem.name[0] = string;
            tempitem.line = i;
            tempitem.spine = 0;
            tempitem.name[1] = '\0';
            tempitem.chord = chordQ;
            tempitem.width = getItemWidth(tempitem.name, scaling);
            tempitem.height = getItemHeight(tempitem.name, scaling);
	    if (strchr(notebuffer, 'q') != NULL) {
               tempitem.width *= 0.65;
	       tempitem.grace = 1;
            }
            duration = getKotoDuration(notebuffer);
            tempitem.beams = getBeamCount(notebuffer);

            if (duration >= 0.99) {
               spaceitem.hpos = totalwidth;
               spaceitem.width = 1.0 * getItemWidth("sbar", scaling);
               appendSpace(sarray, spaceitem);
               totalwidth += spaceitem.width;

               if (strchr(notebuffer, 's') != NULL) {
                  shaitem.hpos = totalwidth;
                  shaitem.width = getItemWidth("sha", scaling);
                  totalwidth += shaitem.width;
                  strcpy(shaitem.name, "sha");
                  sarray.append(shaitem);
                  shaitem.clear();
               }

               tempitem.hpos = totalwidth;
               sarray.append(tempitem);
               // standardize width of a note
               totalwidth += tempitem.width;

               if (strchr(notebuffer, '.') != NULL) {
                  int dotcount = countKotoDots(notebuffer);
                  for (int m=0; m<dotcount; m++) {
                     tempitem.hpos = totalwidth;
                     tempitem.width = getItemWidth("augdot", scaling);
                     totalwidth += tempitem.width;
                     strcpy(tempitem.name, "augdot");
                     sarray.append(tempitem);
                  }
               }

               // white space after beat
               spaceitem.hpos = totalwidth;
               spaceitem.width = getItemWidth("A", scaling);
               appendSpace(sarray, spaceitem);
               totalwidth += spaceitem.width;
            } else {

               if (strchr(notebuffer, 's') != NULL) {
                  shaitem.hpos = totalwidth;
                  shaitem.width = getItemWidth("sha", scaling);
                  totalwidth += shaitem.width;
                  strcpy(shaitem.name, "sha");
                  sarray.append(shaitem);
                  shaitem.clear();
               }

               // shorter than one beat
               tempitem.hpos = totalwidth;
               totalwidth += tempitem.width;
               if (duration > 0.45) {
                  sarray.append(tempitem);

                  if (strchr(notebuffer, '.') != NULL) {
                     int dotcount = countKotoDots(notebuffer);
                     for (int m=0; m<dotcount; m++) {
                        tempitem.hpos = totalwidth;
                        tempitem.width = getItemWidth("augdot", scaling);
                        totalwidth += tempitem.width;
                        strcpy(tempitem.name, "augdot");
                        sarray.append(tempitem);
                     }
                  }
                  spaceitem.hpos = totalwidth;
                  spaceitem.width = 0.3 * getItemWidth("A", scaling);
                  appendSpace(sarray, spaceitem);
                  totalwidth += spaceitem.width;

                  // add a little bit of space at the end of the beat
                  if (endOfBeat(infile, i)) {
                     spaceitem.hpos = totalwidth;
                     spaceitem.width = 0.2 * getItemWidth("A", scaling);
                     appendSpace(sarray, spaceitem);
                     totalwidth += spaceitem.width;
                  } 

               } else {
                  sarray.append(tempitem);

                  if (strchr(notebuffer, '.') != NULL) {
                     int dotcount = countKotoDots(notebuffer);
                     for (int m=0; m<dotcount; m++) {
                        tempitem.hpos = totalwidth;
                        tempitem.width = getItemWidth("augdot", scaling);
                        totalwidth += tempitem.width;
                        strcpy(tempitem.name, "augdot");
                        sarray.append(tempitem);
                     }
                  }
                  totalwidth += 0.0;

                  if (endOfBeat(infile, i)) {
                     spaceitem.hpos = totalwidth;
                     spaceitem.width = 0.3 * getItemWidth("A", scaling);
                     appendSpace(sarray, spaceitem);
                     totalwidth += spaceitem.width;
                  } 
               }

            }
            break;
         default:
            break;
      }

      i++;
   }


endofloop:
   if (justifyQ == 0) {
      // debugging code: don't justify 
      return i;
   }
   double spacelength = 0.0;

   if (totalwidth>targetwidth) {

      // find closest barline to targetwidth
      currentpos = totalwidth;
      lastbpos = sarray[lastlastmeasure].hpos;
      if (fabs(currentpos - targetwidth) < fabs(lastbpos - targetwidth)) {
         // current barline is closest to the target length: need to expand
         i = sarray[lastlastmeasure].line;
         sarray.setSize(lastlastmeasure+1);
         // remove extra blank space after last barline if necessary
         if (strcmp(sarray[sarray.getSize() - 1].name, " ") == 0 &&
            strstr(sarray[sarray.getSize() - 2].name, "bar") != NULL) {
            sarray.setSize(sarray.getSize() - 1); 
         }
         totalwidth = sarray[sarray.getSize() - 1].hpos + 
                      sarray[sarray.getSize() - 1].width +
                      getItemWidth("sbar", scaling);

         spacelength = 0.0;
         for (n=0; n<sarray.getSize(); n++) {
            if (sarray[n].name[0] == ' ') {
               spacelength += sarray[n].width;
            }
         }

         double delta = totalwidth - targetwidth;
         stretchfactor = spacelength/(spacelength-delta);
// stretchfactor = 10.0;

         totalwidth = 0.0;
         for (n=0; n<sarray.getSize(); n++) {
            if (sarray[n].name[0] == ' ') {
               sarray[n].width *= stretchfactor;
            }
            sarray[n].hpos = totalwidth;
            totalwidth += sarray[n].width;
         }

      } else {
         // last barline is closest to the target length, so use it instead
         // need to contract

         // remove extra blank space after last barline if necessary
         if (strcmp(sarray[sarray.getSize() - 1].name, " ") == 0 &&
            strstr(sarray[sarray.getSize() - 2].name, "bar") != NULL) {
            sarray.setSize(sarray.getSize() - 1); 
         }
         totalwidth = sarray[sarray.getSize() - 1].hpos + 
                      sarray[sarray.getSize() - 1].width + 
                      getItemWidth("sbar", scaling);

         spacelength = 0.0;
         for (n=0; n<sarray.getSize(); n++) {
            if (sarray[n].name[0] == ' ') {
               spacelength += sarray[n].width;
            }
         }

         double delta = totalwidth - targetwidth;
         if (delta > spacelength) {
            stretchfactor = 0.0;
         } else {
            stretchfactor = (spacelength-delta)/spacelength;
         }
// stretchfactor = 2.0;

         totalwidth = 0.0;
         for (n=0; n<sarray.getSize(); n++) {
            if (sarray[n].name[0] == ' ') {
               sarray[n].width *= stretchfactor;
            }
            sarray[n].hpos = totalwidth;
            totalwidth += sarray[n].width;
         }

      }

   }

//   if (strstr(sarray[sarray.getSize() - 1].name, "bar") != NULL) {
//      if (strcmp(sarray[sarray.getSize() - 1].name, "doublebar") != 0) {
//         strcpy(sarray[sarray.getSize() - 1].name, "rbar");
//      }
//   }

   return i;
}


//////////////////////////////
//
// processComment -- 
//

void processComment(const char* cstring, StaffItem& textitem, 
      StaffItemArray& sarray, int line, int spine, double& totalwidth) {

   if (strncmp(cstring, "!FT:", 4) == 0) {
      int length = strlen(cstring);

      if (length >= 5) {
         int font = cstring[4];
         font = toupper(font);
         if (font != 'T' && font != 'H' && font != 'C') {
            // unknown font, do nothing
         } else {
            textfont = font;
         }
      }

      if (length >= 6) {
         int face = cstring[5];
         face = toupper(face);
         if (face != 'R' && face != 'I' && face != 'B') {
            // unknown font, do nothing
         } else {
            textface = face;
         }
      }

      if (length > 6) {
         int just = cstring[length-1];
         just = toupper(just);
         if (just != 'L' && just != 'R' && just != 'C') {
            // unknown font, do nothing
         } else {
            textjustify = just;
         }
      }

      if (length > 6 && isdigit(cstring[6])) {
         double fsize = 0.0;
         int count = sscanf(&cstring[6], "%lf", &fsize);
         if (count == 1) {
            textsize = fsize;
         }
      }

   } else if (strncmp(cstring, "!TA:", 4) == 0) {
      strcpy(textitem.name, "textabove");
      textitem.width = 0;
      textitem.hpos = totalwidth;
      textitem.line = line;
      textitem.spine = spine;
      textitem.textfont = textfont;
      textitem.textsize = textsize;
      textitem.textface = textface;
      textitem.textjustify = textjustify;
      sarray.append(textitem);
   } else if (strncmp(cstring, "!TB:", 4) == 0) {
      strcpy(textitem.name, "textbelow");
      textitem.width = 0;
      textitem.hpos = totalwidth;
      textitem.line = line;
      textitem.spine = spine;
      textitem.textfont = textfont;
      textitem.textsize = textsize;
      textitem.textface = textface;
      textitem.textjustify = textjustify;
      sarray.append(textitem);
   } else if (strncmp(cstring, "!CLR:", 5) == 0) {
      processColor(&cstring[5], sarray, totalwidth);
   }

}



//////////////////////////////
//
// processColor -- 
//

void processColor(const char* cstring, StaffItemArray& sarray, double hpos) {
   int red   = 0;
   int green = 0;
   int blue  = 0;
   
   int length = strlen(cstring);
   char *Cstring = new char[length + 1];
   strcpy(Cstring, cstring);
   int i;
   for (i=0; i<length; i++) {
      Cstring[i] = toupper(Cstring[i]);
   }

   if (strcmp(Cstring, "RED") == 0) {
      red   = 255; green = 0;   blue  = 0;
   } else if (strcmp(Cstring, "BLUE") == 0) {
      red   = 0;   green = 0;   blue  = 255;
   } else if (strcmp(Cstring, "GREEN") == 0) {
      red   = 0;   green = 255; blue  = 0;
   } else if (strcmp(Cstring, "BLACK") == 0) {
      red   = 0;   green = 0;   blue  = 0;
   } else if (strcmp(Cstring, "WHITE") == 0) {
      red   = 255; green = 255; blue  = 255;
   } else if (strcmp(Cstring, "PURPLE") == 0) {
      red   = 128; green = 0;   blue  = 128;
   } else if (length == 6) {
      int allhex = 1;
      for (i=0; i<length; i++) {
         if (!isxdigit(Cstring[i])) {
            allhex = 0;
            break;
         }
      }
      if (allhex) {
         blue  = strtol(&Cstring[4], NULL, 16);
         Cstring[4] = '\0';
         green = strtol(&Cstring[2], NULL, 16);
         Cstring[2] = '\0';
         red   = strtol(Cstring, NULL, 16);
      }
   }

   char colorstring[7] = {0};
   colorstring[0] = hexdigit(red,   1);
   colorstring[1] = hexdigit(red,   0);
   colorstring[2] = hexdigit(green, 1);
   colorstring[3] = hexdigit(green, 0);
   colorstring[4] = hexdigit(blue,  1);
   colorstring[5] = hexdigit(blue,  0);
   

   StaffItem coloritem;
   coloritem.width = 0;
   coloritem.hpos  = hpos;
   strcpy(coloritem.name, "color=");
   strcat(coloritem.name, colorstring);
   
   sarray.append(coloritem);
   delete [] Cstring;
}


//////////////////////////////
//
// hexdigit --
//

char hexdigit(int number, int digit) {
   if (number > 255) { number = 255; }
   if (number < 0)   { number = 0;   }
   int value;
   if (digit == 1) {
      value = number / 16; 
   } else {
      value = number % 16;
   }
   if (value < 10) {
      return '0' + value;
   } else if (value < 16) {
      return 'A' + value - 10;
   }

   return 0;
}



//////////////////////////////
//
// endOfBeat -- returns true if the next note or rest is in a
//   different beat.
//

int endOfBeat(HumdrumFile& infile, int line) {
   int beat = (int)infile[line].getBeat();
   int newbeat = 0;
   int i = line+1;
   while (i < infile.getNumLines()) {
      if (infile[i].getType() == E_humrec_data) {
         newbeat = (int)infile[i].getBeat();
         if (newbeat == beat) {
            return 0;
         } else {
            return 1;
         }
      } else if (infile[i].getType() == E_humrec_data_kern_measure) {
         return 0;  // end of beat, but the barline will add its own spacer
      }
      i++;
   }
   return 1;
}



//////////////////////////////
//
// endOfBeat2 -- returns true if the next note or rest is in a
//   different beat. Used for beaming.
//

int endOfBeat2(HumdrumFile& infile, int line) {
   int beat = (int)infile[line].getBeat();
   int newbeat = 0;
   int i = line+1;
   while (i < infile.getNumLines()) {
      if (infile[i].getType() == E_humrec_data) {
         newbeat = (int)infile[i].getBeat();
         if (newbeat == beat) {
            return 0;
         } else {
            return 1;
         }
      } else if (infile[i].getType() == E_humrec_data_kern_measure) {
         return 1;  // end of beat, but the barline will add its own spacer
      }
      i++;
   }
   return 1;
}



///////////////////////////////
//
// appendSpace -- add space to end of array.  If last item in array
//     contains a space, then add with to existing space.
//

void appendSpace(StaffItemArray& sarray, StaffItem& spaceitem) {
   int endp = sarray.getSize() - 1;
   if (strcmp(sarray[endp].name, " ") == 0) {
      sarray[endp].width += spaceitem.width;
   } else if (sarray.getSize() > 2 
         && strncmp(sarray[endp].name, "color=", 6) == 0
         && strcmp(sarray[endp-1].name, " ") == 0) {
      sarray[endp-1].width += spaceitem.width;
   } else {
      sarray.append(spaceitem);
   }
}



///////////////////////////////
//
// countKotoDots --
//

int countKotoDots(const char* kstring) {
   int length = strlen(kstring);
   int count = 0;
   int i = 0;
   for (i=0; i<length; i++) {
      if (kstring[i] == '.') {
         count++;
      }
   }
   return count;
}



//////////////////////////////
//
// getKotoDuration -- 
//

double getKotoDuration(const char* kstring) {
   int bars = 0;
   int dots = 0;
   int i;
   int length = strlen(kstring);
   for (i=0; i<length; i++) {
      if (kstring[i] == '|') {
         bars++;
      } else if (kstring[i] == '.') {
         dots++;
      }
   }

   double duration = 1.0;
   for (i=0; i<bars; i++) {
      duration *= 0.5;
   }
   double dotadd = 0.0;
   for (i=0; i<dots; i++) {
      dotadd += duration * pow(2.0, -(i+1));   
   }
   return duration + dotadd;
}



//////////////////////////////
//
// getStringSymbol --
//

char getStringSymbol(const char* string) {
   if (strchr(string, '0') != NULL) { return '0'; }
   if (strchr(string, '1') != NULL) { return '1'; }
   if (strchr(string, '2') != NULL) { return '2'; }
   if (strchr(string, '3') != NULL) { return '3'; }
   if (strchr(string, '4') != NULL) { return '4'; }
   if (strchr(string, '5') != NULL) { return '5'; }
   if (strchr(string, '6') != NULL) { return '6'; }
   if (strchr(string, '7') != NULL) { return '7'; }
   if (strchr(string, '8') != NULL) { return '8'; }
   if (strchr(string, '9') != NULL) { return '9'; }
   if (strchr(string, 'A') != NULL) { return 'A'; }
   if (strchr(string, 'B') != NULL) { return 'B'; }
   if (strchr(string, 'C') != NULL) { return 'C'; }
   if (strchr(string, 'D') != NULL) { return 'D'; }
   if (strchr(string, '-') != NULL) { return '-'; }
   if (strchr(string, '.') != NULL) { return '.'; }
   if (strchr(string, 'W') != NULL) { return 'W'; }
   if (strchr(string, 'Z') != NULL) { return 'Z'; }
   if (strchr(string, 'z') != NULL) { return 'z'; }
   cout << "Error: Unknown string character in " << string << endl;
   exit(1);
}



//////////////////////////////
//
// example -- example usage of the koto2eps program
//

void example(void) {
   cout <<
   "                                                                        \n"
   << endl;
}



//////////////////////////////
//
// usage -- gives the usage statement for the koto2eps program
//

void usage(const char* command) {
   cout <<
   "                                                                        \n"
   << endl;
}





//////////////////////////////
//
// storeEpsHeader --
//

void storeEpsHeader(SSTREAM& out, int pagecount) {
   out << 
        "%!PS-Adobe-3.0 \n"
        "%%BoundingBox: 24 24 588 768 \n"
        "%%Title: Enscript Output \n"
        "%%For: root \n"
        "%%Creator: GNU enscript 1.6.1 \n"
        "%%CreationDate: Thu Dec 27 19:43:14 2001 \n"
        "%%Orientation: Portrait \n"
        "%%Pages: " << pagecount << " \n"
        "%%DocumentMedia: Letter 612 792 0 () () \n"
        "%%DocumentNeededResources: (atend) \n"
        "%%EndComments \n"
        "%%BeginProlog \n"
        " /bdef { bind def } bind def    /ldef { load def } bdef \n"
        " /m /moveto ldef \n"
        " /l /lineto ldef \n"
        " /C /curveto ldef \n"
        " /f /fill ldef \n"
        " /s /stroke ldef \n"
        " /w /setlinewidth ldef \n"
        " /gs /gsave ldef \n"
        " /gr /grestore ldef \n"
        " /cl /closepath ldef \n"

        "% \n"
        "% Procedures. \n"
        "% \n\n"
   ;


   storeSymbols(out);

   out << "%%EndProlog \n";
}
  


//////////////////////////////
//
// storePageStart --
//

void storePageStart(SSTREAM& out, int pagenum) {
   out <<
        " \n\n"
        "%%Page: " << pagenum << " \n"
        "%%BeginPageSetup \n"
        "%%EndPageSetup \n"
   ;
   if (debugQ) {
      drawPrintingMargin(out);
   }
}



////////////////////////////////
//
// storeEpsFooter --
//

void storeEpsFooter(SSTREAM& out) {
   out << 
        "%%Trailer\n"
   ;
}




//////////////////////////////
//
// getItemWidth  -- get the width of a staff item in PostScript points.
// getItemHeight -- get the height of a staff item in PostScript points.
//

/* Nominal sizes of various symbols:        symbol  height  width
        0       12.80        9.1375
        1       12.5625 5.8
        2       12.9375 9.3
        3       13.0    9.7125
        4       12.625  9.675
        5       12.5    9.5625
        6       12.5    9.375
        7       12.5    8.75
        8       13.0375 9.5
        9       12.8125 9.375
        A       12.875  12.4375
        B       12.75   10.875
        C       13.0625 12.125
        D       12.78   11.765
        W       15.225  13.80625
        Z       12.80        9.1375
        z       12.80        9.1375
        augdot        4.0       4.0
        sharp         3.125     6.25
        doublesharp   3.125     6.25
        triplesharp   6.25      6.25
        oshi          3.125     6.25
        oshith        3.125     9.375
        hiki          3.125     6.25
        sha           12.5      1.25
        sbar    16.25     4.0
        fbar    16.25     4.0
        bar     16.25     0.5
        letter  792.0   612.0
        ledger  1224.0  792.0
        legal   1008.0  612.0
        a4      841.89  595.276
        a3      1190.55 841.89
        b4      1000.63 708.66
*/

double getItemWidth(const char* name, double scaling) {
   if (strcmp(name, "0") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "1") == 0) { return  5.8   * scaling; }
   if (strcmp(name, "2") == 0) { return  9.3   * scaling; }
   if (strcmp(name, "3") == 0) { return  9.7125* scaling; }
   if (strcmp(name, "4") == 0) { return  9.675 * scaling; }
   if (strcmp(name, "5") == 0) { return  9.5625* scaling; }
   if (strcmp(name, "6") == 0) { return  9.375 * scaling; }
   if (strcmp(name, "7") == 0) { return  8.75  * scaling; }
   if (strcmp(name, "8") == 0) { return  9.5   * scaling; }
   if (strcmp(name, "9") == 0) { return  9.375 * scaling; }
   if (strcmp(name, "A") == 0) { return 12.4375* scaling; }
   if (strcmp(name, "B") == 0) { return 10.875 * scaling; }
   if (strcmp(name, "C") == 0) { return 12.125 * scaling; }
   if (strcmp(name, "D") == 0) { return 11.765 * scaling; }
   if (strcmp(name, "W") == 0) { return 15.225 * scaling; }
   if (strcmp(name, "Z") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "z") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "-") == 0) { return  9.375 * scaling; }
   if (strcmp(name, "augdot") == 0) { return 4.0 * scaling; }
   if (strcmp(name, "hiki") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "sharp") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "doublesharp") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "triplesharp") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "oshi") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "oshith") == 0) { return 9.375 * scaling; }
   if (strcmp(name, "sha") == 0) { return 1.375 * scaling; }
   if (strcmp(name, "vrepeat") == 0) { return 0.5 * scaling; }
   if (strcmp(name, "lbar") == 0) { return 0.5 * scaling; }
   if (strcmp(name, "rbar") == 0) { return 0.5 * scaling; }
   if (strcmp(name, "cbar") == 0) { return 0.5 * scaling; }
   if (strcmp(name, "sbar") == 0) { return 4.0 * scaling; }
   if (strcmp(name, "fbar") == 0) { return 4.0 * scaling; }
   if (strcmp(name, "doublebar") == 0) { return 2.0 * scaling; }
   cout << "Error: unknown symbol: " << name << endl;
   exit(1);
}

double getItemHeight(const char* name, double scaling) {
   if (strcmp(name, "0") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "1") == 0) { return 12.5625* scaling; }
   if (strcmp(name, "2") == 0) { return 12.9375* scaling; }
   if (strcmp(name, "3") == 0) { return 13.0   * scaling; }
   if (strcmp(name, "4") == 0) { return 12.625 * scaling; }
   if (strcmp(name, "5") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "6") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "7") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "8") == 0) { return 13.0375* scaling; }
   if (strcmp(name, "9") == 0) { return 12.8125* scaling; }
   if (strcmp(name, "A") == 0) { return 12.875 * scaling; }
   if (strcmp(name, "B") == 0) { return 12.75  * scaling; }
   if (strcmp(name, "C") == 0) { return 13.0625* scaling; }
   if (strcmp(name, "D") == 0) { return 12.78  * scaling; }
   if (strcmp(name, "W") == 0) { return 13.80625 * scaling; }
   if (strcmp(name, "Z") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "z") == 0) { return 12.5   * scaling; }
   if (strcmp(name, "-") == 0) { return 13.25  * scaling; }
   if (strcmp(name, "augdot") == 0) { return 4.0 * scaling; }
   if (strcmp(name, "hiki") == 0) { return 3.125 * scaling; }
   if (strcmp(name, "sharp") == 0) { return 3.125 * scaling; }
   if (strcmp(name, "doublesharp") == 0) { return 3.125 * scaling; }
   if (strcmp(name, "triplesharp") == 0) { return 6.25 * scaling; }
   if (strcmp(name, "oshi") == 0) { return 3.125 * scaling; }
   if (strcmp(name, "oshith") == 0) { return 3.125 * scaling; }
   if (strcmp(name, "sha") == 0) { return 1.25 * scaling; }
   if (strcmp(name, "rbar") == 0) { return 16.25 * scaling; }
   if (strcmp(name, "cbar") == 0) { return 16.25 * scaling; }
   if (strcmp(name, "sbar") == 0) { return 16.25 * scaling; }
   if (strcmp(name, "fbar") == 0) { return 16.25 * scaling; }
   if (strcmp(name, "doublebar") == 0) { return 16.25 * scaling; }
   cout << "Error: unknown symbol: " << name << endl;
   exit(1);
}



//////////////////////////////
//
// storeSymbols --
//

void storeSymbols(SSTREAM& out) {

   out << " /pagewidth  " << pagewidth << " def \n";
   out << " /pageheight " << pageheight << " def \n";
   out << " /lmargin    " << lmargin << " def \n";
   out << " /rmargin    " << rmargin << " def \n";
   out << " /tmargin    " << tmargin << " def \n";
   out << " /bmargin    " << bmargin << " def \n\n";

   out << 
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% shape definitions \n"
"%%\n"
"\n"
"/symbolscale 0.125 def\n"
"\n"
"% dash\n"
"%BBOX: 0 47 75 53\n"
" /dashheight 53 symbolscale mul def\n"
" /dashwidth  75 symbolscale mul def\n"
" /dashleft    0                 def\n"
" /dashbelow   0                 def\n"
" /dashshape {\n"
"        0 47 m\n"
"        75 47 l\n"
"        75 53 l\n"
"        0 53 l\n"
"        0 47 l\n"
"        cl f s\n"
" } def\n"
"\n"
"\n"
"% string 0 -- old version: the numeral 0.\n"
"%BBOX: 0.0 -2.5 73.1 102.4\n"
"% /string0height 102.4 symbolscale mul def\n"
"% /string0width   73.1 symbolscale mul def\n"
"% /string0left       0          def\n"
"% /string0below   -2.5 symbolscale mul def\n"
"% /string0shape {\n"
"%        % outside of 0\n"
"%        1.18 63.42 m\n"
"%        -1.08 59.38 0.6 50.62 0.6 46 C\n"
"%        0.6 31.96 2.94 16.8 13.18 6.58 C\n"
"%        28.04 -8.3 54.04 -3.8 63.6 14 C\n"
"%        74.74 34.74 76.66 61.94 67.26 84 C\n"
"%        60.78 99.26 32.06 108.32 18.76 97.8 C\n"
"%        13.12 93.32 3.76 80.98 2.6 74 C\n"
"%        1.94 70.04 3.2 67.06 1.18 63.42 C\n"
"%        cl\n"
"%\n"
"%        % inside of 0 \n"
"%        21.18 65.42 m\n"
"%        19.58 62.54 20.6 57.24 20.6 54 C\n"
"%        20.6 41.66 20.14 28.82 27.18 18.28 C\n"
"%        30.6 13.14 44.94 14.8 47.1 20 C\n"
"%        53.4 35.14 55.58 55.72 50.94 72 C\n"
"%        47.8 82.94 37.14 89.5 27.02 81.42 C\n"
"%        23.02 78.22 23.44 69.52 21.18 65.42 C\n"
"%        cl \n"
"% } def\n"
"\n"
"% Zuu (left pointing arrow on top of rest)\n"
"%BBOX: 0.0 0 75 100\n"
" /Zuheight 100 symbolscale mul def\n"
" /Zuwidth  100 symbolscale mul def\n"
" /Zuleft     0                 def\n"
" /Zubelow    0                 def\n"
" /Zushape {\n"
"        % outside of Zu\n"
"	50.0 50 50.0 0 360 arc\n"
"        cl\n"
"\n"
"        % inside of Zu \n"
"	50.0 50 36.0 0 360 arc\n"
"        cl \n"
" } def\n"
"\n"
"% zuu (right pointing arrow on top of rest)\n"
"%BBOX: 0.0 0 75 100\n"
" /zuheight 100 symbolscale mul def\n"
" /zuwidth  100 symbolscale mul def\n"
" /zuleft     0                 def\n"
" /zubelow    0                 def\n"
" /zushape {\n"
"        % outside of zu\n"
"	50.0 50 50.0 0 360 arc\n"
"        cl\n"
"\n"
"        % inside of zu \n"
"	50.0 50 36.0 0 360 arc\n"
"        cl \n"
" } def\n"
"\n"
"% string 0\n"
"%BBOX: 0.0 0 75 100\n"
" /string0height 100 symbolscale mul def\n"
" /string0width  100 symbolscale mul def\n"
" /string0left     0                 def\n"
" /string0below    0                 def\n"
" /string0shape {\n"
"        % outside of 0\n"
"	50.0 50 50.0 0 360 arc\n"
"        cl\n"
"\n"
"        % inside of 0 \n"
"	50.0 50 36.0 0 360 arc\n"
"        cl \n"
" } def\n"
"\n"
"% string 1\n"
"%BBOX: 0.0 -0.4 46.4 100.5\n"
" /string1height 100.5 symbolscale mul def\n"
" /string1width   46.4 symbolscale mul def\n"
" /string1left     0            def\n"
" /string1below   -0.4 symbolscale mul def\n"
" /string1shape {\n"
"        45.82 99.42 m\n"
"        43.2 100.48 33.2 101.32 30.82 99.42 C\n"
"        28.26 97.36 29.34 93.02 26.4 90.66 C\n"
"        22.02 87.16 16.46 85.48 11.82 82.58 C\n"
"        9.1 80.86 1.1 84.18 0.4 80 C\n"
"        0 77.64 -0.76 68.3 0.98 66.58 C\n"
"        5.84 61.7 26.4 72 26.4 62 C\n"
"        26.4 4 l\n"
"        26.4 -2.38 35.68 0 40.4 0 C\n"
"        41.82 0 44.68 -0.58 45.82 0.58 C\n"
"        46.64 1.4 46.4 3.08 46.4 4 C\n"
"        46.4 96 l\n"
"        46.4 98.52 46.64 97.38 45.82 99.42 C\n"
"        cl\n"
" } def\n"
"\n"
"% string 2\n"
"%BBOX: 0.0 0 74.4 103.5\n"
" /string2height 103.5 symbolscale mul def\n"
" /string2width   74.4 symbolscale mul def\n"
" /string2left     0            def\n"
" /string2below    0            def\n"
" /string2shape {\n"
"        45.82 101.42 m\n"
"        28.38 108.4 12.76 95.04 6.5 80 C\n"
"        4.92 76.2 -1.22 66.76 2.98 62.58 C\n"
"        4.56 60.98 20.24 60.98 21.82 62.58 C\n"
"        24.76 65.5 21.52 73.74 24.78 77.8 C\n"
"        34.14 89.52 53.14 83.4 52.4 68 C\n"
"        51.98 59.06 43.4 53.3 36.4 49 C\n"
"        25.48 42.3 13.12 33.3 6.6 21.86 C\n"
"        4.26 17.78 -5.62 0 4.4 0 C\n"
"        68.4 0 l\n"
"        74.6 0 74.1 17.38 70.4 18 C\n"
"        59.74 19.78 47.22 18 36.4 18 C\n"
"        34.16 18 26.46 16.1 26.4 18 C\n"
"        26.2 23.4 40.66 29.74 44.4 32.28 C\n"
"        59.22 42.34 87.56 70.4 66.74 89.34 C\n"
"        63.96 91.86 60.78 95.28 57.82 97.42 C\n"
"        54.62 99.78 49.16 98.92 45.82 101.42 C\n"
"        cl\n"
" } def\n"
"\n"
"% string 3\n"
"%BBOX: 0.0 -2.5 77.7 104\n"
" /string3height 104   symbolscale mul def\n"
" /string3width   77.7 symbolscale mul def\n"
" /string3left     0            def\n"
" /string3below   -2.5 symbolscale mul def\n"
" /string3shape {\n"
"        48.42 101.42 m\n"
"        36.34 108.14 15.68 98.86 10 88 C\n"
"        9.1 86.28 0.16 70.12 3.58 69.14 C\n"
"        8.28 67.8 15.74 67.12 21 68 C\n"
"        24.56 68.6 22.48 75.4 24 78 C\n"
"        25.5 80.56 32.9 83.9 35.58 85.42 C\n"
"        36.66 86.06 37.84 84 39 84 C\n"
"        46.92 84 58.72 77.52 52 66 C\n"
"        48.88 60.66 37.98 62.32 33 60.34 C\n"
"        31.48 59.72 31 49.6 31 48 C\n"
"        31 44.32 42.5 46.34 45 45.72 C\n"
"        54.14 43.42 56.7 31.96 54.72 24 C\n"
"        52.76 16.18 32.78 11.52 27.66 18 C\n"
"        25.8 20.38 20.12 33.82 19 34 C\n"
"        16.12 34.48 3.62 35.48 1.58 33.42 C\n"
"        -3.5 28.36 5.08 11.76 9.28 8.58 C\n"
"        28.48 -6.06 60.04 -7.94 72 16 C\n"
"        73.18 18.36 76.6 21.54 77 24 C\n"
"        78.2 31.24 77.84 42.12 72.72 47.8 C\n"
"        70.92 49.8 62.14 53.02 62.14 55.72 C\n"
"        62.14 59.52 72.24 65.38 73 70 C\n"
"        76.18 89.06 61.66 94.08 48.42 101.42 C\n"
"        cl\n"
" } def\n"
"\n"
"% string 4\n"
"%BBOX: 0.0 -0.5 77.4 101\n"
" /string4height 101   symbolscale mul def\n"
" /string4width   77.4 symbolscale mul def\n"
" /string4left     0            def\n"
" /string4below   -0.5 symbolscale mul def\n"
" /string4shape {\n"
"        % the outer part of the 4\n"
"        61.92 99.42 m\n"
"        59.2 100.52 45.28 101.64 43.08 99.42 C\n"
"        38.4 94.76 34.44 85.64 30.22 80 C\n"
"        18.14 63.88 -3.1 47.6 0.5 26 C\n"
"        1.06 22.58 8 24 10.5 24 C\n"
"        18.5 24 26.5 24 34.5 24 C\n"
"        36.28 24 40.54 24.82 41.92 23.42 C\n"
"        46.46 18.9 38.54 5.1 43.08 0.58 C\n"
"        44.46 -0.82 48.72 0 50.5 0 C\n"
"        52.94 0 60.12 -1.24 61.92 0.58 C\n"
"        66.46 5.1 58.54 18.9 63.08 23.42 C\n"
"        65.78 26.14 75.66 21.02 76.5 26 C\n"
"        76.94 28.62 77.82 39.54 75.92 41.42 C\n"
"        71.48 45.86 62.5 36.42 62.5 44 C\n"
"        62.5 96 l\n"
"        62.5 98.52 62.74 97.38 61.92 99.42 C\n"
"        cl\n"
"\n"
"        %inside of 4\n"
"        42.22 72.86 m\n"
"        41.68 72.86 38.86 68.42 38.5 68 C\n"
"        34.14 62.92 30.22 57.36 26.22 52 C\n"
"        24.96 50.32 15.12 40 18.5 40 C\n"
"        22.54 40 27.74 42 32.5 42 C\n"
"        35.68 42 39.68 38.32 41.92 40.58 C\n"
"        44.56 43.2 42.5 56.28 42.5 60 C\n"
"        42.5 61.12 42.74 72.86 42.22 72.86 C\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"% string 5\n"
"%BBOX: 0.0 -2.8 76.5 100\n"
" /string5height 100   symbolscale mul def\n"
" /string5width   76.5 symbolscale mul def\n"
" /string5left     0            def\n"
" /string5below   -2.8 symbolscale mul def\n"
" /string5shape {\n"
"        68.42 99.42 m\n"
"        66.38 100.24 67.52 100 65 100 C\n"
"        17 100 l\n"
"        11.34 100 13.06 94.36 12.34 90 C\n"
"        10.56 79.32 8.68 68.62 6.6 58 C\n"
"        6.08 55.3 1.42 46.72 3.58 44.58 C\n"
"        10.4 37.74 24.64 48.14 29.58 51.42 C\n"
"        40.68 58.84 53.4 45.6 55 36 C\n"
"        56.92 24.48 42.96 9.36 31 15.34 C\n"
"        24.1 18.78 24.78 25.08 20.42 29.42 C\n"
"        18.84 31.02 3.16 31.02 1.58 29.42 C\n"
"        -3.64 24.22 4.2 13.04 8 10 C\n"
"        19.32 0.94 34.32 -5.52 49 -1.34 C\n"
"        68.16 4.14 85 36.08 70.8 53.8 C\n"
"        63.38 63.08 52.16 68 41 68 C\n"
"        37.18 68 34.46 67.72 31 66 C\n"
"        30.36 65.68 26.02 62.14 25.58 62.58 C\n"
"        24.18 63.96 24.7 70.18 25 72 C\n"
"        25.28 73.66 26.74 82.58 27.58 83.42 C\n"
"        29.18 85.04 34.88 84 37 84 C\n"
"        45 84 53 84 61 84 C\n"
"        62.78 84 67.04 83.18 68.42 84.58 C\n"
"        70.38 86.52 69.36 97.08 68.42 99.42 C\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"\n"
"% string 6\n"
"%BBOX: 0.0 -2 75 104\n"
" /string6height 104   symbolscale mul def\n"
" /string6width   75   symbolscale mul def\n"
" /string6left     0            def\n"
" /string6below   -2   symbolscale mul def\n"
" /string6shape {\n"
"        % outside of 6\n"
"        48.42 101.42 m\n"
"        32.12 110.48 14.18 93 8 80 C\n"
"        -0.06 63.1 -6.26 25.44 10.6 10.8 C\n"
"        30.42 -6.4 57.48 -8.28 70 18 C\n"
"        71.66 21.5 75 26.24 75 30 C\n"
"        75 46.94 68.58 64.74 49 68 C\n"
"        42.56 69.08 34.6 68.36 29 65 C\n"
"        27.48 64.08 21.74 55.5 21 60 C\n"
"        18.6 74.4 31.08 88.08 45 86 C\n"
"        49.78 85.28 50.46 78.98 53.28 76 C\n"
"        55.94 73.22 56.52 79.02 58.42 77.42 C\n"
"        58.42 77.42 59.58 74.58 59.58 74.58 C\n"
"        60.7 73.46 71.16 73.56 72.34 74.58 C\n"
"        73.56 75.62 71.88 80.66 71.66 82 C\n"
"        69.7 93.84 57 96.68 48.42 101.42 C\n"
"        cl\n"
"\n"
"        % inside of 6 \n"
"        31.58 16.58 m\n"
"        42.7 10.4 53.32 21.9 55 32 C\n"
"        56.56 41.32 51.24 46.9 44.42 51.42 C\n"
"        35.68 57.26 28.78 48.22 25.66 42 C\n"
"        21.42 33.5 21.92 21.94 31.58 16.58 C\n"
"        cl\n"
" } def\n"
"\n"
"% string 7\n"
"%BBOX: 0.0 -1 70 100\n"
" /string7height 100   symbolscale mul def\n"
" /string7width   70   symbolscale mul def\n"
" /string7left     0            def\n"
" /string7below   -1   symbolscale mul def\n"
" /string7shape {\n"
"        67.92 99.42 m\n"
"        65.88 100.24 67.02 100 64.5 100 C\n"
"        4.5 100 l\n"
"        -1.7 100 -1.2 82.62 2.5 82 C\n"
"        13.16 80.22 25.68 82 36.5 82 C\n"
"        38.2 82 46.82 83.06 47.64 81.42 C\n"
"        49.4 77.94 38.72 66.84 36.8 64.04 C\n"
"        27.14 49.96 23.6 33.6 17.7 18 C\n"
"        16.34 14.42 11.46 4.18 15.08 0.58 C\n"
"        16.74 -1.1 34.26 -1.1 35.92 0.58 C\n"
"        37.32 1.96 36.5 6.22 36.5 8 C\n"
"        36.5 15.04 37.92 21.14 39.3 28 C\n"
"        41.9 41 47.26 55.06 54.82 66.06 C\n"
"        62.2 76.8 73.92 84.46 67.92 99.42 C\n"
"        cl \n"
" } def\n"
"\n"
"% string 8\n"
"%BBOX: 0.0 -1.5 76 104.3\n"
" /string8height 104.3 symbolscale mul def\n"
" /string8width   76   symbolscale mul def\n"
" /string8left     0            def\n"
" /string8below   -1.5 symbolscale mul def\n"
" /string8shape {\n"
"        % outside of 8\n"
"        39.42 103.42 m\n"
"        36.78 104.9 32.76 103.36 30 102.8 C\n"
"        19.12 100.62 6 92.04 4 80 C\n"
"        3.08 74.46 3.36 64.34 8.28 60.58 C\n"
"        9.9 59.34 16.86 58.3 16.86 55.72 C\n"
"        16.86 54.18 8.7 50.12 7.34 48 C\n"
"        -1.72 33.92 -4.66 16.3 12.12 6.06 C\n"
"        38.9 -10.32 78.64 -0.88 76 36 C\n"
"        75.54 42.32 71.16 46.9 66 49.9 C\n"
"        64.9 50.54 59.14 52.52 59.14 54 C\n"
"        59.14 55.02 62.54 56.84 63.2 57.6 C\n"
"        66.08 60.92 71.3 67.74 72 72 C\n"
"        74.32 85.88 61.36 99.78 48 102 C\n"
"        44.62 102.56 42.52 101.7 39.42 103.42 C\n"
"        cl\n"
"\n"
"        % bottom inside of 8  \n"
"        30.58 14.58 m\n"
"        40.66 8.96 54.28 17.68 56 28 C\n"
"        57.44 36.64 51.58 41.32 45.42 45.42 C\n"
"        35.52 52.04 21.64 41.82 20 32 C\n"
"        18.82 24.96 25 17.68 30.58 14.58 C\n"
"        cl\n"
"\n"
"        % top inside of 8\n"
"        41.42 87.34 m\n"
"        31.48 91.58 21.32 78.94 22.28 70 C\n"
"        22.74 65.8 29.46 62.64 32.58 60.58 C\n"
"        41.06 54.92 53.68 65.5 53.86 74 C\n"
"        54.04 82.5 47.56 84.72 41.42 87.34 C\n"
"        cl\n"
" } def\n"
"        \n"
"\n"
"% string 9\n"
"%BBOX: 0.0 -2.4 75 102.5\n"
" /string9height 102.5 symbolscale mul def\n"
" /string9width   75   symbolscale mul def\n"
" /string9left     0            def\n"
" /string9below   -2.4 symbolscale mul def\n"
" /string9shape {\n"
"        % outside of 9\n"
"        45.42 101.42 m\n"
"        42.54 103.02 37.24 102 34 102 C\n"
"        9.06 102 -6.26 72.4 2.14 50 C\n"
"        6.94 37.24 30.22 29.9 42 33.6 C\n"
"        44.38 34.34 47.9 36.28 49.42 38.28 C\n"
"        49.98 39 51.5 45.04 53.42 43.42 C\n"
"        55.36 41.82 53.92 34.06 53.34 32 C\n"
"        50.66 22.66 40 7.48 28.2 14.58 C\n"
"        24.92 16.54 22.26 25.62 20 26 C\n"
"        17.38 26.44 4.34 27.42 2.66 25.42 C\n"
"        -0.28 21.9 5.84 10.74 8.28 8.28 C\n"
"        28.16 -11.58 57.94 -1.92 67.9 22 C\n"
"        75.38 39.92 79.34 71.14 65.82 87.78 C\n"
"        60.66 94.12 51.86 97.86 45.42 101.42 C\n"
"        cl\n"
"\n"
"        % inside of 9 \n"
"        39.42 85.42 m\n"
"        30.18 90.56 26.62 79.42 23 74 C\n"
"        16.54 64.32 21.68 54.98 30.58 48.58 C\n"
"        39.22 42.34 50.72 54.34 52 62 C\n"
"        53.92 73.48 48.94 80.14 39.42 85.42 C\n"
"        cl \n"
" } def\n"
"\n"
"% string 10\n"
"%BBOX: 0.0 -1 99.5 103\n"
" /string10height 103   symbolscale mul def\n"
" /string10width   99.5 symbolscale mul def\n"
" /string10left     0            def\n"
" /string10below   -1   symbolscale mul def\n"
" /string10shape {\n"
"        % outside of A\n"
"        60.92 101.42 m\n"
"        58.26 102.92 40.28 103.64 38.08 101.42 C\n"
"        35.6 98.96 34.24 87.86 32.5 84 C\n"
"        24.66 66.68 18.56 47.92 12.16 30 C\n"
"        9.54 22.62 6.6 15.24 3.6 8 C\n"
"        3.3 7.3 0 0.66 0.08 0.58 C\n"
"        1.68 -1.04 7.38 0 9.5 0 C\n"
"        13.08 0 22.28 -1.76 24.16 2 C\n"
"        25.94 5.54 28.62 23.52 31.5 24 C\n"
"        40.28 25.46 50.58 24 59.5 24 C\n"
"        61.96 24 67.04 24.98 69.12 23.42 C\n"
"        75.16 18.9 71.64 5 76.08 0.58 C\n"
"        78.46 -1.82 94.08 -0.56 97.5 0 C\n"
"        101.68 0.7 98.32 7.78 97.4 10 C\n"
"        93.58 19.18 89.98 28.56 86.84 38 C\n"
"        81.66 53.52 74.68 68.46 69.5 84 C\n"
"        67.84 88.98 65.84 98.7 60.92 101.42 C\n"
"        cl\n"
"\n"
"        %inside of A \n"
"        51.22 76.86 m\n"
"        50.22 76.86 49.08 72.66 48.84 72 C\n"
"        46.68 65.98 44.18 60.04 42.16 54 C\n"
"        41.26 51.28 35.72 40 37.5 40 C\n"
"        42.12 40 48.12 42 53.5 42 C\n"
"        55.28 42 62.02 39.56 62.92 40.58 C\n"
"        65.32 43.22 57.88 58.94 56.5 62 C\n"
"        55.24 64.8 51.96 69.2 51.5 72 C\n"
"        51.44 72.36 51.82 76.86 51.22 76.86 C\n"
"        cl \n"
" } def\n"
"\n"
"% string 11\n"
"%BBOX: 0.0 0 87 102\n"
" /string11height 102   symbolscale mul def\n"
" /string11width   87   symbolscale mul def\n"
" /string11left     0            def\n"
" /string11below    0            def\n"
" /string11shape {\n"
"        % outside of B\n"
"        61.42 101.42 m\n"
"        59.38 102.24 60.52 102 58 102 C\n"
"        4 102 l\n"
"        0.66 102 0 101.34 0 98 C\n"
"        0 4 l\n"
"        0 0.66 0.66 0 4 0 C\n"
"        56 0 l\n"
"        75.5 0 93.18 22.9 85 42 C\n"
"        82.66 47.46 79.18 50.28 74 53 C\n"
"        73.14 53.44 69.14 54.68 69.14 56 C\n"
"        69.14 58.08 79.76 68.06 81.42 70.58 C\n"
"        82.7 72.46 82 75.84 82 78 C\n"
"        82 93.64 71.48 93.9 61.42 101.42 C\n"
"        cl\n"
"\n"
"        % bottom inside of B \n"
"        22.58 18.58 m\n"
"        24.6 16.54 33.24 18 36 18 C\n"
"        41.96 18 52.74 15.92 58 19 C\n"
"        63.3 22.08 65.92 35.14 61.72 39.8 C\n"
"        54.16 48.22 44.52 46 34 46 C\n"
"        31.56 46 24.38 47.24 22.58 45.42 C\n"
"        20.64 43.5 20.64 20.5 22.58 18.58 C\n"
"        cl\n"
"\n"
"        % top inside of B\n"
"        53.42 83.42 m\n"
"        48.2 86.34 36 84 30 84 C\n"
"        28.22 84 23.96 84.82 22.58 83.42 C\n"
"        20.76 81.62 22 74.44 22 72 C\n"
"        22 69.88 20.96 64.18 22.58 62.58 C\n"
"        24.38 60.76 31.56 62 34 62 C\n"
"        39.66 62 48.88 60.24 54 63 C\n"
"        63.18 67.94 61.06 79.18 53.42 83.42 C\n"
"        cl \n"
" } def\n"
"\n"
"% string 12\n"
"%BBOX: 0.0 -2.5 97 104.5\n"
" /string12height 104.5 symbolscale mul def\n"
" /string12width   97   symbolscale mul def\n"
" /string12left     0            def\n"
" /string12below   -2.5 symbolscale mul def\n"
" /string12shape {\n"
"        95.92 34.58 m\n"
"        100.16 42.2 77.8 42.16 75.08 39.42 C\n"
"        72.32 36.68 73.34 29.66 70.22 26.2 C\n"
"        59.34 14.1 42.24 13.4 31.08 24.58 C\n"
"        28.48 27.16 27 34.48 25.84 38 C\n"
"        21.72 50.36 20.42 66.78 31.08 77.42 C\n"
"        34.9 81.24 44.2 82.98 49.08 85.34 C\n"
"        57.18 89.24 67.88 79.04 71.92 73.42 C\n"
"        73.3 71.54 71.38 68.52 74.5 68 C\n"
"        77.68 67.46 93.92 66.5 94.5 70 C\n"
"        96.44 81.58 85.68 91.42 76.5 96 C\n"
"        60.18 104.16 34.12 110.78 19.16 94.34 C\n"
"        2.74 76.28 -4.52 51.36 3.84 28 C\n"
"        12.94 2.48 51.54 -10.12 74.5 3 C\n"
"        87.14 10.22 89.76 23.48 95.92 34.58 C\n"
"        cl\n"
" } def\n"
"\n"
"% string 13\n"
"%BBOX: 0.0 0 94.12 102.24\n"
" /string13height 102.24 symbolscale mul def\n"
" /string13width   94.12 symbolscale mul def\n"
" /string13left     0             def\n"
" /string13below    0             def\n"
" /string13shape {\n"
"        % outside of D\n"
"        0.82 101.42 m\n"
"        0 99.38 0.24 100.52 0.24 98 C\n"
"        0.24 4 l\n"
"        0.24 0.66 0.9 0 4.24 0 C\n"
"        52.24 0 l\n"
"        70.1 0 81.06 14.48 86.24 30 C\n"
"        94.12 53.64 92.66 79.08 70.24 94.28 C\n"
"        65.86 97.26 57.48 102 52.24 102 C\n"
"        4.24 102 l\n"
"        1.72 102 2.86 102.24 0.82 101.42 C\n"
"        cl\n"
"\n"
"        % inside of D\n"
"        24.82 81.42 m\n"
"        24 79.38 24.24 80.52 24.24 78 C\n"
"        24.24 24 l\n"
"        24.24 17.48 51.42 18.12 56.04 22.28 C\n"
"        67.44 32.54 71.42 58.72 63.24 72 C\n"
"        57.08 82 35.16 85.58 24.82 81.42 C\n"
"        cl \n"
"} def\n"
"\n"
"\n"
"% sha arpeggio\n"
"%BBOX: 0.0 0.0 11 100\n"
" /shaheight   100.0 symbolscale mul def\n"
" /shawidth     11.0 symbolscale mul def\n"
" /shaleft       0                   def\n"
" /shabelow      0                   def\n"
" /shashape {\n"
"        0 100 m\n"
"        2 100 l\n"
"        10 81 l\n"
"        10 79 l\n"
"        2 60 l\n"
"        10 41 l\n"
"        10 39 l\n"
"        2 20 l\n"
"        10 0 l\n"
"        8 0 l\n"
"        0 19 l\n"
"        0 21 l\n"
"        8 40 l\n"
"        0 59 l\n"
"        0 61 l\n"
"        8 80 l\n"
"        0 100 l\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"% Wa technique\n"
"%BBOX:  8.50 3.23 110.45 121.8\n"
" /waheight   121.8 symbolscale mul def\n"
" /wawidth    110.45 symbolscale mul def\n"
" /waleft      -8.5  symbolscale mul def\n"
" /wabelow     -3.23 symbolscale mul def\n"
" /washape {\n"
"	43.29 4.29 m\n"
"	45.93 3.23 48.47 5.12 51.00 5.75 C\n"
"	60.99 8.25 66.25 14.44 73.15 21.64 C\n"
"	76.97 25.62 81.80 29.54 84.94 34.08 C\n"
"	87.72 38.09 89.18 42.76 91.50 47.00 C\n"
"	93.86 51.31 97.20 55.39 98.93 60.00 C\n"
"	102.82 70.39 104.85 81.94 105.40 93.00 C\n"
"	105.58 96.51 105.21 100.58 105.95 104.00 C\n"
"	106.45 106.29 109.55 106.30 110.00 109.00 C\n"
"	110.45 111.72 104.74 116.22 102.71 117.71 C\n"
"	97.19 121.80 94.33 112.55 91.00 112.00 C\n"
"	86.83 111.30 82.24 112.24 78.00 111.91 C\n"
"	64.43 110.85 49.01 110.05 36.00 106.33 C\n"
"	28.89 104.30 25.88 111.14 20.75 115.33 C\n"
"	18.64 117.06 14.36 119.93 11.71 117.29 C\n"
"	8.50 114.07 14.63 113.28 15.01 111.00 C\n"
"	15.74 106.56 15.19 101.51 15.28 97.00 C\n"
"	15.45 88.33 15.63 79.67 15.80 71.00 C\n"
"	15.85 68.48 14.96 63.26 16.28 61.10 C\n"
"	18.61 57.28 28.00 55.92 28.00 62.00 C\n"
"	28.00 97.00 l\n"
"	28.00 100.27 37.19 99.37 40.00 99.57 C\n"
"	53.27 100.52 66.86 102.14 80.00 104.33 C\n"
"	83.67 104.94 86.14 106.00 90.00 106.00 C\n"
"	91.15 106.00 93.73 106.60 94.00 105.00 C\n"
"	97.21 85.75 91.59 66.99 83.50 50.00 C\n"
"	81.19 45.14 78.95 38.30 75.28 34.28 C\n"
"	67.81 26.09 59.38 17.95 51.71 10.29 C\n"
"	50.56 9.13 47.48 9.86 46.00 8.79 C\n"
"	45.22 8.22 45.06 7.18 44.00 7.00 C\n"
"	43.02 6.84 41.08 7.51 40.29 6.71 C\n"
"	38.73 5.16 42.62 4.79 43.29 4.29 C\n"
"	cl\n"
"} def\n"
"\n"
"\n"
"% Hiku technique\n"
"%BBOX:  0 0 50 25\n"
" /hikiheight   25 symbolscale mul def\n"
" /hikiwidth    50 symbolscale mul def\n"
" /hikileft      0 symbolscale mul def\n"
" /hikibelow     0 symbolscale mul def\n"
" /hikishape {\n"
"\n"
"	27 21 m\n"
"	48 21 l\n"
"	37.5 3 l\n"
"	27 21 l\n"
"	cl\n"
"\n"
"	0 25 m\n"
"	50 25 l\n"
"	37.5 0 l\n"
"	25 21 l\n"
"	0 21 l\n"
"	0 25 l\n"
"	cl\n"
"} def\n"
"\n"
"\n"
"\n"
"% augmentation dot\n"
"%BBOX: 0.0 0.0 32 32\n"
" /augdotheight   32.0 symbolscale mul def\n"
" /augdotwidth    32.0 symbolscale mul def\n"
" /augdotleft     0                    def\n"
" /augdotbelow    0                    def\n"
" /augdotshape {\n"
"        16 8 8 0 360 arc\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"\n"
"% doublesharp\n"
"%BBOX: 0.0 0.0 50 25\n"
" /doublesharpheight  25.0 symbolscale mul def\n"
" /doublesharpwidth   50.0 symbolscale mul def\n"
" /doublesharpleft     0                    def\n"
" /doublesharpbelow    0                    def\n"
" /doublesharpshape {\n"
"        0 0 m\n"
"        50 0 l\n"
"        25 25 l\n"
"        0 0 l\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"\n"
"% sharp\n"
"%BBOX: 0.0 0.0 50 25\n"
" /sharpheight  25.0 symbolscale mul def\n"
" /sharpwidth   50.0 symbolscale mul def\n"
" /sharpleft     0                   def\n"
" /sharpbelow    0                   def\n"
" /sharpshape {\n"
"        % outside of sharp\n"
"        0 0 m\n"
"        50 0 l\n"
"        25 25 l\n"
"        0 0 l\n"
"        cl\n"
"\n"
"        % inside of sharp sign\n"
"        1 1 m\n"
"        49 1 l\n"
"        25 24 l\n"
"        1 1 l\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"\n"
"% triple sharp\n"
"%BBOX: 0.0 0.0 50 50\n"
" /triplesharpheight  50.0  symbolscale mul def\n"
" /triplesharpwidth   50.0  symbolscale mul def\n"
" /triplesharpleft     0                    def\n"
" /triplesharpbelow    0                    def\n"
" /triplesharpshape {\n"
"        % outside of sharp\n"
"        0 0 m\n"
"        50 0 l\n"
"        25 50 l\n"
"        0 0 l\n"
"        cl\n"
"\n"
"        % inside of sharp\n"
"        1 1 m\n"
"        49 1 l\n"
"        25 49 l\n"
"        1 1 l\n"
"        cl\n"
"\n"
"        % double sharp marker\n"
"        10  7   m\n"
"        40  7   l\n"
"        25 36.5 l\n"
"        10  7   l\n"
"        cl\n"
"\n"
" } def\n"
"\n"
"\n"
"% oshi\n"
"%BBOX: 0.0 0.0 50 25\n"
" /oshiheight  25.0  symbolscale mul def\n"
" /oshiwidth   50.0  symbolscale mul def\n"
" /oshileft     0                    def\n"
" /oshibelow    0                    def\n"
" /oshishape {\n"
"        0 0 m\n"
"        50 0 l\n"
"        37.5 25 l\n"
"        25 4 l\n"
"        0 4 l\n"
"        0 0 l\n"
"        cl\n"
"\n"
" } def\n"
"\n"
"\n"
"\n"
"% oshith\n"
"%BBOX: 0.0 0.0 75 25\n"
" /oshithheight  25.0  symbolscale mul def\n"
" /oshithwidth   75.0  symbolscale mul def\n"
" /oshithleft     0                    def\n"
" /oshithbelow    0                    def\n"
" /oshithshape {\n"
"        0  0 m\n"
"        75 0 l\n"
"        75 4 l\n"
"        62.5 4 l\n"
"        50 25 l\n"
"        25 25 l\n"
"        12.5 4 l\n"
"        0 4 l\n"
"        0 0 l\n"
"        cl\n"
" } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% drawstring -- draw a string note object.\n"
"%%\n"
"\n"
" /StringDict 10 dict def\n"
" /drawstring { gsave\n"
"        StringDict begin\n"
"        /left     exch def        % negative width to left of align point\n"
"        /below    exch def        % negative height below align point\n"
"        /width    exch def        % width to right of align point\n"
"        /height   exch def        % height above align point\n"
"        /shape    exch def        % lines to create shape\n"
"        /sscale          exch def        % scaling for object\n"
"        /vpos     exch def        % vertical position\n"
"        /hpos     exch def        % vertical position\n"
"\n"
"        hpos vpos translate        % move to object position (centered)\n"
;

if (debugQ) {
   out <<
"        % draw the bounding box for objects (for debugging)\n"
"        0 1 0 setrgbcolor\n"
"        0.0 w\n"
"        left  sscale mul below  sscale mul m\n"
"        left  sscale mul height sscale mul l\n"
"        width sscale mul height sscale mul l\n"
"        width sscale mul below  sscale mul l\n"
"        left  sscale mul below  sscale mul l\n"
"        cl s\n"
"  \n";
}

   out <<
"        symbolscale sscale mul dup scale % nominal size times input scale\n"
"\n"
"        red green blue setrgbcolor\n"
"        0.000 w\n"
"        shape\n"
"        eofill\n"
"        s\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% string0 to string13 -- write correct marker for string\n"
"%% 3 Parameters:\n"
"%%    position x, position y, scale\n"
"%%\n"
"%%\n"
"\n"
" /string0  { //string0shape string0height string0width  string0below string0left\n"
"             drawstring } def\n"
" /string1  { //string1shape string1height string1width  string1below string1left\n"
"             drawstring } def\n"
" /string2  { //string2shape string2height string2width  string2below string2left\n"
"             drawstring } def\n"
" /string3  { //string3shape string3height string3width  string3below string3left\n"
"             drawstring } def\n"
" /string4  { //string4shape string4height string4width  string4below string4left\n"
"             drawstring } def\n"
" /string5  { //string5shape string5height string5width  string5below string5left\n"
"             drawstring } def\n"
" /string6  { //string6shape string6height string6width  string6below string6left\n"
"             drawstring } def\n"
" /string7  { //string7shape string7height string7width  string7below string7left\n"
"             drawstring } def\n"
" /string8  { //string8shape string8height string8width  string8below string8left\n"
"             drawstring } def\n"
" /string9  { //string9shape string9height string9width  string9below string9left\n"
"             drawstring } def\n"
" /string10 { //string10shape string10height string10width  string10below \n"
"             string10left drawstring } def\n"
" /string11 { //string11shape string11height string11width  string11below \n"
"             string11left drawstring } def\n"
" /string12 { //string12shape string12height string12width  string12below \n"
"             string12left drawstring } def\n"
" /string13 { //string13shape string13height string13width  string13below \n"
"             string13left drawstring } def\n"
" /dash     { //dashshape dashheight dashwidth  dashbelow \n"
"             dashleft drawstring } def\n"
" /sharp    { //sharpshape sharpheight sharpwidth sharpbelow sharpleft\n"
"             drawstring } def\n"
" /doublesharp  { //doublesharpshape doublesharpheight doublesharpwidth \n"
"                doublesharpbelow doublesharpleft drawstring } def\n"
" /triplesharp  { //triplesharpshape triplesharpheight triplesharpwidth \n"
"                triplesharpbelow triplesharpleft drawstring } def\n"
" /oshi     { //oshishape oshiheight oshiwidth \n"
"                oshibelow oshileft drawstring } def\n"
" /oshith   { //oshithshape oshithheight oshithwidth \n"
"                oshithbelow oshithleft drawstring } def\n"
" /wa       { //washape waheight wawidth \n"
"                wabelow waleft drawstring } def\n"
" /Zu       { //Zushape Zuheight Zuwidth \n"
"                Zubelow Zuleft drawstring } def\n"
" /zu       { //zushape zuheight zuwidth \n"
"                zubelow zuleft drawstring } def\n"
" /hiki     { //hikishape hikiheight hikiwidth \n"
"                hikibelow hikileft drawstring } def\n"
" /sha      { //shashape shaheight shawidth \n"
"                shabelow shaleft drawstring } def\n"
" /augdot   { //augdotshape augdotheight augdotwidth \n"
"                augdotbelow augdotleft drawstring } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% beam -- draw a beam\n"
"%%\n"
"\n"
" /beam { gsave\n"
"        BarDict begin\n"
"        /sscale exch def                % scale factor for barline\n"
"        /level  exch def                % beaming level\n"
"        /width  exch def                % width of beam (absolute size)\n"
"        /vpos   exch def                % horizontal position\n"
"        /hpos   exch def                % vertical position\n"
"        /bheight 1.5 sscale mul def        % height of beams\n"
"        /bspace  1.0 sscale mul def        % spacing between beams\n"
"        /vposcur 0.0 def\n"
"\n"
"        red green blue setrgbcolor\n"
"\n"
"        hpos vpos m\n"
"        hpos width add vpos l\n"
"        hpos width add vpos bheight sub l\n"
"        hpos vpos bheight sub l\n"
"        hpos vpos l\n"
"        cl f s\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"% /oldbeam { gsave\n"
"%        BarDict begin\n"
"%        /sscale exch def                % scale factor for barline\n"
"%        /level  exch def                % beaming level\n"
"%        /width  exch def                % width of beam (absolute size)\n"
"%        /vpos   exch def                % horizontal position\n"
"%        /hpos   exch def                % vertical position\n"
"%        /bheight 1.5 sscale mul def        % height of beams\n"
"%        /bspace  1.0 sscale mul def        % spacing between beams\n"
"%        /vposcur 0.0 def\n"
"%\n"
"%        red green blue setrgbcolor\n"
"%        \n"
"%        1 level {\n"
"%                dup\n"
"%                /vposcur exch dup bspace mul vpos exch sub exch 1 sub\n"
"%                        bheight mul sub def\n"
"%                1 add\n"
"%                hpos vposcur m\n"
"%                hpos width add vposcur l\n"
"%                hpos width add vposcur bheight sub l\n"
"%                hpos vposcur bheight sub l\n"
"%                hpos vposcur l\n"
"%                cl f\n"
"%        } repeat\n"
"%        s\n"
"%\n"
"%        end\n"
"% grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% finger -- draw a fingering number\n"
"%%\n"
"\n"
" /finger { gsave\n"
"        BarDict begin\n"
"        /fnum   exch def                % fingering number\n"
"        /sscale exch def                % scale factor for barline\n"
"        /level  exch def                % beaming level\n"
"        /offset exch def                % offset from note number\n"
"        /vpos   exch def                % horizontal position\n"
"        /hpos   exch def                % vertical position\n"
"        /fsz        6.0 sscale mul def\n"
"        /bheight 1.5 sscale mul def        % height of beams (same as beam fun.)\n"
"        /bspace  1.0 sscale mul def        % spacing between beams (same as beam)\n"
"        \n"
"        /fvpos vpos level 1 add bspace mul sub bheight level 1 sub mul sub \n"
"                fsz sub def\n"
"        % pop  % extra number bug right now (2)\n"
"\n"
"        red green blue setrgbcolor\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        hpos offset add fvpos fnum centershow\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% textabove -- draw text above a staff\n"
"%%\n"
"\n"
" /textabove { gsave\n"
"        BarDict begin\n"
"        /text   exch def                % text to display\n"
"        /fsize  exch def                % fontsize\n"
"        /font   exch def                % fontname\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % horizontal position\n"
"        /hpos   exch def                % vertical position\n"
"        \n"
"        red green blue setrgbcolor\n"
"        font findfont fsize sscale mul scalefont setfont\n"
"        hpos vpos m text show\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% textbelow -- draw text above a staff\n"
"%%\n"
"\n"
" /textbelow { gsave\n"
"        BarDict begin\n"
"        /text   exch def                % text to display\n"
"        /fsize  exch def                % fontsize\n"
"        /font   exch def                % fontname\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % horizontal position\n"
"        /hpos   exch def                % vertical position\n"
"        \n"
"        red green blue setrgbcolor\n"
"        font findfont fsize sscale mul scalefont setfont\n"
"        hpos vpos m text show\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% verse -- print lyrics (below the music)\n"
"%%\n"
"\n"
" /verse { gsave\n"
"        BarDict begin\n"
"        /just   exch def                % justification\n"
"        /vnum   exch def                % verse number of lyric\n"
"        /text   exch def                % text to display\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % horizontal position\n"
"        /hpos   exch def                % vertical position\n"
"        /fsize  8 sscale mul def        % fontsize for lyric\n"
"        /font   /HelveticaNarrow def    % fontname\n"
"	/dspace 13 def			% spacing below the vertical position\n"
"	/newvpos vpos dspace sub fsize vnum mul sub def\n"
"        \n"
"        red green blue setrgbcolor\n"
"        font findfont fsize sscale mul scalefont setfont\n"
"	just 0 eq {\n"
"           hpos newvpos text centershow\n"
"	} if\n"
"	just -1 eq {\n"
"           hpos newvpos text centershow\n"
"	} if\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% pagenumber -- draw a page number whereever\n"
"%% Input parameters:\n"
"%%        fsz = font size\n"
"%%        text = text for page number\n"
"%%\n"
"\n"
" /pagenumber { gsave\n"
"        BarDict begin\n"
"        /text  exch def\n"
"        /fsz   exch def\n"
"\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        pagewidth 2 div bmargin fsz sub 2.0 sub text centershow\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% title -- print the title\n"
"%% Input parameters:\n"
"%%        fsz = font size\n"
"%%        text = text for page number\n"
"%%\n"
"\n"
" /title { gsave\n"
"        BarDict begin\n"
"        /text  exch def\n"
"        /fsz   exch def\n"
"\n"
"        0 0 0 setrgbcolor\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        pagewidth 2 div pageheight tmargin sub 40.0 add text centershow\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% composer -- print the composer\n"
"%% Input parameters:\n"
"%%        fsz = font size\n"
"%%        text = Composer name\n"
"%%        text = composer dates\n"
"%%\n"
"\n"
" /composer { gsave\n"
"        BarDict begin\n"
"        /date  exch def\n"
"        /text  exch def\n"
"        /fsz   exch def\n"
"\n"
"        0 0 0 setrgbcolor\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        pagewidth rmargin sub pageheight tmargin sub fsz 2 mul \n"
"                add text rightshow\n"
"        pagewidth rmargin sub pageheight tmargin sub fsz add date rightshow\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% tuning -- print the tuning directions for the koto\n"
"%% Input parameters:\n"
"%%        fsz = font size\n"
"%%        text = free-form tuning direction\n"
"%%\n"
"\n"
" /tuning { gsave\n"
"        BarDict begin\n"
"        /text  exch def\n"
"        /fsz   exch def\n"
"\n"
"        0 0 0 setrgbcolor\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        lmargin pageheight tmargin sub moveto text show\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% titlefooter -- print the title information at the bottom of the page\n"
"%%     (on pages other than the first page).\n"
"%% Input parameters:\n"
"%%        fsz = font size\n"
"%%        text = text for page number\n"
"%%\n"
"\n"
" /titlefooter { gsave\n"
"        BarDict begin\n"
"        /text  exch def\n"
"        /fsz   exch def\n"
"\n"
"        0 0 0 setrgbcolor\n"
"        /Times-Roman findfont fsz scalefont setfont\n"
"        20 20 m text show\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% cbar -- make a center-justified barline.  Barline's center will match\n"
"%%     the horizontal position given as input to the function.\n"
"%% 3 Parameters:\n"
"%%    horizontal position, vertical start position, sscale\n"
"%%\n"
"\n"
"/BarDict 10 dict def\n"
"\n"
"/cbar { gsave\n"
"        BarDict begin\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % vertical position of the baseline\n"
"        /hpos   exch def                % horizontal position\n"
"        /downunits 50.0 sscale symbolscale mul mul def % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def % ext above baseline\n"
"        /lwidth     4.0 sscale symbolscale mul mul def % line width for barline\n"
"        red green blue setrgbcolor\n"
"        lwidth w\n"
"        hpos vpos downunits sub m\n"
"        hpos vpos upunits   add l\n"
"        s\n"
"        end\n"
"grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% doublebar -- make a double-lined thin barline.  \n"
"%%     the horizontal position given as input to the function.\n"
"%% 3 Parameters:\n"
"%%           horizontal position, \n"
"%%        vertical start position, \n"
"%%        sscale\n"
"%%        centering\n"
"%%\n"
"\n"
"%BBOX: 0 -50 16 130\n"
"/doublebar { gsave\n"
"        BarDict begin\n"
"        /sscale  exch def                % scale factor for barline\n"
"        /vpos    exch def                % vertical position of the baseline\n"
"        /hpos    exch def                % horizontal position\n"
"        /downunits 50.0 sscale symbolscale mul mul def        % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def        % ext above baseline\n"
"        /lwidth     4.0 sscale symbolscale mul mul def        % line width for barline\n"
"        /offset     lwidth def                % offset to justify\n"
"        red green blue setrgbcolor\n"
"        lwidth w\n"
"\n"
"        hpos vpos translate\n"
"        0 -1 downunits mul m\n"
"        0 upunits l\n"
"        lwidth upunits l\n"
"        lwidth -1 downunits mul l\n"
"        0 -1 downunits mul l\n"
"        cl \n"
"\n"
"        12.0 sscale symbolscale mul mul 0.0 translate\n"
"        0 -1 downunits mul m\n"
"        0 upunits l\n"
"        lwidth upunits l\n"
"        lwidth -1 downunits mul l\n"
"        0 -1 downunits mul l\n"
"        cl \n"
"\n"
"        f s\n"
"        end\n"
"grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% lbar -- make a left-justified barline.  Barline's left edge will match\n"
"%%     the horizontal position given as input to the function.\n"
"%% 3 Parameters:\n"
"%%    horizontal position, vertical start position, sscale\n"
"%%\n"
"\n"
"/lbar { gsave\n"
"        BarDict begin\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % vertical position of the baseline\n"
"        /hpos   exch def                % horizontal position\n"
"        /downunits 50.0 sscale symbolscale mul mul def        % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def        % ext above baseline\n"
"        /lwidth     4.0 sscale symbolscale mul mul def        % line width for barline\n"
"        /offset     lwidth def                % offset to justify\n"
"        red green blue setrgbcolor\n"
"        lwidth w\n"
"        hpos vpos translate\n"
"        0 -1 downunits mul m\n"
"        0 upunits l\n"
"        lwidth upunits l\n"
"        lwidth -1 downunits mul l\n"
"        0 -1 downunits mul l\n"
"        cl f s\n"
"        end\n"
"grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% rbar -- make a right-justified barline.  Barline edge will match\n"
"%%     the horizontal position given as input to the function.\n"
"%% 3 Parameters:\n"
"%%    horizontal position, vertical start position, sscale\n"
"%%\n"
"\n"
"/rbar { gsave\n"
"        BarDict begin\n"
"        /sscale exch def                % scale factor for barline\n"
"        /vpos   exch def                % vertical position of baseline\n"
"        /hpos   exch def                % horizontal position\n"
"        /downunits 50.0 sscale symbolscale mul mul def % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def % ext above baseline\n"
"        /lwidth     4.0 sscale symbolscale mul mul def % line width for barline\n"
"        /offset     lwidth 2.0 div def        % offset to justify\n"
"        red green blue setrgbcolor\n"
"        lwidth w\n"
"        hpos offset sub vpos downunits sub m\n"
"        hpos offset sub vpos upunits   add l\n"
"        s\n"
"        end\n"
"grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% sbar -- system barline.\n"
"%% 3 Parameters:\n"
"%%    horizontal position, vertical start position, sscale\n"
"%%\n"
"\n"
"/SystemBarDict 10 dict def\n"
"/sbar { gsave\n"
"        SystemBarDict begin\n"
"        /sscale    exch def\n"
"        /vpos      exch def\n"
"        /hpos      exch def\n"
"        /lwidth    20   sscale symbolscale mul mul def\n"
"        /downunits 50.0 sscale symbolscale mul mul def   % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def   % ext above baseline\n"
"        /sspacing  10.0 sscale symbolscale mul mul def\n"
"        /offset     lwidth 0.5 mul def\n"
"\n"
"        red green blue setrgbcolor\n"
"\n"
"        lwidth w\n"
"        hpos offset add vpos downunits sub m\n"
"        hpos offset add vpos upunits   add l\n"
"        s\n"
"\n"
"        4 symbolscale sscale mul mul w\n"
"        hpos offset 2 mul add sspacing add vpos downunits sub m\n"
"        hpos offset 2 mul add sspacing add vpos upunits   add l\n"
"        s\n"
"\n"
"        end\n"
"grestore\n"
"} def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% fbar -- final barline.\n"
"%%\n"
"\n"
"/SystemBarDict 10 dict def\n"
"/fbar { gsave\n"
"        SystemBarDict begin\n"
"        /sscale    exch def\n"
"        /vpos      exch def\n"
"        /hpos      exch def\n"
"        /lwidth    20   sscale symbolscale mul mul def\n"
"        /downunits 50.0 sscale symbolscale mul mul def   % ext below baseline\n"
"        /upunits  130.0 sscale symbolscale mul mul def   % ext above baseline\n"
"        /sspacing  10.0 sscale symbolscale mul mul def\n"
"        /offset     lwidth 0.5 mul def\n"
"\n"
"        red green blue setrgbcolor\n"
"\n"
"	% narrow part\n"
"        4 symbolscale sscale mul mul w\n"
"        hpos 2 symbolscale sscale mul mul add vpos downunits sub m\n"
"        hpos 2 symbolscale sscale mul mul add vpos upunits   add l\n"
"        s\n"
"\n"
"	% wide part\n"
"        lwidth w\n"
"        hpos offset add 2 symbolscale sscale mul mul add sspacing add vpos downunits sub m\n"
"        hpos offset add 2 symbolscale sscale mul mul add sspacing add vpos upunits   add l\n"
"        s\n"
"\n"
"        end\n"
"grestore\n"
"} def\n"
"\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% rightshow -- display text to the right of a position\n"
"%% input parameters (3):\n"
"%%    horizontal center position\n"
"%%    vertical center position\n"
"%%    text to display\n"
"%%\n"
"\n"
" /rightshow {\n"
"        dup\n"
"        stringwidth pop \n"
"        4 -1 roll exch sub\n"
"        3 -1 roll moveto\n"
"        show\n"
" } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% centershow -- display text in the middle of a position\n"
"%% input parameters (3):\n"
"%%    horizontal center position\n"
"%%    vertical center position\n"
"%%    text to display\n"
"%%\n"
"\n"
" /centershow {\n"
"        dup\n"
"        stringwidth pop 2 div\n"
"        4 -1 roll exch sub\n"
"        3 -1 roll moveto\n"
"        show\n"
" } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% barnum -- print the measure number centered at the given location\n"
"%%\n"
"\n"
" /barnum { gsave\n"
"        StringDict begin\n"
"        /number   exch def      % measure number to display\n"
"        /size     exch def      % scaling of the measure number\n"
"        /vpos     exch def      % vertical position\n"
"        /hpos     exch def      % horizontal position\n"
"\n"
"        red green blue setrgbcolor\n"
"        /Times-Italic findfont size scalefont setfont\n"
"        hpos vpos number centershow\n"
"\n"
"        end\n"
" grestore } def\n"
"\n"
"\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% savecolor --\n"
"%%\n"
"\n"
" /setcolor {\n"
;

if (colorQ) {
   out << 
"        /oldred   red def\n"
"        /oldgreen green def\n"
"        /oldblue  blue def\n"
"        /blue  exch def\n"
"        /green exch def\n"
"        /red   exch def\n"
"  \n";
} else {
   out << 
"	/oldred   exch def\n"
"	/oldgreen exch def\n"
"	/oldblue  exch def\n"
"\n";
}

   out << 
" } def\n"
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% restorecolor -- restore the previous color before last savecolor\n"
"%%\n"
"\n"
" /restorcolor {\n"
"        /red   oldred def\n"
"        /green oldgreen def\n"
"        /blue  oldblue def\n"
" } def\n"
"\n"
"\n"
"/red   0 def\n"
"/green 0 def\n"
"/blue  0 def\n"
"\n";

if (debugQ) {
   out << 
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% spacer -- draw a space for debugging purposes.\n"
"%%\n"
"\n"
" /spacer { gsave\n"
"        StringDict begin\n"
"        /width    exch def        % width in points\n"
"        /vpos           exch def        % vertical position\n"
"        /hpos     exch def        % horizontal position\n"
"        /height   10.0 def        % height in points\n"
"\n"
"        hpos vpos translate        % move to object position (centered)\n"
"\n"
"        0.0 0.8 0.2 setrgbcolor\n"
"        0.0 w\n"
"        0 0 m\n"
"        0 height l\n"
"        width height l\n"
"        width -1 height mul l\n"
"        0 -1 height mul l\n"
"        0 0 l\n"
"        cl \n"
"        s\n"
"\n"
"        end\n"
" grestore } def\n"
;

} else {
   out << 
"\n"
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
"%%\n"
"%% spacer -- draw a space marker for debugging purposes.\n"
"%%\n"
"\n"
" /spacer { gsave\n"
"        StringDict begin\n"
"        /width    exch def        % width in points\n"
"        /vpos           exch def        % vertical position\n"
"        /hpos     exch def        % horizontal position\n"
"        /height   10.0 def        % height in points\n"
"\n"
"%        hpos vpos translate        % move to object position (centered)\n"
"%\n"
"%        0.0 0.8 0.2 setrgbcolor\n"
"%        0 0 m\n"
"%        0 height l\n"
"%        width height l\n"
"%        width -1 height mul l\n"
"%        0 -1 height mul l\n"
"%        0 0 l\n"
"%        cl f s\n"
"        end\n"
" grestore } def\n"
;

}



}




/*
   **koto representation
============================================================================

   Pitch Related Codes
   ===========================================================
   0 = rest
   1 = string 1 (furthest from the performer)
   2 = string 2
   3 = string 3
   4 = string 4
   5 = string 5
   6 = string 6
   7 = string 7
   8 = string 8
   9 = string 9
   A = string 10
   B = string 11
   C = string 12
   D = string 13 (closest to the performer)

   W = wa
   Z = Zu
   z = zu

Rhythm Related Codes
===========================================================

   no rhythm indication = quarter note
   | = half the previous duration
   . = augmentation dots, similar to **kern, first dot adds 1/2 of original
        rhythm, second dot adds 1/4 of original rhythm. 
   - = add one beat to the duration, or without a string, is a place
        holder in the score equal to one beat.

Technique Related Codes
===========================================================

Accidentals:

   #   = sharpen string by a 1/2-step
   ##  = sharpen string by a wholestep
   ### = sharpen string by a 1 and 1/2 steps

Glissandos:
   o = oshi tome: start in natural position, then glissando up a wholetone
        by the end of the note.
   r = oshi tome hanashi: press down, hold and then release.

Fingerings:
   
   a = first finger(thumb) is to be used to play the note
   b = second finger(index finger) is to be used to play the note
   c = third finger(middle finger) is to be used to play the note
   d = fourth finger(ring finger) is to be used to play the note

Other:

   V = repeated string in the reverse direction, string is not indicated
        in score.
   v = same as V, but string is indicated explicitly in the score.
   q = grace note


Preferred form of a **koto datum:
   string -- rhythm -- accidentals -- articulations -- fingerings



Measure Related Codes
===========================================================

   barlines are equivalent to those in the **kern representation

Interpretations
===========================================================

Most **kern interpretations are understood, in particular:

*M4/4        = 4/4 time signature
*MM120        = tempo marking of 120 beats per minute



===========================================================================
===========================================================================

Coding specific to this program

!CLR:xxx   = set the printing color to xxx, where xxx is a particular
                color, or a 6-hex digit color code in the form RRGGBB as
                in HTML color codes.
!!CLR:xxx  = same but for all staves in system



!TXA:xxx             = text above a staff
!TXB:xxx             = text below a staff
!FNT:TR14L    = set text font to Times Roman 14 point left centered 
               at current position
                T = times        R = regular/roman   C = center justify
                H = helvetica    I = italic          L = left justified
                C = courier      B = bold            R = right justified

!!TXA:xxx      = same as !TA:xxx, but applies to whole system
!!TXB:xxx      = same as !TB:xxx, but applies to whole system
!!FNT:xxx      = same as !FT:xxx, but applies to whole system



*/


// md5sum: 14ba8aacbafc505904d44e863935732a koto2eps.cpp [20050403]