// // Programmer: Craig Stuart Sapp // Creation Date: Tue Mar 8 17:05:00 PST 2011 // Last Modified: Sun Mar 27 13:36:19 PDT 2011 added label hyperlinks // Last Modified: Sun Mar 27 17:34:54 PDT 2011 added ref record tooltips // Last Modified: Thu Jun 26 16:07:42 PDT 2014 generalized CSS class markup // Filename: ...sig/examples/all/humtable.cpp // Web Address: http://sig.sapp.org/examples/museinfo/humdrum/humtable.cpp // Syntax: C++; museinfo // // Description: Print Humdrum file as an HTML table. // #include "humdrum.h" #include "PerlRegularExpression.h" #include #include #include #include // function declarations void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void createTable (ostream& out, HumdrumFile& infile); void printGlobalComment (ostream& out, HumdrumFile& infile, int line); void printReferenceRecord (ostream& out, HumdrumFile& infile, int line); void printFields (ostream& out, HumdrumFile& infile, int line); int getSubTracks (HumdrumFile& infile, int line, int track); void addLabelHyperlinks (string& strang); void addLabelHyperlinkName(string& strang); ostream& printHtmlPageHeader (ostream& out); ostream& printHtmlPageFooter (ostream& out); ostream& printHtmlPageFooter (ostream& out); ostream& printCss (ostream& out); ostream& printClassInfo (ostream& out, HumdrumFile& infile, int line); void getMarks (HumdrumFile& infile, string& chars, vector& colors); ostream& printMarkStyle (ostream& out, HumdrumFile& infile, int line, int track, string& chars, vector& colors); void markupKernToken (string& strang, HumdrumFile& infile, int line, int field); void printHtmlCharacter (ostream& out, char ch); void markNullToken (string& strang); // global variables Options options; // database for command-line arguments int fullQ = 1; // used with --page option int classQ = 1; // used with -C option int cssQ = 0; // used with --css option int textareaQ = 0; // used with --textarea option int markQ = 1; // used with -M option int kernQ = 0; // used with -k option string prefix = "hum"; // used with --prefix option string Markchar; vector Markcolor; /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { checkOptions(options, argc, argv); HumdrumFileSet infiles; infiles.read(options); if (fullQ) { printHtmlPageHeader(cout); } else if (cssQ) { printCss(cout); exit(0); } for (int i=0; i\n"; return out; } ////////////////////////////// // // printHtmlPageHeader -- // ostream& printHtmlPageHeader(ostream& out) { out << "\n\nfull page\n"; if (cssQ) { out << "\n\n"; } out << "\n\n\n"; return out; } ////////////////////////////// // // createTable -- // void createTable(ostream& out, HumdrumFile& infile) { if (markQ) { getMarks(infile, Markchar, Markcolor); } else { Markchar.resize(0); Markcolor.resize(0); } out << "
\n"; out << "\n"; int i; for (i=0; i\n"; out << "\n"; if (textareaQ) { out << "\n"; } } ////////////////////////////// // // getMarks -- Return a list of mark characters in **kern data. Only // considering **kern markers for the moment. // void getMarks(HumdrumFile& infile, string& chars, vector& colors) { string defaultcolor = "#dd0000"; string color = defaultcolor; PerlRegularExpression pre; char marker; for (int i=0; i"; int& i = line; int j; int track; int counter; int subtracks; PerlRegularExpression pre; string strang; for (track=1; track<=infile.getMaxTracks(); track++) { subtracks = getSubTracks(infile, line, track); out << ""; if (subtracks > 1) { out << "
"; out << ""; counter = 0; for (j=0; j for now: pre.sar(strang, ">", ">", "g"); pre.sar(strang, "<", "<", "g"); if (pre.search(strang, "^\\*>.*\\[", "")) { addLabelHyperlinks(strang); } else if (pre.search(strang, "^\\*>", "")) { addLabelHyperlinkName(strang); } } out << ""; counter++; } } out << "
" << strang << "
"; } else { for (j=0; j for now: pre.sar(strang, ">", ">", "g"); pre.sar(strang, "<", "<", "g"); if (pre.search(strang, "^\\*>.*\\[", "")) { addLabelHyperlinks(strang); } else if (pre.search(strang, "^\\*>", "")) { addLabelHyperlinkName(strang); } } out << strang; } } } out << ""; } out << "\n"; } ////////////////////////////// // // markNullToken -- // void markNullToken(string& strang) { stringstream buffer; buffer << ""; buffer << "."; buffer << ""; buffer << ends; strang = buffer.str(); } ////////////////////////////// // // markupKernToken -- // void markupKernToken(string& strang, HumdrumFile& infile, int line, int field) { stringstream buffer; string token = infile[line][field]; vector states(token.size(), 0); char ch; for (int i=0; i<(int)token.size(); i++) { if (std::isdigit(token[i])) { states[i] = 2; // part of rhythm continue; } ch = std::tolower(token[i]); if ((ch >= 'a') && (ch <= 'g')) { states[i] = 1; // part of pitch continue; } switch (ch) { case '#': case '-': case 'n': case 'r': states[i] = 1; // pitch break; case '%': case '.': states[i] = 2; // rhythm break; } } int lstate = 0; buffer << ""; if (token == ".") { buffer << "."; } else { for (int i=0; i<(int)token.size(); i++) { if (states[i] == lstate) { // nothing new to markup. printHtmlCharacter(buffer, token[i]); continue; } if ((i > 0) && (lstate > 0)) { // turn off old span buffer << ""; } if (states[i] == 0) { printHtmlCharacter(buffer, token[i]); lstate = states[i]; continue; } // turn on new span: buffer << ""; printHtmlCharacter(buffer, token[i]); lstate = states[i]; } } buffer << ""; buffer << ends; strang = buffer.str(); } ////////////////////////////// // // printHtmlCharacter -- // void printHtmlCharacter(ostream& out, char ch) { switch (ch) { case '>' : out << ">"; break; case '<' : out << "<"; break; case '&' : out << "<"; break; case ' ' : out << " "; break; case '\'': out << "'"; break; case '"' : out << """; break; default : out << ch; } } ////////////////////////////// // // printMarkStyle -- Have to do spine split marks as well. // ostream& printMarkStyle(ostream& out, HumdrumFile& infile, int line, int track, string& chars, vector& colors) { if (!infile[line].isData()) { return out; } int ii, jj; int j; int k; int ttrack; for (j=0; j([^\\[]+)$", "")) { return; } string buffer = ""; buffer += strang; strang = buffer; } ////////////////////////////// // // addLabelHyperlinks -- // void addLabelHyperlinks(string& strang) { PerlRegularExpression pre; if (!pre.search(strang, "^\\*>(.*)\\[(.*)\\]", "")) { return; } string buffer; buffer.reserve(10123); buffer = "*>"; buffer += pre.getSubmatch(1); buffer += "["; PerlRegularExpression pre2; vector tokens; pre2.getTokens(tokens, ",", pre.getSubmatch(2)); int i; for (i=0; i<(int)tokens.size(); i++) { buffer += ""; buffer += tokens[i]; buffer += ""; if (i < (int)tokens.size() - 1) { buffer += ","; } } buffer += "]"; strang = buffer; } ////////////////////////////// // // printReferenceRecord -- // void printReferenceRecord(ostream& out, HumdrumFile& infile, int line) { int& i = line; PerlRegularExpression pre; if (!pre.search(infile[line][0], "^!!!([^!:]+):(.*)$", "")) { out << ""; out << infile[i] << "\n"; return; } string description; infile[line].getBibliographicMeaning(description, pre.getSubmatch(1)); PerlRegularExpression pre2; pre2.sar(description, "\"", "", "g"); out << ""; out << ""; out << "!!!"; out << pre.getSubmatch(1); out << ":"; out << pre.getSubmatch(2); out << ""; out << "\n"; } ////////////////////////////// // // printGlobalComment -- // void printGlobalComment(ostream& out, HumdrumFile& infile, int line) { int& i = line; out << ""; out << infile[i] << "\n"; } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("p|page|full=b", "print a full page instead of just table"); opts.define("C|no-class=b", "don't label elements with classes"); opts.define("css=b", "Print an example CSS "); opts.define("textarea|ta|t=b", "print data in a textarea after main table"); opts.define("M|no-marks=b", "don't highlight marked notes"); opts.define("P|prefix=s:hum", "prefix for CSS classes"); opts.define("k|kern=b", "markup kern data with spans"); opts.define("author=b", "author of program"); opts.define("version=b", "compilation info"); opts.define("example=b", "example usages"); opts.define("h|help=b", "short description"); opts.process(argc, argv); // handle basic options: if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, March 2011" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: June 2014" << endl; cout << "compiled: " << __DATE__ << endl; cout << MUSEINFO_VERSION << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand().data()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } fullQ = opts.getBoolean("page"); classQ = !opts.getBoolean("no-class"); cssQ = opts.getBoolean("css"); textareaQ = opts.getBoolean("textarea"); markQ = !opts.getBoolean("no-marks"); kernQ = opts.getBoolean("kern"); prefix = opts.getString("prefix").data(); Markchar.resize(0);; Markcolor.resize(0);; } ////////////////////////////// // // example -- example usage of the humtable program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the humtable program // void usage(const char* command) { cout << " \n" << endl; }