Using The Happy Hands Java Speech Editor

Introduction

The Happy Hands Java Speech Editor is an elaborate text editor designed to convert speech input into perfect Java code. This is accomplished as the user speaks on the level of their thoughts, not Java syntax. The Happy Hands Java Speech Editor changes the state of mind of the programmer by enabling him to rise above the details of entering text into a document.

The Happy Hands Java Speech Editor written by Sean W Hennessy. He was a virtuosic piano player. He wrecked his hands because he was programming software at least 10 hours a day, then going home and banging on a piano for 2 hours a day. He wrote this program to try to salvage his career as a programmer, his piano, and hopefully make a significant contribution to the world.

Document conventions

Code elements enclosed are like this, [code element], to indicate the red selection square is around the element in the Happy Hands editor.

Technical Overview

Requirements

Happy Hands is a Java program. We assume you have a Java virtual machine if you are doing Java coding. Version 1.4.1 or greater is required.

Happy Hands relies on an external speech recognition engine. We have tested IBM ViaVoice and the Microsoft speech engine. IBM's seems to be better.

Speech Input

Happy Hands uses a rule based speech input. It builds grammars based on what you are trying to do, and the current insert point in the code. There grammars are submitted to the speech recognizer engine. The engine will recognize only these grammars. This means Happy Hands is 100% accurate if the recognizer property matches what you are saying. Possible responses to your speech are: The first case is the most common. On a good day this is what will happen 90% of the time. The second case is the next most common. It can be frustrating, but just try to relax and its not a big deal, since its harmless aside from the wasted time. The last two cases happen about equally, not often enough to worry about. As you practice, using a consistent microphone position and tone of voice, especially if you tend to edit code that makes use of the same libraries (with the same symbol names) consistently, your results will improve.

At all the times Happy Hands in a set of speech handlers that are in a waiting state. A speech handler is an internal mechanism that may not seem important to the user, however since Happy Hands is a ground-breaking program in computer science, we feel that some technical explanation of these mechanisms is important. A speech handler is a collective set of behaviors and states that defines both the grammar to listen for and how to respond to the user's speech when it matches that grammar. It is the logical equivalent to the graphical dialog box that presents an input mechanism and handles input. In Happy Hands, a speech handler can be in an active or a waiting state. In the waiting mode, the handler is listening for speech that has a very simple grammar that's main purpose is to activate the handler. When it is activated, it changes its available grammars according to the context at hand. This two-stage mechanism is employed because it makes recognition easier on the underlying speech recognizer engine. Generally the activation grammars are simple and not context sensitive, however the grammars and the activated state may be very complex, containing thousands of alternative recognitions.

We call the speech handlers concerned with generating Java code transcribers. Other speech handlers do things like opening files, selecting text, moving about, operating on the source code, etc. These often do not have a distinct active state.

Choosing a recognizer

When Happy Hands starts, it queries the system about what recognizers are available. At this time Happy Hands can use only recognizers that implement the SAPI4 specification. This includes IBM's ViaVoice and the Microsoft recognizer. To find the what recognizer are availible, use the "Recognizer Controls" function under the "File" menu. This gives you a list of usable recognizers on your system. From this panel is also possible to change the recognizer that Happy Hands is using on the fly. Select the recognizer a from the list and hit the "Use the Recognizer" button. Then use the "Reinit speech" function to make the change take effect.

If you are considering trying Happy Hands and you have no recognizer installed at all, we sugest getting the Microsoft recognizer from their web site for free. This will enable you to try out Happy Hands without spending any money at all. On the other hand, Happy Hands works beautifully, so you might as well get Via Voice. Via Voice is generally a more conservative recognizer. It requires a greater confidence level to respond than the Microsoft recognizer. This means you get fewer false positives. The Microsoft recognizer is eager to respond, and is faster in deciding what you said, but sometimes responds to utterances it seems to imagine. Via Voice has the advantage of having a formal training system that makes you read it stories, so it will already know your voice when you start using Happy Hands. If you have already trained Via Voice for dictating letters, it is ready for Happy Hands.

If you have purchased a recognizer not mentioned here it is possible that Happy Hands can use this recognizer just as well. Before you go out and buy a new recognizer we recommend you simply run Happy Hands and consult this list to find out if the recognizer you already have will work. When choosing the recognizer from this list, try to pick one that includes "Command and Control", or sounds like it is intended for limited grammars rather than letter writing.

Context Sensitivity

Happy Hands keeps lists of alternative speech tokens that are submitted to the recognizer for uttering the name variable, a field, a method, a target, a type, or a package. These lists of alternatives, which are usually implemented practice as a more highly developed grammar than a simple list, maybe inspected in the "Types", "Vars", "M.Fld", "M.Meth", "S.Fld", and "S.Meth" grammar views. Inspecting the will convince you that the context reflects the current insert point in the source code. The symbol lists, however, are not used as stand-alone grammars. They are part the grammars offered by the transcribers specific to the type of lexical element being editing at the time. The context sensitivity varies by not only the list of alternatives symbols offered for certain point to the source code, but also by the transcriber that defines speech grammars intended to edit the specific type of lexical element at that point. In other words, Happy Hands understands the target of your speech at every point, and the options at that point.

Symbol renaming and remapping

Happy Hands specially prepares symbol names for the recognizer to make them easy to speak. For example, because "awt" is not an English word, it will be broken up into its component letters, so you will say "a - w - t". Other renaming rules Happy Hands applies to symbols include breaking up compound words that are notated as in "setClipRect" into phrases such as "set clip rect". The renaming rules it applies are applied recursively to each sub part of the new phrase, so that "rect" will become "r - e - c - t", because rect is not an English word. However, whenever words are broken to component letters, the original unchanged word is offered as an alternative, so that saying "set clip rect" and "set clip r e c t" will both map to the same result. Another renaming that Happy Hands applies replaces all underscores with spaces, unless the underscores appear at the beginning or end of the symbol, in which case is represented by saying "underscore", so _getGraphics becomes "underscore get graphics". The list of words Happy Hands considers to be English is read from a file "settings/words" in the installation directory. You may add words to this file and if you wish. Before symbols are coerced, a remap table is consulted to find out if the word should be spoken in some completely different way. The remapping table is built by reading the file "remap" in the Happy Hands installation directory. If you inspect this file, you will see that the symbol "Integer" has been remapped to "capital integer", and "javax" has been remapped to "java x". For maximum versatility, the remapping is done before the renaming, and also to generated sub words.

Syntax Tree

When you open a file and Happy Hands Java code transcriber, a file is parsed and converted into syntax tree, and the tree is then rendered to text and presented in the text editor. The syntax tree has the same information as the tree handed to the Java byte code generator, with the addition of comments. The tree is composed of pieces each with an easily understandable meaning, and therefore easier to work with for either a person or a computer. It is not simply an engineering solution, but a feature of the Happy Hands system.

Tree to text conversion

As the tree is modified, a tree to text generator updates the text in the editor. We cannot emphasize enough that when you use Happy Hands you do not have to worry about detailed syntax elements such as semicolons, braces and parentheses, because it generates these for you in converting from the tree to text. This fact, combined with the context sensitivity, means that most causes of compiler errors are eliminated. Often when you compile a text file generated with Happy Hands, it compiles with no errors the first time. The tree to text conversion takes place incrementally. The smallest group of tree elements that needs to be updated is run through the tree to text generator, resulting in a snappy response.

Text to tree conversion

Although speech is more humane than typing, it is also essential for the user to be able to simply type, because sometimes Happy Hands, despite its greatness, cannot always understand you. Therefore Happy Hands can convert the text to the tree (and then back to text). It does this in an incremental way for speed. As you type it assumes the probable type of lexical element of the insert point is unchanged since the previous time, and submits this text to a general Java parser in the section of the parser logic designed for parsing that type of grammar. If this parsing fails, it gives a larger section of text to the parser, and so on until it achieves a successful re-parse. Because it does this in an incremental manner, the size of the document is not a factor in re-parsing to the tree, or rendering of the syntax tree to text. Happy Hands is usually able to convert from text to tree and to text in a fraction of a second. As you type, your typed text is a light gray color indicating it has not been generated from the syntax tree. The text will not be re-parsed with every keystroke - it is re-parsed after you finished typing for half a second. In the event of a syntax error, the unparsed the text will remain until the problem is fixed.

File opening

Upon the opening of the Java source code file, the file is parsed and converted into the syntax tree that Happy Hands keeps. The file must be free of syntax errors. If there are any syntax errors they will be highlighted and the file will be displayed as originally on disk, and keyboard entry mode will be started. Once all the syntax errors have been fixed, simply exit keyboard entry mode and the file will be re-parsed. The file does not have to be able to compile without errors, but the simply able to parse without errors. This means the braces and semicolons need to be in the right places, but the symbols do not have to be resolvable. In practice this requirement does not seem to be hard to achieve.

File saving

When Happy Hands saves a file, it is saving the text generated by its tree to text generator. This means the file will be saved in the current coding style Happy Hands is using. At the time this document was written, only one coding style is offered, but this will become customizable. The upside of this is that the files run through Happy Hands are very neat and regular. The downside of this is the any special formatting that that has special meaning to the developer is lost.

Undo system

Happy Hands has an undo system that tracks changes made either by speaking or typing. To save memory an undo limit is imposed, which defaults to 10.

Projects

Although Happy Hands is not intended to be an integrated development environment that provides a universal solution for all your coding needs, it does have some rudimentary bookkeeping that keeps track of your project. These abilities simply make it easier to use and will not interfere with your projects from other development environments. Happy Hands does not try to run the whole show.

A project consists of a single file that has information regarding what source directories should be considered in the project, what compiler to use, the class path setting, and other various settings needed to run the compiler. The list of available projects is found by reading the file "settings/workspace.xml" in installation directory. This file is so simple and readable that it should be possible to create projects by editing this file instead of using the user interface, however one is provided.

Compiling

Happy Hands can run the compiler on single files or directories. The compiler to use is set in "settings/workspace.xml". Settings such as the class path are set in the file specific to the current project. These can be controlled from the projects panel. Compiler errors are listed in the box on the right. Clicking on an element in the list takes you to the error. It is also possible to say "next error" and "previous error" to iterate through without using your hands at all. The top file in the editor can be compiled by saying "compile top file" or hitting the button for it.

Testing

Happy Hands can run a Java program and capture the programs output in the box labeled "Testing". To start the test, say "test program". To stop the test, say "stop test".

Tips and Tricks

Editing of existing elements

Existing code elements can be modified by selecting them with the red selection box. This starts a transcriber designed to edit this type of element. In fact, the editing of existing elements is what Happy Hands is doing most of the time. After a new element is created it is treated the same as any other element and editing begins as if an existing element was selected. There is scarcely any difference between creating a new code and editing old code. We will admit that creating new code is generally faster because you are saying expressions in big streams of thought instead of short utterances. For making tiny changes sometimes it is best to simply use the keyboard.

Grammar stringing

Most transcribers have several independent grammars they are listening for. These may strung together in one utterance, without pausing to see the text update. The effect of each rule will be applied in the order they were spoken. As long as the speech keeps coming, no text will be updated, because the recognizer is waiting to find out if an as yet unspoken rule could be matched.

Reparsing and keyboard mode (the Esc key)

A mode of operation is available that allows you to enter text using the keyboard with the incremental reparsing and transcription disabled. You can always enter text with the keyboard, and normally this causes an automatic local reparse. However, if you switch to keyboard only mode, the reparsing will not happen, nor will you be able to enter code by speaking. Happy Hands becomes a normal text editor in this mode. To switch to keyboard mode, hit the Esc key. To switch back, hit it again. When you switch back to transcription mode, the entire file is reparsed and regenerated, in one or two tenths of a second. Note that hitting the Esc key twice is a handy way to cause a full reparse in the unlikely event that the Happy Hands incremental reparse has become confused. This mode is especially useful for entering comments, and doing big pastes and deletes.

A transcriber is finished by starting another

There is no need to explicitly end an active transcriber. Simply by starting another, either by invoking its waiting state grammar to append an element, or by selecting an existing element, the active transcriber is be ended and replaced with the new one.

Single utterance functions will not interfere

Using a non transcription speech function will not stop the active transcriber, unless the function requires additional speech input. This enables one to say things like "save top file" in the middle of transcription.

Always a waiting handler

When a transcriber is moved from the waiting state to the active state, it is copied, the copy is placed in the waiting state. This enables the creation of an element while another element of the same type is being edited.

Long names are better

Long names are more likely to be recognized, because they have a more distinctive profile. Try to use longer names when naming new symbols. You will never have to type them again, so there is no reason for brevity.

Room noise

Happy Hands only responds to certain specific grammars. It will not be confused by conversations, frustrated muttering, or the radio.

Default values

In several cases, optional language elements are offered as place holders in the text while the owning element is selected. For example, a for-loop does not require expressions in the header, but they are offered so that they may be selected while the for-loop is selected.

User Interface Components

Text editor component

The text editor component is the large white if box located in the upper left corner. It is a traditional text editor that does some fancy graphics to indicate the state of the user's input. As you move the mouse over the source code, a green rectangle appears over various elements in the source code. The green rectangle shows you which element is currently selected. The green rectangle selection sets the insertion point for new elements, and the target for operations such as deleting or copying an element. If you click the mouse on an element (it will already have the green selection rectangle around it), it is further selected for transcription, acquiring a red square. A transcriber appropriate for editing the selection is started and the context is updated. If the "auto edit" switch is enabled, element is selected for transcription after half of second of no mouse movement.

The syntax colors may be changed by editing the file settings/settings.xml.

Grammar views

The grammar views describe what it is possible to say. The grammar view is organized into a tree in which some sets of children run horizontally and others run vertically. All non leave elements are expanded and contracted by pressing them once with a mouse. (We have made every effort in the development of Happy Hands to avoid requiring the use of the mouse and especially mouse button presses, however the mouse's utility as a geometrical picking tool is unparalleled, so we continue to target it for this.)

There are four basic types of elements in a Happy Hands grammar. These elements are each rendered in a different way in the grammar view.

There are several grammar views that each describe a grammar that is used for a different purpose. These are:

Syntax tree view

The syntax tree component is a rendition of the internal tree data structure that is the principle target of the user's input. This component is provided mostly to satisfy the user's curiosity. It was used during the development of Happy Hands.

Undo history view

This shows a list of undoable actions.

Files view

The project files component has a listing of files known to be part of the current project. The primary purpose of this component is the fast opening of files. Later we will describe is not necessary use this component if you can remember and speak the file's name. The project files component is drawn like a traditional file browser. At the top level there is a list of available projects. The list of available projects is found by reading the file "settings/workspace.xml" in the Happy Hands installation directory. Under each project node in the project files component is a list of directories. Under each directory are the Java packages arranged in a hierarchical manner. The list of directories in the project is a user setting, however the Java source files of the project are found by looking on the disk. Every Java file under one of the project directories is assumed to be a file in the project. You do not have to explicitly add every Java file to the project. Maybe this behavior could be a problem if you have some files not intended to be the project, but are in the project directory. However since we believe that it is bad coding practice to keep such stray files in with the good ones, these files should be moved to different directory in order to not appear here and not be subject to compilations.

Projects component

The project component has a list of projects and a gui for assigning the project settings.

The project file setting controls the name of the file where project information is stored. When you create the new project, a file chooser appears to set this value. The value will also be added to the "settings/workspace.xml" file.

The source code directories setting is a list of directories where the source code of the project should be found. Each directory should go up to and including the first directory of the package. For example, if you have a package tree that goes pac_x.pac_y.pac_z, it is not necessary to make the directory end at the package root, pac_x. You could stop it at pac_y, and only these files will be included.

The "classpath" setting effects the following:

Note the CLASSPATH environment variable is not included. The classpath setting is a set of files and directories. The files need to be .jar or .zip files.

The "lib path" setting controls the dynamic link libraries or shared object libraries used by the Java virtual machine, when testing.

The "test class" setting is used when testing. It is the class you want the Java virtual machine to enter.

The "arguments" setting is used when testing. These are the arguments are given to Java program being tested.

The "vm arguments setting is used when testing. These are the arguments given to the VM.

Menus

Happy Hands has conventional graphical function launcher menus, although every function in the menu is accessible via speech. Happy Hands has only the basics: a "File" menu, a "Edit" menu, and a "Build" menu. The functions are described below, in the speakable functions section.

Standard Grammars

Type grammar

Many of the transcribers in Happy Hands make use of the standard type grammar within their specialized grammars. The first word of the standard type grammar is always "type". This convention avoids ambiguity in recognition. If the type is a non array type, the next word is the either the type name or the fully specified type name. For example, "type string" and "type java Lang string" will generate the text "String". Primitive types use slightly modified names to aid recognition: "integer" means into, "floating point" means float, "double" means double, "long integer" means long, "character" means char, "byte" means byte, "Boolean" means Boolean, and "void" means void. The expression for an array type is done as follows: For the type String[], say "one-dimensional string array", or "one-dimensional java lang string array". For the type int[][], say "two dimensional integer array". The available type names in the grammar are determined by the import statements of the file. If the type you are trying to speak is not being recognized, make sure you importing that type in the import statements. Note that the ambiguity between the type names integer and Integer is solved by remapping the name Integer to "capital integer", as defined in the remapping file. All of the other class types in java.lang that are proxies for primitive types follow the same convention.

Insert prefixes

Many of the transcribers in Happy Hands that insert statements into the code offer several prefixes that come before their particular grammar. These prefixes specify where the insert will happen.

The Transcribers

The transcribers are the devices in Happy Hands that translate speech to code. They are the raison d'etre of the program.

Please note that in these descriptions we refer to specific utterances that they have since changed either because of implementation changes, or changes in user settings. The exact words that may be spoken at any point maybe discovered by looking at the grammar views.

Package transcriber

To create a new package statement, say "insert prefix package declaration". (The usual utterance is "append package declaration"). This tells the waiting package transcriber that you would like to append a package declaration. It does this and then changes to the active state grammars. The default looks like:

package no_name;

Before this phrase is uttered, the package declaration transcriber is in a waiting state in the "Transcribers" grammar view. The grammar view shows that "append package declaration" is one of the grammars that the package listens for. Upon uttering the phrase, the package transcriber is moved to the active grammar view.

When the package declaration is inserted into the document, the first element of the package is selected. The package specifier defaults to "no_value". The package name is spoken in it's entirety. For example, to declare your file a member of the java.awt package, say "java a w t" in one utterance.

An incremental specification system may be used as well. Note that this feature has come and gone but may come back. When first element of the package specifier is selected, the transcriber is listening for any one of the root package specifiers found in the class path. Examples of root package specifiers are "java" and "javax". Upon recognition of one of these alternatives, another "no_value" package specifier is appended. The recognizer is now listening for package specifiers that are found in with in the first package specifier, for example "awt". Once you have spoken the last element of a package specifier, you need to manually delete the last element with the backspace key.

Please note the Happy Hands specially prepares symbol names for the recognizer so they will be easy to speak. Because "awt" is not an English word it will be broken up into its component letters, so you say "a - w - t". See the section on symbol renaming for details.

Import transcriber

To create import statement, say "insert prefix import statement". The import transcriber works much like the package transcriber, with the additional ability to add a star. The default import statement looks like:

import no_name;

For example to generate the import statement "import java.awt.*;" say "java a w t" in one utterance. Like the package transcriber, and incremental ability has come and gone. In this mode, if you choose to enter a package specifier by typing it, after the new text is parsed the import transcriber will change the available grammar to the set of package specified within the name of the name you just typed.

Class definition transcriber

To create a new class definition, say "insert prefix class definition". (The phrase "append class definition" appends after the current element, "insert class definition" inserts before the current element. Also try "insert in block class definition", "replace with class definition", and "enclose with class definition".) The default class definition element looks like:

class [no_name]{ }

The red square around the class definition means the class definition transcriber is waiting for speech. The red square around the class name means that the naming transcriber is also waiting for speech. In Happy Hands, a transcriber may be assisted by a sub transcriber. In this case, the class definition transcriber is assisted by the naming transcriber.

Class name

The easiest way to name the class is to simply type it. This is usually the best way to supply any new symbol name. The class name text is highlighted and ready to be replaced when the new class element is created. When you have finished typing the syntax tree will be regenerated reflecting the new name. With Happy Hands, once the name is typed once, you will be able to refer to it with speech. It is always possible to tell when a piece of text has not been generated from the syntax tree when is a light gray color. This means the parser has not been run on this text, or it has been run but did not succeed because of a syntax error.

It is also possible to give the name by speaking. The naming transcriber is started automatically when a new class is started. (The naming transcriber will start automatically only if the "auto name" option is enabled. It is disabled by default.) This transcriber accepts is a sequence of English words, or letters using the alpha-bravo-charlie alphabet. For example, to name your class "Sean", say "capital sierra echo alpha november". If the naming transcriber is not active, activate it by saying "class name", or click the mouse on the class name.

Access Modifier

To change the access modifier of the class you may say "public", "protected", "private", or "package".

Memory Modifier

To change the memory modifier of the class you may say "static" or "non static". The memory modifier, of course, has application only to an inner class.

Base Class

To specify the class's base class, say "extends standard type grammar". The available type names are affected by the import statements of the file. For example, to make the class extend JPanel, make sure javax.swing.* is imported, and say "extends type j panel".

Interfaces

To specify that the class implements an interface, say "implements standard type grammar". For example, to implement ActionListener, make sure java.awt.event.* is imported and say "implements type action listener". Multiple interfaces may be specified. To remove a interface from implements list, move the mouse over to and say "delete selection". The "delete selection" function is a general function that removes the selected element from the list it is in.

Inner elements

To enter any element in the class body, select the class definition with the red square and use the "insert in block" prefix before the type of element to insert. For example, to insert a method definition, say "insert in block method definition".

Example of how to create this class definition:

public class SubButton extends JButton implements ActionListener{ }

Field declaration transcriber

To create a new field declaration, say "insert prefix field declaration". To insert the field within the class definition, say "insert in block field declaration". To insert after an existing class member, say "append field declaration". Note that either phrase might work because Happy Hands attempts to insert elements in reasonable places. It will never insert a field declaration at the file scope; if "append field declaration" is said while a class definition selected, the field will appear within the class. The default field declaration looks like:

int [no_name] = 0;

Field Name

To name the field, notice that the red square is already surrounding the name of the field, allowing you speak or type in its name immediately. With the name element selected, you have the option of speaking to the name transcriber, although it is usually easier to type new names. Longer names are easier for Happy Hands to recognize. The naming transcriber can be started by clicking the field name with the mouse, or by speaking "field name".

Access Modifier

To change the access modifier of the field you may say "public", "protected", "private", or "package".

Memory Modifier

To change the memory modifier of the field you may say "static" or "non static".

Constant Modifier

To change the constant modifier the field you may say "final" and "non final".

Field Type

To change the type of the field, speak "standard type grammar". When you change the type of field declaration, the field is given a default initializing value corresponding to the type, unless the field is already initialized to some non-default value. In this case the initializer value is not changed.

Example of how to create this field declaration:

static protected Component defaultView = null;

Notice it does not matter what order you specify the parts of the declaration, because Happy Hands has a broad view. To change the null value, select the null element and use the expression transcriber.

Method definition transcriber

To create a new method definition, say "insert prefix method definition". To insert the method within the class definition, say "insert in block method definition". To insert after an existing class member, say "append method definition". The default method definition looks like:

void [no_name] (){ }

Method Name

To name the method, notice that the name of the method is already selected, allowing you to type in its name immediately, or use the naming transcriber.

Return Type

The method return type is set by saying "type grammar". For example, to make the method return a String, say "type string". To make the method return an integer array, say "type one dimensional integer array".

Access Modifier

The access modifier of the method is set by saying "public", "protected", "private", or "package".

Memory Modifier

The memory modifier of the method is set by saying "static" or "non static".

Thread Modifier

The thread modifier to the method is set by saying "synchronized" and "non synchronized".

Adding an argument

To add an argument to the method, say "add argument type grammar" to append to the argument list, or "insert argument type grammar" to insert before the currently selected argument.

Adding a throws declaration

To add a throws declaration, say "add throws type grammar"

Base class override

To make the method automatically override a method in a base class, say "override base class method name". This handy feature will change the method name, the method return type, and the arguments to match the method in the base class. If the method in the base class has multiple overloaded arguments, you may say "next overload" to cycle through them.

Constructor

To make the method a constructor, simply say "constructor". This will remove the type specification and change the method name to the name of the enclosing class.

Example of how to create this method definition:

public synchronized int arraySet(int[] src, int[] dst) throws ArrayLengthException{ }

Variable declaration transcriber

To start a variable declaration, say "insert prefix variable declaration". The variable declaration transcriber is just like the field declaration transcriber. The only difference is the absence of access modifiers and memory modifiers.

Expression statement transcriber

To create a new expression statement, say "insert prefix executable". The expression statement transcriber starts and then starts an expression transcriber to transcribe the expression element. The default expression statement looks like:

[no_value];

The expression statement transcriber itself has no abilities other than creating new expression statement. It simply hands control to the expression transcriber.

Expression transcriber

The expression transcriber is what is used to dictate expressions, such as a = b+c, which is said as "variable a, assignment, variable b, addition, variable c". Pauses are optional. The expression transcriber is always started as a child of another transcriber, like the if test transcriber or the return statement transcriber. It is not in the waiting transcriber group, so you cannot say "append expression". It never adds an element to a block. The expression transcriber can also be started by selecting an expression with the mouse or keyboard.

The expression transcriber is by far the most sophisticated transcriber in the Happy Hands system. It handles the transcription of all elements that may occur within an expression, including references to variable names, field names, method invocations, and object instantiations, binary operators, unary operators, tertiary operators, type casts, array initializations, anonymous classes, and more.

The expression transcriber is very context sensitive. You may notice a pause (of maybe a second) as the expression transcriber starts, because it is preparing the grammars speakable within the expressions context. The length of the pause will vary according to how much the context changed since the last time the expression transcriber was used.

The basic insert mode of the expression transcriber is replacement. Expressions are for the most part binary trees, with some lists too. When you utter an expression grammar, the currently selected expression element is usually replaced by what you have said. The exception to this rule is the utterance of operators, such as "addition", which adds siblings to the expression tree, and the grammars related to building method argument lists or array initialization lists. New expression parts requiring specification are called "no_value".

Expression utterances can be as short or as long as you like. It is not necessary to pause between different clauses in the utterance. To make the expression a = b + c(d) you could pause frequently, saying: "variable a, assignment, variable b, addition, method c, variable d", or you could say it all together: "variable a assignment variable b addition method c variable d". Saying sentences as long as you can will enable you to code faster, and improve recognition.

Variable identifiers

Variable identifiers are spoken by saying "variable variable name". The variable name alternatives are found by examining the current method body for variable declarations, from within the current block up to the method block. Example: "variable i".

If the local variable has a class type it is possible to also speak a member name of the class after the variable name, in one utterance. (This behavior is available only if the "variable members" setting is enabled. The default is true.) Example: if the variable is called filename and it is of type String, you could say: "variable file name sub string", or "variable file name length". If the member is a function, default arguments are added automatically.

Binary operator

There is another group in the expression grammar called binary operators. The utterance of any one of the binary operators will put the operator on the right side of the currently selected value, create the right hand side element of the operator and select it. Inspecting these elements in the syntax tree view or waving the mouse over an expression and observing how the selection rectangle changes shows that the expression is mostly a tree grouped by binary operators.

Example: the expression is formerly "[a]".
Say "addition" and it becomes "a + [no_value]".
To attach a binary operator to the left side of the currently selected value, say "left side ".

Example: the expression is formerly "[a]".
Say "left side addition" and it becomes "[no_value] + a".
To replace the currently selected value with a binary operator with default left and right values, say "replace with ".

Example: the expression is formerly "a + [b]".
Say "replace with addition" and it becomes "a + [no_value] + no_value".
Operator precedence is inferred from the selection state when operators are added.

Example: the expression is formerly "a + [b]".
Say "multiplication" and it becomes "a + b*[no_value].

Example: the expression is formerly "[a + b]".
Say "multiplication" and it becomes "(a + b)*[no_value].

Example: the expression is formerly "a * [b]".
Say "addition" and it becomes "a * (b+no_value)".

To get a full list of binary operators, look under the operator tree node in the expression grammar, under the "Active" panel, while an expression transcriber is active.

Unary operator

There is another group and the expression grammar called unary operators. The utterance of a unary operator will append the operator either on the right or left side of the currently selected value, depending on the type of the operator. The currently selected value actually becomes the operator's child, and the operator takes its place.

Example: the expression is formerly "[i]".
Say "post increment" and it becomes "[i++]".
Say "pre increment" and it becomes "[++i]".

Example: the expression is formerly "[a && b]".
Say "logical not" and it becomes "[!(a && b)]".

To get a full list of unary operators, look under the operator tree node in the expression grammar, under the "Active" panel, while an expression transcriber is active.

Tertiary operator

The single tertiary operator is spoken as "tri graph".
Example: the expression is formerly "[a]".
Say "tri graph" and it becomes "[no_value] ? no_value : no_value".

Field identifier for this object

Field identifiers belonging to the current class are spoken by saying "field ". This indicates a field preceded by the implicit this. The field name alternatives are found by examining the current class body for field declarations, as well as any super classes or interfaces.

Example: if there is a field declared within the class being edited called nCount, say "field n count". Like variable identifiers, if a field that has a class type it is possible to speak a member name of the class after the field name, in one utterance. (This behavior is enabled with the "field members" option. It is true by default.)

Continuing a dot selection

As described above, the variable and field grammars have the capability of adding one member of the variable or field after a dot, in one utterance, enabling a one dotted member selection, such as: "a.length", "b.toString()", "c.setClip(null)". But sometimes you need to select an existing element and add a dotted member selection after it. Sometimes you need more than one dot. To do this, select the element to add the dot after, and say "chose member". This adds the code ".no_selection" and updates the expression grammar to include members for the element before the dot. You then select members with "select field field name", and "select method method name". The expression grammar then reverts back to normal.

Example: the expression is formerly "[a]".
Say "chose member".
The expression becomes: "a.[no_selection]".
Say "select method get graphics".
The expression becomes: "a.getGraphics()".
In this case it would have also been possible to say "variable a get graphics" in one utterance.

Field identifier selected after a dot

To add a field identifier after a dot, say "select field method name". The field alternatives are found by identifying the type of the object before the dot and offering the fields that are accessible from within the local access privileges.

Method invocation for this object

Method invocations belonging to the current class are spoken by saying "method method name". This indicates a method preceded by the "implicit this". The method alternatives are found by examining the current class body for method definitions, as well as any super classes. This system also applies to methods added in a continued utterance from another value, as in "variable g draw string". Also, this system applies to methods added via "variable g chose member, select method draw string". Happy Hands adds fake values within the method arguments list to remind you how many and what types of arguments the method requires. (The fake values are expression roots called "no_value"). These fake values are replaced as the arguments are filled in. To change to a different overload, say "next overload" or "previous overload", or say "one argument", "two arguments," "three arguments", etc. The overloads are offered sorted by argument count.

As with every other transcriber in Happy Hands, the method invocation transcriber pulls as much information as it can from the context of the code, rather than keeping track of the events that got it to its current state. This means that the overload switching grammars can be used even if the method was not just recently named.

After the method to invoke is identified, the first argument of the method is selected. (If the method has no arguments the method name element is selected.) A value can be uttered as in the standard expression transcription. To move to the next argument, say "next argument". To move to the previous argument, say "previous argument". You can also use the mouse or move the keyboard caret to do this.

Example: the expression is formerly "g.drawString(no_value, no_value, no_value)".
Say "variable text next argument variable x next argument variable y".
The expression becomes "g.drawString(text, x, y)".

Example: the expression is formerly "g.drawString(no_value, no_value, no_value)".
Say "variable text next argument, variable x addition integer two, next argument variable y multiplication integer negative one".
The expression becomes "g.drawString(text, x*2, y*-1)".

Within method argument lists, there is a special convenience that lets you move to the next argument automatically when the current argument is fully specified. If you say "sequence" at any time during an expression utterance, this puts the transcriber into a mode that automatically moves to the next argument when the current argument is fully specified. The special mode ends at the end of the utterance. Of course, it is not completely clear when an expression is fully specified. The transcriber uses the following rule: if the expression has no "no_value" elements in it, it is fully specified. Another value uttered after this, in sequence mode, will be applied to the next argument list element.

Example: the expression is formerly "g.drawString(no_value, no_value, no_value)".
Say "sequence variable text variable x variable y".
The expression becomes "g.drawString(text, x, y)".

Example: the expression is formerly "g.drawString(no_value, no_value, no_value)".
Say "sequence variable text variable x addition integer two variable y multiplication integer negative one".
The expression becomes "g.drawString(text, x, y)".
After the "addition", the second argument was "x + [no_value]". When "integer two" was processed, the current list element was not fully specified so the 2 was applied here rather than to the next argument.

It is possible too add arguments with "add argument". This appends to the argument list. To insert an argument before the argument of the selected element, say "insert argument". To remove an argument, say "delete selection". This function removes the selected list element.

Method invocation selected after a dot

To add a method invocation after a dot, say "select method method name". The method alternatives are found by identifying the type of the object before the dot and offering the methods that are accessible from within the local access privileges. The standard method argument grammars apply.

Object instantiation

To instantiate an object, say "new type grammar". Instantiation is just like a method call. The standard method argument grammars apply.

Example: "new type dimension sequence integer two integer three" gives "new Dimension(2, 3)".

Example: if the recognizer is having trouble understanding "type Dimension" you could say "new type java a w t dimension sequence integer two integer three", giving "new java.awt.Dimension(2, 3)".

Array instantiation

To instantiate an array, say "new type grammar", using a type grammar that means an array. The array brackets with default to dimension values are added automatically.

Example: "new type one dimensional floating point array" gives "new float[[no_value]]".

Array indexing

To index an array, say "index array". Brackets are added after the current value, which is required to be an array type. The indexing value is selected automatically.

Example: the expression is formerly: "[lines]".
Say "index array variable i", the expression becomes "lines[i]".

Type cast

To make a type case, say "type cast". A type cast is inserted before the current element. The current selected element is now a type identifier, and type can be specified.

Example: the expression is formerly: "String text = [textVector.elementAt(i)]".
Say "type cast".
The expression becomes "String text = ([no_type])textVector.elementAt(i)".
Say "type string".
The expression becomes String text = ([String])textVector.elementAt(i)".
Usually it is easier to say it all in one utterance: "type cast type string".

Numeric constant

To add a numeric constant, say "primitive type name numeric value". For example to add the integer 5, say "integer five". To add a long integer 1,211,262 say "long integer one million two hundred and eleven thousand two hundred and sixty two". To add 3.14f, say "floating point three point one four". To make the number negative, say "negative" before the number expression. To add -273 say "floating point negative two hundred and seventy three".

String constant

To add a string constant, say "string constant". This creates an empty string.

You can use the normal expression grammar within a string by saying "append text" first. Example: the expression is formerly: "".
Say "append text variable apple"
The expression becomes "apple"
Create the expression "apple="+apple, type the =, then say "addition variable apple".

You might be able to enable English dictation for strings by saying "use English". This feature is tentative. The majority of strings are short debugging print outs, making English dictation involving long sentences inappropriate most of the time.

This, super, null, true, and false

These are spoken as follows: "this object", "super object", "null constant", "true constant", "false constant"

Anonymous class

To define a class within an expression, say "new anonymous type grammar". The class implements or extends the type given type grammar.
Example: the expression is formerly: "new Thread([no_value])".
Say "new anonymous type runnable".
The expression becomes "new Thread(new Runnable(){ ... })".

Removing expression elements

Happy Hands does not have a good way to remove elements from expressions, other than using the backspace key. Since the expression is quickly re-parsed and active transcribers are updated, this is perfectly valid the result is no different.

Examples of expressions......

The context:



import java.awt.*;
public class FruitBowl extends Jpanel{
	static class Fruit{
		int size;
		String name;
		
		Fruit(){
		}
		Fruit(String name, int size){
			this.name = name;
			this.size = size;
		}
	}
	int banana = 30;
	
	static class Knife{
		Fruit[] cut(Fruit fruit, float where){
			Fruit a = new Fruit();
			Fruit b = new Fruit();
			a.size = fruit.size*where;
			b.size = fruit.size*(1.f-where);	
			return new Fruit[]{a, b};
		}
	}
	
	void makeFruits(){
		int apple = 10;
		int orange = 20;
		Fruit kiwiFruit;
		Fruit[] fruitArray;
		...........
	}
}

Example: apple = orange*banana
Speak: "variable apple assignment variable orange multiplication field banana"

Example: apple = (orange+banana)*5
Speak: "variable apple assignment variable orange addition field banana" (pause anytime)
Select the addition element by moving the mouse over the +.
Speak: "multiplication integer 5". The () are added automatically.

Example: apple =orange+banana*5
Speak: "variable apple assignment variable orange addition field banana" (pause anytime)
Leave banana selected
Speak: "multiplication integer 5"

Example: kiwiFruit = new Fruit()
Speak: "kiwi fruit assignment new type fruit"

Example: kiwiFruit = new Fruit("kiwi", 10)
Speak: "kiwi fruit assignment new type fruit two arguments"
Speak: "string constant"
Type: kiwi
Speak: "integer 10"

Example: kiwiFruit.size = 20
Speak: "kiwi fruit chose member" (required pause)
Speak: "select field size assignment integer 20"

Example: kiwiFruit.size = 20
Speak: "kiwi fruit size assignment integer 20"

Example: fruitArray = new Knife().cut(kiwiFruit, 0.5f)
Speak: "fruit array assignment new type knife chose member" (required pause)
Speak: "select method cut" (good time to pause)
Speak: "sequence variable kiwi fruit floating point zero point five"

Example: fruitArray[0].size = banana
Speak: "variable fruit array index array integer zero"
Move selection to hold [fruitArray[0]]
Speak: "chose member" (require pause)
Speak: "select field size assignment variable banana"

That explains the transcription of expressions. The rest of the Happy Hands language is a cinch.

If test transcriber

To create an if test, say "insert prefix if test". The default if test looks like:


            if([no_value]){
            }
	

The element filling in the test expression is selected. Speak an expression to fill in the value.

Example: if(a != b){...}
Speak: "append if test" (Required pause)
Speak: "variable a is not equal to variable b"

All of the transcribers that generate a block offer an additional insert prefix: "enclose with". Using this prefix will cause the selected element(s) to be enclosed with the block element.

Example: the expression is formerly: [System.out.println("debugging string")]
Speak: "enclose with if test" (Required pause) Speak: "variable b debug" The code becomes:


         if(bDebug){
              System.out.println("debugging string")
         }
	

Else if test transcriber

To create an else if test, say "insert prefix else if test". The default else if test looks like:

        else if([no_value]){
        }
	
The element filling in the test expression is selected. Speak an expression to fill in the value.

Else block transcriber

To create an else block, say "insert prefix else block". The default else block looks like:

        else{
        }
	

While loop transcriber

To create a while loop, say "insert prefix while loop". The default while loop looks like:

        while([no_value]){
        }
	
The element filling in the test expression is selected. Speak an expression to fill in the value.

Do while loop transcriber

To create a do while loop, say "insert prefix do while loop". The default do while loop looks like:

        do {
        } while(no_value);
	
The element filling in the test expression is selected. Speak an expression to fill in the value.

For loop transcriber

To create a for loop, say "insert prefix for loop". The default for loop looks like:

        for(no_value; no_value; no_value){
        }
	
To declare a variable in the initialization section, say "declare initializer". To simply enter an expression in the initialization section, "enter initializer", or just move the mouse over the initializer and start speaking the expression. To enter expression in the condition section, say "enter condition", or move there with the mouse or the arrow keys. To enter an expression in the incrementation section, say "enter incrementer". The default values in the for loop header are optional to the tree to text render. They are only rendered if the for loop or any of its children are selected. They will not be saved to a file.

Switch block transcriber

To create a switch block, say "insert prefix switch block". The default the switch block looks like:

        switch([no_value]){
        }
	
The element filling in the switch value is selected. Speak an expression to fill in the value.

Case block transcriber

To create a case block, say "insert prefix case block". The default case block looks like:
	
        case [no_value]:{
        }
	
To add a case with no block, say "insert prefix case label". The case value is selected. Speak an expression to fill in the value.

Return transcriber

To create a return statement, say "insert prefix return". The default looks like:
	
        return [no_value];
	
A default return value is selected. This default value only be added if the function declares a return value.

Throw transcriber

To create throw statement, say "insert prefix throw". The default looks like:
	
        throw [no_value];
	
A default throw value is selected. Speak the expression to throw.

Break transcriber

To create a break statement, say "insert prefix break". The default looks like:
	
		break [no_target];
	
A default target is selected. Speak the target to break to. The default target value is optional and appears only if the break statement is selected.

The continue transcriber

To create a continue statement, say "insert prefix continue". The default looks like:
	
        continue [no_target];
	
A default target is selected. Speak a target to continue to. The default target value is optional and appears only if the continue statement is selected.

The label transcriber

To create a label declaration say "insert prefix target block". The default looks like:
	

        [no_name]{
        }
	
The target name is selected. Fill in the name typing it in, or use the naming transcriber. Adding a target block is a very good use for the "enclose with" prefix.

The try catch block transcriber

To create try-catch block, say "insert prefix try catch block". The default looks like:
	
        try{
        } 
        catch(no_type [no_name]){
        }
	
Both the try block and catch block are appended together, because only a try block would be invalid Java grammar. A variable declaration is automatically added in the catch block header. Use the variable declaration transcriber (which is already active) to fill in the type of the exception to catch, and is name.

Example:


        try{
        } 
        catch(FileNotFoundException ex){
        }
	
Speak: "append try catch block"
Speak: "type FileNotFoundException"
Type: ex

Catch block transcriber

To create a catch block, say "insert prefix catch block". The default looks like:
	
        catch(no_type [no_name]){
        }			
	
A variable declaration is automatically added in the catch block header. Use the variable declaration transcriber (which is already active) to fill in the type of the exception to catch, and is name.

Finally block transcriber

To create a finally block, say "insert prefix finally block". The default looks like:
	
        finally{
        }
	

Synchronized block transcriber

To create a synchronized block, say "insert prefix synchronized block". The default looks like:
	
        synchronized([no_value]){
        }	
	
The value to wait on is automatically selected. You may now speak the expression to wait on.

The doc comment transcriber

To create a doc comment, say "insert prefix doc comment". The default doc comment looks like:
	
        /**
         * 
         */
	
The keyboard insert point is after the * in the middle line. By default English dictation is not enabled. To enable it, say "use English". This starts the English dictation transcriber, which can be used in conjunction with typing to form the comment.

The star comment transcriber

To create a start comment, say "insert prefix star comment". The default star comment looks like:
	
        /*
         * 
         */
	
This works just like the doc comment transcriber

The line comment transcriber

To create a line comment, say "insert prefix line comment". The default line comment looks like:
	
        //
	
This works just like the doc comment transcriber.

Other speech activated functions

Open file

Spoken as "open file ". If the file specifier is left unspoken a general file open dialog box is presented. Only the files in the project file view are understood. The file name is spoken either as a simple file name without the ".java", or as a series of directories plus the file name, beginning at the first directory known to the project if. These directories are usually the same as the package names.

Example: Opening the file demo.sorting.Sort
Speak: "open file demos sorting sort"
or "open file sort"

New file

Spoken as "new unnamed file". This create a new text editor component.

Save top file

Spoken as "save top file". This saves the top file in the text component. The file is saved with the text that currently appears in the text component. If the text editor has no known file name, Happy Hands attempts to guess the name by looking at the first public class and the file and the package specifier, and presents the save as dialog box with these defaults. The file is saved exactly as it appears in the editor at the time of the save. The tree to text generator is not run when saving the file, in order to preserve any non parseable text of the document. When the file is reopened, any non parse able text will still be there.

Save file as

Spoken as "save file as". This shows a file chooser dialog box and saves the top file of the text component to a given file name. The file you have open keeps the same name it had before.

Close top file

Spoken as "close top file". This saves the top text editor, and removes the text editor. To close the top file without saving it first, say "close without saving".

Save and close top file

Spoken as "save and close top file". Saves the top file and closes it.

Save all files

Spoken as "save all files". Save all files.

Revert to auto save file

Spoken as "revert to auto save file". This replaces the content of the top text editor to the information in the most recent auto save file. This is a way to do an undo without using the undo system. (The auto save file is beside the regular file on disk, with the additional extension ".autosave".)

Revert file

Spoken as "revert file". This changes the content of the top text editor to the information on disk. This is a way to do an undo without using the undo system.

Compile top file

Spoken as "compile top file". This run the compiler on the file of the top text editor. Any errors are printed out in the build window and highlighted in the text.

Compile directory

Spoken as "compile directory directory specifier". The directory specifier is the the Java package of the directory, within the current project. Note any compiler errors that result may point to the wrong line numbers in the editor when the file is opened, if the files on disk are not formatted in the Happy Hands style. Use the Format Directory function to solve this problem.

Cancel Build

Spoken as "cancel build". Stops the compiler.

Format Directory

Spoken as "format directory directory specifier". If you are beginning work on a directory that has files not formatted in the Happy Hands style, it may be a good idea to use this function on the files. It opens all the files in the directory, formats them, and saves them. This ensures the line number output by the compiler matches the line number in the Happy Hands editor.

Start test

Spoken as "test program". Starts the test process. The project settings control the class to test. The standard output and standard error from the test process taken up in the "Testing" window.

Stop test

Spoken as "stop test". Stops the test process.

Goto line

Spoken as "go to line line number". Makes the specified line visible in the editor and highlights it.

Show methods

Spoken as "show methods". Shows the member methods of the type of the current element, in the right panel.

Show fields

Spoken as "show fields". Shows the member fields of the type of the current element, in the right panel.

Show methods of type

Spoken as "show methods of type grammar". Shows the member methods of the given type in the right pane.

Show fields of type

Spoken as "show fields of type grammar". Shows the member fields of the given type in the right pane.

Use speech entry

Spoken as "use speech entry". Enables the transcribers and the element selection system. If you are in keyboard entry mode, hitting the esc key will switch too speech entry mode too.

Use keyboard entry

Spoken as "use keyboard entry". Disables the transcriber and the element selection system. This can be useful for making large edits with the keyboard. The keyboard is enabled at all times in any case. Normally if you use the keyboard, the changed elements are re-parsed when you're finished typing. In keyboard entry mode this will not happen. When you exit keyboard entry mode the entire file is re-parsed and transcription is enabled.

Reinitialize speech

Spoken as "re-initialize speech". This re-initializes the recognizer engine. If you think it has become bogged down, and it just doesn't seem to be understanding you, use this function to restart the recognizer. Happy Hands normally does this automatically. The active grammars become available again after the re-initialization completes, after about 15 seconds.

Add to selection

Spoken as "add to selection". The currently selected element is added to the selection set.

Add to selection range

Spoken as "add selection range". The currently selected element is added to the selection set. Additionally, every element in between this element and the current selection set is selected.

Clear selection

Spoken as "clear selection". Clears the selection set.

Code to comments

Spoken as "code to comments". Converts the currently selected elements to a comment.

Comments to code

Spoken as "comments to code". Converts the currently selected elements (they should be comments) to regular code.

Delete selection

Spoken as "delete selection". Removes the currently selected elements from the syntax tree. This function examines the currently selected elements, moving up the syntax tree hierarchy, until it finds an element that is within a variable size list, such as a block, or a method argument list. It then removes this element. This mean you don't have to be very precise in selecting the element you really want to remove.

Copy selection

Spoken has "copy selection". Makes a copy of the elements in the selection set and set them aside.

Paste copy

Edit element

To move to a method definition: say "edit method definition method name" To move to a field declaration: say "edit field declaration field name"

Undo

Spoken as "undo change". Happy Hands tracks changes made either by speaking or typing. To undo the last change, say "undo change". To save memory an undo limit is imposed, which defaults to 10.

Parse file

Spoken as "parse file". This the re-parses the text of the entire file, rebuilding the syntax tree.

Parse element

Spoken as "parse element". This the re-parses the text of the currently selected element, rebuilding the syntax tree for this element.

Regenerate file

Spoken as "regenerate file". This regenerates the text of the file based on the syntax tree. Normally this happens automatically and should be called only of some other behavior has gone wrong.

Page up

Spoken as "page up". Moves one page up in the editor.

Page down

Spoken as "page down". Moves one page down in the editor.

Exit Happy Hands

Spoken as "exit happy hands". Ends the Happy Hands program.

User Defined Macros

Happy Hands has a macro facility that enables common pieces of code to be generated easily. The macro text is inserted by saying insert-prefix macro-name. Once the macro is inserted, it is possible to use the expression grammar to specify the macros parameters. If the macro only has one parameter, the expression grammar alone is all that is required. If it has multiple parameters, you say: paramter-name expression-grammar.

To define your own macro, you need to write a small Java class the uses the small macro API. You then put the fully qualified class name in the file settings/macros, and change the class path in the Happy Hands start up script to include your macro. The macro API is this:

	package lde;
	
	public class Macro{
		public static final String VALUE = "Value";

		/**
		 * Makes a macro
		 * @param name The macro name that is spoken
		 */		
		public Macro(String name);

		/**
		 * Add an argument to collect with a grammar appropriate to the type.
		 * Only type==VALUE is supported now.
		 */		
		public void addArgument(String name, String type);

		/**
		 * Add an argument to collect with a grammar appropriate to the type.
		 * Only type==VALUE is supported now.
		 */	
		public void setMacroName(String name);

		/**
		 * Retrieves the value of the argument of the given name
		 */
		public String getArgument(String name);

		/**
		 * Called by the macro manager to get the current macro text.  This should be
		 * overridden to build the text based on some constants and the argument values.
		 * This is called when the macro is inserted the first time and every time a value
	 	 * is specified by the user.
		 */
		public String makeText();
	}
	

Happy Hands comes with some factory defined macros, described below.

Print out

Inserts the text: System.out.println(no_value);
Example: "append print out".

Debug print out

Inserts the text: System.out.println("no_value: " + no_value);. Then the expression grammar is then availible to specify the value.
Example: "append debug print out" ... "variable lexer next token"

Loop over length

Inserts the text:
		for(int i = 0; i < no_value.length; i++){
		}  
	
The the expression grammar is then availible to specify the array name.
Example: "append loop over length" ... "variable line array"

Loop over size

Inserts the text:
		for(int i = 0; i < no_value.size(); i++){
		}  
	
The the expression grammar is then availible to specify the container name.
Example: "append loop over size" ... "variable line vector"