Labs/Ubiquity/Writing Noun Types
Back to Labs/Ubiquity.
Author: mitcho (Michael Yoshitaka Erlewine)
Introduction
Different arguments are classified into different kinds of nouns in Ubiquity using noun types. For example, a string like “Spanish” could be construed as a language, while “14.3” should not be. These kinds of relations are then used by the parser to introduce, for example, language-related verbs (like translate) using the former argument, and number-related verbs (like zoom or calculate) based on the latter. Ubiquity nountypes aren’t exclusive—a single string can count as valid for a number of different nountypes and in particular the “arbitrary text” nountype (noun_arb_text) will always accept any string given.
In addition to the various built-in nountypes, Ubiquity lets command authors write their own nountypes as well.
This guide will walk you through some of the builtin nountypes and then describe the API for writing your own nountypes.
Builtin noun types
Before you try to write a new noun type, it's good to make sure you're not reinventing the wheel. Here are some noun types which are bundled with Ubiquity:
- noun_arb_text (Arbitrary text)
- noun_type_language (Name of a human language, e.g. "English", "Japanese")
- noun_type_url (A URL)
- noun_type_contact (An email address from your address book)
- noun_type_date (A date, in any format, or a word like "tomorrow")
- noun_type_time (A time, in any format)
- noun_type_percentage
- noun_type_address
- noun_type_tab
- noun_type_searchengine
- noun_type_tag
- noun_type_geolocation
You can look at the source of all of these noun types at nountypes.js.
Specifying your own Noun Types
Regexps as Noun Types
If none of the nountypes above is what you're looking for, there are several ways to define your own. The simplest is to use a regular expression. Suppose that (for whatever odd reason) you wanted your command to accept only arguments that begin with the letter N. The following regexp matches words that start with N:
/^[nN]/
You could use it as a noun type, like so:
arguments: [{role: "object",
nountype: /^[nN]/,
label: "word that starts with n"}]
(Note that you do not put quotes around the regexp.)
A regexp nountype will reject input that doesn't match, but it doesn't know how to help the user by suggesting appropriate input.
Lists as Noun Types
Suppose you're writing a command that takes a color as an argument (perhaps it outputs a hexadecimal RGB representation of that color.) To make a nountype that accepts colors, you can simply pass in an array of strings:
names: ["convert color"],
arguments: [{role: "object",
nountype: ["red", "orange", "yellow", "green",
"blue", "violet", "black", "white",
"grey", "brown", "beige", "magenta",
"cerulean", "puce"],
label: "color to convert"}]
One benefit of using a list is that the parser can use it offer the user suggestions. If the user enters "get-color bl", for instance, Ubiquity will be able to suggest "black" and "blue" as the two valid completions based on the input. This makes list-based nountypes very useful for any command that can accept only a finite set of values.