CIF/SVG output mappings

For each update of a single attribute of an element in the SVG image, an output mapping is needed. An output mapping essentially defines a connection between the CIF specification and the SVG image, for updating that specific attribute of that specific element.

A simple output mapping

Assume we have the following CIF specification:

cont pos der 1.0;

Where variable pos is the position of some object, say a box. Then the following output mapping:

svgout id "box" attr "x" value pos;

Keeps the value of the x attribute of the SVG element with id box equal to the value of continuous variable pos.

Syntax

The general syntax of CIF/SVG output mappings is:

svgout id <id> attr <attr> value <value>;
svgout id <id> attr <attr> value <value> file <file>;
svgout id <id> text        value <value>;
svgout id <id> text        value <value> file <file>;

The svgout keyword is followed by a specification of an SVG element id. Every output mapping must specify the id of an SVG element, and an SVG element with that id must exist in the SVG image. The id indicates the element for which an attribute or text is to be updated.

The id is followed by a specification of what part of the SVG element is to updated. That is, either an attribute or text (label) is updated.

After that, the value of the attribute or text (label) is specified.

In the syntax examples above, we see that it is also allowed to declare an optional local SVG file declaration, that only applies to that specific output declaration.

SVG element id

Every output mapping needs to specify the id of the SVG element to update. The id is checked, to make sure an SVG element with that id actually exists in the SVG image.

Only valid SVG names may be used as ids. Valid SVG names start with a letter (a to z, A to Z), an underscore (_), or a colon (:), and may be followed by more of the same characters, as well as dashes (-), dots (.), and numbers (0 to 9).

Ids must be put between double quotes. For instance, to use some-name as id, it must be written as "some-name".

Instead of using a hard coded SVG element id, it is also allowed to use an expression that when evaluated results in the SVG element id. Such an expression must evaluate to a string typed value, and must be statically evaluable (must not refer to variables that can change value during simulation, etc). For instance:

// Hard coded SVG element id.
svgout id "box" attr "width" value ...;

// Computed SVG element id.
const string c = "bo";
svgout id c + "x" attr "width" value ...;

The first output mapping applies to the SVG element with the id box. The box id is hard coded into the output mapping. The second output mapping uses the expression c + "x" to specify the SVG element id. Once the expression is evaluated (its value is computed), this results in the string typed value "box". As such, the second mapping applies to the SVG element with id box as well.

The expressions may also refer to for instance algebraic parameters of automaton definitions. Since different values can be given to the parameters for each instantiation, this allows the SVG element id to vary for the different instantiations of the automaton definition. This particular usage allows for reuse and scalable solutions. The lamps example and workstation example are good examples of this usage. This usage is often combined with CIF/SVG copy declarations and CIF/SVG move declarations.

SVG attribute name

Every output mapping needs to specify the name of the attribute of the SVG element to update (or text, see the Text labels section). Similarly to specifying ids, attribute names must be valid SVG names. They also need to be put between double quotes. Unlike SVG element ids, it is not possible to use expressions to specify attribute names. That is, only hard coded names can be used to specify attribute names.

It is not allowed to change the ids of SVG elements, as it could lead to duplicate or missing ids. As such, output mappings for the id attribute (in any casing) are explicitly not supported. Similarly, changing the style attribute (in any casing) using an output mapping is explicitly not supported, to avoid conflicting style changes. See also the SVG presentation attributes vs CSS style attributes section for more information about the style attribute.

The supported attributes for an SVG element depend on what kind of element it is. For instance, a rect element can have an x and y position, a width and height, a fill color, etc. A g element (a group) however, does not support those position attributes. It is beyond the scope of this document to go into more detail. The software however, will warn about using attribute names that are not supported according to the SVG standard (to catch simple spelling mistakes), and specifying attributes on elements that don’t support them. Consult the official SVG specification for further details. The examples showcase several commonly used attributes as well.

SVG presentation attributes vs CSS style attributes

SVG uses two kinds of attributes: SVG presentation attributes, and CSS style attributes. For instance, in the following partial SVG image:

<rect fill="red"        id="rect1" width="25" height="25" x="65" y="5"/>
<rect style="fill:red;" id="rect2" width="25" height="25" x="15" y="5"/>

Rectangle rect1 uses the SVG presentation attribute fill to specify the fill color the rectangle. Rectangle rect2 uses the CSS style attribute fill to specify the fill color the rectangle. The SVG presentation attributes are all direct attributes of the SVG element. CSS style attributes on the other hand, are always part of the SVG presentation attribute style.

CSS stands for Cascading Style Sheets, and it is a style sheet language used for describing the look and formatting of a document. It’s best known for its use in styling web pages written in HTML. Like SVG, CSS is an international standard developed and maintained by the World Wide Web Consortium (W3C). SVG reuses the CSS standard for its CSS style attributes. The most commonly used attributes for certain elements are also available in the SVG standard as SVG presentation attributes. Furthermore, SVG adds additional presentation attributes not found in CSS.

If an attribute is specified on an element using both an SVG presentation attribute, and a CSS style attribute, the CSS style attribute usually takes precedence. The output mappings handle all of this automatically and transparently. That is, you just specify the attribute name in the header of the output mapping, and the simulator makes sure the proper attribute is update, regardless of whether it is an SVG presentation attribute, or a CSS style attribute. It is explicitly not supported to change the style attribute directly (using an output mapping), in order to avoid conflicting style changes when other output mappings update CSS style attributes that are part of that same style SVG presentation attribute.

Text labels

Changing the text of text labels is a special case, as text is not stored in attributes. Consider the following partial SVG image, which contains a text label (created using Inkscape, and with some of the irrelevant details omitted):

<text x="5" y="5" id="text1" style="font-size:16px;">
  <tspan x="5" y="5" id="tspan2">
    The actual text.
  </tspan>
</text>

Here we see a text element with id text1, which contains a tspan element with id tspan2. The tspan element contains some text. To change the text of this text label, use one of the following mappings:

svgout id "text1" text value ...;

svgout id "tspan2" text value ...;

Here, instead of the attr keyword followed by the name of the attribute, we simply specify the text keyword. We can either use the id of the text element, or the id of the tspan element. More precisely, we can use the id of an element that contains text (such as the tspan element in our example), or an element (such as the text element in our example) that has a single child, which contains text, or an element that has a single child, which has an single child, which contains text, etc.

In practice, it is usually the easiest to use the Object Properties panel of Inkscape, to get the properties of the text label. The ID that is then shown, is the id of the text element.

Output mapping value

In order for an output mapping to be able to update attributes or text labels, it needs a value. The simple output mapping example already showed how a value can be specified. This section further explains the details of the specification of such values.

The value keyword is followed by an expression. This expression may for instance be a literal value, such as 1, true, 1.0, "some text", or [1, 2]. At first, it might not seem useful to use a literal as a value for an output mapping, since the mapping will then produce the same value every time it is applied. However, the rate example shows why this can in fact be very useful.

The expressions however, may also contain references to variables (discrete, input, continuous, or algebraic), functions, constants, locations, etc. For instance, we could use the value of a continuous variable and multiply it by two, by using x * 2 as expression, assuming that the continuous variable is named x. Since we may refer to the state of the CIF specification, the value of the expression can change as the simulation continues, resulting in different values being mapped to the image.

The expressions can also include if expressions, which are particularly powerful in this context. Using if expressions, a different value can be used for several different conditions. See the workstation example for an example of using if expressions in an output mapping.

Quoting and escaping

The value expression of an output mapping may be of any type. The result of evaluating the expression is converted to a textual representation that closely resembles the textual syntax of CIF, before using it to set the value of an attribute, or the text of a text label. For string literals this means that the text is escaped, and double quotes are added. If however the result of the expression is a string typed value, then that string is used 'as is' (without quoting, and without escaping). Thus, consider the following examples:

svgout id "..." attr "..." value ["a\"b"];
svgout id "..." attr "..." value "a\"b";

The value of the first output mapping is a list that contains a single string value, while the value of the second output mapping is a string value directly. This results in the following texts being used as values of the attributes:

["a\"b"]
a"b

That is, in general string values are quoted and escaped, as is the case for the first example, where the result is a list. However, if the entire result is a string, as is the case with the second example, the string value is used 'as is', without quoting and without escaping.

Whitespace handling

If the textual result of an output mapping contains a new line character (for instance due to including \n in a string literal or format pattern), the new line character is ignored by SVG. Furthermore, tabs (\t) are replaced by a single space character. Finally, by default consecutive spaces (including tabs) are merged together into a single space, and spaces at the beginning and end of the output of a mapping are discarded by SVG.

This essentially renders \n and \t useless, as the first is ignored, and for the second spaces can be used instead.

This also means that it is not possible to set multiple lines of text using a single output mapping. This is a fundamental restriction of SVG, not of CIF/SVG output mappings. In order to set multiple lines of text, multiple output mappings are needed, where each mapping sets a different text label (a different line).

Note that if you enter multiple lines of text in Inkscape, this results in a single text element, with multiple tspan child elements. The actual text of such tspan elements can then be updated using an output mapping for each tspan element. The benefit over multiple text labels (multiple text elements with a single tspan child element each) is that the one text element can be moved, making all the tspan child elements automatically move with it. That is, the lines of text are kept together by Inkscape.

Uniqueness of output mappings

All output mappings must be unique, per SVG image. That is, no two mappings may use the exact same SVG element id and attribute name. Similarly, no two mappings may update the same text. That is, for the example above, it is not allowed to specify two mappings for the text of the SVG element with id text1. However, since both elements text1 and tspan1 have the same text, it is also not allowed to specify output mappings for the text of those two elements.

Application

SVG output mappings are applied for states frames, throughout simulation. Their first application is after copy declarations and move declarations declarations have been applied. For more information, see the Application order section.