// // Programmer: Craig Stuart Sapp // Creation Date: Sun Aug 5 12:58:51 PDT 2012 // Last Modified: Sun Aug 5 12:58:55 PDT 2012 // Filename: ...sig/examples/all/sverse.cpp // Web Address: http://sig.sapp.org/examples/museinfo/score/sverse.cpp // Syntax: C++; museinfo // // Description: Display staff information for a SCORE page file. // #include "PerlRegularExpression.h" #include "ScorePageSet.h" #include "Options.h" #include #include #include // function declarations: void checkOptions (Options& opts, int argc, char* argv[]); void example (void); void usage (const char* command); void printLyrics (ScorePageSet& work, Array& staves); void printLyricsByLineBreak(ScorePageSet& work, Array& staves); void printLyricsInfo (ScorePageSet& work, Array& staves); void printVerseWithBreaks (ScorePageSet& work, int staffidx, int verseidx); void printVerse (ScorePageSet& work, int staffidx, int verseidx); int getPrettyScoreText (Array& textdata, ScoreRecord& arecord); // block parsing functions: void fillFieldData (Array& field, const char* fieldstring, int maxval); void processFieldEntry (Array& field, const char* string, int maxval); void removeDollarsFromString(Array& buffer, int maxval); void printInfo (ScorePage& page); // interface variables: Options options; int verboseQ = 0; // used with -v option int debugQ = 0; // used with --debug option int breakQ = 0; // used with -b option int infoQ = 0; // used with -i option int staffQ = 0; // used with -s option int plainQ = 0; // used with -p option int htmlQ = 0; // used with -h option ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { checkOptions(options, argc, argv); int i; ScorePageSet work; for (i=1; i<=options.getArgCount(); i++) { work.appendRead(options.getArg(i), verboseQ); } work.analyzeContent(); // determine the extraction staves Array versestaves; if (staffQ) { fillFieldData(versestaves, options.getString("staff-list"), work.getPartCount()); for (i=0; i& versestaves) { int count = 0; int pcount = work.getPartCount(); int i; for (i=0; i=0; i--) { if (work.getVerseCount(i)) { cout << "\t-- Staff " << pcount-i << " has " << work.getVerseCount(i); if (work.getVerseCount(i) > 1) { cout << " verses."; } else { cout << " verse."; } cout << endl; } } } ////////////////////////////// // // printLyricsByLineBreak -- // void printLyricsByLineBreak(ScorePageSet& work, Array& versestaves) { int count = 0; int pcount = work.getPartCount(); int i; for (i=0; i 1) { cout << " verses:"; } else { cout << " verse:"; } cout << endl; for (j=0; j& versestaves) { int count = 0; int pcount = work.getPartCount(); int i; for (i=0; i 1) { cout << " verses:"; } else { cout << " verse:"; } cout << endl; for (j=0; j textdata; int endhyphen = 0; cout << "\n@Verse: " << verseidx+1 << endl; if (verseidx > 0) { cout << endl; } int tcount; int charcount = 0; Array syllable(100); syllable.setSize(0); int blankchecking = 0; for (i=0; iisTextItem()) { continue; } tvindex = srecord->getVerseIndex(); if (tvindex != verseidx) { continue; } charcount = getPrettyScoreText(syllable, *srecord); if (charcount == 0) { continue; } if (tcount++ && srecord->isWordStart()) { cout << " "; } cout << syllable; if (charcount > 0) { blankchecking++; } endhyphen = !(srecord->isWordEnd()); } if (endhyphen) { cout << "-"; } if (blankchecking == 0) { cout << "[blank]"; } cout << endl; } cout << endl; } } ////////////////////////////// // // getPrettyScoreText -- returns the number of charcters printed // int getPrettyScoreText(Array& textdata, ScoreRecord& arecord) { arecord.getTextDataWithoutFonts(textdata); if (plainQ) { ScoreRecord::convertScoreTextToPlainText(textdata); } else if (htmlQ) { ScoreRecord::convertScoreTextToHtmlText(textdata); } return strlen(textdata.getBase()); } ////////////////////////////// // // printVerse -- // void printVerse(ScorePageSet& work, int staffidx, int verseidx) { int i, j, k; int tvindex; ScoreRecord* srecord; Array textdata; int endhyphen = 0; cout << "\n@Verse: " << verseidx+1 << endl << endl; int linebreak = 0; Array syllable(100); syllable.setSize(0); int tcount; tcount = 0; int lastsys = -1; int system = -1; for (i=0; iisTextItem()) { continue; } tvindex = srecord->getVerseIndex(); if (tvindex != verseidx) { continue; } if (!linebreak && tcount++ && srecord->isWordStart()) { cout << " "; } if (lastsys < system-1) { cout << "[blank] "; } // cout << srecord->getTextDataWithoutFonts(textdata); getPrettyScoreText(syllable, *srecord); lastsys = system; cout << syllable; linebreak = 0; endhyphen = !(srecord->isWordEnd()); } } cout << endl; linebreak = 1; } } ////////////////////////////// // // checkOptions -- validate and process command-line options. // void checkOptions(Options& opts, int argc, char* argv[]) { opts.define("i|info=b", "display lyric informatio"); opts.define("v|verbose=b", "verbose display of information"); opts.define("b|break|line-breaks=b", "break lyric lines by staff line breaks"); opts.define("s|staff|staff-list=i", "give a list system staves from which to extract"); opts.define("p|plain=b", "convert verse text to plain ASCII text"); opts.define("html=b", "convert verse text to HTML text"); opts.define("debug=b"); // determine bad input line num 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, Aug 2012" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << argv[0] << ", version: 5 Aug 2012" << endl; cout << "compiled: " << __DATE__ << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } staffQ = opts.getBoolean("staff-list"); debugQ = opts.getBoolean("debug"); breakQ = opts.getBoolean("break"); infoQ = opts.getBoolean("info"); plainQ = opts.getBoolean("plain"); htmlQ = opts.getBoolean("html"); if (plainQ && htmlQ) { cerr << "ERROR: plain and html text conversions not allowed at the same time." << endl; exit(1); } } ////////////////////////////// // // example -- example usage of the quality program // void example(void) { cout << " \n" << endl; } ////////////////////////////// // // usage -- gives the usage statement for the meter program // void usage(const char* command) { cout << " \n" << endl; } /////////////////////////////////////////////////////////////////////////// // // Spine field list extraction functions // ////////////////////////////// // // fillFieldData -- // void fillFieldData(Array& field, const char* fieldstring, int maxval) { field.setSize(maxval); field.setGrowth(0); field.setAll(0); Array tempfield; tempfield.setSize(maxval); tempfield.setSize(0); PerlRegularExpression pre; Array buffer; buffer.setSize(strlen(fieldstring)+1); strcpy(buffer.getBase(), fieldstring); pre.sar(buffer, "\\s", "", "gs"); int start = 0; int value = 0; value = pre.search(buffer.getBase(), "^([^,]+,?)"); while (value != 0) { start += value - 1; start += strlen(pre.getSubmatch(1)); processFieldEntry(tempfield, pre.getSubmatch(), maxval); value = pre.search(buffer.getBase() + start, "^([^,]+,?)"); } if (debugQ) { cout << "# tempfield: " << tempfield << endl; } field = tempfield; //int i; //for (i=0; i& field, const char* string, int maxval) { PerlRegularExpression pre; Array buffer; buffer.setSize(strlen(string)+1); strcpy(buffer.getBase(), string); // remove any comma left at end of input string (or anywhere else) pre.sar(buffer, ",", " ", "g"); pre.sar(buffer, "\\s+$", ""); pre.sar(buffer, "^\\s+", ""); if (debugQ) { cout << "MAXBLOCK = " << maxval << endl; cout << "INPUT BLOCK STRING TO DOLLAR: " << buffer << endl; } // first remove $ symbols and replace with the correct values removeDollarsFromString(buffer, maxval); if (debugQ) { cout << "OUTPUT BLOCK STRING FROM DOLLAR: " << buffer << endl; } if (pre.search(buffer.getBase(), "^(\\d+)-(\\d+)$")) { int firstone = strtol(pre.getSubmatch(1), NULL, 10); int lastone = strtol(pre.getSubmatch(2), NULL, 10); if ((firstone < 1) && (firstone != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at start: " << firstone << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } if ((lastone < 1) && (lastone != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at end: " << lastone << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } if (firstone > maxval) { cerr << "Error: range token: \"" << string << "\"" << " contains number too large at start: " << firstone << endl; cerr << "Maximum number allowed is " << maxval << endl; exit(1); } if (lastone > maxval) { cerr << "Error: range token: \"" << string << "\"" << " contains number too large at end: " << lastone << endl; cerr << "Maximum number allowed is " << maxval << endl; exit(1); } int i; if (firstone > lastone) { for (i=firstone; i>=lastone; i--) { field.append(i); } } else { for (i=firstone; i<=lastone; i++) { field.append(i); } } } else if (pre.search(buffer.getBase(), "^(\\d+)")) { int value = strtol(pre.getSubmatch(1), NULL, 10); if ((value < 1) && (value != 0)) { cerr << "Error: range token: \"" << string << "\"" << " contains too small a number at end: " << value << endl; cerr << "Minimum number allowed is " << 1 << endl; exit(1); } if (value > maxval) { cerr << "Error: range token: \"" << string << "\"" << " contains number too large at start: " << value << endl; cerr << "Maximum number allowed is " << maxval << endl; exit(1); } field.append(value); } } ////////////////////////////// // // removeDollarsFromString -- substitute $ sign for maximum track count. // void removeDollarsFromString(Array& buffer, int maxval) { PerlRegularExpression pre; char buf2[128] = {0}; int value2; if (debugQ) { cout << "IN DOLLAR STRING MAXBLOCK = " << maxval << endl; } if (pre.search(buffer.getBase(), "\\$$")) { sprintf(buf2, "%d", maxval); pre.sar(buffer, "\\$$", buf2); } if (debugQ) { cout << "IN DOLLAR STRING = " << buffer << endl; } if (pre.search(buffer.getBase(), "\\$(?![\\d-])")) { // don't know how this case could happen, however... sprintf(buf2, "%d", maxval); pre.sar(buffer, "\\$(?![\\d-])", buf2, "g"); } if (pre.search(buffer.getBase(), "\\$0")) { // replace $0 with maxval (used for reverse orderings) sprintf(buf2, "%d", maxval); pre.sar(buffer, "\\$0", buf2, "g"); } while (pre.search(buffer.getBase(), "\\$(-?\\d+)")) { value2 = maxval - (int)fabs(strtol(pre.getSubmatch(1), NULL, 10)); sprintf(buf2, "%d", value2); pre.sar(buffer, "\\$-?\\d+", buf2); } } // // Spine field list extraction functions // /////////////////////////////////////////////////////////////////////////// // md5sum: b3ffb1c66363946fb3bd519900302055 sverse.cpp [20120811]