NoteWorthy Composer Forum

Forums => Tips & Tricks => User Tools => Topic started by: Warren Porter on 2013-01-27 06:18 pm

Title: Multi Measure Rest tool
Post by: Warren Porter on 2013-01-27 06:18 pm
The following tool should provide a convenient way to convert consecutive measures of whole rests into MMR's, or convert MMRs back to whole rests.  Installation instructions are on the bottom.  First save the following with the name mmr.js and remember its location:
Code: [Select · Download]
/*
 mmr.js  by Warren Porter

 <PROMPT:MMR?:=|Yes|Undo> <PROMPT:Options:=|HideAll|ShowAll|ShowBar|ShowRst|LayerHide>
                                  Multi Measure Rest Tool
 This tool gives the user the ability to convert consecutive measures of whole rests into Multi-Measure Rests.  When hidden,
 the user can choose to show bars and rests, bars only, rests only, or neither.  If a "conductor" or "tempo" staff is being
 layered into a part to be printed, the "LayerHide" option will prevent any MMR on that part from being displayed.  Boundary
 collapse and cancel collapse commands are created around the multi measure rests.

 Changes made can be backed out with the "Undo" prompt.  All options on the 2nd prompt are ignored.  The above boundary commands
 are removed and MMRs are replaced by the approprate number of whole rests separated by bar lines.

 This tool can operate on ONLY a selected part of a staff, or, if nothing has been selected, the entire staff.
 */

rc=0, errMsg="";

function doProcess(clip) {
  var result=new Array(), nlines=new Array(), ii=0, lastBar=-1,cntRest=0,lastRest=0;
  var mmrOption = "|PrintOnce:Y";
  if (WScript.Arguments.Item(1) == "ShowAll")
    mmrOption += "|WhenHidden:ShowBars,ShowRests";
  else
if (WScript.Arguments.Item(1) == "ShowBar")
  mmrOption += "|WhenHidden:ShowBars";
else
  if (WScript.Arguments.Item(1) == "ShowRst")
    mmrOption += "|WhenHidden:ShowRests";
  else
    if (WScript.Arguments.Item(1) == "LayerHide")
          mmrOption = "|PrintOnce:N|Visibility:Never"; // Used for hiding tempo or conductor stave.

  lines = clip.split("\r\n"); // lines === existing lines; nlines === lines to be created

  for (var i=0; i < lines.length; i++) {  // Main processing loop
    switch (cntRest) {
  case 0 :
    if (lines[i].slice(0,15) == "|Rest|Dur:Whole") {  //Found first rest
  cntRest++; lastRest = i; }
else {
  nlines[ii++] = lines[i]; } // Didn't find a rest and have no backlog, copy line to OP array.
break;
  case 1 :  // Have found exactly one whole rest
        if (lines[i].slice(0,15) == "|Rest|Dur:Whole") {
          cntRest++; lastBar = 0; }
        else
          if ((lines[i].slice(0,4) == "|Bar") && (lines[i].slice(4,11) != "|Style:")) {
            lastBar = i; }
          else {  //  Found whole rest not followed by bar or another rest
            if (lastRest) {
              for ( ; lastRest <= i; lastRest++) {
                 nlines[ii++] = lines[lastRest] }
            cntRest=0,lastBar=0; } }
        break;
      default: // cntRest is 2 or more.
        if (lines[i].slice(0,15) == "|Rest|Dur:Whole") {
          cntRest++; lastBar = 0; }
        else
          if ((lines[i].slice(0,4) == "|Bar") && (lines[i].slice(4,11) != "|Style:")) {
            lastBar = i; }
          else {  //  Found whole rest not followed by bar or another rest, must create MMR
            nlines[ii++] = "|Boundary|Style:Collapse";
            nlines[ii++] = "|RestMultiBar|NumBars:" + cntRest + mmrOption;
            if (lines[i].slice(0,27) != "!NoteWorthyComposerClip-End" || lastBar) {
              nlines[ii++] = "|Boundary|Style:EndCollapse"; }
cntRest = 0;
            if (lastBar)   // If MMR was followed by a barline and something else
              nlines[ii++] = lines[lastBar];  // first move the barline over
            lastBar = 0;
            nlines[ii++] = lines[i] //  Move the non-rest non-bar over to OP buffer.
            }
        }   //End of switch
  }           //End main processing loop
  /* Next loop will place the Boundary Collapse BEFORE a bar line and the Cancel Collapse AFTER a bar line. This will stop empty
     bars from being displayed when a part begins or ends on a complete system.  The loop after that will remove EndCollapse and
Collapse when they are next to each other.
   */

  for (i=1; (i+1) < nlines.length; i++) {  // Start fixit loop.
    if ((nlines[i].slice(0,4) == "|Bar") && (nlines[i+1].slice(0,24) == "|Boundary|Style:Collapse")) {
  var tempi = nlines[i];
  nlines[i] = nlines[i+1];
  nlines[++i] = tempi; }
else
  if ((nlines[i].slice(0,27) == "|Boundary|Style:EndCollapse") && (nlines[i+1].slice(0,4) == "|Bar")) {
    tempi = nlines[i];
    nlines[i] = nlines[i+1];
    nlines[++i] = tempi; }
  }    //End fixup loop

  for (i=1; (i+1) < nlines.length; i++) {
    if ((nlines[i].slice(0,27) == "|Boundary|Style:EndCollapse") && (nlines[i+1].slice(0,24) == "|Boundary|Style:Collapse")) {
  nlines[i] = "#";  //Turn both lines into a comment
  nlines[++i] = "#"; }
else
  if (WScript.Arguments.Item(1) == "LayerHide" && nlines[i].slice(0,5) =="|Rest" && nlines[i].indexOf("|Visibility:Never") == -1)
    nlines[i]+= "|Visibility:Never";
  }

  return nlines;
}
/*
!NoteWorthyComposerClip(2.51,Single)
|Rest|Dur:Half
|Tempo|Tempo:70|Pos:10
|Rest|Dur:4th|Visibility:Never
|Tempo|Tempo:67|Pos:10
|Rest|Dur:4th
|Bar|Visibility:Never
|Rest|Dur:Whole|Visibility:Never
!NoteWorthyComposerClip-End

 */

function doUndo(clip) {
  var result=new Array(), nlines=new Array(), ii=0, lastRest=0,cntRest=0;
  var restLit = "|Rest|Dur:Whole", barLit = "|Bar";
  lines = clip.split("\r\n"); // lines === existing lines; nlines === lines to be created

  for (var i=0; i < lines.length; i++) {  // Main processing loop
    if (lines[i].match(/Boundary.*Collapse/) != null)
      continue;
    result = lines[i].match(/(RestMultiBar\|NumBars:)(\d+)(\|PrintOnce)/)
    if (result == null) {
      nlines[ii++] = lines[i]; }
    else {
      lastRest = Number(result[2])
      for (cntRest=0; cntRest < lastRest; cntRest++) {
        nlines[ii++] = restLit;
        if ((cntRest + 1) < lastRest)
          nlines[ii++] = barLit;
      }
    }
  }           //End main processing loop
   if (WScript.Arguments.Item(1) == "LayerHide") {
     for (i = 0; i < nlines.length; i++)
   if (result = nlines[i].match(/Rest.*Never/))
     nlines[i] = nlines[i].replace("|Visibility:Never","") }
  return nlines;
}
var myLines;
  if (WScript.Arguments.length != 2) {
    errMsg="NO Prompt read.";
rc=1; }
  else {
    if (WScript.Arguments.Item(0).slice(0,4) == "Undo")
  myLines=doUndo(WScript.StdIn.ReadAll()).join("\r\n");
else
  myLines=doProcess(WScript.StdIn.ReadAll()).join("\r\n"); }

if (rc == 0)
  WScript.StdOut.Write(myLines);
else
  WScript.StdErr.Write(errMsg);
WScript.quit(rc);


Paste this prompt (include leading space) " <PROMPT:MMR?:=|Yes|Undo> <PROMPT:Options:=|HideAll|ShowAll|ShowBar|ShowRst|LayerHide>" at the end of the command line.

Edit 13-01-28: Corrected Options.
Edit 14-06-19: Replace script.
Edit 17-11-08: Replace script (bug fix)
Title: Re: Multi Measure Rest tool
Post by: Opagust on 2013-01-28 09:31 am
the installation instructions are perfect!
Title: Re: Multi Measure Rest tool
Post by: Rick G. on 2013-01-28 11:34 am
the installation instructions are perfect!
Not quite. This line is unneeded:
  • Under "Options", check Prompts for User Input.
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2013-01-28 12:25 pm
Not quite. This line is unneeded:
Why isn't Under "Options", check Prompts for User Input. necessary?  When would it be necessary to check it?
Title: Re: Multi Measure Rest tool
Post by: Rick G. on 2013-01-28 12:39 pm
Why isn't Under "Options", check Prompts for User Input. necessary?
Because your program does not prompt the user for input. All the prompting is done by NWC and it knows how to take care of itself.
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2013-01-28 07:04 pm
Because your program does not prompt the user for input. All the prompting is done by NWC and it knows how to take care of itself.
Thanks.  I've corrected that instruction in my initial post.
Title: Re: Multi Measure Rest tool
Post by: ECorganist on 2013-04-07 12:45 am
I have to say that I love this tool so far! It helps make orchestral parts scores look much more professional when there are multi-measure rests and also helps save space on those scores! Excellent!
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2013-04-07 11:56 am
I have to say that I love this tool so far.
Am happy to hear it's useful.
Title: Re: Multi Measure Rest tool
Post by: brado on 2014-01-21 04:09 pm
I gather you can use this only when all the staves have the same number of multi measure rests?
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2014-01-23 01:03 am
I gather you can use this only when all the staves have the same number of multi measure rests?
All of the staves should have the same number of measures, but the number of MMR's doesn't have to be the same unless, perhaps, similar parts are on a two staff system, i.e. three horn parts.  It might be helpful to replace the last few bars of an MMR with regular whole rest measures so that cues can be inserted for just the part(s) about to come in.
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2014-06-19 11:33 am
I was working with an imported midi file with the idea of moving the conductor/tempo staff to the top, doing a layerhide on it and layering it into the first staff.  A tempo change in the middle of some measures left visible rests on top of the first staff.  The new version in the first message will hide all rests when this option is selected.  When Undo is selected along with layerhide, visibility on all rests will be reset to the default.
Title: Re: Multi Measure Rest tool
Post by: Warren Porter on 2017-11-09 01:07 am
Bug fix:  Unless a whole rest is the last thing selected or is at the end of a staff when no selection is done, a cancel collapse statement will be created.  The script in the initial post has been replaced.