SparseWare
Sage Data Format
The primary data format for Sage is the Sage Data Format (SDF). This format is CSS-like
with added capabilities. Like CSS, SDF has a selector, a property, and a value. In addition, is has attributes that can constrain or enhance a property or selector.
Below is the structure of an SDF element.
Selector{
value: "property value"
} [ onClick="attribute value"]
The selector is either the name of a Configuration object or the name of a property that represents
a Configuration object. In the following example, both "Label"
and "font"
are selectors and "onClick" is an attribute for "Label".
Label {
value: "Hello World"
font {
size: "+1"
style: bold
}
} [ onClick="alert('Testing')" ]
The valid properties
and attributes for each Configuration object are defined in the Configuration Objects
section.
SDF also supports hierarchy flattening. That is, any Configuration object hierarchy can
be flattened by using a dash to separate the property names that make up the
hierarchy. Thus, the previous example can
be redefined as follows:
Label {
value: "Hello World"
font-size: "+1" // use a font that is one point larger
font-style: bold
} [onClick="alert('Testing')" ]
Like CSS multiple properties can be placed on a single line by separating each property
with a semicolon. Also, both single line and block comments are supported (use // for single line and
/* */ for multi-line)
In addition, SDF supports a couple of other features. The first of these, is the
ability to specify a preformatted block of text that is not interpreted by the parser.
This is similar to CDATA sections in XML documents. To utilize this feature simply
enclose the value between "<<" and ">>".
It is important to note that the data itself cannot
contain the text ">>"
as this will terminate the block. In cases where the ability
to have the text ">>"
inside of a preformatted block would make things simpler, the text ">>"
can be replaced by any string that does not occur within the preformatted block
of text. The unique string must also immediately follow the’>>’ and terminate
with a whitespace character. The syntax is similar to the Perl and Ruby Heredoc
syntax with the exception that the terminating string is not required to be on a
separate line. For example:
dataURL:<<EOF
First|t-6,1|t-5,4|t-4,15|t-3,17|t-2,15|t-1,13|t,16
Second|t-6,2|t-5,6|t-4,11|t-3,12|t-2,17|t-1,10|t,13
EOF [aggregate="true" ]
Another feature is the ability to name and later inherit a definition. To name a
definition, append a colon and an "at" sign (@) to a selector, followed by the name
you want to use. To later inherit that named definition, append a colon and a dollar
sign ($) to a selector followed by the name of the definition you want to inherit
from. You can then augment or enhance that definition. The following example assigns
the name ‘bigAndBold to our Label definition:
Label:@bigAndBold {
value: "Hello World"
font {
size: "+1"
style: bold
}
}
Now we can inherit this definition and augment it as follows:
Label:$bigAndBold {
value: "Big And Bold Text"
} [ onClick="alert('Testing')" ]
This feature is most useful when combined with the ability to dynamically import
other definitions. The SDF format supports the importing of other definitions via
the "@import" command at the top of an SDF file. The import command is followed
by the URL of the definition you want to import. So, if the "bidAndBold" label definition
was stored in a file called label_templates.sdf, it would be referenced from another
file as follows:
@import "label_emplates.sdf"
Label:$bigAndBold {
value: "Big And Bold Text"
} [ onClick="alert('Testing')" ]
You can also simultaneously inherit and define a new reference by simply combining
the two naming constructs. From the previous example, you can create a new reference-able
entity called ‘bigAndBold2’ as follows:
@import "label_emplates.sdf"
Label:@bigAndBold2:$bigAndBold {
value: "Big And Bold Text"
} [ onClick="alert('Testing')" ]
If you create template objects that are meant to only be inherited and never meant to be loaded directly, you can use any selector name you like. The import and reference
resolution are handled by the parser. The parser does not understand or interpret
configuration objects. It only understands the SDF file structure. Its job is to parse
the SDF file and create nodes that can be passed to the runtime for interpretation.
This means that intermediate names and structures are irrelevant (as long as the
structure is valid). Your template
objects can be arbitrary buckets of attributes that any type of Configuration object
can inherit from, as long as the properties are relevant to the inheriting object.