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:
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 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.
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.
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 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.
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".
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".
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.
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. |
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 | |
e | Choose 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" | |
u | Choose the top radio button ("Use the HTML editor to compose messages") | |
{Enter} | Hit the "OK" button |
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.
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.
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". |
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.
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. |
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. |
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.
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. |
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} ); |
When you say "Go Back", the function argument "{Alt+Left}" is constructed by combining the characters "{Alt+", the reference $1, and the character "}"
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.
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 |
|
|||
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):
|
Syntax | Repeat(count, actions) | |||||||||
Description | Executes an action sequence a specified number of times. | |||||||||
Arguments |
|
|||||||||
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:
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:
|
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 |
|
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 |
|
||||||||||||||||
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 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.
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.
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).
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.
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}; |
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> := |
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".
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".
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 |
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 Print Message = {Ctrl+p}{Tab_6}1{Enter}; Sort by (Date=e | Sender=r | Subject=s) = {Alt+v}o $1; # Choose HTML editor or plain text editor # Extract a file pathname from a mail message ### Composing email messages Send That = {Ctrl+Enter}; I Meant Reply All = ### Editing HTML documents Fixed Width [Font] = {Alt+o}{Right}{Down}{Enter}; Style Normal
= {Alt+o}p{Enter}; Promote That = {Ctrl+-}; |
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
With Vocola you don't need to pause, so you can say"3 Words Right" (pause) "2 Right" (pause) "Kill Char".
"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.
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
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.
Use the following instructions for your first installation of Vocola.
Or, see below to upgrade 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:
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)
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.
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:
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