Stacking

It is possible for multiple occurrences of the same mapping to be active simultaneously. Consider a <list> element containing a number of <item> elements. If one of those items contains a sub-list, then we could have two list mappings and two item mappings in effect at the same time, one pair for the main list and one for the sub-list.

Ordinarily, user variables are global in scope, which means they can be seen and set by any mapping. If a sub-list mapping alters a variable, then that change will be seen in the main list mappings. This may be what is needed but, if the variable were (say) an item count, then we really want separate counts for the main list and the sub-list.

To achieve this, TopLeaf uses a technique called stacking. Any mapping can request that a particular user variable is to be stacked. This in effect creates a private copy of the variable which is visible within the element and its descendants. The original value of the variable is restored at the end of the element.

In our example, this means that the list mapping stacks the item counter which is then visible to any items in the list. If a sub-list is invoked then the new list mapping will stack its own item counter. When the sub-list is complete the original main list item counter is restored. In this way both the main and sub-lists can maintain item counts without interfering with each other.

To stack a variable, a mapping can execute a command like:

<stack var="Vname" value="VAL" />

or

<stack var="Vname" string="STR" />

The options available are the same as the <set/> command. The difference is that <stack/> creates a temporary copy of the variable, and restores the original value at the end of the element.

The default action is to restore the value at the end of the element being mapped. You can modify this behavior so that the value is restored at the end of one of the ancestors of the element. For example, the following restores the value at the end of the current chapter:

<stack var="Header" string="Introduction" ancestor="chapter" />

The closest enclosing ancestor is used. If there is no such ancestor this argument is ignored and the value is restored at the end of the current element.

Like the set command, it is only possible to stack user variables.

[Note] Note

If a variable is undefined before it is stacked it will be restored to an empty value. Attempts to reference the variable after this will not produce an error message.