A language for flexible & consistent control panel user interfaces

Harold Thimbleby, 2011

For more details, see the draft paper (PDF)

This is a work-in-progress and some features may not be exactly as advertised.

Version 3.1, 20 June 2011. Earlier Version 2.2, 4 December 2010

Click the ‘’ button to generate the data entry fields specified in the light-blue text area below.

You can edit the text as you wish. You can generate almost any simple number or text data user interface using the specification language. If you can’t generate the control panel you want using this language, then what you want to do is probably too sophisticated for a single data entry panel!


(demo buttons)
 Show parse tree:
Generate Dot: Show NFA output:
Generate Mathematica: Show DFA output:
Generate JSON recogniser:

Nothing compiled yet

Brief language summary

A device specification is a set of keywords and properties associated with those keywords.

Ignored comment to end of line — allows (-; (-: (-! and so on as you wish
name: "description of the device"
A device has a name.
features: keywords...
Keywords are words like autocomplete and no-key-delete. Misspell any, and you'll get a list of the currently available features. There is a summary list of specific features activated when a device has been compiled successfully (just below the device control panel).
input: regular expression
Describes the input rules a device must adhere to. The syntax of regular expressions is given below.

Regular expressions

The input: keyword is followed by a regular expression that specifies permitted input forms, as follows.

name = re

Name definition (definitions can be in any order). Names start with a letter, and may contain letters, digits and dash. If names are used in prompts, they can only be defined as strings or as other names, themselves defined as strings...

Recursive definitions (e.g., n = m ... m = n), undefined names, and unused names are not permitted.

( re )
re re
Equivalent to ("s" "t" "r" "i" "n" "g")
re | re
[ re ]
Optional — equivalent to 0 or 1 occurrences
re *
Kleene star — 0 or more occurrences
re +
At least one; equivalent to (re re*) — 1 or more occurrences
p >> re
Use p as the prompt for the re; p can be a string or a variable name.
p initially >> re
Use p as the prompt for the first transition of re
re << p
Alternative form for p >> re
re << initially p
Alternative form for p initially >> re
re & re
Not yet implemented. Requires both regular expressions to match simultaneously (use for multi-touch operations, like control keys)

Check and change sounds

Use the radio buttons in the table below to assign sound effects to various user interface conditions. If you do not want a sound, set the relevant feature no-sound-meta, no-sound-click, etc. (Note that the feature name starts “no-” so that the sound is switched off; all these sounds are on by default.)

Note that if you switch off various sounds (such as the sound for errors), keys should still click even when errors are made (which you thought were going to be silent), unless you also switched off key clicking.

If you have some funny browser that doesn’t understand HTML5 audio and .wav files, none of this is going to work anyway.


We specify the width of the display using the feature value-buffer-length, however typographic details and the layout of the buttons is not parameterised. However, the control panel design is done with CSS. For example, if you want upper case letters displayed, you can use text-transform: uppercase in the style file.

Ideas and dreams

Here are some ideas I’ve had but not implemented.

layout: strings...
Specify the keyboard layout. Taken as one string per row of keys, separated by slashes. Delete, Cancel, Confirm are special keys.
render: regular expressions + HTML...
Specify how keystrokes appear in the display.


The render: keyword is followed by an annotated regular expression that provides HTML specifying how to render each keystroke.

Render regular expressions match the display not the user’s actual keystrokes (they will be different if there is any autocompletion).

When a regular expression matches (and it may match several times as the user presses keys), if it is followed by HTML, that HTML is used to render the last keystroke. Thus

any-digit* dot <font size=+3>&bull;</font>

Means that when the expression (presumably with its obvious meaning!) matches, which it will when the user presses the dot key after zero or more digits, then the final key is rendered as a large dot.

Since a regular expression may match many keys, the entity &key; is used to represent the last key press. For example

any-digit any-digit* <font color=red>&key;&nbsp;</font>

would display each digit in red, followed by a gap.

If no HTML matches, then it is treated like <span>&key;&</span>

re <tag...> ... </tag...>HTML tags to insert on matching each keystroke matching the re. If no tag is provided, keys insert themselves.
re <tag.../>
&key;Replace with each matching key (used inside HTML)

Faint prompting

Some web sites show data entry fields like dd/mm/yyyy as a prompt for a date.

We could get this feature by writing (digit digit):"dd" "/" (digit digit):"mm" "/" (digit digit digit digit):"yyyy" (for example), with the prompts being gobbled up as the user keys the (correct) data.

More reading...

See Truly Useful Form Validation Scripts for Front End Development