Copyright 2002-2015 Rick Mohr

Vocola supports three special forms useful in writing command actions:

Repeat- Execute actions a specified number of times.
If- Perform different actions depending on a conditional value.
Eval- Evaluate a JavaScript expression.

While these forms look like function calls they are not because each evaluates its arguments in a special way different from a function call. They are part of the Vocola language, not part of the Function Library.


Repeat(count, actions)

Repeat executes an action sequence a specified number of times—actions specifies the actions and count specifies how many times.

For example, in an "Open File" dialog box, this command moves up a given number of levels in the folder hierarchy:

Vocola: Go Up 1..9 = Repeat($1, ..\) {Enter};

Say: Go Up 3  Sent: ..\..\..\{Enter}

Saying "Go Up 3" constructs the pathname "..\..\..\" to move up three levels.

In the Thunderbird mailer it's useful to delete several messages in a row by saying for example "Kill 3" to send three {Del} keystrokes. But unless these keystrokes are separated by calls to Wait, only 1 message is deleted. This command uses Repeat to send the specified number of {Del} keystrokes, separated by Wait calls:

Vocola: Kill 1..10 = Repeat($1, {Del} Wait(100));

Say: Kill 3  Sent: {Del} Wait(100) {Del} Wait(100) {Del} Wait(100)


If(condition, actions, alternateActions)

If executes one of two specified action sequences depending on the value of condition. If condition has the value "True" (case insensitive) the actions are executed; otherwise, the alternateActions are executed.

Often condition is determined by the value of a function call, as in the next example—the built-in dictation command "Fix That". If Vocola dictation is available this command activates the Vocola correction panel; otherwise it activates the WSR correction panel:

Fix That = If( Dictation.CanGet(),

               HearCommand("Correct That") );

The library function Dictation.CanGet returns "True" if a just-dictated Vocola phrase is available, and "False" otherwise. This command uses If to test that return value and activates either the Vocola correction panel (via Dictation.Correct) or the WSR correction panel (via HearCommand).

Note that If as described in this section is distinct from the Vocola context statement $if.



Eval evaluates an expression in the language JScript (Microsoft's dialect of JavaScript), and can be useful when you need to write simple expressions such as arithmetic. (If you need to perform computations beyond what Eval can achieve consider writing a Vocola Extension.)

For example, using the following command you can say "Join 3 Words" to remove spaces between the 3 words preceding the insertion point. It works by repeating the keystroke sequence {Ctrl+Left} (to move left a word) and {Backspace} (to delete the previous space). Since there are one fewer spaces than words, Repeat's first argument needs to be one fewer than the spoken number. Vocola doesn't support arithmetic directly, but you can do the subtraction using Eval:

Vocola: Join 1..9 Words = Repeat( Eval($1-1), {Ctrl+Left}{Backspace} );

Say: Join 3 Words  Sent: {Ctrl+Left}{Backspace}{Ctrl+Left}{Backspace}

Here $1 matches the spoken "3", so Eval($1-1) returns 2 and the Repeat block is executed 2 times.

Sometimes it's useful for the evaluated expression to contain Vocola function calls, as in the next example—the built-in command "Show Error":

$using Library.CommandFile;
Show Error = Open( GetErrorFilename() )
             {Down_  Eval( GetErrorLineNumber()   - 1) }
             {Right_ Eval( GetErrorColumnNumber() - 1) };

This command uses functions from the CommandFile library class to open the command file containing the last Vocola error and navigate to the offending line and column. Eval is used for subtraction in constructing a keystroke sequence to move {Down} and {Right} the correct amount.

In most cases you can use Eval without a deep understanding of how it works. If you want a fuller understanding, read on.

How Eval works

Eval builds a JScript function from the sequence of Vocola actions making up the expression argument. Any keystroke actions (i.e. literal text) become part of the function body, and any non-keystroke actions (such as references and function calls) become JScript variables. The first example above contains a single non-keystroke action, the reference $1. The constructed JScript function is:

    function evalFunction(v1) {
        return v1-1;

When the command is executed, the non-keystroke actions are evaluated and passed as arguments to the constructed function. The function's return value becomes the Eval statement's return value.

As it happens, the constructed JScript functions for the Eval calls in the second example above are the same as the constructed function for the first example. Each Eval call in the second example contains a single non-keystroke action (the Vocola function call) from which 1 is subtracted.