xOWL Visual Notation Specification Language

A visual notation is specified in a .view file (one specification per file). The name of the file does not have to match the name of the view. A dedicated language is used to express the visual notations.

I - Overview

A view specification contains 2 to 3 parts:

  • The specification of the visual elements as a grammar
  • The definition of the available toolboxes
  • The definition of the available libraries

The general structure us as follow:

view "View Name" {
 rules => axiom {
 }
 toolboxes {
 }
 libraries {
 }
}

The “rules” block contains in its header after the “rules” keyword the name of the grammar’s axiom, that is to say the top-level grammar rule.

The “libraries” block is optional (can be omitted).

II - Visual Grammar

The visual notational elements are defined using grammar rules, similar to grammars for texts. The terminal elements, however, are visual elements such as shapes and labels. A grammar rules is written as follow:

Head -> body ;

A grammar rule means that the visual symbol whose name is used as the head will be visually composed of the elements in the rule’s body. Rules’ head are called variables and are referred to by their name. The rules’ body can be composed of multiple elements that can be organized using operators.

A - Terminals

The most basic elements that can be used are called terminals. In this language, terminals can be:

  • Shapes (rectangle, ellipse, etc.)
  • Images
  • Labels (text)
  • Placeholders for some piece of data

They are called terminals because they are not defined by other grammar rules.

1 - Rectangle

A black rectangle of 150 pixels width and 50 pixels height:

[[] 150*50 |#000000|]

Note that the color is noted with its RGB value in hexadecimal preceded by “#”. The two “|” symbols around it symbolizes the border of the shape, thus specifying the color between them defines the filling color.

The size of the rectangle must always be specified and is always in pixels.

A white rectangle with a black border:

[[] 150*50 |#FFFFFF|#000000]

The color of the border is noted outside the “|” symbols. The thickness of the border is implicitly 1 pixel.

A white rectangle with a black border of 3 pixels:

[[] 150*50 |#FFFFFF|#000000:3]

An invisible rectangle of size 150*50:

[[] 150*50]

This construction is useful in order to position visual elements.

A rectangle whose default width and height are respectively 150 and 50 but that grows with its container:

[[] 150*50< |#000000|]

The “>” symbol is used after the specification of the initial size to indicate the shape can grow with its container. The initial size is also the minimal size. The rectangle will grow to occupy all the space available to it.

2 - Ellipse

A black ellipse of 150 pixels width and 50 pixels height:

[() 150*50 |#000000|]

The size and coloring mechanisms are the same as for rectangles.

3 - Polygon

A black hexagon:

[<0,5, 5,0, 10,0 15,5, 10,10, 5,10> |#000000|]

A polygon is defined as a sequence of its vertices, whose coordinates are given in pixels. The coloring mechanisms are the same as for rectangles.

4 - Image

Image icon.png:

[@"path/to/icon.png"]

The size of this terminal is the size of the referenced image (it cannot be scaled). The specified path can be absolute or relative to the main directory of the environment (where the .jar is located).

5 - Label

A label displaying “Hello World!” of width 150 and height 25 pixels:

<"Hello World !" 150*25>

The text will be vertically and horizontally centered within the label’s bounds. The “<” symbol can also be used to indicate the label can grow with its container.

The same label with the “Courier New” font in size 10 and black color.

<"Hello World !" 150*25 : "Courier New" 10 #000000>

When specifying a font, these three elements are mandatory.

The same but in italic:

<"Hello World !" 150*25 : "Courier New" italic 10 #000000>

Other font styles are “bold” and “underline”.

6 - Placeholder

This is a place where the user can type any text. A placeholder of width 150, height 25 and described as expecting a name:

<s "Name:" 150*25>

The “s” symbol means this is a string placeholder. Other accepted types are “i” for integers and “f” for floats. Placeholders can also grow by using the “<” symbol. The descriptor in double quotes is free text and helps identify what is expected in this placeholder.

A specific font can also be specified as follow (same mechanism as labels):

<s "Name:" 150*25 : "Courier New" 10 #000000>

B - Reference to a variable

In a rule’s body, you can refer to another variable:

A -> {B C}:top ;
B -> ... ;
C -> ... ;

This means that the visual element A is composed of the B and C elements. They are organized using the concatenation operator and aligned along a horizontal axis on their top border. They will appear from left to right in the same order as in the rule.

C - Operators

1 - Concatenation

The concatenation operator is used to specify the geographical organization of two or more elements:

{A B C} : top

Given the three elements A, B and C, their concatenation is a visual element containing the three elements. The concatenated elements are noted between curly brackets { and }. How the concatenated elements are geographically organized is specified after the “:” symbol by keywords. Possible alignment options are as follow:

By default, the concatenation operator “packs” its inner elements so that it takes the minimum size. To change this behavior and allow the operator to grow its size to fill its container, use the “fill” keyword as follow:

{A B C} : fill top

2 - Union

The union operator is used to specify it can be replaced by one and only one of its inner elements:

{A | B | C }

The above example means the operator can contain either a A, a B or a C. This operator is generally used in conjunction with a repetition operator as described hereafter.

3 - One or More

This operator is used to specify one or more element may be present. It is noted as follow:

A+

This example means one or more may be present. The operator becomes an area where the user can drop more elements.

It is possible to specify the geographical organization of the inner elements using the same construction as the concatenation operator. For example to specify a repetition of one or more A elements horizontally aligned:

A+ : horizontal

The “fill” keyword can also be used.

The inner element can be anything and in particular a union operator:

{A | B}+ : fill top

This specifies one or more of kind A or B can be added. They will be horizontally aligned on along their top border.

By default, the order of the elements within the operator is not important. In order to the order is important, use the “^” as follow:

{A | B}+^ : fill top

This specifies the order of the A and B elements within the operator is important and enable the user to change this order. Inserting A or B elements will also allow the user to change the insertion index.

4 - Zero or More

This operator is the same as the “+” operator, except it can have no inner element. It is noted “*”:

A* : horizontal

5 - Optional

The optional operator is used to specify an element can be present or absent. It is noted as follow:

A?

6 - Graph and Connectors

A graph is a set of zero or more nodes and connectors. Consequently, a graph can be specified as follow:

{ node1 | node2 | … }* : free

This is simply a union operator contained within a repetition operator. The special “free” alignment keyword is used to specify that the inner elements are freely positioned by the users on a diagram.

A special construct is used for expressing connectors within a graph:

{ node1 | node2
  | <Connector1
    {@node1 simple}
    {@node2 arrow}>
}* : free

This defines a connector Connector1 that can connect an element node1 to a an element node2. The “simple” keyword specifies the connector’s end is just a link. The “arrow” keyword specifies an arrow as the connector’s end.

It is possible to specify multiple accepted types of nodes on a connector’s end:

<Connector1 {@node1, node2 simple} {@"node." arrow}>

The accepted node can be enumerated, or a regular expression matching the node names specified. In this example, the regular expression “node.” matches both “node1” and “node2”. Thus the Connector1 can connect any node1 or node2 to any node1 or node2.

The color and thickness of the connector can be specified as follow:

<Connector1 #FF0000:1 {@node1, node2 simple} {@"node." arrow}>

The fill color, border color and thickness of connector’s ends can be specified as follow:

<Connector1 {@node1, node2 simple} {@"node." arrow |#FFFFFF|#FF0000:1}>

Legends can be attached to the connector itself. It is specified as a symbol, which must be defined using other grammar rules.

<Connector1 #FF0000:1 ^Legend {@node1 ^LegendO simple} {@node2 ^LegendT arrow}>

In this example, the Legend symbol will be attached as a legend to the connector. The LegendO will be the legend at the connector’s origin end and the LegendT will be the legend at the connector’s target end.

D - Template rules

In order to simplify the writing of repetitive rules, it is possible to write template rules. A template rule takes parameter that can be used in its body. A parameter can be used wherever a string, an number or a color is expected.

MyRectangle($color) -> [[] 150*50 |$color|] ;

In this example, the MyRectangle element takes a parameter named $color that is used to specify the fill color of a rectangle terminal.

Template elements can be referred to as follow:

MyElement -> MyRectangle(#00FF00) ;

III - Toolboxes and Libraries

In the “toolboxes” block, you can have zero or more toolboxes. They will be visually rendered in the same order. A toolbox is expressed as follow:

toolbox "Name" {
}

The name of the toolbox is indicated in a double quoted string. This is the name that will be displayed to the users.

A toolbox can contain one or more elements expressed as follow:

element SymbolName "Visual Name"

The “element” keyword is used to indicate this is a toolbox element. It is followed by the name of the symbol made available by this toolbox element. It can be the name of variable in the grammar, in which case this element will be used to create new visual elements of this kind. It can also be the name of a connector, in which case it will be used to create connections of this kind. The name visible to the uses will be in the double quoted string after the symbol’s name.

The “libraries” block is optional but, if present, it must follow the “toolboxes” block. It can contain zero or more library definition. A library is defined as follow:

library SymbolName "Visual Name"

A library is an area that will display a list of the visual elements already existing that are of the type given by the specified SymbolName. This symbol must be the name of variable in the grammar. The example bellows defines a library that will list all the existing Task visual elements:

library Task “Tasks”

Libraries can be used by the users to add already existing elements to their diagram.

IV - Complete Grammar

public cf text grammar GMIView
{
  options
  {
    Axiom = "view";
    Separator = "SEPARATOR";
  }
  terminals {
    NEW_LINE    -> 0x000D /* CR */
            | 0x000A /* LF */
            | 0x000D 0x000A /* CR LF */
            | 0x2028 /* LS */
            | 0x2029 /* PS */ ;
    WHITE_SPACE    -> 0x0020 | 0x0009 | 0x000B | 0x000C ;
    COMMENT_LINE  -> '//' (.* - (.* NEW_LINE .*)) NEW_LINE ;
    COMMENT_BLOCK  -> '/*' (.* - (.* '*/' .*)) '*/' ;
    SEPARATOR    -> (WHITE_SPACE | NEW_LINE | COMMENT_LINE | COMMENT_BLOCK)+;
    
    INTEGER    -> [1-9] [0-9]* | '0' ;
    COLOR    -> '#' [0-9a-fA-F]+ ;
    NAME    -> [a-zA-Z_] [a-zA-Z0-9_]*;
    PARAMETER  -> '$' NAME ;
    STRING    -> '"' ["]* '"' ;
  }
  rules {
    value_int    -> INTEGER | PARAMETER ;
    value_color    -> COLOR | PARAMETER ;
    value_string  -> STRING| PARAMETER ;
    
    shape_size    -> value_int '*' value_int '<'? ;
    shape_fillcolor  -> value_color? ;
    shape_border  -> (value_color (':' value_int)?)? ;
    shape_drawing  -> ('|' shape_fillcolor '|' shape_border)? ;
    text_font    -> (':' value_string text_font_styles value_int value_color)? ;
    text_font_styles-> text_font_style* ;
    text_font_style  -> 'italic' ;
    text_font_style  -> 'bold' ;
    text_font_style  -> 'underline' ;
    
    rectangle    -> '[' '[' rectangle_round ']' shape_size shape_drawing ']' ;
    rectangle_round  -> value_int? ;
    ellipse      -> '[' '()' shape_size shape_drawing ']' ;
    path      -> '[' path_points shape_drawing ']' ;
    path_points    -> '<' path_point (',' path_point)+ '>' ;
    path_point    -> value_int ',' value_int ;
    image      -> '[' '@' value_string ']' ;
    label      -> '<' value_string shape_size text_font '>' ;
    placeholder_s  -> '<s' STRING shape_size text_font '>' ;
    placeholder_d  -> '<d' STRING shape_size text_font '>' ;
    placeholder_f  -> '<f' STRING shape_size text_font '>' ;
    placeholder_b  -> '<b' STRING shape_size text_font '>' ;
    
    connector    -> '<' NAME shape_border legend connector_end connector_end '>';
    legend      -> '' NAME ;
    legend      -> ;
    connector_end  -> '{' connector_nodes legend connector_style shape_drawing '}' ;
    connector_nodes  -> '@' connector_node (',' connector_node)* ;
    connector_node  -> NAME | STRING;
    connector_style  -> 'simple' | 'arrow' | 'circle' | 'diamond' ;
    
    ordering    -> '' ;
    ordering    -> ;
    layout      -> ':' packing alignment;
    layout      -> ;
    packing      -> 'packed' ;
    packing      -> 'fill' ;
    packing      -> ;
    alignment    -> ;
    alignment    -> 'free' ;
    alignment    -> 'horizontal' ;
    alignment    -> 'vertical' ;
    alignment    -> 'left' ;
    alignment    -> 'right' ;
    alignment    -> 'top' ;
    alignment    -> 'bottom' ;
    alignment    -> 'stack' ;
    alignment    -> 'stack' 'center' ;
    alignment    -> 'stack' 'top' ;
    alignment    -> 'stack' 'bottom' ;
    alignment    -> 'stack' 'left' ;
    alignment    -> 'stack' 'right' ;
    alignment    -> 'stack' 'top' 'left' ;
    alignment    -> 'stack' 'top' 'right' ;
    alignment    -> 'stack' 'bottom' 'left' ;
    alignment    -> 'stack' 'bottom' 'right' ;
    
    concat      -> '{' concat_childs '}' layout ;
    concat_childs  -> element* ;
    optional    -> element '?' ;
    zeromore    -> element '*' ordering layout ;
    onemore      -> element '+' ordering layout ;
    union      -> '{' element ('|' element)+ '}' ;
    
    variable_ref  -> NAME values ;
    values      -> ('(' value (',' value)* ')')? ;
    value      -> INTEGER | STRING | COLOR | PARAMETER ;
    
    element      -> rectangle
            | ellipse
            | path
            | image
            | label
            | placeholder_s
            | placeholder_d
            | placeholder_f
            | placeholder_b
            | connector
            | concat
            | optional
            | zeromore
            | onemore
            | union
            | variable_ref ;
    
    
    rule      -> NAME parameters '->' element ';' ;
    parameters    -> ('(' PARAMETER (',' PARAMETER)* ')')? ;
    
    view      -> 'view' STRING '{' gram toolboxes libraries '}' ;
    gram      -> 'rules' '=>' NAME '{' gram_rules '}' ;
    gram_rules    -> rule* ;
    
    toolboxes    -> 'toolboxes' '{' toolbox* '}' ;
    toolbox      -> 'toolbox' STRING '{' toolbox_elems '}' ;
    toolbox_elems  -> toolbox_elem* ;
    toolbox_elem  -> 'element' NAME STRING STRING? ;
    
    libraries    -> 'libraries' '{' library* '}' ;
    libraries    -> ;
    library      -> 'library' NAME STRING ;
  }
}

Last edited May 11, 2012 at 5:57 AM by lwouters, version 3

Comments

No comments yet.