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.
Assume we have the following CIF specification:
cont pos der 1.0;
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
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>;
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.
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.
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 (
Z), an underscore (
_), or a colon (
:), and may be followed by more of the same characters, as well as dashes (
-), dots (
.), and numbers (
Ids must be put between double quotes. For instance, to use
some-name as id, it must be written as
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 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.
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
The supported attributes for an SVG element depend on what kind of element it is. For instance, a
rect element can have an
y position, 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 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"/>
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
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.
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
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
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.
value keyword is followed by an expression. This expression may for instance be a literal value, such as
"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.
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:
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.
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
\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.
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
tspan1 have the same text, it is also not allowed to specify output mappings for the text of those two elements.