• No results found

The behaviour of hashes under composition allows templates to provide an inheritance behaviour. The prior template of each atom is a hash, which in general will contain a number of keys, propagated from other atoms that occur earlier in the structure. Consider the following lish where, anticipating the next chapter, I am assuming a tabular interpretation.

              h ( font family: Helvetica )

, {value: Name}, {value: Dept}, ( value: Phone, font size: 14 ) i 

{}, {value: Alan}, {value: Computing}, {value: 1234}  

{}, {value: Brenda}, {value: Chemistry}, {value: 2345}  

(

font size: 16

)

, {value: Charles}, {value: Chemistry}, {value: 3456}  

{}, {value: Davina}, {value: Physics}, {value: 4567}               

In the above lish, the key “font family” with value “Helvetica” which occurs in the first atom of the first sublist can be shown to be in the prior template of all nineteen of the other atoms. Similarly, the key “font size” with value 16 at the left hand side of the row for Charles is in the prior template of every other atom in that row – but not in the other rows. The other “font size” key with value 14 at the top of the Phone column is in the

prior template of all the other atoms in that column, except the one in the Charles row, where the order of composition means that the equivalent key with value 16 has overridden it.

This propagation of key-value pairs through templates has an obvious interpretation: we can say that atoms “inherit” properties that are defined elsewhere. In terms of tables, all the cells in a table inherit from the cell in the top left corner, all cells in a column inherit from the top cell in the column, and all cells in a row inherit from the left hand cell of that row. Where a cell could inherit the same property that is defined in more than one of those positions, the property at the innermost level of the nested structure takes precedence. Other more complicated inheritance patterns can arise when the lish contains more than one table, or structure within a table.

As a straightforward extension, we can of course let any cell in the table body have a property just its own by including the appropriate key-value pair in the hash representing that cell. For example, if we wanted Physics to be in bold we could expand its hash representation to {value: Physics, font weight: bold}. The “bold” property is then in the posterior template of the Physics cell, but not in the prior template of that cell, nor any of the others. The lish editor in fact generates the posterior template of the entire lish in order to decide what to render.

So far I have described inheritance only in how it might be applied to cosmetic properties of a lish being displayed. It has a more substantial application, namely its use in the formula model for the lish. A full descrip- tion of the formula model will be given in Chapter 6, but it will be useful to provide one more definition here.

4.8.1 The inheritors of an atom

Suppose an atom were to be assigned a key-value pair where the key was unique within the entire lish. Then the inheritors of that atom are defined to be the set of atoms that would have this unique key-value pair in their prior template. Note that it is not required that the first atom actually does possess such a key: the inheritors are simply those atoms that would inherit it, were it to be present. This hypothetical construct identifies all those atoms that could in principle inherit some property from the first atom, regardless of whether they actually do so in any particular case. For example, in the telephone list above, the inheritors of the Phone atom are

all the other cells in that column, even the cell where the font size property was overridden so that nothing was actually inherited.

The concept of inheritors will be applied to multiple cell selections in the next chapter, and to calculations in the following one.

4.9

Conclusion

In this chapter, I have formalised the definition of the lish, expressed in terms of lists of atoms and sublists; the notion of conformance played a key role in describing how one part of the structure may be governed by another part. This led to a preliminary definition in which all lish elements conformed to the head of their parent lish.

I then extended the definition to address the problem of inconsistent templates raised in the previous chapter. To do so I introduced the trace, which separates the representation of the template from the representation of the lish itself. A trace has an archetype which lets it express the idea of repeating structures having a common origin. By defining composition on traces, I provided the necessary fine control over how templates are com- bined.

I turned next to basic operations on the lish. These were closely based on the corresponding operations on an ordinary list, but were modified to ensure that lish constraints were respected. I then expanded the role of the atomic elements to enable them to model spreadsheet cells, by using a hash representation to express cell properties beyond a simple numeric or string value.

Finally, I showed how the lish definition gives rise to an inheritance be- haviour. In the next chapter, I shall make use of this behaviour in visualising the lish, and in supporting multiple cell selections. In the following chapter, I shall call upon it again when defining calculations over multiple cells.

Chapter 5

The lish in two dimensions

5.1

Lishes as tables

In the previous chapter, some tabular behaviour has emerged in the lish: if we represent a table within a lish such that each row is a sublist with a common archetype, the lish operations (for inserting columns, and so forth) have been seen to produce the results expected under the tabular interpretation. But the underlying representation remained simply a list of elements enclosed in square brackets. In this chapter, I shall present a method for typesetting such lists so that they look like tables. I shall then introduce my prototype editor, which allows the resulting tables to be edited interactively.

Typesetting a lish is one of a class of problems where content is modelled as a series of rectangular boxes, which then have to be arranged in a two dimensional space according to certain constraints. The approach is not dissimilar to the one taken by a GUI layout engine, such as GTK or Qt, when it decides how to pack a collection of widgets in a window. A web client rendering HTML/CSS would be another example. In both cases, the objects to be rendered have a specified (but possibly elastic) size, and certain objects have to be vertically or horizontally aligned with others.

A lish in general does not have a straightforward mapping to the various box layouts provided by GUI managers, nor to an HTML table. The way in which lish templates are constructed can result in mixed structures, where some parts are grid-like and other parts are ragged. This can result in cells needing to be kept aligned in the visual representation even when they are not adjacent. Another aspect of the lish that affects the typesetting process is that it prefers structure over markup in determining which elements are

interrelated. With the exception of cosmetic properties such as font size (as described in subsection 4.7.1), the visual layout is determined by parsing the structure, as opposed to inspecting object classes or tags.

One choice in deciding how a table should be represented is whether the innermost sublists should be the rows, or the columns. The lish in fact does not impose one over the other. In particular, the way inheritors were defined in the previous chapter means that either way around, cells in the top row have cells in their respective columns as inheritors, and cells in the left hand column have cells in their respective rows as inheritors. The inheritance abstraction has created a symmetry that was not present in ordinary nested lists.

This abstraction is all very well, but if a lish is to be presented visually then clearly each sublist present must be assigned a concrete orientation. Its elements will be arranged next to each other, on the page or the display device, running either from left to right or from top to bottom. Deciding which sublist will run which way is the first task of the geometry manager.