lacona-phrase
This package is used to create lacona
phrases. It works with lacona
but is maintained separately to allow libraries to be versioned independently of the parser.
A lacona
phrase is a Javascript descriptor of some natural language construct. The syntax is modeled after React, but rather than specifying HTML output, it specifies a language.
Like React, lacona
phrases can be specified using JSX. This is recommended, but not required. While JSX is a much more succinct and readable way to express the phrase's structure, it does necessitate a transpilation step. lacona
itself is built this way, using the excellent babel transpiler. In addition to transpiling JSX, it also transpiles ES6 functionality, which can result in very simple code. All examples in this document will have two examples - JSX/ES6 code to be transpiled using Babel, and standard ES5. Note that it is possible to ES6 without JS (or vice-versa), but those examples are left as an exercise to the developer (but the tests may point you in the right direction).
Using Javascript Classes
A lacona
phrase is expressed as a Javascript class. For use with ES5, a shorthand method is provided that will create this class for you, without requiring you to interact with prototypes.
Using ES6
{ // no need to call super() } static { return a: 'test' } { return // ... }
Using ES5
var createPhrase = createPhrase moduleexports =
Describing Language
In lacona
, language is described using Element
s. Each Element
can be thought of as an instance of a Phrase
. Each Element
can have props
which govern its behavior.
Please note that Phrases
should never be instantiated directly, and Elements
should never be used outside of the context of a describe()
call. An Element
is ultimately just a small descriptor of its inputs - the actual Phrase
instantiation and parsing is all done by lacona
itself.
Using ES6/JSX
In JSX, all lowercase tags refer to elements built-in to lacona
. Custom classes must be uppercase. Please note the @jsx
pragma in the initial comment. Unlike React, this comment is required. It must specify the name of the createElement
function.
/** @jsx createElement */ { return <choice> <literal text='Google' /> <literal text='Yahoo' /> <literal text='Bing' /> </choice> }
Using ES5
In ES5, elements are specified in the form phrase.createElement(constructor, props[, ...children])
. You can also create a factory to free you from continually needing to call createElement
, using createFactory
.
var phrase = var factory = phrase// these two lines are equivalentphrase
The module contains shorthand factories for the builtin elements.
var phrase = moduleexports = phrase
Supporting multiple languages
The pesky thing about language is that there are lots of them. A single phrase can (and should) support as many languages as possible, all expressing the same fundamental thing. This is done using the translations
property. Note that while describe()
is specified as a single function, translations
is specified as a Static Property (see below for more information).
Using ES6/JSX
/** @jsx createElement */ static { return langs: 'en' { return <literal text='hello' /> } langs: 'zh' { return <literal text='你好' /> } }
Using ES5
var phrase = moduleexports = phrase
Phrase Properties
A Phrase
is ultimately just a class - it can have any methods or properties. However, some methods and properties govern the Phrase
's behavior, and should not be used outside of that context.
Static Properties
Some of a Phrase
's behavior is governed by Static Properties, which are specific to the Phrase
, not to any particular Element
. When using createPhrase
, these are specified directly as objects. However, because ES6 does not directly support static properties, these cannot be expressed using ES6 class syntax alone. They can set be set as static getters, or directly as properties on the constructor.
defaultProps
supplements
overrides
translations
Using ES6
The two strategies below are precisely equivalent
static { return myProp: 'test' } static { return } { return // ... }
{ return // ... }MyPhrasedefaultProps = myProp: 'test'MyPhrasesupplements =
Using ES5
var phrase = moduleexports = phrase