Skip to main content
Topic: Multi Measure Rest tool (Read 14017 times) previous topic - next topic

Multi Measure Rest tool

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);

  • Open a file with NWC and enter Alt/F8.
  • Choose a group and give it a name "Multi Measure Rests".
  • In the Command line, hit Browse and find the file.
  • At the beginning of the command line insert "wscript " (include trailing space).
  • At the end of the command line, append the prompt below.
  • The Input Type is Clip Text.
  • Under "Options", leave all boxes unchecked.
  • Click OK.  It is ready to run.

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)
Since 1998

Re: Multi Measure Rest tool

Reply #1
the installation instructions are perfect!
Always look on the bright side of life!


Re: Multi Measure Rest tool

Reply #3
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?
Since 1998

Re: Multi Measure Rest tool

Reply #4
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.
Registered user since 1996

Re: Multi Measure Rest tool

Reply #5
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.
Since 1998

Re: Multi Measure Rest tool

Reply #6
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!


Re: Multi Measure Rest tool

Reply #8
I gather you can use this only when all the staves have the same number of multi measure rests?

Re: Multi Measure Rest tool

Reply #9
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.
Since 1998

Re: Multi Measure Rest tool

Reply #10
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.
Since 1998

Re: Multi Measure Rest tool

Reply #11
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.
Since 1998