Prerequisites: You should have read Text Generation Part Two.
The first two parts of this tutorial covered basic text generation. We are now ready create some more advanced phrases.
Tagged phrases are available through the
The first sub-phrase of
example1 is tagged as
pet In the second sub-phrase,
_.a.tags.pet is used to refer to the sub-phrase tagged as
.tags prefix provides access to the collection of tagged phrases and it must be followed by the name of the sub-phrase. The
.a prefix adds the appropriate indefinite article to the sub-phrase. During text generation a new (and different) animal will be picked at random for each of the two sub-phrases.
Sometimes when referring to a tagged phrase, we don't want to generate entirely new text; we just want repeat the same text that was already generated in an earlier sub-phrase. The third expression in
exammple1 is an arrow funciton. Whenever a function is encountered during text generation, the function is called with the tags collection as its argument. This gives the function access to the tagged phrases. In this case the text property of the
pet sub-phrase is returned.
pet tag refers to the whole phrase,
_.a.pick(), which first picks an item and then adds an indefinite article. When the
pet phrase is populated, the data needs to go to the inner
pick() phrase, not the outer
a phrase, but the tag refers to the phrase as a whole. This does not cause a problem, however, because
.populate() will always identify the innermost (terminal) phrase of a tagged phrase and deposit the data there.
We can reference the data associated with the phrase by using the
.data property. Here,
tags=>pet.data.problem returns the problem associated with the selected pet and
tags=>tags.pet.data.value returns the primary data associated with the
pet phrase, in this case the selected animal with an indefinite article prepended. In this instance
.data.animal are equivalent. This is due to how
.populate() works. If the incoming data object does not explicitly have a
.value property, it will be created and set to the first property of the incoming data object.
pet tag for
example2 references the pick phrase with the indefinite article prepended. If we want the bare pick phrase, we can use the
.inner property of the pet tag,
tags=>tags.pet.inner.data.value. We can chain as many
.inner properties as needed to reach a deeply nested phrase.
Alternatively, we can use parentheses to nest phrases and create tags at different levels of nesting. This is shown in
Some prefixes expose additional metadata. Phrase definitions that include
.total as properties of
.index property is zero based. Listing 2 shows examples of using metadata.
.series property requires some special handling when accessing metadata. Once the entries in the series are depleted, the series returns an empty array for the results and there are no items of metadata to access. Attempting to access not existent properties will cause an error. Therefore, we can only access the metadata under certain conditions. Examine
example2 in the listing above. The
.also suffix signals the start of another
ishml.Phrase that will only be evaluated and appended if the preceding phrase returned at least one result. If the preceding series is depleted, the phrase associated with
.also will be skipped. Like
.then, it is acceptable to chain prefixes after
.per suffix repeats a phrase for as many entries as there are in the referenced tagged phrase. Use it whenever you want to iterated through the array of sub-phrases. See listing 3 below.
.concur suffix filters a set of sub-phrases so that it conforms to the criteria of a provided rule. See listing 4 below.
example1 phrase picks a hobby for each person based on their interest. To filter the possible hobbies to those that match the person's intersest, we add the
.concur suffix to the
hobby sub-phrase. The rule function returns true if the hobby matches the persons interest or false if it does not. This function receives the tags collection as its first parameter and the result of each sub-phrase evalution of the target phrase as the second parameter. sub-phrases that do not meet the criteria are removed from consideration before
.pick is applied.
Continue to part four to learn about recursive phrases.