Introduction

Introduction to Vocola

Vocola is a voice command language -- a language for defining commands to control a computer by voice -- developed for use with Dragon NaturallySpeaking and implemented using NatLink. While these systems do the heavy lifting, Vocola (pronounced "vo-CO-luh") concentrates on features and ease of use. In particular, Vocola offers the following:

Examples

Here are four voice commands defined in Vocola:

 Copy That = {Ctrl+c};

 Copy to NatSpeak = {Ctrl+a}{Ctrl+c} AppBringUp(NatSpeak); 

 1..40 (Left | Right | Up | Down) = {$2_$1};

 Sort by (Date=e | Sender=r | Subject=s) = {Alt+v}o $1;

The first is a simple keystroke command -- saying "Copy That" sends the keystroke Control-C, which copies the current selection to the clipboard. The great majority of commands needed for controlling a computer by voice are simple keystroke commands like this. 

The second command, invoked by saying "Copy to NatSpeak", copies a window of text (Control-A selects all text and Control-C copies it) and brings up the NaturallySpeaking editor (using the built-in function AppBringUp ).

The third command allows controlling the cursor, by saying for example "3 Left" to move left three characters, or "6 Down" to move down six lines. Spoken words match variable terms on the left and are substituted into the keystroke sequence on the right. For example, when saying "3 Left" the spoken "3" matches the numeric range "1..40" and the spoken "Left" matches the alternative set "(Left | Right | Up | Down) ". The keystroke sequence "{Left 3}" is constructed and sent, and the cursor moves left three characters.

The fourth command allows sorting messages in the Netscape Mailer, by saying "Sort by Date", "Sort by Sender", or "Sort by Subject". The matched word "Date", "Sender", or "Subject", causes the appropriate keystroke "e", "r", or "s" to be inserted into the keystroke sequence.

These and other features are discussed in greater detail in the Vocola Tutorial.

Why a New Voice Command Language?

Existing voice command languages are grafted onto existing programming languages. This means you can program any behavior you want, but you're stuck with the syntactic overhead of the base language. In contrast, Vocola is designed specifically as a voice command language, not as a general-purpose programming language. This means you can write quickly and concisely the great majority of voice commands you need, and use another language in the few cases where you need more power. When I switched to Vocola I was able to convert all but two of my 200+ Dragon macros, and at this writing use something over 900 Vocola commands.

Alternatives to Vocola include NatSpeak Pro's VisualBasic-based language (introduced in version 6), the older Dragon Macro Language (used through version 5 and still functional), and NatLink. Each of these languages has advantages, but (in my humble and not unbiased opinion) none offers Vocola's features and ease of use.

Acknowledgments

Joel Gould for his time and care in designing, building, and "productizing" NatLink, which enabled and inspired Vocola. The authors and voice community members listed in Voice Resources. Scott Weinstein for building and maintaining his NatLink + Vocola installer.

This Web Site

This web site was created using a Python program developed and shared by Joel Gould, in another admirable display of community-mindedness. His description and sources are here.

A single-page version of the site is available here.


Using Vocola

Using Vocola

The easiest way to create and manage Vocola commands is by voice, using Vocola's built-in commands. Beginning and intermediate users should only need to learn the two commands described in the first subsection. The remaining subsections discuss commands for advanced features.

In the command descriptions below, words in square brackets are optional. For example, "Edit [Voice] Commands" means you can say either "Edit Voice Commands" or "Edit Commands".

How to Create and Load Voice Commands

With Vocola you can define commands for a specific application program, or define global commands which are active for all applications. You can use the following built-in commands to open the right command files:

When you say Vocola will
"Edit [Voice] Commands" Open the Vocola file defining commands for the currently running application (using your favorite editor).
"Edit Global [Voice] Commands" Open the Vocola file defining commands for all applications (using your favorite editor).

After creating or modifying commands and saving the file, your commands will be loaded automatically and usable immediately. Any errors will be displayed in a pop-up window titled "Messages from Python Macros".

Machine-Specific Commands

If you need to control more than one computer by voice (for example at work and at home) you can define commands which will only be enabled on a particular computer:

When you say Vocola will
"Edit Machine [Voice] Commands" Open the Vocola file defining commands for the currently running application on the current computer.
"Edit Global Machine [Voice] Commands" Open the Vocola file defining commands for all applications on the current computer.

Machine-specific command files are also reloaded automatically.

Direct Loading

Sometimes it's useful to reload your command files explicitly. For example, if you modify an include file, Vocola doesn't know enough to reload all command files which use that include file. You can do it yourself using the following commands:

When you say Vocola will
"Load All [Voice] Commands" Reload all commands you have defined.
"Load [Voice] Commands" Reload commands for the currently running application.
"Load Global [Voice] Commands" Reload global commands.

File Organization and Naming

If you don't want to use the built-in commands, or if you want to understand the underlying organization they depend on, here are the relevant conventions:

Language Tutorial

Vocola Tutorial The following sections describe the Vocola language, with examples:

Keystroke Commands

Keystroke Commands

Most of the everyday commands you will need are simple -- "When I say this, send these keystrokes." For example, the following command types the word "Greetings" when you say "Hello World": 

 Vocola: Hello World = Greetings; 
 Say: Hello World  Sent: Greetings 

In most cases the keystrokes you want to send will use modifier key sequences to control a particular application. For example, most Windows applications perform a "Copy" operation when you hold down the "Control" key and type the letter "c". The next command uses the phrase "Copy That" to invoke such a "Copy" operation:

 Vocola: Copy That = {Ctrl+c}; 
 Say: Copy That  Sent: {Ctrl+c}

The Vocola syntax for specifying modifier key sequences such as {Ctrl+c} is borrowed from the Dragon Macro Language, which describes the syntax. (See the discussion on pp. 13-14 and the table on pp. 116-117, or just absorb it from the Vocola examples.)

Each Vocola command contains a series of terms (indicating what is said) and a series of actions (indicating what is done), separated by "=" and terminated by ";". In this section the terms are words and the actions are keystrokes; later sections introduce other possibilities.

Because Windows applications allow keyboard control of almost everything, you can usually write a keystroke command to do what you want. The next example tells the Netscape 4 mail program to use its HTML editor (rather than the plain text editor) for composing messages:

 Vocola: HTML Editor = "{Alt+e}e{Shift+Tab}{Down 8}{Tab}{Up}{Enter}"; 
 Say: HTML Editor  Sent: {Alt+e}e{Shift+Tab}{Down 8}{Tab}{Up}{Enter}

Here's how it works:

 {Alt+e}Open the "Edit" menu

eChoose the "Preferences..." menu item, raising the Preferences panel

{Shift+Tab} Move back one field in the panel, to the "Category" list

{Down 8}Move down 8 lines, to the "Formatting" category

{Tab}Move forward one field in the panel, to "Message formatting"

uChoose the top radio button ("Use the HTML editor to compose messages")

{Enter}Hit the "OK" button

Quotes And Whitespace

Quotation Marks and White Space Quotation marks are optional around keystroke sequences. For example, the following commands are equivalent, specifying one action (the keystroke sequence {Ctrl+a}{Ctrl+c}):
Copy All = {Ctrl+a}{Ctrl+c};
Copy All = "{Ctrl+a}{Ctrl+c}";
Copy All = '{Ctrl+a}{Ctrl+c}';

Whitespace (any sequence of blank, tab, and newline characters) is used to separate actions. The following commands are also equivalent, specifying two actions (the keystroke sequence {Ctrl+a} followed by the keystroke sequence {Ctrl+c}):

Copy All = {Ctrl+a} {Ctrl+c};
Copy All = {Ctrl+a}
           {Ctrl+c};

In general it does no harm to separate keystroke sequences into multiple actions, so you can add whitespace wherever it is useful in formatting your commands. However, watch out for keystroke sequences containing space characters, such as the "HTML Editor" command above. That command specifies one action:

HTML Editor = "{Alt+e}e{Shift+Tab}{Down 8}{Tab}{Up}{Enter}";

Because this command contains a space character, omitting the quotation marks would unintentionally specify two actions, "{Alt+e}e{Shift+Tab}{Down" followed by "8}{Tab}{Up}{Enter}". This command would not behave as intended.

An alternative to quotation marks in this example is using the syntax "{Down_8}" instead of "{Down 8}":

HTML Editor = {Alt+e}e{Shift+Tab}{Down_8}{Tab}{Up}{Enter};

This is a Vocola extension to the Dragon Macro Language keystroke syntax -- within braces, underscore may be used instead of space to separate the keystroke name from the repetition count.

Some characters must be quoted

In addition to whitespace characters, the following characters must appear within quotes when used in a keystroke sequence:

( ) [ ] = | , " '

All other characters may appear without quotes. For example, pathnames do not need to be quoted, as in this command to open a temporary file:

Open Temp = {Ctrl+o}C:\Temp\temp.txt{Enter};

The examples in this tutorial use quotation marks only where necessary; you might prefer to use them more consistently. 


Using Alternatives

Alternatives And References Sometimes you will want to create a group of similar commands. Instead of creating a separate command for each, you can often write a single command which works for the whole group.

For example, you might want to be able to say either "Switch View" or "Next View" to switch between views in an application:
 
 Vocola: (Switch | Next) View = {Ctrl+Tab}; 
 Say: Switch View  Sent: {Ctrl+Tab}
 Say: Next View    Sent: {Ctrl+Tab}

Here the alternative term (Switch | Next) allows you to say either.

In many cases you want the actions invoked by a command to depend on which alternative was spoken. For example, you might want to move the cursor in one of four directions by saying "Move Left", "Move Down", etc.:
 
 Vocola: Move (Left | Right | Up | Down) = {$1}; 
 Say: Move Left  Sent: {Left} 
 Say: Move Down  Sent: {Down} 

Here the reference "$1" specifies that the first variable term should be substituted. So, when you say "Move Left" the value of the first variable term is "Left" and the keystroke"{Left}" is sent.
 
References may appear anywhere in a sequence of actions (i.e. on the right hand side of an "="), even inside quoted strings. If you want to insert the literal text "$1", use the escape sequence "\$1".

Number Ranges

Often you will want to specify a range of numbers as alternatives in a command.  This can be specified concisely in Vocola, as in the following example:
 
 Vocola: Move Down 1..10 = {Down_$1}; 
 Say: Move Down 1  Sent: {Down 1}
 Say: Move Down 6  Sent: {Down 6}

Here the syntax "1..10" is shorthand for "(1|2|3|4|5|6|7|8|9|10) ". On the right hand side we substitute the spoken number (e.g. "6 ") to construct the syntax for a repeated keystroke ("{Down 6}") and we have a command which moves the cursor down a specified number of lines.

In real life it's very useful to control the arrow keys by saying simply "1 Down", "3 Left", "6 Up", etc. Here's how to write it in Vocola:
 
 Vocola: 1..40 (Left | Right | Up | Down) = {$2_$1}; 
 Say: 3 Left   Sent: {Left 3}
 Say: 12 Down  Sent: {Down 12}

This command has two variable terms. On the right-hand side the second term (which direction to move) is substituted first and the first term (how many times) is substituted second, to create the necessary keystroke syntax.
 


Defining Variables

Defining Variable Terms If you want to re-use an alternative set in several different commands, you can assign it to a variable. For example, we can create a variable called <direction> to hold the alternatives "Left | Right | Up | Down", and use it in a command:
 
 Vocola: <direction> := Left | Right | Up | Down; 
         Move <direction> = {$1}; 
 Say: Move Left  Sent: {Left} 
 Say: Move Down   Sent: {Down} 

This command is equivalent to the second command in the previous section, allowing you to move the cursor in one of four directions.

The following command defines the variable <number>, and is equivalent to the third command in the previous section:
 
 Vocola: <number> := 1..40; 
         Move Down <number> = {Down_$1}; 
 Say: Move Down 1   Sent: {Down 1}
 Say: Move Down 12  Sent: {Down 12}

This moves the cursor down a given number of lines.

Finally, we can write our general-purpose arrow-key command (move a given number of steps in any direction) using both the <direction> and <number> variables:
 
 Vocola: <number> <direction> = {$2_$1}; 
 Say: 3 Left   Sent: {Left 3}
 Say: 10 Down  Sent: {Down 12}
 
Note that a variable reference may appear earlier in a Vocola command file then the definition of that variable.


Substituting Actions

Substitutions So far the spoken words in our alternative sets have been substituted directly into our keystroke sequences. Actually it is more commonly useful to substitute a different set of keystrokes than the spoken words.

For example, suppose we want "Move Back" to move the cursor left and "Move Forward" to move the cursor right. We can specify that this way:
 
 Vocola: Move (Back=Left | Forward=Right) = {$1}; 
 Say: Move Back      Sent: {Left}
 Say: Move Forward   Sent: {Right}

The alternative set "(Back=Left | Forward=Right)" means you can say either "Back" or "Forward", but the value substituted on the right hand side will be "Left" or "Right".

Here's another example. The Netscape Mailer has several options for sorting messages. This command allows you to change the sort by saying "Sort by Date", "Sort by Sender", or "Sort by Subject":
 
 Vocola: Sort by (Date=e | Sender=r | Subject=s) = {Alt+v}o $1; 
 Say: Sort by Date     Sent: {Alt+v}oe 
 Say: Sort by Sender   Sent: {Alt+v}or 

This alternative set allows you to say "Date", "Sender", or "Subject", and substitutes "e", "r", or "s" into the keystroke sequence.

Another common use of alternative sets with substitution is when you want to pick from a long list of specific items such as files, folders, or email addresses. For example, we can define the variable <EmailAddress> to contain a list of email addresses and shorthands to invoke them:
 
 Vocola: <EmailAddress> := ( Bill = bsmith@mediaone.net 
                           | Dragon = info@dragonsys.com 
                           | Voice Coder = VoiceCoder@yahoogroups.com 
                           ); 
         Address <EmailAddress> = $1 {Enter};
 Say: Address Bill         Sent: bsmith@mediaone.net{Enter}
 Say: Address Voice Coder  Sent: VoiceCoder@yahoogroups.com{Enter}

The command "Address <EmailAddress>" allows you to say, for example, "Address Bill" or "Address Voice Coder" to insert the desired email address. The list can be modified over time to add new addresses.
 
An alternative and its substitution (e.g. Dragon = info@dragonsys.com )  is actually a mini-command -- "when I say this, send these keystrokes". As with a command, the left-hand side may be an alternative set and the right-hand side may contain a sequence of actions. However, the left-hand side may not contain variables or ranges, and the right-hand side may not contain references.


Capturing Dictation

Defining Variable Terms

Sometimes you want a command which recognizes any words you might say rather than recognizing a particular set of alternatives. For example, searching for text is a common operation in Microsoft Word. It would be nice to be able to speak a single command to search for the text you want rather than needing to speak a command to open the "Find" dialog box, pausing, and then speaking the text you want to search for.

You can use the special variable <_anything> in a command to match any spoken words:
 
 Vocola: Find Text <_anything> = {Ctrl+f} $1 {Enter};
 Say: Find Text will do  Sent: {Ctrl+f}will do{Enter} 

With this command you could search for the text "will do" by saying "Find Text will do", which opens the "Find" dialog box, enters the text "will do", and launches the search. (Note: if using this macro for Internet Explorer you need to call wait after the {Ctrl+f})

Note that <_anything> matches anything you say, including saying nothing. So in the above example saying "Find Text" would bring up the "Find" dialog box to search for nothing. Since this may be unexpected it's a good idea to use at least two keywords in these commands (i.e. Find Text <_anything> instead of Find <_anything>) to reduce unwanted recognitions.

<_anything> may appear anywhere a regular variable term appears, and may even appear more than once in a command.


Optional Words

Optional Words Sometimes you want to create a command with optional words. For example, you might want to be able to say either "Hit Start Menu" or just "Hit Start" to bring up the Windows Start Menu:
 
 Vocola: Hit Start [Menu] = SendSystemKeys( {Ctrl+Esc} ); 
 Say: Hit Start Menu  Sent: {Ctrl+Esc}
 Say: Hit Start       Sent: {Ctrl+Esc}

Enclosing the optional word "Menu" in square brackets does the trick.

Note that optional words are not considered variable terms. Consider this example:
 
 Vocola: [Move] Down 1..10 = {Down_$1}; 
 Say: Move Down 1  Sent: {Down 1}
 Say: Down 6       Sent: {Down 6}

Because the optional word "[Move]" is not considered variable, the range "1..10" is the first variable term and is referenced using "$1".
 
Note that a command must have at least one non-optional term.


Function Calls

Function Calls Not everything can be accomplished with keystroke sequences -- Vocola commands can also include calls to built-in functions and user-defined functions.

Here are two simple examples:

 Vocola: Die Die = GoToSleep(); 
         Hit Down = ButtonClick(1,1); 

The first example puts NaturallySpeaking in sleep mode when you say "Die Die". The second example clicks the mouse when you say "Hit Down".

The function HeardWord is useful for writing a command which invokes another command. Any command recognized by NaturallySpeaking may be invoked this way, whether it was defined in Vocola, NatLink, or the Dragon Macro Language.

For example, maybe you'd like to say "Kill Word" to delete a word rather than using the built-in NaturallySpeaking command "Delete Next Word", but you don't want to take the time to figure out the exact keystroke sequence. This command does the trick:

 Vocola: Kill Word = HeardWord(Delete,Next,Word); 

A command's actions can be a mix of keystroke sequences and function calls. For example, this command performs a "paste" at the current mouse location (saving you a mouse click):

 Vocola: Paste Here = ButtonClick(1,1) {Ctrl+v}; 

Function arguments aren't always constant -- you can use a reference to a variable term as an argument to a function call. For example, this command allows you to copy a window's contents to either NaturallySpeaking or Emacs, by saying "Copy to NatSpeak" or "Copy to Emacs":

 Vocola: Copy to (NatSpeak|Emacs) = {Ctrl+a}{Ctrl+c} AppBringUp($1); 

Here the result of the first variable term "(NatSpeak|Emacs)" is passed to the function AppBringUp to bring up the desired application.

Finally, a function argument can be built by concatenating more than one action. For example, the "Back" and "Forward" buttons in a Web browser use by convention the keystrokes Alt+Left and Alt+Right. In Lotus Notes these keystrokes only work when passed via the SendSystemKeys function:

 Vocola: Go (Back=Left | Forward=Right) = SendSystemKeys( {Alt+$1} ); 
 Say: Go Back  Sent: SendSystemKeys( {Alt+Left} ) 

When you say "Go Back", the function argument "{Alt+Left}" is constructed by combining the characters "{Alt+", the reference $1, and the character "}"


Built-in Functions

Built-in Functions

Vocola supports all scripting commands defined for the Dragon Macro Language, as well as adding some built-in functions. Here are the most useful functions in the combined set:

Command Description
AppBringUp Start or switch to an application
ButtonClick Click the specified mouse button
DragToPoint Drag the mouse to the current point
Eval Evaluate a Python expression
HeardWord Execute a command as if words were spoken
MenuPick Select a menu or menu item
RememberPoint Record the current mouse pointer position
Repeat Execute actions a specified number of times
SendSystemKeys Send system keystrokes to Windows
SetMousePosition Place the mouse pointer at a specified position
ShellExecute Execute an application, with command line arguments
Wait Pause for a specified time interval

Here is the complete list:

ActiveControlPick
ActiveMenuPick
AppBringUp
AppSwapWith
Beep
ButtonClick
ClearDesktop
ControlPick
DdeExecute
DdePoke
DllCall
DragToPoint
Eval
GoToSleep
HeardWord
MenuCancel
MenuPick
MouseGrid
MsgBoxConfirm
PlaySound
RememberPoint
Repeat
RunScriptFile
SendKeys
SendSystemKeys
SetMicrophone
SetMousePosition
SetNaturalText
ShellExecute
ShiftKey
TTSPlayString
Wait
WakeUp
WinHelp

The Dragon Macro Language documentation describes most of these functions (see pp. 74-115.) For those not so described, and for Vocola's built-in functions, see the descriptions below.


Eval

Syntax Eval(expression)
Description Evaluates an expression in the Python language. Vocola is not a general-purpose programming language, so expressions such as arithmetic and conditionals are achieved using Python. The specified expression (which may be constructed from a sequence of Vocola actions) is evaluated using the Python interpreter, and the resulting value is used as a Vocola action or function argument.
Argument
expression     Vocola actions, which when evaluated and concatenated yield an expression in the Python language.
Example

It's useful to position the mouse by voice using screen units larger than pixels. This command places the mouse pointer at a specified screen position using a coordinate system of 15 pixels per unit. Saying for example "30 10 Go" moves the mouse pointer to screen pixel position (150, 450):

 Vocola: <n> := 0..99;
         <n> <n> Go = SetMousePosition( 0, Eval(15*$2), Eval(15*$1) ); 

 Say: 30 10 Go  Sent: SetMousePosition( 0, 150, 450 )

Repeat

Syntax Repeat(count, actions)
Description Executes an action sequence a specified number of times.
Arguments
count   Number of times to repeat the specified actions.
     
actions     Vocola actions to be performed the specified number of times.
Examples

In an "Open File" dialog box, this command moves up a given number of levels in the folder hierarchy. Saying for example "Go Up 3" constructs the pathname "..\..\..\" to move up three levels:

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

In the Mozilla mailer it's useful to delete several messages in a row by saying for example "Kill 3" to send 3 "delete" keystrokes. But unless these keystrokes are separated by "Wait" commands only 1 message is deleted. This command sends a specified number of "delete" keystrokes, separated by "Wait" commands:

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

SetNaturalText

Syntax SetNaturalText(enable)
Description Controls whether dictation is enabled in applications which do not support "Select-and-Say". (No visual feedback such as a system tray icon is provided.) This is an undocumented built-in function of the Dragon macro language.
Argument
enable     A value of 1 enables dictation, while a value of 0 disables dictation.

ShiftKey

Syntax ShiftKey([option[, action]])
Description

Either adds the specified key to the first character of the next non control keystroke or clears the specified key from the keystroke if the keystroke would normally be applied. That is, ShiftKey doesn't actually press any keys. Instead, it alters the keystroke that follows. You can sequentially execute more than one ShiftKey command to specify multiple keys.

This is an undocumented built-in function of the Dragon macro language. In Vocola it must be followed by a call to another built-in function such as ButtonClick or SendKeys.

Arguments
option    

Specifies which key to add to the first character of the next non-control key, as follows:

0   Clears all (ignores the action argument)
1   Left Shift (default)
2   Left Control
3   Left Alt
4   Right Shift
5   Right Control
6   Right Alt
 
action    

Specifies the key state, as follows:

0   Clear
1   Set (default)
Example

This example shows how to use modifier keys with mouse clicks, such as saying "Control Click" to click the mouse while holding the Ctrl key:

 Vocola: (Shift=1 | Control=2 | Alt=3) Click = ShiftKey($1) ButtonClick(); 
 Say: Control Click  Sent: ShiftKey(2) ButtonClick(); 

 

 


Defining Functions

Function Calls

Vocola supports user-defined functions as well as built-in functions. If you find yourself copying an action sequence for use in several commands, defining a function can make the commands more concise and understandable. (This is also possible using the built-in function HeardWord, but creating your own function makes for clearer code and faster execution.)

For example, in the Netscape/Mozilla mailer it's useful to define commands to move around in the "summary" window (which shows a one-line summary of each e-mail message). Here we define the function goToSummary to make sure the summary window has the focus:

goToSummary() := 
    SetMousePosition(4, 7)        # Window's bottom left edge
    SetMousePosition(2, 15, -45)  # Bottom left of folder list
    ButtonClick()                 # Folder list now has focus
    {Tab_3};                      # Summary pane now has focus

The left side of the definition specifies the function's name (goToSummary) and arguments (none in this case). The right side of the definition is a standard Vocola action sequence. Here we position the mouse over the bottom left corner of the mailer window, move up and to the right slightly to be over the folder list panel, click the mouse so the folder list has focus, and finally press the tab key three times so the summary window has focus.

Now we can define 3 commands using this function. Saying "Final Message" moves to the last message in the summary. Saying "First Unread" moves to the first unread message. And saying for example "Summary 3 Up" moves to the summary window and up three messages:

Final Message = goToSummary() {End};
First Unread  = goToSummary() {End}n;
Summary 1..20 (Up|Down) = goToSummary() {$2_$1};

Each of these commands uses our function goToSummary, making them shorter and clearer than if each had to include that function's actions explicitly.

Defining Functions with Arguments

You can also specify arguments when defining a function. For example, here's a function which switches to the nth application on the Windows taskbar:

switchToTaskBar(number) := SendSystemKeys( {Ctrl+Esc} )
                           {Tab_2}{Right_$number}{Left} " ";

This function, switchToTaskBar, is defined to take the single argument number (indicating which taskbar slot to switch to). {Ctrl+Esc} opens the start menu (just to get focus on the taskbar), and {Tab_2} moves to the first application. Then $number (referring to the function argument) is used to move right the specified number of slots. Finally, sending a "space" keystroke makes the selected application active. (Note that this function works in Windows XP -- a slightly different version is needed for Windows 2000.)

Now we can use this function in several commands. Let's say that Microsoft Word is the third application from the left on the taskbar. Saying "Switch to 3" makes Word the active application. Saying "Close 3" closes Word. And saying "Copy to 3" copies everything from the current application and switches to Word:

<n> := 1..20;
Switch to <n> = switchToTaskBar($1);
Close     <n> = switchToTaskBar($1) {Alt+F4};
Copy to   <n> = {Ctrl+a}{Ctrl+c} switchToTaskBar($1);

Each of these commands uses the variable <n> to specify a number between 1 and 20, which is then passed to the switchToTaskBar function to specify the target application.

Multiple Arguments and Nested Function Calls

Here's another example, defining two functions which each take 2 arguments. First is the function moveBy, which moves the mouse a distance (x,y) from the current position. Note that it uses the built-in Vocola function Eval to multiply each coordinate by 15, providing more convenient units than pixels. (I have rulers taped to my screen in these units, thanks to Kim Patch's idea. With this approach you can place the mouse anywhere on a large screen by speaking only 2-digit numbers, which are recognized much more reliably than 3-digit numbers. See the file _vocola.vcl in the shipping Vocola samples for more examples.)

moveBy is used twice by the next function, moveWindowBy, which moves the current window a specified distance (x,y) in these same 15-pixel units.

moveBy(x,y) := SetMousePosition(2, Eval(15*$x), Eval(15*$y));

moveWindowBy(x,y) :=
    SetMousePosition(4,1)  # Top window edge, center
    moveBy(0,1)            # Down into title bar
    RememberPoint()        # Store initial drag point
    moveBy($x,$y)          # Move by given amount
    DragToPoint();         # Do the drag

Note again that a function's arguments may be referenced in its action sequence using "$". That's $x and $y in these functions.

Now here are two commands using moveWindowBy, allowing you to say for example "Window 10 Up"or "Window 20 Right" to move the current window:

<n> := 0..99;
Window <n> (  Up='-' |  Down='+') = moveWindowBy(0, $2$1);
Window <n> (Left='-' | Right='+') = moveWindowBy($2$1, 0);

Note here how a function argument can be built from two variables. When you say "Window 10 Up", the first variable term <n> has the value "10" and the second variable term has the value "-". These are concatenated by the double reference $2$1 to form the final function call moveWindowBy(0, -10).


Contextual Commands

Vocola Tutorial: Enable by Context

We've discussed how to create "global" commands (which are always enabled) as well as application-specific commands (which are enabled only when a particular application is active). In addition, you can create contextual commands, which are enabled only when a particular window has the focus.

By specifying all or part of the window title in a context statement you can create commands specific to that window. For example, here are three groups of commands for Microsoft Outlook (from the application-specific command file "outlook.vcl"): 

 Microsoft Outlook:
   New Message = {Ctrl+n};
   Reply to Message = {Ctrl+r};
   Reply to All = {Ctrl+Shift+r};
   Forward Message = {Ctrl+f};

 Message (Plain Text):
   Send That = {Alt+s};
   Reply Here = "{Home}{Shift+End}{Del}{Enter 3}{Left 2}";

 Calendar:
   View Month = {Alt+m};
   View Work Week = {Alt+r};

The context statement "Microsoft Outlook:" specifies that subsequent commands should be active only when "Microsoft Outlook" is part of the title of the active window. When reading mail using Outlook the main window title is "Inbox - Microsoft Outlook", so the first group of commands above (to create, reply to, or forward a message) will be enabled.

Similarly, when editing a mail message the window title is "Message (Plain Text)", so the second group of commands above will be enabled. Finally, the third group of commands above will be enabled when the Outlook calendar is displayed.

Here is another example. The text editor application Emacs can be customized so that the window title includes the name of the currently-edited file. For example, when editing iexplore.vcl (the file of Vocola commands for Internet Explorer) the Emacs window title is "Emacs - iexplore.vcl - 01.05.02". This allows defining a set of contextual commands for editing Vocola files. The application-specific command file "emacs.vcl" would include:

 ### Editing Vocola files
 .vcl:
   Insert             <key> = {$1       Wait(0) }; 
   Insert       <mod> <key> = {$1+$2    Wait(0) }; 
   Insert <mod> <mod> <key> = {$1+$2+$3 Wait(0) }; 
 
 ### Editing Perl files
 .pl:
   New Statement = {Ctrl+e}{Ctrl+j};
   New Statement Above = {Ctrl+a}{Ctrl+b}{Ctrl+j}; 
   Insert Hash Reference = ->{}{Ctrl+b};

So for example when the Emacs window title contains ".vcl", saying "Insert Shift Tab" inserts the text "{Shift+Tab}" into the file. These commands allow speaking keystroke sequences when writing Vocola code. (The variable definitions for <mod> and <key> are omitted here, but available with the Vocola distribution.)

Similarly, the second group of commands above is active only when editing Perl files.

Global Contextual Commands and Multiple Context Choices

Contextual commands don't need to be application-specific. You can also create global contextual commands, as in this example from the global command file "_vocola.vcl":

 Open:
   Go Up = ..{Enter};
   Folder List = {Shift+Tab_2}{Down}{PgUp}; 

This defines two commands for use in a "File Open" dialog box, regardless of the current application. Whenever the window title includes the word "Open", you can say "Go Up" to move to the parent folder or "Folder List" to open the folder hierarchy drop down at the top of the dialog.

As it happens, "File Chooser" dialog boxes appear with a wide range of titles, such as "Open File", "Save As", "Browse for Folder", etc. Ideally we want the same set of context-specific commands to be available for all such dialogs. Vocola supports this by allowing the "|" character in context statements. Here is the full set of context titles and commands I use:

 Open | New | Save | File | Attachment | Browse | Directory: 
   Folder <folder> = {Ctrl+c}$1\{Enter};
   Go Up = ..{Enter};
   Go Up <n> = Repeat($1, ..\) {Enter};
   Folder List = {Shift+Tab_2}{Down}{PgUp};
   Choose <n> = {Down_$1}{Enter}{Esc};

Include Statements

Built-in Functions Sometimes you will want to use a set of Vocola definitions in more than one application. The Vocola "include" statement allows you to put such shared definitions in a single file, and include that file in each of several application-specific command files.

For example, many applications need to navigate the file system to find specific files or folders. But speaking pathnames can be difficult, as can navigating through folder hierarchies by voice. What you'd really like to do is define a single list of shortcuts to interesting folders, and have that list available in any program which needs to navigate the file system.

I've created a file called "folders.vch" ("vch" stands for "Vocola header") to contain my personal list of interesting folders, defined as a Vocola variable:

From file folders.vch:
<folder> := 
( Home = C:\Rick
| Temp = C:\Temp
| Downloads = C:\Programs\Downloads
| Start Menu ="C:\Documents and Settings\Rick Mohr\Start Menu"
| Vocola = C:\Programs\NatLink\Vocola
| NatLink = C:\Programs\NatLink\MacroSystem
);

With the Vocola "include" statement this list can be used in several Vocola command files. Here's part of my command file for Windows Explorer:

From file explorer.vcl:

include folders.vch;
Folder <folder> = {Alt+d} $1 {Enter}{Tab_2};

So for example, saying "Folder NatLink" to Windows Explorer switches to the folder "C:\Programs\NatLink\MacroSystem".

The folder list is also useful in a Command Prompt (DOS box), where saying for example "Folder Temp" performs the command "cd C:\Temp":

From file ntvdm.vcl:

include folders.vch;
Folder <folder> = "cd $1{Enter}";

Last and perhaps most useful is the following global command to move quickly to a specific folder in a "File Open" dialog box:

From file _vocola.vcl:

include folders.vch;

Open | New | Save | File | Attachment | Browse | Directory:
  Folder <folder> = $1\{Enter};

This global contextual command is active when the window title of any application contains one of the words shown. For example, when saving an attachment in Microsoft Outlook the window title is "Save Attachment", so saying "Folder Temp" switches the dialog's current folder to "C:\Temp".

Include using a variable filename

The "include" statement's filename can be varied using references to environment variables. For example, you might have a different set of interesting folders at home than at work, and so want to include a different file depending on which machine you are currently using. Since the environment variable "COMPUTERNAME" contains the name of your machine, you could say:

include folders_$COMPUTERNAME.vch;

If your work machine were called "Venus" and your home machine were called "family", you would define your list of interesting folders in two separate files, "folders_Venus.vch" and "folders_family.vch".


Comments

Comments

Using comments in your Vocola command files can help you or somebody else understand the sometimes-cryptic keystroke sequences.

Comments in Vocola are specified by the "#" character. Anything on a line following a "#" character is ignored by the command parser. Here is an example:

 # Extract a file pathname from a Netscape 4 mail message
 Get File Name = 
    {Ctrl+l} Wait(500)           # Open a "forward" window 
    {Enter_2}                    # Move to message body
    {Ctrl+f}:\{Enter}{Esc}       # Search for ":\"
    {Left_3}{Shift+End}{Ctrl+c}  # Copy entire pathname
    {Alt+F4};                    # Close the window




Example File

Example File Here's a longer example of a Vocola command file, taken from my "netscape.vcl" file for controlling the various Netscape applications.

It contains commands for reading email, composing email messages, and editing HTML files, activated contextually by the window title. It contains simple one-line keystroke commands, some longer keystroke commands, several "alternative set" commands with substitutions, a variable definition, and a few function calls mixed in.
 
 # Voice commands for Netscape 4 

 ### Reading email
 Netscape Folder:
   New Message      = {Ctrl+m};
   Reply to Message = {Ctrl+r};
   Reply to All     = {Ctrl+Shift+r};
   Forward Message  = {Ctrl+l};

   Print Message = {Ctrl+p}{Tab_6}1{Enter};
   Search Messages = {Ctrl+Shift+F};

   Sort by (Date=e | Sender=r | Subject=s) = {Alt+v}o $1;

   # Choose HTML editor or plain text editor
   Use (HTML={Up} | Plain Text={Down}) = 
       "{Alt+e}e{Shift+Tab}{Down 8}{Tab}$1{Enter}";

   # Extract a file pathname from a mail message
   Get File Name = 
       {Ctrl+l} Wait(500)           # Open a "forward" window
       {Enter_2}                    # Move to message body
       {Ctrl+f}:\{Enter}{Esc}       # Search for ":\"
       {Left_3}{Shift+End}{Ctrl+c}  # Copy entire pathname
       {Alt+F4};                    # Close the window

 ### Composing email messages
 Composition:
   <EmailAddress> := ( David = dsmith@netscape.com
                     | Emily = egreene@aol.com
                     | Mike  = mike@orangerooster.com
                     | Sue   = suenew@brown.net
                     );
   Address <EmailAddress> = $1 {Enter};
   Cc <EmailAddress> = "{Shift+Tab} {Down 2}{Enter}$1{Enter}"; 

   Send That = {Ctrl+Enter};

   I Meant Reply All =
       {Ctrl+Home}{Ctrl+Shift+End}{Ctrl+c}  # Copy message
       {Alt+F4}n                            # Close window
       {Ctrl+Shift+r};                      # Reply to All

 ### Editing HTML documents
 Netscape Composer:
   Save (File|That) = {Ctrl+s};
   Save and Close   = {Ctrl+s}{Alt+F4};
   Show Preview     = {Ctrl+s} AppBringUp(iexplore) {F5};

   Fixed    Width [Font] = {Alt+o}{Right}{Down}{Enter};  
   Variable Width [Font] = {Alt+o}{Right}{Enter};  

   Style Normal         = {Alt+o}p{Enter};
   [Style] Heading 1..6 = {Alt+o}h $1;

   Promote That = {Ctrl+-};
   Demote That  = SendSystemKeys("{Ctrl+=}");


 
 


Command Sequences

Comments

You can configure Vocola to allow speaking several commands in a row without pausing. For example, assume your commands allow you to say:

"3 Words Right"   to move the cursor 3 words to the right,
"2 Right"
to move the cursor 2 characters to the right, and
"Kill Char"
to delete 1 character.

If you wanted to speak these three commands in succession you would normally have to pause between commands, saying

"3 Words Right" (pause) "2 Right" (pause) "Kill Char".

With Vocola you don't need to pause, so you can say

"3 Words Right 2 Right Kill Char".

Once you get used to speaking command sequences, text editing by voice becomes faster and less frustrating.

Warning: A bug introduced in Dragon NaturallySpeaking 7.0 and worsened in 8.0 can cause unacceptable performance if command sequences are enabled. With 7.0 switching to or from an application becomes slow if a large number of commands are defined for the application. With 8.0 users have reported that command recognition is very slow even when only a few commands are defined.

Because of these NaturallySpeaking bugs (which ScanSoft has essentially refused to fix), Vocola command sequences are disabled by default and not recommended with version 8.0. Personally I find them so productive that I've stayed with NaturallySpeaking 6.0.

How to Enable and Disable Command Sequences

To enable command sequences (in Vocola 2.5 or later), open the file:

NatLink\Vocola\Exec\vocola.ini

and modify it to contain the line:

Use Command Sequences=1

Then say "Load All Commands".

To disable command sequences, proceed as above but with the line:

Use Command Sequences=0

Caveats

Note that only commands defined in the same file can be spoken in sequence. For me this causes occasional mistakes but is not a major limitation. And using include files can help. For example, if you find you want to sequence some of your global commands with commands local to Microsoft Word, you could put the global commands in a separate .vch file and include that file in both word.vcl and _vocola.vcl.

You might think command sequences would lead to mistakes when an unexpected combination of commands is recognized, but in practice I have not found this to be the case. It's a good idea to avoid single-word commands, but that's a good idea anyway.


Install Vocola

Install Vocola

Use the following instructions for your first installation of Vocola.
Or, see below to upgrade from an earlier version of Vocola.

Installing Vocola for the first time

  1. Install Dragon NaturallySpeaking, version 3.5 or later, any edition.

  2.  
  3. Install Python. Version 2.3 is recommended, with 2.0 and 2.2 also supported. Earlier versions are not supported.
     
  4. Install NatLink and Vocola.
  5. Associate the .vcl file extension (used for Vocola command files) with your favorite text editor. This allows you to open your Vocola files using built-in voice commands. An easy way to set up this association is to right-click on any .vcl file (such as Vocola\Samples\notepad.vcl), select "Open With" or "Open", and pick your favorite text editor (for example, Notepad).

    Note that Scott's installer associates the .vcl file extension with the free editor Notepad2, which it also installs.

    Emacs users should install gnuserv and associate the .vcl file extension with gnuclientw.exe. (Make sure the directory containing gnuclientw.exe is included in your PATH environment variable.)
     
  6. Test Vocola. 

Upgrading from an Earlier Version of Vocola

If you originally installed NatLink + Vocola using Scott Weinstein's installer, you must upgrade using the latest version of that installer. The installer will detect if there is an older version, and upgrade correctly. (You can't change any installed files manually because the current version of the installer automatically changes them back when you start NatSpeak.)

If you originally installed Vocola directly you can either switch to the installer or follow these steps:

  1. Rename your existing Vocola folder (it's in your NatLink folder)
  2. Install Vocola as described below.
  3. Copy all files from your old Vocola/Commands folder to your new Vocola/Commands folder
  4. Restart NatSpeak

Installing Vocola Directly 

  1. Download the Vocola zip file.
     
  2. Extract the Vocola zip file into the NatLink directory. For example, if you installed NatLink in C:\NatLink, you should choose C:\NatLink as the folder to extract to. After unpacking you should see folder C:\NatLink\Vocola, with subfolders Commands, Doc, Exec, Samples, and Simpscrp.
     
  3. From the Vocola\Exec folder, copy the files _vocola_main.py and VocolaUtils.py to the NatLink\MacroSystem folder. This activates Vocola's built-in voice commands.

Vocola Versions

Download And Install

This page lists the released versions of Vocola and the changes they included, with the most recent version first. To download Vocola, click on the link next to the version you want.

Version 2.5 -- January 10, 2005 (Vocola-2-5.zip)

Version 2.4 -- September 28, 2003 (Vocola-2-4.zip)

Version 2.0 -- June 7, 2003

Version 1.1 -- May 11, 2002 (Vocola-1-1.zip)


Converting DVC Files

Converting DVC Files If you have created voice commands using the Dragon macro language you may want to jumpstart your repertoire of Vocola commands using the utility dvc2vcl.exe, found in the folder Vocola\Exec. Note: this utility is  provided "as is". You are welcome to make improvements.

This utility converts many commands correctly, handling keystroke sequences, function calls, word arguments, lists, and lists with substitution. Most of my 200+ macros converted fine, with some manual cleanup required for the rest. If the utility cannot handle a particular command construct it is replaced with "[]" and the resulting command is commented out.

The utility takes two arguments -- an input folder containing Dragon voice command files (*.dvc), and an output folder to contain Vocola files (*.vcl). For example, the script might be invoked as follows (assuming Vocola is installed in C:\NatLink\Vocola and NatSpeak is installed in C:\NatSpeak):

cd C:\NatLink\Vocola
Exec\dvc2vcl C:\NatSpeak\Users\Rick\current Commands

Each .dvc file in the input folder C:\NatSpeak\Users\Rick\current is converted to one or more .vcl files, which are written to the output folder C:\NatLink\Vocola\Commands. Global commands are written to the file _vocola.vcl, and application-specific commands for an application named foo.exe are written to foo.vcl.

If you have added commands to the default Dragon command file global.dvc, you may want to make a copy of the file and delete the Dragon-supplied commands so that you only convert your own commands. There's no particular value in converting the Dragon-supplied commands to Vocola.


Troubleshooting

Troubleshooting Writing Vocola commands is straightforward with a little practice. This page summarizes some potential problems, and how to solve them.

My command doesn't work

You've written a Vocola command but nothing happens when you speak the command. Here are some possible causes:
  1. You didn't save the .vcl file.

  2.  
  3. Your command had a syntax error.
  4. You're speaking the command in a different context than you defined it for.
  5. You changed an include file (.vch) and didn't run the Vocola translator by saying "Load Voice Commands".
     
  6. NatLink didn't load the translated Python file.

My command doesn't work right

Your command gets executed, but doesn't work correctly. Here are some possible causes:
  1. Another command is being executed instead.

  2. You need to use quotation marks in your Vocola command. Quotation mark delimiters are usually optional in Vocola, but are required in some cases:

Support

Support I will do my best to fix Vocola problems, but as usual with free software supported in spare time I make no guarantees. Before e-mailing, please consult the Language Tutorial, the section on Troubleshooting, and the list of known bugs below. I wrote this documentation with you in mind, so please read it and try to solve your problem before contacting me.

Known Bugs

The following problems are known to exist with Vocola 2.5:

Email

Send bug reports and other feedback by clicking on the button below. Please indicate what version of Windows, NatSpeak, and Vocola you are running. Positive feedback welcome. (Many thanks to the user who sent an Amazon gift certificate!)

I'm hoping to keep this address away from junk e-mailers, so if for some reason you are posting information about Vocola please use the web page address (http://home.comcast.net/~vocola) rather than this e-mail address.


Wish List

Wish List

Here is a list of potential Vocola enhancements. Let me know if any of these are particularly important to you.

New built-in functions:

Language improvements:

Other:


 

My RSI Story

My RSI Story

In March 1998 I worked an entire weekend to meet a major deadline with important revenue consequences for my employer. By Sunday night my wrists and hands were tingling and sensitive, and the next day I had significant wrist pain. In previous years I had had minor symptoms, but they had always gone away.

I knew to treat my injury seriously since I have friends with debilitating RSI problems. But, I was starting at square zero in terms of knowledge and treatment, and still in the middle of a high-pressure work situation. As I began to realize my injury was serious I started searching for solutions. Everyone I talked to had different ideas, and every idea seemed to involve 30-90 minutes a day of work on my part. I could handle the regimen of one or two of these, but in the absence of real progress it was hard to have confidence. In the subsequent months I tried doctors, occupational therapy, anti-inflammatories, massage, a new chair, acupuncture, rolfing, special keyboards, physical therapy, drinking lots of water, chiropractic, vitamins, myotherapy, and glucosamine sulfate. Nothing seemed to make a reliable difference.

Meanwhile my company was supportive and willing to provide what I asked. But while it was easy to ask for new equipment and small schedule accommodations, I couldn't bring myself to ask for major time commitments from other people or major project slippage. I adjusted all my habits to require as little typing is possible, but continued to type when necessary (occasionally a considerable amount).

Unfortunately it took a year of this before I began using voice recognition and started truly resting my hands. I can't know for sure, but I believe that had I started using voice recognition right away I would have recovered. During several periods I've made significant recovery, but despite vigilance in most every activity I have always slipped up. Once it was snow shoveling, once un-careful fiddling, and once not-wimpy-enough weightlifting in a strengthening program. Of all the things I have tried, the only ones that have reliably helped are avoiding irritating activities and voice recognition. Of some help have been stretching, posture improvement, myotherapy, and massage.

Since resting my hands seemed so important I tried for hands-free computer use as much as possible. The Dragon Macro Language made this possible but was excruciatingly cumbersome, so I was very excited when Joel Gould released NatLink. Shortly thereafter (at NEFFA) Patricia Hawkins and I were comparing notes about NatLink. Her comment "yeah, but you still have to change two places" got me thinking about Vocola.

Designing, implementing, and using Vocola has been a rewarding bright spot among otherwise unsuccessful attempts at recovery. And thankfully, with Dragon NaturallySpeaking, NatLink, and Vocola I've continued to be effective at my job.

The main lesson I take away is to stand up for my own needs when they conflict with the needs and desires of others. That Monday deadline seemed very important at the time, but everybody would have survived just fine if I had delivered a week later. The customer was adamant about the deadline, but as it happens they ultimately canceled the project! And even after my initial injury, if I had been brave enough during the first year to ask for difficult adjustments at work I might have been able to recover quickly.

One doctor I saw said "With constant vigilance you can get a little better every year" and at this writing (December 2004) things are looking up somewhat, I'm starting to type a little and play some careful fiddle.

Rick Mohr, Watertown, Massachusetts, USA, December 2004


Voice Resources

My RSI Story

Web Sites

Mailing Lists