Prerequisites: You should have read Text Generation Part Three.
We are now ready to look at phrase factories and tackle recursion.
A phrase factory is a function that generates a new instance of
ishml.Template object and its many prefixes are phrase factories. The suffixes of
ishml.Phrase are phrase factories. However, not all methods of
ishml.Phrase are phrase factory. Some merely return the existing phrase rather than a new instance. Take a look at listing 1.
Here an attempt was made to create new phrases from the
animal phrase. It does not work because
.populate() merely returns the original
animal phrase with new data and does not generate a new phrase. As a result, both
example2 refer to the same instance of
animal does. Instead of producing an amphibian and a rodent respectively, the examples both produce rodents because that was the last set of data populated.
Listing two below demonstrates how to properly create a phrase factory. Here
example2 reference separate instances of
ishml.Phrase and act independently of each other.
A phrase factory is made by simply creating a function that returns new instance of
ishml.Phrase. Phrase factories are very useful for recursive phrases. They may also be used to extend
example1 of listing 3 below, we see a simple, non-recursive phrase for generating an unordered HTML list. This is fine as far is it goes, but it would be more useful if it automatically genereated sub-lists on demand to display deeply nested data. Recursion is used in
example2 to provide a nested list that expands indefinitely to accomodate on the data provided.
A phrase factory function is assigned to the variable
ul. The phrase generated by this function also includes a call to this phrase factory function, making it recursive. The second expression in the phrase checks to see if
.list is present in the
data collection. If it is, the data associated with
.list is passed in the call to
ul. This embeds a new instance of the phrase inside the phrase. The embedding of a new phrase will continue recursively as long as
.list property is present in the phrase's data collection. If it is not present, the expression evaluates to an empty string. When writing recursive functions you must always ensure that there is always a way for the recursion to end, otherwise you will generate a stack overflow error.
List 4 shows another example of a recursive phrase.Listing 4
The phrase factory,
inside creates a phrase about opening a random number of containers, each inside the other and eventually revealing a treasure of some sort. This function is called recursively as long as the result of
_.favor(...) is a container.
We have now covered the essentialss of working with ISHML phrases and templates. We have introduced most of built-in prefixes and suffixes, which should cover the majority of your text generation needs. Occasionally, you may want to use a custom function to modify the results of a phrase. Listing 5 introduces the
.modify() suffix in
example1. It takes a callback function as its argument. During evaluation, each is element in the phrase's result array is sent to the callback function. The callback funtion returns a text string that
.modify() replaces in the results array.
.modify()lets us apply modifications to phrases, the syntax is a bit bulky compared to custom prefixes and suffixes. Any function that returns a phrase, i.e., a phrase factory, can be defined as a custom prefix or suffix. In the listing above, the variable
prefixis assigned to a phrase factory that does the same uppercase conversion seen in example1. The static method
ishml.Template.defineadds the phrase factory to the collection of available prefixes with the name
example2we see the newly defined
.shoutprefix in use.
We may also create simple suffixes that take no parameters by using the static method
ishml.Phrase.define. In the list above we define a suffix called
tron to append
O-Tron to the ends of phrases. We use the
.tron suffix in
We could have just as easily made the
.tron suffix a prefix; there really isn't much advantage of one over the other. However, as a general rule, if the intent is to modify the end of the phrase, it is better to create a suffix. It just makes the subsequent phrase definitions easier to read.
This has been a brief tour of text generation using the ISHML API. We did not cover all of the available prefixes and suffixes. See the API Reference for complete documentation.
I will happily answer any questions you may have about text generation on intfiction.org. Be sure to label your questions with the ISHML tag for promptest attention.