Introducing Mesquite Using Mesquite How Mesquite Works
Concepts Help Tutorial Projects and Files Managing Modules Menus Windows Scripting

Scripting Mesquite

(updated August 2000)

Mesquite's scripting system allows modules and other objects to be scripted using text commands. This can be done in the scripts found in the Mesquite blocks of NEXUS files, in macro files, and in other contexts.

The scripting system takes advantage of the fact that modules and other objects are often commanded within Mesquite by being passed strings of text (using the doCommand method of the Commandable interface; see the developer's documentation). Most user interaction is routed through these commands (e.g, selection of a menu item). For this reason, most user interface controls are automatically available for scripting without much special effort on the part of the programmer.

The particular commands to which a module or other object responds will depend on the object. When Mesquite starts, it attempts to compile automatically documentation for scripting commands that is available. This includes commands predefined by the scripting language, and commands belonging to particular modules. This compiled documentation is available from the web page linked from the "Scripting Commands" menu item in the Help menu when Mesquite is running.

Apology: Mesquite's scripting language is not as human-friendly as it might be at present, especially in its handling of variables and aspects such as the lack of "else" statements. Since the vast majority of Mesquite scripts won't be written by humans but by Mesquite itself, that is not such a liability as it might seem. We hope to reform the scripting language in the future.

Learning about scripting

Users can learn about the scripting language from these web pages, but also by inspection of existing scripts. Some sources of scripts to examine are:

Another way to learn about the language and particular scripting commands is to look at the web pages linked from the "Scripting Commands" menu item in the Help menu when Mesquite is running. In particular, examine the page on universal commands, which shows basic commands available regardless of the object being scripted, including the basic flow control and variable-defining commands of the system. (We cannot provide a link here to this web page because this web page is created by Mesquite when it runs, and is placed in a location that depends on your particular computer. After running Mesquite once, you may want to find some of these files and save a bookmark/alias/shortcut to them -- the file on basic scripting commands is named 'puppeteer.html').

Commands within scripts

In general, a command found within a script takes the following form:


     commandName  argument1 argument2 ...;

The commandName is a single word (token); the arguments can be multiple tokens, so long as the module knows how to interpret them. Typically each argument is a single token (though this may be string of multiple tokens converted to a single token by quotation).

Scripts

A script consists of a series of commands. At each stage in the script, there is an implicit recipient of the command given (for instance, a module or a window). For instance, here is a script within the MESQUITE block of a NEXUS file. To the right of the commands are comments to explain them.


Begin MESQUITE;
  getNumberOfDataSets;      [file coordinator queried for number of data sets]
  Integer.dataSets *it;     [storing number of data sets in integer variable 'dataSets']
  getEmployee 'Data Window Coordinator'; [querying file coordinator for reference to Data Window Coordinator module]
  tell It;                  [commands to follow will be sent to the Data Window Coordinator]
    Integer.dataNum 0;      [Define integer variable 'dataNum' and assign it 0]
    for *Integer.dataSets;  [for loop; cycle as many times as there are data sets]
      showDataWindow *Integer.dataNum;  [commands the Data Window Coordinator to make a data window for dataset]
      tell It;              [commands to follow will be sent to the module that makes the data window]
        showWindow;         [tells the module to make the data window visible]
      endTell;              [finished sending commands to the module that makes the data window]
      increment.dataNum;    [add 1 to the variable 'dataNum']
    endFor;                 [end of the for loop]
  endTell;                  [finished sending commands to the Data Window Coordinator]
  getNumberOfTaxas;         [file coordinator queried for number of sets of taxa]
  Integer.taxaSets *it;     [storing number of sets of taxa in integer variable 'taxaSets']
  getEmployee 'Tree Window Coordinator';  [querying file coordinator for reference to Tree Window Coordinator module]
  tell It;                  [commands to follow will be sent to the Tree Window Coordinator]
    Integer.taxaNum 0;      [Define integer variable 'taxaNum' and assign it 0]
    for *Integer.taxaSets;  [for loop; cycle as many times as there are sets of taxa]
      makeTreeWindow *Integer.taxaNum;  [commands the Tree Window Coordinator to make a tree window for set of taxa]
      tell It;              [commands to follow will be sent to the module that makes the tree window]
        getTreeWindow;      [queries the module to return a reference to the tree window itself]
        tell It;            [commands to follow will be sent to the tree window]
          newAssistant 'Trace Character';  [the tree window is asked to hire the module 'Trace Character']
        endTell;            [finished sending commands to the tree window]
        showWindow;         [tells the module to make the tree window visible]
      endTell;              [finished sending commands to the module that makes the tree window]
      increment.taxaNum;    [add 1 to the variable 'taxaNum']
    endFor;                 [end of the for loop]
  endTell;                  [finished sending commands to the Tree Window Coordinator]
END;

This MESQUITE block causes Mesquite to show a data window for each of the data sets, and a tree window for each of the Taxa blocks; the tree windows are shown with a character traced.

This script illustrates some of the features of Mesquite's scripting language:

Some of the lines of this script are commands unique to particular commandable objects (getNumberDataSets, getEmployee, showDataWindow, etc.); others are predefined by the scripting language (e.g., Integer, tell, for). More details on particular commands can be found in the web pages linked from the "Scripting Commands" menu item in the Help menu when Mesquite is running. Some details are found below.


Variables: Integers, Strings and Objects

Three sorts of variables are supported. Reference to each requires the type of variable with name appended, as in "Integer.numberOfCharacters" or "Object.treeDrawCoordinator". The generic variable "it" refers to the object last returned by a command.

When the variable is passed as an argument for a command, it should be preceeded by an asterisk. This allows the system to know that a variable, and not a constant string, is being passeed.

Numerical variables

Two sorts of numerical variables are supported: Integer and Number. The former contain whole numbers. The latter can contain whole or decimal numbers. Reference to each requires the type of variable with name appended, as in "Integer.numberOfCharacters" or "Object.treeDrawCoordinator". The generic variable "it" refers to the object last returned by a command.

When the variable is passed as an argument for a command, it should be preceeded by an asterisk. This allows the system to know that a variable, and not a constant string, is being passeed. The commands concerning variables are:

String variables

One sort of variable contains a string of text. The command to define and assign values to a string variable is:

Object variables

One sort of variable contains a objects (such as modules, or windows). The command to define and assign values to an object variable is:

The variable "It"

Standard Mesquite Commands to modules return an object. In the scripting language, this returned object is stored in the variable "It". Thus, after a command "getNumberDataSets" to the FileCoordinator, the FileCoordinator returns an Integer variable containing the number of data sets. This can be stored in an Integer variable by following the command by "Integer.numDataSets *it". Likewise, "tell" often makes use of "it".


Flow and command control

As noted above Mesquite's scripting language has flow control as well as control of the object to be commanded.

Using "tell" to direct commands

Commands are directed toward commandable objects, including modules, windows, and others. Since different objects might use the same command names, the object to which a command is directed must be indicated. In the scripting language, at any point there is an implicit object being commanded. Subsequent commands are directed to a different object using the "tell" command, which must be balanced by "endTell". At the root level, the FileCoordinator is being commanded.

Flow control

Flow control statements include "if", "for", and "while". Others are available (such as ifnot, stop, exitTell). Details on these can be found via the web page shown by selecting Scripting Commands from the Help menu while Mesquite is running.


Debugging

There are a number of commands that are useful for debugging. For instance, if the Command "debug" is placed in the block, a debugging mode will be enabled which reports in the console more details about the commands as they are executed. More information about such commands can be found by selecting the "Scripting Commands" menu item under the Help menu when Mesquite is running.


Macros

For some calculations or display functions, the number of different analyses a user might like to do are too many to be easily supported by a graphical user interface. For instance, the user might like to print the ancestral state reconstruction of a character using a series of different stepmatrices. One can invent many such scenarios in which something repetitious is needed, and a module would be hard-pressed to maintain each as an option. Thus, small scripts using Mesquite's scripting language can be written and placed in the "macros" folder. They will appear as options in an appropriate place, depending upon where they are applicable. When the user selects the menu item, the script is executed.

Thus, scripts performing some special function can be written and distributed by programmers to end users.

Technical Details

(See the developer's documentation.) The Puppeteer is in charge of defining the basic language as it relates to variables and flow control. For an object to be scriptable, it must be of the Commandable interface. Commands internally in Mesquite are remembered in objects called MesquiteCommands.


© W. Maddison & D. Maddison 2000