SPFE Documentation | Collections > Essays on SPFE > Declarative markup
Declarative markup
By Mark Baker
Summary
SPFE is intended to support a declarative approach to markup -- one in which authors use markup to declare what something is, rather than the give and instruction about how something is to be handled. Some other systems rely on imperative markup (which gives instructions). SPFE will allow for imperative markup, but is generally intended to avoid the need for it.
In structured writing, markup is a means of inserting metadata into content so that the content can be identified or manipulated by algorithms, and it ensure that the content meets a set of required constraints. This metadata can be divided into two broad categories, declarative and imperative.
Declarative markup - Declares what a piece of content is, either its role in a document (such as paragraph or list item) or what subject matter it refers to (such a an ingredient in a recipe or a parameter in a API routine).
Imperative markup - Gives an instruction about how to handle the content under certain conditions. For instance, a conditional statement that includes certain content when a condition is true, or an instructions to reuse a piece of content by inserting it at a particular point in a text. Links are also a form of imperative markup as they tell the algorithm where to link to.
The main reason for using imperative markup is to make it easy for writers to specify certain behaviors in the content without the need to create specific markup or specialized algorithms to support them. The inclusion of a standard set of imperative markup in a markup language, along with a corresponding set of algorithms to process the imperative markup, can allow an organization to manipulate content in useful ways without the need for additional structures or coding. DITA, in particular, makes extensive use of imperative markup, largely as a means to do content reuse.
However, there are several downsides to the use of imperative markup:
-
Imperative markup does not make objectively true statements about the content. This make the content dependent on a particular markup and processing system. Purely declarative markup is objectively true, and therefore the markup is processable (with appropriate preprocessing) by any processing system. Content that includes imperative markup cannot be easily moved to another system.
-
When imperatives are embedded in content, they are scattered through the content set. Any change in policy that requires a change in the embedded imperatives, which may involve editing many files scattered throughout the content set. For instance, a change in linking policy could require editing virtually every file in a content set. This involves a lot of work, is prone to errors and omissions, and may trigger costly review and approval cycles.
-
A markup system that uses imperative markup requires all authors, editors, and maintainers of the content to understand the imperatives and their operation. This means that they need to become experts not only in their subject and in communicating about it, but in the publishing functions that are driven by the imperatives.
-
Imperative markup is an instruction to be interpreted by an algorithm. That means, in effect, that the imperative markup constitutes a programming language embedded in the content. (This is not unusual. PHP and JavaScript are programming languages that are commonly embedded in web pages.) However, if you have more than one imperative element in your markup, you can run into issues with the interactions between different imperatives. This potentially makes life even more difficult for authors who now are being asked to think like programmers (and who may not understand how the imperatives they have created will be interpreted by the algorithm). It can also make like more difficult for people writing algorithms to process the content, who now have to make sure that the rules for handling then imperatives are clear, complete, and consistent, which can be quite difficult if the are many ways in which the effects of the imperatives can impinge on each other.
Many (not all) of the effects that can be achieved using imperative markup can also be achieved using declarative markup. Where imperative markup puts the instruction in the content, declarative markup puts information needed to make a decision into the content, but places the instructions itself in an algorithm. For example:
-
Instead of attaching a link instruction to a phrase in the content (and instruction to the processing software), declarative markup can specify the type and subject matter that the phrase refers to (a declaration about the subject matter) and leave it to an algorithm to find a resource to link to on that subject when the content is published (soft linking).
-
Instead of inserting an instruction to insert a reusable admonition component above a procedure that is dangerous (an instruction to the processing software), declarative markup can add an attribute to a procedure to state that it is dangerous (a declaration about the subject matter) and leave it to an algorithm to insert the appropriate admonition when the content is published.
The SPFE architecture is designed to facilitate the use of declarative markup as much as possible. Imperative markup can still be use (and if used is resolved in the resolve step of the synthesis stage), but the use of declarative markup is encouraged by the following features:
-
Soft linking support means that direct links (imperative) in the content can be replaced by annotations (declarative). Support for link resolution based on annotation is built into the default SPFE build and the default EPPO-simple scripts, so you don't need to write additional code to get soft linking.
-
The declarative approach often involves the use of subject-specific markup, meaning you need to add additional markup and processing to your system to use the declarative approach. SPFE's structures make it easy to add new structures and their associates processing code to your system.
-
SPFE's loosely coupled architecture and clear delineation of the role of each processing step and stage provides a clear separation of concerns that makes it easy to add processing code at the right place without having to worry about how it will interact with other parts of the processing system.