# The jsRealB Text Realizer:
Organization and Use Cases
_Revised version_

Guy Lapalme
RALI-DIRO
<EMAIL_ADDRESS>

###### Abstract

This paper describes the design principles behind jsRealB (Version 4.0), a
surface realizer written JavaScript for English or French sentences from a
specification inspired by the _constituent syntax_ formalism but for which a
dependency-based input notation is also available. jsRealB can be used either
within a web page or as a node.js module. We show that the seemingly simple
process of text realization involves many interesting implementation
challenges in order to take into account the specifics of each language.
jsRealB has a large coverage of English and French and has been used to
develop realistic data-to-text applications and to reproduce existing literary
texts and sentences from Universal Dependency annotations. Its source code and
that of its applications are available on GitHub. The port of this approach to
Python (pyrealb) is also presented.

##  1 Introduction

A text realizer sits at the very end of a text generation pipeline. Important
decisions about _What to say_ must have already been made, sentence structure
and most content word choices must also have been decided. Final realization
is an often _neglected_ part in NLG systems because it is dubbed to be
_pedestrian_ , often associated with _glorified_ format statements, even
though its output is the only thing that the end user sees and that is used to
evaluate the whole system. How reasonable is an output if word agreements are
not properly done or if it consists of a mere list of tokens? This might be
sufficient for machine evaluation, but it cannot practically be used in a
production setting. A well formatted and grammatically correct output is
important for the _social acceptability_ of a system. This is why we decided
to study this process more closely.

A text realizer has much interesting work to do: it must take care of many
language peculiarities such as number and person agreements, conjugation, word
order and elision. On top of these tasks, jsRealB also allows creating many
variations (e.g., negative, passive or interrogative) from a single
affirmative sentence structure. We first briefly present jsRealB and compare
it with existing text realizers.

##  2 jsRealB

jsRealB (JavaScript Realizer Bilingual) [JSreal14, molins-
lapalme-2015-jsrealb] is a bilingual French and English text realizer that
generates well-formed expressions and sentences and that can format them in
HTML to be displayed in a browser. As its name indicates, jsRealB is written
in JavaScript, a programming language that, when used in a web page, runs in
the client browser. A web programmer who wishes to use jsRealB to produce
flexible French or English textual output only needs to add one line in the
header of the page, similarly to what is done for other browser frameworks
such as jQuery. jsRealB is aimed at web developers. It carries out crucial
tasks from taking care of morphology, subject-verb agreement and conjugation
to creating entire HTML documents. jsRealB has been used for creating data-to-
text systems. It has also been used as an intermediary for realizing sentences
produced by a Prolog program taking input from AMR structures [AMR-2019] or
from Universal Dependencies in the context of the Surface Realization Shared
Task (SR’19) at EMNLP [Lapalme19SRST] and for the WebNLG Challenge [castro-
ferreira20:_2020_bilin_bidir_webnl].

jsRealB was strongly influenced by SimpleNLG [gatt-reiter-2009-simplenlg] in
which realization is achieved by programming language instructions that create
data structures corresponding to the constituents of the sentence to be
produced. Once the data structure (a tree) is built in memory, it is traversed
to produce a string. Like SimpleNLG, jsRealB has the following components :

  * •

a lexicon defining the word category, gender, number, irregularities and other
features;

  * •

morphological rules to determine the appropriate word forms, such as plurals
and conjugations;

  * •

syntactic rules to properly order words in a sentence, perform agreement
between constituents and carry out other interactions.

jsRealB integrates other useful tools, such as the spelling out of numbers and
the wording of temporal expressions. Since it produces web content, it can add
HTML tags for links, for formatting, to create headers and lists. It takes
them into account so that they do not interfere with the proper processing of
words within a sentence.

jsRealB has been under development in our lab since 2013111The source code is
available on the RALI-GitHub with a tutorial and many demonstration
applications.. Since then it has been reengineered while keeping the same
external interface. This paper is the result of this recent work, which
revealed many intricacies that must be dealt with and that we thought it would
be interesting to document more formally. In the current version 4.0, a
dependency notation has been added. jsRealB has also been ported to Python
keeping the same notation for specifying the content of the sentences, see
Section LABEL:sub:python_implementation for more details.

###  2.1 Input to the realizer

In jsRealB, JavaScript expressions create data structures corresponding to the
constituents of the sentence to produce. When the need arises to produce a
string realization (i.e. its toString() function is called), the data
structure (a tree) is traversed to produce the tokens of the sentence, taking
care of capitalization, elision and appropriate spacing around punctuation. It
is also possible to wrap portions of text in HTML tags. The realizer accepts
two types of input: constituents or dependents.

####  2.1.1 Constituent notation

In the constituent notation, the data structure is built by function calls
whose names222Traditionally in JavaScript, identifiers starting with a capital
letter are constructors not functions. However in linguistics, symbols for
constituents start with a capital letter so we kept this convention. were
chosen to be similar to the symbols typically used for constituent syntax
trees333See the documentation for the complete list of functions and parameter
types:

  * •

Terminal: N (Noun), V (Verb), A (adjective), D (determiner) …

  * •

Phrase: S (Sentence), NP (Noun Phrase), VP (Verb Phrase) …

Features added to these structures using the dot notation can modify their
properties. For terminals, their person, number, gender can be specified. For
phrases, the sentence may be negated or set to a passive mode; a noun phrase
can be pronominalized. Punctuation signs and HTML tags can also be added.

####  2.1.2 Dependency Notation

In the dependency notation, the data structure is built by function calls
whose names are similar to the _main_ dependency relations as used in the
Universal Dependencies [10.1162/coli_a_00402] (UD). UD relations were
originally defined to be able to take into account most linguistic phenomena
that occur in existing texts so many variations exist. But, in a generation
context in French and English only, it was not felt necessary to keep all
these nuances, so only a small subset of dependency relations was kept:

  * •

Dependent: root, subj (subject), comp (complement), mod (modifier), det
(determiner) and coord (coordinate)

A dependency is specified by a function named after the dependency name taking
as first parameter its head, a Terminal like in the constituent notation. The
other parameters, if any, are other Dependents.

The organization of these relations follows roughly the conventions used in
the Universal Dependencies [10.1162/coli_a_00402] except for coord for which
the head is taken as the coordination conjunction or a special symbol, perhaps
an empty string; the relations in dependents must all be the same (e.g. all
subj or comp) which is considered as the global relation for the whole
coordinate. In the _traditional_ UD notation, the head is instead the first
coordinated term which is then linked to other members of the coordinate with
a conj relation. Given the fact that the number, gender and person of the
dependents within a coordinate must be combined in order to compute the global
number, person and number444This process is detailed in Section 5.5, it was
found more practical to identify the coordinate with a special relation
delimiting its dependents.

Even though, we had initially chosen this representation of coordination for
implementation purposes, it was then pointed out to us that Tesnière had
proposed a similar view coordination which he referred to as _jonction_
[Tesniere-59, p 326].

> La jonction s’opère entre deux noeuds de même nature, quelle que soit par
> ailleurs cette nature.[…] Mais il est indispensable que les deux noeuds
> soient de même nature.[…] on ne saurait joncter un actant et un circonstant,
> ni un noeud verbal et un noeud adjectival.
> _[Junction works between two nodes of the same type, no matter this type.
> But it is necessary that the two nodes be of the same type, one cannot join
> an actant or a circonstant, neither a verbal node nor an adjectival node]_

Realization sorts the dependents of a relation: det and subj are realized
before the head, comp and mod are realized after the head. The ordering within
the specification is used in the case of ties both before and after the head.
A ("pre") or ("post") feature can be specified to alter the default ordering
to force its realization before or after the head. The position of adjectives
is dealt according to the rules of English or French grammar, unless changed
by .pos.

####  2.1.3 Programming aspects

Since jsRealB expressions are standard JavaScript expressions built by
functions and possibly modified with methods, no additional parsing of the
input to jsRealB is necessary. Usual browser-based JavaScript development
tools can thus be used to develop the realizer functions while allowing a
seamless integration in webpages. The special terminal Q (_Quote_) allows the
insertion of _canned text_ , a feature that caters for special needs and is
often useful in practical applications, but is not discussed further here. The
Python implementation uses exactly the same notation; although it is less
convenient within a web page because Python is not directly interpreted by the
browser. On the other side, when used offline, it allows an easier integration
with many other NLP tools.

⬇

// CONSTITUENT notation

S( // Sentence

Pro("him").c("nom"), // Pronoun (citation form), nominative case

VP(V("eat"), // Verb at present tense by default

NP(D("a"), // Noun Phrase, Determiner

N("apple").n("p") // Noun plural

).tag("em") // add an  tag around the NP

)

)

// DEPENDENCY notation

root(V("eat"), // Sentence with a verb as head, two dependents

subj(Pro("him").c("nom")), // Subject with a pronoun as head

comp(N("apple").n("p"), // Complement with a noun as head

det(D("a"))) // dependent with a determiner

.tag("em") // add an  tag around the comp

)

⬇

Lexicon lexicon = new XMLLexicon(); // default simplenlg lexicon

NLGFactory nlgFactory = new NLGFactory(lexicon);

NPPhraseSpec np= nlgFactory.createNounPhrase("a", "apple");// create NP

np.setFeature(Feature.NUMBER,NumberAgreement.PLURAL); // set plural

SPhraseSpec s = nlgFactory.createClause("he","eat", np);// create sentence

DocumentElement sentence = nlgFactory.createSentence(s);

Realiser realiser = new Realiser(lexicon);

NLGElement realised = realiser.realise(sentence);

System.out.println(realised.getRealisation());

⬇

from CoreNLG.DocumentConstructors import TextClass

class Content(TextClass):

def __init__(self, section):

super().__init__(section)

self.text = self.free_text(

"he",

"eats",

self.nlg_tags("em",text="apples")

)

Figure 1: Top: JavaScript using constituent or dependency notation with
comments at the right realized by jsRealB or pyrealb as: He eats
apples. Middle: SimpleNLG Java statements to print a roughly
equivalent sentence: He eats some apples. Bottom: Python class from CoreNLG
project to create a web page displaying He eats _apples_.

jsRealB can also be used as a standalone node.js module555Installable with npm
i jsreal taking input created by an external system. By experience, we know
that creating syntactically valid JavaScript expressions from a program
written in another programming language can be cumbersome and tricky.
Therefore jsRealB also allows a JSON input format666The specifics are
described in this document for which convenient APIs are available in almost
all programming languages. This idea is similar in principle to the XML input
format allowed in SimpleNLG. The JSON input format has been used to realize
sentences from structures built by Prolog and Python programs. For Python,
this is now less useful because of the port of jsRealB to Python discussed in
Section LABEL:sub:python_implementation.

The top part of Figure 1 shows our running example in both constituency and
dependency notation, for the realization of the utterance He eats
apples. in which the word apple would appear emphasized when
displayed in a browser.

##  3 Previous text realizers

Realizers have been an integral part of Natural Language Generation (NLG)
systems since the eighties. Realizers such as KPML [KPML], Surge [elhadad-
robin-1996-overview], RealPro [lavoie-rainbow-1997-fast], Forge [mille-
etal-2017-forge] and GenDR [lareau-etal-2018-gendr] are based on linguistic
theories, taking into account many details in the construction of sentences,
which allows powerful realizations. However, that complexity hinders their
ease of use: writing specifications for them requires an intimate knowledge of
the underlying theory.

In fact, most existing realizers are considered so complex that SimpleNLG
[gatt-reiter-2009-simplenlg], as its name implies, defines itself by its ease
of learning and of use. Words, phrases and other structures are Java objects
created and manipulated intuitively by a programmer and easily integrated into
a Java project. While its principles somewhat limit the power of its
realizations compared to other systems, these realizations are largely
sufficient for many uses. SimpleNLG has been used in a variety of text
generation projects.777SimpleNLGis freely available at
https://github.com/simplenlg/simplenlg Our realizer was originally inspired by
SimpleNLG for which we have developed a bilingual (French and English) version
[Vaudry2013ENLG].888Available at https://github.com/rali-udem/SimpleNLG-EnFr

But with the rise of web applications, we found that the use of Java for
building a text realizer was complicated by the need of creating a distinct
web server for building new web pages and creating an XML structure for
realization. As the Java notation is relatively verbose, we decided to develop
a notation that mimics the usual notation of the constituent grammar.
Embedding the realizer in the web page itself greatly simplifies the
architecture of the application. but jsRealB would probably never have been
created without our previous experience with SimpleNLG. The middle part of
Figure 1 shows the input to create a almost equivalent sentence to the one
written in JavaScript. SimpleNLG does provide some HTML formatting but only at
the paragraph level (list and title) and not at the token level; the plural of
the indefinite article a is realized as some.

Many data-to-text information systems can _get away_ with template-based text
generators in which it is sufficient to be able to deal with the description
of a iist of items. Van Deemter et al. [van-deemter-etal-2005-squibs] argue
that these types of systems are interesting and useful and not necessarily
_inferior_ to the more general approaches.

One the first template system to be described in detail is YAG [Mcroy-2003]
which bridges the gap between linguistic theories and the need for practical
data-to-text generation systems.

RosaeNLG999https://rosaenlg.org is a JavaScript NLG library based on the Pug
templating engine101010https://pugjs.org. It supports languages such as
English, French, German, Italian and Spanish with some features such as
agreement within noun phrases, a few tenses and agreement at the third person
of some simple tenses. RosaeNLG was developed for realizing some simple data
to text applications and is especially tuned for outputting lists of objects
and properties using appropriate commas and a conjunction at end of the list.
RosaeNLG being built over a template engine, it is not so well integrated
within a web page as jsRealB because a distinct specific file must be written
and transformed into JavaScript before being integrated in the web page.
Moreover the linguistic coverage of jsRealB, for French and English at least,
is much more complete than what is offered by RosaeNLG.

CoreNLG111111https://github.com/societe-generale/core-nlg is a Python library
for Natural Language Generation providing some tools to structure and write
NLG projects, agreement between elements must be based on external resources.
Like jsRealB, it deals with some typographical conventions and elisions and
also allows choosing randomly between synonyms, but it is mostly grammar
unaware. A simplistic example of its formalism is shown in the bottom part of
Figure 1.

jsRealB differs from compromise121212http://compromise.cool which is a low-
level JavaScript API for both parsing English and extracting information. It
dubs itself as _trying its best, and being small, quick, and usually good
enough_. It also provides functions for generating English dealing with
conjugation at simple tenses and with the plural of nouns. compromise stays at
the level of the JavaScript program and generates list of tokens, while
jsRealB is oriented toward the specification of the constituent structure from
which the basic tools are automatically called.

Text realizers are important in commercial systems such as
ARRIA131313https://www.arria.com/ that provide sophisticated templates that
can be customized with a specialized programming language within well-
developed web-based environments. The strength of the system lies with the
ease of linking with different types of data sources and analytic tools, but
it requires learning a specialized language instead of relying on the
underlying and well-known JavaScript formalism.

Neural models for end-to-end data-to-text generation have been proposed, but
they focus on the whole process and pay relatively little attention to the
final realization step, which we address here. Castro Ferreira _et al._
[castro-ferreira-etal-2019-neural] found that having intermediate steps in the
generation process generally leads to better texts than end-to-end systems.
This is one of the reasons why we devoted time to study this _final_ process
of NLG.

We now detail some interesting aspects of the organization of jsRealB to take
care of the automatic agreement between constituents which is an important
feature in order to limit the number of annotations to give and to add some
flexibility when individual components are combined in different ways.

##  4 Steps of the realization process

###  4.1 Structure creation

To illustrate the steps to go from a jsRealB expression, using the constituent
notation, to the corresponding English sentence, we start with the sentence
structure in Figure 1 whose corresponding internal data structure is shown in
Figure 2.

Figure 2: Internal data structure corresponding to the expression in
constituent notation of Figure 1

Diagrams in this paper use these graphical conventions:

  * •

a Phrase is shown as a rectangle containing its name on the first line and
possibly options on the following line;

  * •

a Dependent is shown as a pentagon (used in Figure 3) containing the name of
the relation on the first line and possibly options on the next line;

  * •

a Terminal (to be realized as a string of words, possibly none) is displayed
as a rounded rectangle containing its name followed by its _lemma_ in
parentheses; options may appear on the second line. On a third line, will be
the realization string once it has been determined.

  * •

Full line arrows indicate parent-child relationships, lines with larger width
link a parent with its _head_ child. Dashed lines link a constituent with its
_shared_ properties. Shared properties are first associated with terminals:
they are person (pe), number (n) and gender (g) (shown as a flat octagon in
Figure 2) for nouns, pronouns, adjectives, determiners and verbs; verbs also
have two other shared properties, tense (t) and auxiliary (aux) (in French
only), shown as a flat hexagon in Figure 2.

These properties are _shared_ to ensure that proper agreement is done between
constituents141414In Prolog, this would be achieved by unification between
shared variables that are changed as soon as one of its occurrences is
changed. so that when a property of constituent is changed then all dependent
constituents will be changed accordingly.

When phrases are created from terminals and other phrases, the shared
properties of the parent are set to the ones of its head so that modifications
to the parent will be propagated to its children. In Figure 2, the tense of
the VP is set to the one of the V, and the number of the NP is set to the one
of the N. But other links must also be added: a VP must also be linked with
its subject in order to properly agree in person, gender and number, this is
why the VP is linked with the shared property of the Pro. Agreement must also
be made between children of a NP: a determiner, adjectives must agree with the
head of a NP, so they all share the same properties.

Some properties (such as formatting) are not shared, they only apply to the
current constituent. The only shared properties are those dealing with an
agreement between constituents.

Figure 3: Internal data structure corresponding to the expression in dependent
notation of Figure 1

Figure 3 shows the diagram of the internal data structure when using the
dependent notation with the agreement links. One interesting implementation
advantage of this notation is the fact that the head of a relation is
explicitly given and does not have to be found using heuristics described
previously. Once the appropriate agreement links are set up, propagation is
performed as for the constituent notation.

###  4.2 Realization of Constituents

We now explain how to go from an input structure to an English sentence. To
realize a sentence, the toString() function performs two tasks:

  * •

_stringification_ which computes the realization property of a terminal
possibly modified with some formatting;

  * •

_detokenization_ which creates a single final string for a phrase.

These steps, which are the same for both the constituent and the dependency
notations, are now detailed.

####  4.2.1 Stringification of constituents

The production of strings from terminals and phrases is carried out
recursively. Realization strings are produced for each terminal, but also for
each phrase at each level of the tree. This process builds lists containing
the original terminals, using information from the original data structure
(e.g., number, gender or agreement links) for proper conjugation and
declension.

Figure 4: Tokens from Figure 2 once their realization field is filled in.

####  4.2.2 Computing the realization property

The toString() function of a _Phrase_ calls toString() on its children to
create into a flat list containing the original terminals with their
realization field filled in.

The toString() function of a _Terminal_ applies declension or conjugation
rules taking into account the gender, number, person and possibly tense
information in order to fill in the realization field of the terminal. Figure
4 illustrates a few interesting cases.

  * •

Pro("him").c("nom") is realized as he because the declension rules set its
gender to masculine, its person to third and its number to singular;

  * •

VP("eat") is realized by the string eats because the verb is conjugated at the
present tense by default as given by its shared property and, as shown in
Figure 2 it is as third person singular, from the shared property of its
subject, the Pro;

  * •

D("a") produces an empty string because it is a plural indefinite article as
given by its shared property with the N.

  * •

N("apple").n("p") produces apples, the plural declension of the lemma
apple. As will be explained in the next section, the formatting em tags come
from the surrounding NP.

Using the shared properties allows global modifications to the original
expression, although it does not override locally set properties. For example,
adding .t("ps") at the end of the expression in Figure 1 indicates that the
whole expression should be at the simple past. The modified expression would
then be realized as He ate apples.

####  4.2.3 Formatting the realization property

Formatting is carried in a series of optional steps:

  1. 1.

Apply language-dependent token modification rules taking into account the
surrounding words:

     * •

English:

       * –

the determiner a which changes to an depending on the first letter of the next
word, most often a vowel.

     * •

French:

       * –

_elision_ for determiners such as le, ce, la, etc., or conjunctions such as
que, puisque. If the next word starts with a vowel, then the current word’s
last letter is changed to an apostrophe ’’, which will be joined with the next
word. In fact, rules for French are a little more complicated because this
case also applies to some words starting with an h.

       * –

_euphony_ for adjectives such as beau, fou or vieux which are changed to bel,
fol or vieil if the next word starts with a vowel.

       * –

_contraction_ combining words such as de le to du, si il to s’il’, à les to
aux.

  2. 2.

Modify the realization string to insert strings that should appear before
.b(..), after .a(...) or around .ba(...) the realization string;

  3. 3.

Surround the realization string with HTML tags given by .tag(...).

In our example, only the HTML tag em was added when formatting the NP. Section
5.7 will discuss why formatting can interfere with the realization process.

####  4.2.4 Detokenization

When the toString() method is called for a constituent at the _top-level_ of
an expression, a _detokenization_ process is applied to produce a well-formed
English sentence. In our running example, this produces He eats
apples.

Detokenization creates a single string by inserting appropriate whitespace
between the realization strings of the terminals. When detokenization is
applied to the top-level S, it capitalizes the first letter of the sentence
and adds a full stop at the end unless indicated otherwise.

We thus see that even for our example’s simple _three words_ sentence, many
steps are needed to produce a well-formed sentence.

Figure 5: Variations on the sentences of Figure 1 combining negation, passive,
yes or no question and possibility modality.

##  5 Structure modifications

One very useful feature of jsRealB, inspired by a similar one in SimpleNLG, is
the fact that a single affirmative sentence structure can be realized as
negative, passive, interrogative or with a modality verb by setting a _type_
flag on the sentence or verb phrase structure without having to change its
structure. Almost 5 000 variations can be generated from a single English
affirmative sentence and 1 250 variations for a French151515See this
demonstration of these variations with example sentences, even though some of
them are not very colloquial or would need a specific context to be valid,
Figure 5 shows a few of them. This capability of the realizer proved very
useful when verbalizing AMR structures in which negation is only indicated by
a negative polarity role on an otherwise affirmative structure. We could just
translate the rest of the sentence as an affirmative one and add a negative
flag at the end. This was also used for creating negations for augmenting a
corpus of negative sentences for training a neural semantic analyzer.

To realize these modifications, jsRealB modifies the original sentence
structure by adding new words and changing word order while keeping agreement
links intact. This section highlights a few interesting cases using the
constituent notation, but the process is similar to the dependent notation.

###  5.1 Negation

⬇

S(Pro("him").c("nom"),

VP(V("eat"),

NP(D("a"),N("apple").n("p")))

).typ({neg:true})

Figure 6: At the top is the example of Figure 2 with a negation flag set; in
the middle is shown the modified data structure produced by jsRealB; the
bottom shows the resulting list of tokens.

We now explain how a negative sentence is realized when .typ({neg:true)} is
added to the top-level S constructor of our previous example. To simplify the
diagram, we removed the .tag("em") from the NP. Figure 6 shows the JavaScript
notation (top) and the resulting data structure (middle) once the .typ(..) is
applied. The structure of the VP is modified. The auxiliary do and the adverb
not are inserted in front of the verb. The head of the VP is now the auxiliary
do which shares its property with the Pro. The tense of the original verb is
now infinitive (b for _base form_). The _stringification_ and _detokenization_
processes are the same as in the previous example. The end result is the
string He does not eat apples.

###  5.2 Passivization

⬇

S(Pro("him").c("nom"),

VP(V("eat"),

NP(D("a"),N("apple")).n("p"))

).typ({neg:true,pas:true})

Figure 7: Figure 6 with passive flag set and the resulting data structure and
tokens after passivization has been performed. The final string is Apples are
not eaten by him.

Figure 7 shows the transformation to the _passive_ form of our running
example. It is now realized as Apples are not eaten by him. In the JavaScript
notation at the top, pas:true is added in the .typ call. The middle part of
the figure shows the data structure once these negative and passive
transformation processes are applied: the object becomes the subject, the main
verb becomes be, the original verb’s tense is changed to the past participle,
and the original subject becomes a prepositional phrase starting with by. In
our example, the original subject being a nominative pronoun, it has to be
changed to its tonic form. The head of the VP is now be whose shared
properties for the subject is the NP As the subject changes, the shared link
for the S must also be changed.

###  5.3 Question generation

Figure 8: Twelve types of questions that can be generated from a single
affirmative sentence

.

Creating questions from an affirmative sentence is quite productive as shown
in Figure 8. In order to create questions from a single dependency structure,
jsRealB uses the _classical_ grammar transformations: for a _who_ question, it
removes the subject (i.e., the subj dependent), for a _what_ question, it
removes the direct object (i.e., the first comp dependent), for other types of
questions (_when_ ,_where_) it removes the a mod or comp having a preposition
as its head. Figure 9 illustrates this process on our running example.

Figure 9: Dependency tree of Figure 1 showing in blue the parts that can be
removed to create two questions: wos (who-subject) Who eats an apple ? and wad
(what-direct object) What does he eat?

Creation of questions from parsed affirmative sentences was used to build a
training corpus for a neural question-answering system [LeBerre2021EMNLP].
Almost 200,000 questions were generated from a corpus of about 140 000
sentences. In order to determine which questions are appropriate for a given
sentence, the dependency structure of the original sentence is checked to
determine if it contains the required part to be removed. Depending on the
preposition, the question will be a _when_ , a _where_ or another type of
question. An interesting side product is the fact that the _removed_ part is
the answer to the generated question, which is very useful in a teaching
context or for generating distractors in multiple-choice questions. Pronoun
only answers (such as he for the wos (who as subject) question in Figure 9)
are not usually informative, so they were ignored in building the training
corpus.

###  5.4 Pronominalization

⬇

S(Pro("lui").c("nom"),

VP(V("donner").t("pc"),

NP(D("un"),N("pomme")).pro()

)

Figure 10: JavaScript specification of a French sentence and the resulting
data structure after pronominalization

Another important structure transformation is the pronominalization process to
change a noun or prepositional phrase to a pronoun having the same number and
gender as the original phrase. That process is indicated by calling .pro()
method on the phrase. We use an example in French because it illustrates more
intricate transformation processes161616In English, this would be realized
simply as He has given it. coupled with agreement difficulties within the
realization process.

Not taking into account the call to .pro(), the top of Figure 10 shows a
variation applied to the French version of our running example. It is realized
as Il a donné une pomme. (_He has given an apple._) in which the verb is
conjugated to _passé composé_ , corresponding approximately to the English
_present perfect_ in its form. When pronominalization is applied, the realized
sentence is Il l’a donnée. (_*He it has given._)

Figure 10 shows the data structure once the call to .pro() has been processed:
the noun used as the direct object must be replaced by an accusative pronoun.
In this case Pro("elle").c("acc") agreeing in gender (feminine) and number
(singular) with the original noun that will not be realized. This is why it is
shown as a dashed rounded rectangle in the figure.

In French, some _interesting_ peculiarities must be taken into account:

  * •

a pronoun used as the direct object must appear before the verb (except for an
imperative verb), so the order of the children of the VP it must be changed
while linking the pronoun with the properties of the original noun to ensure
proper gender and number;

  * •

A verb conjugated at the _passé composé_ is built using an auxiliary verb
(avoir (_have_) in this case) followed by a past participle;

  * •

a past participle with the avoir auxiliary must agree in gender and number
with its direct object when it appears before in the sentence. This was not
the case in the original sentence, but once the pronoun is shifted before the
verb, the past participle must agree with the pronoun. This is why in French a
supplementary link (shown here as a dotted line with a double arrow head)
between a verb and its direct object. So when the past participle is realized,
it checks its position and then uses the gender and number of the direct
object, here the Pro(elle) whose shared properties are the ones of the
original NP. But the auxiliary of the main verb must agree with the original
subject. Another case of past participle agreement occurs with the être (_be_)
auxiliary must agree with its subject. We will see later an instance of this
case.

__

The modified structure is detokenized as in the preceding section to produce
the tokens shown at the bottom of Figure 10. Elision transforms la a to l’a
and the formatting is realized as: Il l’a donnée.

1 |  ⬇ S(Pro("lui").c("nom"), VP(V("donner").t("pc"), NP(D("un"),N("pomme")).pro()) ).typ(neg:true) |  Il ne l’a pas donnée.
_*He it did not give._
---|---|---
2 |  ⬇ S(Pro("lui").c("nom"), VP(V("donner").t("pc"), NP(D("un"),N("pomme")).pro(), PP(P("à"), NP(D("le"),N("fille")))) ).typ({neg:true}) |  Il ne l’a pas donnée à la fille.
_*He it did not give to the girl._
3 |  ⬇ S(Pro("lui").c("nom"), VP(V("donner").t("pc"), NP(D("un"),N("pomme")).pro(), PP(P("à"), NP(D("le"),N("fille"))) .pro()) ).typ({neg:true})\end{lstlisting}& {\vspace*{1ex}Il ne la \underline{lui} a pas donnée.\newline \emph{*He \underline{it} to her did not give.}} \\\ \hline 4&\begin{lstlisting} S(Pro("lui").c("nom"), VP(V("donner").t("pc"), NP(D("un"),N("pomme")).pro(), PP(P("à"), NP(D("le"),N("fille"))) .pro()) ).typ({neg:true,pas:true})\end{lstlisting}& {\vspace*{1ex}Elle ne lui \underline{a} pas \underline{été donnée} \underline{par lui}.\newline \emph{*It \underline{has} not \underline{been given} \underline{to her} \underline{by him}.}} \\\ \hline \end{tabular} \caption{\js{} specifications and the corresponding realizations for combinations of pronominalization, negation and passivation as produced by \jsr{}.} \label{tab:modifications} \end{table} \subsubsection{Further modifications} \label{further-modifications} French negation combined with pronominalization raise delicate word ordering problems. Table~\ref{tab:modifications} illustrates modifications of the example of Figure~\ref{fig:images_French-Active-Pronoun} in which the differences between each example are underlined. The second column gives the \jsr{} specification and the third column shows the corresponding French realization with an English transliteration in italics. \begin{itemize} \item In line 1, \realization{ne\ ...\ pas} wraps around the verb and the preceding pronoun. \item Line 2 adds an indirect object using a \lstinline!PP! (prepositional phrase) at the end of the sentence. \item When the \lstinline!PP! is pronominalized (line 3), the pronoun must also appear before the verb; as the pronoun is combined with \realization{à}, then the dative form \realization{lui} must be used. \item Line 4 shows the passive form in which \realization{par lui} \emph{(by him)} comes from the tonic form of the pronoun that was the subject. In this case, the past participle is still singular feminine but for a different reason. Passivization takes the direct object and makes it the subject of the passive sentence used with the \realization{be} auxiliary. So the past participle must agree with the new subject which, in this case, was the original object occurring before the verb. \end{itemize} \clearpage These examples might seem contrived, but these cases appear in real world texts and it is important that they be handled correctly to create correct French texts. \jsr{} implements the French clitic placement rules as defined by the \emph{Encyclopédie grammaticale du français}~\cite{EGF-clitiques}. They also show the importance of having a distinct realization step that can take care of these cases and make it possible to realize many variations from a single input structure. English passivization also raises interesting problems especially when combined with perfect tenses, progressive mood and modal verbs (possibility, permission, necessity ...) for which \emph{affix hopping} rules~\cite[pp 38--48]{SyntStruct02Chomsky} are implemented. \section{Other useful features to take into account} \label{other-interesting-features-to-take-into-account} \subsection{Incremental building of \emph{phrases}} \label{incremental-building-of-phrases} Although our previous examples of \jsr{} expressions have been created manually, these expressions are most often built by programs by invoking the API’s␣\js{}␣functions.␣Moreover,␣it␣may␣happen␣that␣not␣all␣arguments␣to␣a␣phrase␣are␣known␣before␣calling␣the␣function.␣For␣example,␣the␣subject␣and␣the␣verb␣can␣be␣determined␣in␣one␣part␣of␣a␣program,␣but␣complements␣are␣only␣later␣specified.␣To␣account␣for␣this␣possibility,␣\jsr{}␣allows␣adding␣new␣elements␣to␣an␣existing␣phrase.␣The␣\lstinline!add(Constituent,position)!␣method␣inserts␣either␣a␣phrase␣or␣a␣terminal␣to␣the␣current␣phrase␣at␣a␣certain␣position␣given␣by␣a␣non-negative␣index.␣If␣\lstinline!position!␣is␣not␣specified,␣the␣constituent␣is␣added␣at␣the␣end. For␣example \begin{lstlisting} ␣␣␣␣␣␣␣␣S(Pro("him").c("nom"), ␣␣␣␣␣␣␣␣␣␣VP(V("eat"), ␣␣␣␣␣␣␣␣␣␣␣␣␣NP(D("a"),N("apple").n("p")).add(A("red"))) ␣␣␣␣␣␣␣␣␣).add(Adv("now").a(","),0)’ is realized as Now, he eats red apples.. The adjective red is added at the end of the NP but, because adjectives in English are placed before the noun, it appears before the noun. The adverb now followed by comma is inserted at the start of the sentence because the position is set to 0. This dynamic feature explains why most realization decisions are taken at the very last moment (i.e., when a string is needed) and not while the structure is being built.

###  5.5 Coordination

Data to text applications must often output lists of objects that can be
realized using template-based systems like CoreNLG and RosaeNLG described in
Section 3. But linguistically, these descriptions use coordinated phrases
which are specified in jsRealB with a phrase CP constituent or a coord
dependency in which a conjunction is specified, if any, with as many elements
or dependents as needed. In the corresponding realization, all elements except
for the last one are separated by a comma followed by the conjunction and the
final element. The following example (shown in both constituency and
dependency notations) ⬇ S(CP(C("and"),NP(D("the"),N("apple")),
NP(D("the"),N("orange")), NP(D("the"),N("banana"))), VP(V("be"),A("good")))
//===================================== root(V("be"), coord(C("and"),
subj(N("apple"),det(D("the"))), subj(N("orange"),det(D("the"))),
subj(N("banana"),det(D("the")))), mod(A("good"))) is realized as The apple,
the orange and the banana are good. in which jsRealB takes into account that
the subject is now plural because of the and. If C("or") had been given, the
verb would have been realized as singular. Such coordinated sentences are
often built incrementally and, in some cases, only one element is required.
For example, ⬇ S(CP(C("and"),NP(D("the"),N("apple")), VP(V("be"),A("good")))
//==================================== root(V("be"), coord(C("and"),
subj(N("apple"),det(D("the")))), mod(A("good"))) is realized as The apple is
good. in hich the conjunction is ignored and the number stays singular,
unless, of course, the single subject is plural. The generation of the tokens
for a coordinated phrase must also be performed at the _last minute_ , i.e.,
during stringification, where this special case must be checked.

###  5.6 Reusing jsRealB expressions

One of the advantages of using a programming language for creating text is the
fact that repetitive structures can be coded once and reused as often as
needed. jsRealB expressions, being JavaScript objects, can be saved in
variables, received as parameters or returned as result by functions. This
fact is heavily used in the demos and tutorial. As we have shown earlier,
options may modify the original structure of the expression. It is worth
pointing out that reusing a modified expression will thus realize the modified
object and not the original one according to the usual JavaScript behavior.
For example, given the assignment: ⬇ let apple = NP(D("a"),N("apple")) the
expression ⬇ S(Pro("him").c("nom"), CP(C("and"), VP(V("eat"),apple),
VP(V("love"),apple.pro()))) is realized as He eats an apple and loves it which
is expected. But later in the program, the expression ⬇
S(apple,VP(V("be"),A("red"))) will be realized as It is red., in which the
pronominalization of apple is still in effect. If this is not what was
intended, then a new apple object must be created before pronominalization. To
achieve this, one can call clone() which creates a new copy of the data
structure. This is implemented by traversing the object and creating a string
that corresponds to the jsRealB expression for building this object. The
resulting string is then evaluated in the current context to build a copy of
the original expression. So our previous S could have been coded as ⬇
S(Pro("him").c("nom"), CP(C("and"), VP(V("eat"),apple),
VP(V("love"),apple.clone().pro()))) after which ⬇
S(apple,VP(V("be"),A("red"))) is realized as The apple is red. Seasoned
JavaScript programmers might prefer defining arrow functions instead of
variables that will create a new data structure at each call, thus avoiding
the need for cloning the original expression. For example, we might define ⬇
let apple = ()=>NP(D("a"),N("apple")) and call apple() when needed. This also
allows parametrizing the expression at each call.

###  5.7 Formatting

jsRealB being aimed at web developers, it is important to deal with the
generation of HTML tags using the method tag(name,attributes) where attributes
is an optional object whose keys are attribute names and values are the
corresponding attribute values. When this method is encountered, it saves the
parameters and the values in the constituent. At _stringification_ time, these
values are used to create the final string while taking into account HTML
tags. For example ⬇ S(Pro("him").c("nom"), VP(V("eat"), NP(D("a"), N("apple")
.tag("a", {href:’https://en.wikipedia.org/wiki/Apple’})) )) is realized as He
eats an apple. in which the
elision is performed between a and apple even though in the realized string
the first letter of apple does not appear immediately after a, but it will be
the case when it is displayed. The punctuation before, after and around
constituents is dealt similarly. The appropriate values of the strings to be
inserted are saved within the constituent structure and used during the
_stringification_ process. Note that this implementation choice implies a
_small_ limitation: HTML and other formatting can only be performed at
constituent boundaries.

###  5.8 Bilingual text generation

As the B in its name implies, jsRealB was designed for realizing bilingual
texts (French and English) for which linguistic information differ: each
language has its lexicon, its declension and conjugation rules, word ordering
and even specialized formatting conventions. In jsRealB each Terminal carries
an indication of the language to be used at realization time. This allows
realizing a sentence in which the language of some words differ from the
others. Although this feature is seldom used with in a sentence, it proved
quite useful in some applications. In order to simplify the creation of a
Terminal, most calls are done in the context of the _current language_ which
is set by calling loadEn() for English or loadFr() for French. These functions
can be called as often as necessary even in the middle of a sentence. For
example: ⬇ loadFr(); var dest=NP(D("le"),N("monde")); loadEn();
S(Pro("I").pe(1), VP(V("say"), Q("hello"), PP(P("to"),dest.tag("b")))) will be
realized as I say hello to le monde.

###  5.9 Other issues

jsRealB having been designed for use in the context of data-to-text systems, it must deal with the proper generation of numbers. On top of the usual formatting, it also deals with the writing of numbers in letters while taking into account the number agreement for the noun: NP(NO(1).dOpt({nat:true}),N("plane")) realized as one plane while |