A newer version of the specification is available at this link .

The GRADIFF Specification v0.1-rc9

A Differential File Format for Graphs and Diagrams

Published on:

1. General Information#

1.1. About this Specification#

This specification aims to describe the GRADIFF file format as precisely as possible, to serve as a reference for implementers of software wanting to support GRADIFF. A reference implementation of GRADIFF will be available as at https://codeberg.org/gradis/gradiff-libs.

This document is written in the AsciiDoc markup language. For more information on AsciiDoc, refer to https://asciidoc.org.

The document will contain both free-text descriptions of the various components of a GRADIFF file as well as ABNF snippets for a more formal definition. See https://www.rfc-editor.org/rfc/rfc5234.html for details on ABNF, and https://www.rfc-editor.org/rfc/rfc7405.html for details on the case-sensitive extension of ABNF used throughout this document.

The GRADIFF specification is © 2022 Lucas Hinderberger. It is licensed under the Creative Commons BY-SA 4.0 license. For a summary, refer to https://creativecommons.org/licenses/by-sa/4.0/

As an exception, all examples are published under the terms of CC0 1.0. For a summary refer to https://creativecommons.org/publicdomain/zero/1.0/.

1.2. Purpose and Summary#

The purpose of the GRADIFF file format is to provide a text-based file format for graphs and diagrams which can be easily versioned, stand-alone as well as in a version control system.

To achieve this purpose, GRADIFF is an unambiguous differential file format. This means that a GRADIFF file consists of multiple incremental changes instead of a direct representation of the diagram’s structure, as is the case with most other formats (to retrieve such a structural representation, the changes described in a GRADIFF file must be replayed, a technique known as Event Sourcing). It also means that the GRADIFF specification leaves no room for ambiguities/variations when de/encoding GRADIFF files, such as e.g. leading/trailing zeroes. In other words: One GRADIFF File has only one correct way of being (re-)encoded.

This ensures that diffs between two versions of a diagram remain simple, comprehensible and stable. It also enables standalone versioning of a diagram (meaning without the use of a dedicated version control system) through the use of partial replays.

It is not the purpose of the GRADIFF file format to become a portable and permanent format for diagrams, such as for example SVG or PDF. It is intended as a format used throughout the creation and collaborative editing of diagrams, not for the archival or distribution (to end users) of diagrams.

1.3. Status#

GRADIFF v0.1 will focus on the simplest possible use case: Simple labelled diagrams of boxes and arrows.

Based on GRADIFF v0.1, an MVP version of libgradiff (the reference implementation of GRADIFF) and GRADIS (a graphical editor for GRADIFF diagrams) will be built.

In future iterations, more useful features will be added, such as other shapes, and more styling options.

1.4. Versioning and Compatibility#

The GRADIFF Specification is versioned in a major.minor scheme. There is no Patch version.

Increments of the major version of GRADIFF indicate breaking changes to the format whereas increments of the minor version indicate that new features were added to the format without invalidating GRADIFF files written using older versions of the format. In other words, a valid GRADIFF v1.x file is always also a valid GRADIFF v1.x+1 file, but not necessarily a valid v2.x file.

Caution
For GRADIFF v0.x (i.e. pre-v1.0), new minor-version releases can contain breaking changes. Any breaking changes will be announced in the specification’s changelog.

1.5. Units and Coordinate System#

GRADIFF uses a coordinate system extending from the bottom-left corner of the page outwards in the X (right) and Y (up) directions.

Millimeters are chosen as unit to ensure consistent printing and scaled on-screen rendering, regardless of screen resolution.

For typographical sizing, the unit used is the DTP point (see https://en.wikipedia.org/wiki/Point_(typography)#Desktop_publishing_point).

2. Structure and Parsing#

2.1. Top-level Structure of a GRADIFF file#

A GRADIFF file is a UTF-8 encoded plain-text file with UNIX line endings (line feed).

It consists of a File Header, followed by zero or more Chunks.

For better visual separation, it is required to insert two blank lines before each Chunk.

The final Chunk may be followed by an arbitrary number of blank lines.

This is the ABNF definition for a GRADIFF file:

file = file-header *(2LF chunk) *LF

2.2. File Header#

2.2.1. Structure of the File Header#

The File Header introduces a GRADIFF file with legal and compatibility information.

It consists of an optional section containing legal boilerplate, followed by the Version Line.

This is the ABNF definition for the File Header (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

file-header = [boilerplate LF] version-line

2.2.2. Legal Boilerplate#

At the beginning of a GRADIFF file, you can place legal boilerplate in free-text lines that begin with a hash sign (#).

This is the ABNF definition for the Legal Boilerplate (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”).

boilerplate = 1*[HASH *BPLCHAR LF]

2.2.3. Version Line#

The Version Line is the first line of the File Header. Using the Version Line, GRADIFF implementations can determine if and how they are able to parse a GRADIFF file.

It consists of the word GRADIFF, followed by the version of GRADIFF used. For the present version of GRADIFF, this would for example be:

GRADIFF v0.1

For information about the semantics of the GRADIFF version, please see Section 1.4, “Versioning and Compatibility”.

The permissible range of both major and minor GRADIFF versions is [0;99].

This is the ABNF definition for the Version Line (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

version-line = %s"GRADIFF v" major-version DOT minor-version LF
major-version = 1*2DIGIT
minor-version = 1*2DIGIT

2.2.4. Examples#

A minimal file header
GRADIFF v0.1
A file header with legal boilerplate
# Copyright 2022 John Doe and Contributors <noreply@gradis-project.org>
# SPDX-License-Identifier: CC0-1.0

GRADIFF v0.1

2.3. Chunks#

A Chunk encapsulates a single, coherent set of one or more Changes that was performed on a GRADIFF diagram. A complete diagram is represented by the sum of all Changes represented in all Chunks.

When a GRADIFF diagram is changed, a new Chunk is appended to the diagram’s Chunks. That way, a complete history of changes is preserved.

Besides the Changes themselves, each Chunk also contains metadata about the Change, such as a Timestamp.

Note
The first Chunk in a diagram must start with a CREATE change that creates the Diagram’s Canvas. See Section 4.4, “Canvas” for details.

2.3.1. Structure of a Chunk#

A Chunk is introduced by the sequence [Chunk], and consists of the Chunk’s Metadata Attributes, followed by a separating clear line, concluded by one or more Changes.

The Chunk’s Metadata consists of attributes that may be helpful in analyzing the editing history of a GRADIFF diagram.

This is the ABNF definition for a Chunk (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

chunk = %s"[Chunk]" LF 1*attribute-line LF 1*change

2.3.2. Chunk Metadata#

The Chunk Metadata consists of Attribute Lines, where each Attribute Line is a line of text that contains a Key and a Value.

Note
While in general an Attribute Line is a single line of text, for String Values it can actually span multiple lines, as indicated by the definition of String Values.

The name of an attribute must start with at least one ASCII alphabetic character and it must not be longer than 64 characters.

This is the ABNF definition of an Attribute Line (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of values, please refer to Section 2.5.4, “Value”):

attribute-line = attribute-name COLON SP value LF
attribute-name = ALPHA *63ATTRNCHAR
Note
Implementations must retain the order of all Attributes found in the Chunk when saving a previously loaded file. This is to ensure that diffs remain stable and noise-free.

For a list of available Chunk Metadata Attributes, please refer to Section 3, “Chunk Metadata Attributes”.

2.3.3. Examples#

This is an example for a set of GRADIFF chunks:

[Chunk]
Timestamp: @2022-08-30T17:30:00Z

CREATE boxHello: Box(300, 300, 400, 400)
SET boxHello.Text = "Hello World!"


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T22:00:00Z

CREATE boxFoobar: Box(600, 600, 200, 200)
SET boxFoobar.Text = "Foo, Bar and Baz"
SET boxFoobar.TextColor = FF0000FF

2.4. Changes#

Changes are the atomic building blocks of a GRADIS diagram. Each Change represents a single, small-scale modification to the diagram, such as changing the text or size of an object.

There are six types of Changes:

2.4.1. CREATE#

A CREATE Change creates a new object in the diagram.

When creating an object, you must give it a unique identifier and specify all parameters that are necessary for initializing the object. The concrete parameters for each type of object are specified in the object’s corresponding section in the Section 4, “Object Reference”.

This is the ABNF definition for a CREATE Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definitions of identifiers and values, please refer to Section 2.5.2, “Identifier” and Section 2.5.4, “Value”):

create-change = %s"CREATE" SP identifier COLON SP object-constructor LF
object-constructor = identifier LPAREN [constructor-params] RPAREN
constructor-params = value *(COMMA SP value)

A CREATE Change can look like this:

CREATE boxHello: Box(300, 300, 400, 400)

2.4.2. SET#

A SET Change sets the value of a property of an existing object in the diagram.

This is the ABNF definition for a SET Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of values, please refer to Section 2.5.4, “Value”; for the definition of parameter paths, please refer to Section 2.5.3, “Parameter Path”):

set-change = %s"SET" SP param-path SP EQUAL SP value LF

A SET Change can look like this:

SET boxHello.Text = "Hello World!"

2.4.3. DELETE#

A DELETE Change deletes an object from a GRADIFF diagram.

Note
Deleting objects is only allowed when no other objects refer to them any more. Thus, to for example delete a Point object, you first need to modify the Arrow objects that refer to that Point, e.g. by replacing the Point with another Point or by deleting it from the arrow (if possible).

This is the ABNF definition for a DELETE Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of identifiers, please refer to Section 2.5.2, “Identifier”):

delete-change = %s"DELETE" SP identifier

A DELETE Change can look like this:

DELETE boxHello

2.4.4. RENAME#

A RENAME Change gives an object in a GRADIFF diagram a new identifier. All following Changes must refer to the object using its new identifier. Previous Changes are not affected by a RENAME Change.

This is the ABNF definition for a RENAME Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of identifiers, please refer to Section 2.5.2, “Identifier”):

rename-change = %s"RENAME" SP identifier SP RARROW SP identifier

A RENAME Change can look like this:

RENAME boxHello -> boxBonjour

2.4.5. ARRINSERT#

Some objects in a GRADIFF diagram can have array properties. An ARRINSERT Change inserts a value into the property array at the specified index. If there already is a value at the specified index, it, and any following array elements, will be moved to the next-highest positions; the array will thus be enlarged by one.

This is the ABNF definition for an ARRINSERT Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of parameter paths, please refer to Section 2.5.3, “Parameter Path”; for the definition of array indices, please refer to Section 2.5.1, “Array Index”):

arrinsert-change = %s"ARRINSERT" SP param-path array-index COLON SP value LF

An ARRINSERT Change can look like this:

ARRINSERT fooArrow.Points[1]: "intermediatePointID"

2.4.6. ARRDELETE#

An ARRDELETE Change deletes the element at the given index from a property array.

If there are elements after the deleted element, they will each be moved to the next-lowest positions; the array will thus be shortened by one.

Trying to delete from a non-existing index is not allowed.

This is the ABNF definition for an ARRDELETE Change (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”; for the definition of parameter paths, please refer to Section 2.5.3, “Parameter Path”; for the definition of array indices, please refer to Section 2.5.1, “Array Index”):

arrdelete-change = %s"ARRDELETE" SP param-path array-index LF

An ARRDELETE Change can look like this:

ARRDELETE fooArrow.Points[2]

2.5. Common Definitions#

2.5.1. Array Index#

An array index is used to refer to a particular element of an array.

It consists of the 0-based index, contained in square brackets.

The index must not exceed 999999999.

Note
Implementations must not encode array indices with superfluous leading zeroes. This is to ensure that the diff of a modified GRADIFF file includes only the changes that actually occurred, instead of variations in encoding values that actually have not changed.

This is the ABNF definition of an Array Index (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

array-index = LSQBRACK 1*9DIGIT RSQBRACK

2.5.2. Identifier#

Identifiers are used for naming Attributes, Objects and Properties.

Contrary to String Values, Identifiers are limited in character set and length, with 32 characters being the maximum length for a valid GRADIFF identifier.

Note
When multiple identifiers are specified to be used in conjunction with each other, each of the single identifiers has its own individual length limit.

This is the ABNF definition of an Identifier (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

identifier = 1*32IDCHAR

2.5.3. Parameter Path#

A Parameter Path is used to identify the parameter of a particular Object instance.

It consists of the ID of the object followed by the name of the Parameter, as indicated in the Object Reference (see Section 4, “Object Reference”). Object and Parameter name are separated by a dot.

This is the ABNF definition of a Parameter Path (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”, for the definition of identifiers, please refer to Section 2.5.2, “Identifier”):

param-path = identifier DOT identifier

2.5.4. Value#

Values embody user-defined data e.g. in Attributes or Object Properties.

There are four data types in GRADIFF: Strings, Numbers, Timestamps and Colors.

String Values can contain arbitrary Unicode characters. They are delimited by quotation marks. Quotation marks inside String Values are escaped using a backslash (the same applies to backslashes themselves). They can also be split across multiple lines by way of adding a line feed followed by a space between two pairs of quotation mark-delimited substrings.

Number Values are floating point numbers that must be parsed into IEEE754 double-precision (64-bit) numbers. This means that their range equals that of an IEEE754 double-precision number, unless the range is more restricted in the documentation of the respective Attribute or Object Property. The fractional part of a Number Value may be omitted, if zero. If omitted, the dot that introduces the fractional part must also be omitted. Infinity is expressed by inf or -inf.

Note
Implementations must encode Number Values in a way that uses as few digits as possible (e.g. they must use 1.23 instead of 1.230). Implementations must not convert double-precision numbers to single-precision numbers when saving a previously loaded file.

Timestamp Values are non-quoted strings of the date-time format as described in RFC 3339 (see https://www.rfc-editor.org/rfc/rfc3339.html). They are prepended by an At sign (@) for unambiguous parsing of Values, since a Number Value could otherwise be a prefix of a Timestamp Value. For the avoidance of doubt, Timestamp Values in the context of GRADIFF must use upper-case "T" and "Z" markers as indicated in RFC 3339 and must not use any other separator than "T". Out-of-range values for months, days, hours minute and seconds (e.g. a timestamp referring to hour 25) are not permitted.

Note
Implementations must retain the offset of Timestamp Values when saving a previously loaded file. If the offset is zero, it should be retained whether the zero offset was expressed as +00:00, -00:00 or Z. Also, implementations must encode years, months, days, hours, minutes and seconds with leading zeroes, but must not encode nanoseconds with superfluous trailing zeroes. This is to ensure that the diff of a modified GRADIFF file includes only the changes that actually occurred, instead of variations in encoding values that actually have not changed.

Color Values are hex-encoded RGBA colors with 8 bits per channel, encoded as non-quoted strings of the format #RRGGBBAA.

This is the ABNF definition of a Value (for the definitions of the terminal symbols used, please refer to Section 2.5.5, “Terminal Symbols”):

value = color-value / num-value / str-value / timestamp-value
color-value = HASH 8HEXDIGIT
num-value = [MIN] (1*DIGIT [DOT 1*DIGIT] / %s"inf")
str-value = QUOT 1*(STRCHAR / ESC (ESC / QUOT) / LF SP) QUOT
timestamp-value = AT date-time ; defined in RFC3339, with case-sensitive semantics

2.5.5. Terminal Symbols#

The following terminal symbols are used in ABNF definitions throughout the document:

ALPHA = %x0041-005A / %x0061-007A ; ASCII alphabetic characters
AT = %x0040 ; an At sign (@)
COLON = %x003A ; a colon (:)
COMMA = %x002C ; a comma (,)
DIGIT = %x0030-%x0039 ; a digit (0-9)
DOT = %x002E ; a dot (.)
ESC = %x005C ; a backslash (\) used for escaping
EQUAL = %x003D ; an equal sign (=)
HASH = %x0023 ; an ASCII hash (#)
HEXDIGIT = DIGIT / %x0041-0046 ; A hexadecimal digit, 0-9 or A-F
HYPHEN = %x002D ; a hyphen (-)
GT = %x003E ; a greater-than sign (>)
LF = %x000A ; a line feed
LPAREN = %x0028 ; a left parenthesis
LSQBRACK = %x005B ; a left square bracket ([)
MIN = HYPEN ; alias for HYPHEN, for rules where it is used as a minus sign
QUOT = %x0022 ; an ASCII quotation mark (")
RPAREN = %x0029 ; a right parenthesis
RSQBRACK = %x005D ; a right square bracket (])
SP = %x0020 ; an ASCII space ( )
UNDERSC = %x005F ; an underscore (_)

; Characters valid for use in Attribute Names
ATTRNCHAR = ALPHA / HYPHEN

; Any conceivable Unicode code point except for a line feed
BPLCHAR = %x0000-0009 / %000B-FFFF

; Characters valid for use in identifiers
IDCHAR = ALPHA / UNDERSC

; Any conceivable Unicode code point except for a backslash (\),
; quotation mark or line feed
STRCHAR = %x0000-0009 / %000B-0021 / %x0023-005B / %x005D-FFFF

; A right-facing ASCII arrow (->)
RARROW = DASH GT

Their numbers refer to Unicode code points, not UTF-8 encodings.

3. Chunk Metadata Attributes#

This contains a reference of all Chunk Metadata Attributes that are specified in this version of GRADIFF.

3.1. Required Attributes#

The following attributes are required to be present in every valid GRADIFF Chunk.

3.1.1. Timestamp#

A timestamp that contains the time the corresponding Chunk was added to the GRADIFF diagram.

The instant represented by it must be after or equal to the preceding Chunk’s Timestamp.

For more details on timestamp values, please refer to Section 2.5.4, “Value”.

3.2. Optional Attributes#

3.2.1. Author#

A string value naming the author (or comma-separated authors) of the Chunk.

It is recommended, although not required to use Email/Git-style names with appended email addresses in angled brackets. For example

Author: "John Doe <noreply@gradis-project.org>"

3.2.2. Generator#

A string value containing the name and version of the Software with which the Chunk was created.

There is no prescribed format for the Generator attribute, although it is recommended to keep it simple and use the short name of the software, followed by a space and a v-prefixed semantic version, if possible.

Generator: "GRADIS v1.2.3"

3.3. Custom Attributes#

It is permitted to set additional Chunk Metadata Attributes that are not in the aforementioned list of defined attributes, if and only if their names start with X-. Implementations must retain those header attributes when loading and saving GRADIFF chunks.

4. Object Reference#

This contains a reference of all objects that can be used within GRADIFF files.

4.1. Arrow#

An Arrow is an object that connects a number of Points (see Section 4.5, “Point”) and that has optional labels attached to it (see Section 4.2, “ArrowLabel”).

4.1.1. Constructors#

Default Constructor (Arrow)#

The default constructor of the Arrow type is called with the arguments (StartPointID, EndPointID) and populates the Arrow’s Points property with the two given PointIDs, respectively.

It leaves all other properties of the newly created Arrow to their default values, as indicated in their corresponding documentation.

4.1.2. Properties#

EndTipColor#

The color in which the tip of the Arrow is drawn that points to the end point of the arrow, as a Color Value.

This property defaults to #000000FF (black, non-transparent).

EndTipStyle#

The style in which the tip of the Arrow is drawn that points to the end point of the arrow, as a String Value.

Valid values are one of "EquiliteralTriangle" or "None".

The EndTipStyle defaults to "EquiliteralTriangle".

Interpolation#

The Interpolation property is a String Value that determines how the arrow should connect its Points.

Valid values are one of "Linear" or "Smooth".

The interpolation defaults to "Linear".

LineColor#

The color in which the line of the Arrow is drawn, as a Color Value.

This property defaults to #000000FF (black, non-transparent).

LineStyle#

The style in which the line of the Arrow is drawn, as a String Value.

Valid values are one of "Dashed", "Dotted" or "Solid".

The LineStyle defaults to "Solid".

LineThickness#

The thickness in which the line of the Arrow is drawn, as a Number Value in millimeters.

This also affects the size of the arrow’s tips, which will scale along with the line’s thickness.

The thickness must be positive and nonzero.

The thickness defaults to 0.5mm.

Points#

Points is an array property containing the IDs of all points that are connected by this Arrow, in the order that they are connected.

This array must at all times have at least two entries. Attempting to delete one or both of the last two entries is not permitted.

StartTipColor#

The color in which the tip of the Arrow is drawn that points to the start point of the arrow, as a Color Value.

This property defaults to #000000FF (black, non-transparent).

StartTipStyle#

The style in which the tip of the Arrow is drawn that points to the start point of the arrow, as a String Value.

Valid values are one of "EquiliteralTriangle" or "None".

The StartTipStyle defaults to "None".

4.2. ArrowLabel#

An ArrowLabel is a text label that can be attached to an Arrow (see Section 4.1, “Arrow”).

4.2.1. Constructors#

Default Constructor (ArrowLabel)#

The default constructor of the ArrowLabel type is called with the arguments (ArrowID, Leg, Text).

It leaves all other properties of the newly created ArrowLabel to their default values, as indicated in their corresponding documentation.

4.2.2. Properties#

In addition to the unique properties of ArrowLabels (as listed in this section’s subsections), ArrowLabel includes TextProperties for the text that can be contained in an ArrowLabel. See Section 4.8.1, “TextProperties” for details.

ArrowID#

The ArrowID property contains the ID of the Arrow object to which this ArrowLabel is attached, as a String Value.

This property has no default value, it is initialized using the constructor.

Leg#

The number of the Leg of the Arrow that this label is attached to, as a Number Value.

This must be an integer value in the range of [0,len(Arrow.Points)-2].

This property has no default value, it is initialized using the constructor.

OffsetLateral#

The offset from the center of the Arrow’s leg, orthogonal to its direction, as a Number Value, in millimeters.

This property has the default value 0mm.

For more information about the coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

OffsetLongitudinal#

The offset from the center of the Arrow’s leg, along to its direction, as a Number Value.

The value of this property is a factor of the total length of the leg, without a prescribed limit (although values around -0.5 to 0.5 are considered practical, with deviations until a magnitude of 2.0-3.0 likely being justified in exceptional circumstances).

This property has the default value 0.0.

For more information about the coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

Rotation#

The amount by which the text is rotated relative to the X axis, as a Number Value in degrees, width zero degrees meaning the text is aligned with the X axis.

The valid range for this value is [0.0, 360.0).

This property has the default value 0 degrees.

For more information about the coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

4.3. Box#

A Box is a rectangular-shaped diagram object that can contain text.

4.3.1. Constructors#

Default Constructor (Box)#

The default constructor of the Box type is called with the arguments (X,Y,Width,Height).

It leaves all other properties of the newly created box to their default values, as indicated in their corresponding documentation.

4.3.2. Properties#

In addition to the unique properties of Boxes (as listed in this section’s subsections), Box includes TextProperties for the text that can be contained in a Box. See Section 4.8.1, “TextProperties” for details.

BackgroundColor#

The color with which the background of the Box is filled.

This property defaults to #FFFFFFFF (white, non-transparent).

BorderColor#

The color with which the border of the Box is filled.

This property defaults to #000000FF (black, non-transparent).

BorderThickness#

The thickness of the Box’s border, as a Number Value in millimeters.

If a thickness of zero is specified, the border will not be rendered. Negative thicknesses are not allowed.

This property defaults to 0.5mm.

For more information about the unit used, please refer to Section 1.5, “Units and Coordinate System”.

Height, Width#

The height/width of the Box, as a Number Value in millimeters.

These properties have no default value, they are always set using the constructor.

Their values must be positive and nonzero.

For more information about the unit used, please refer to Section 1.5, “Units and Coordinate System”.

PaddingBottom, PaddingLeft, PaddingRight and PaddingTop#

The inside padding of the Box, as a Number Value in millimeters.

The padding empty space starts at the inside edge of the Box’s border. The thickness of the border is not part of the padding.

The padding defaults to 4mm for all sides of the Box.

For more information about the unit used, please refer to Section 1.5, “Units and Coordinate System”.

X, Y#

The X coordinate of the top-left corner of the Box, as a Number Value in millimeters.

These properties have no default value, it is initialized using the constructor.

For more information about units and coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

4.4. Canvas#

A Canvas determines the size and background of a diagram.

Each diagram must have exactly one Canvas object. Creating more than one Canvas object is not allowed, as well as not creating a Canvas before creating other diagram objects.

The first Chunk in a diagram must start with a CREATE change that creates the Diagram’s Canvas, using one of Canvas’s constructors (see Section 4.4.1, “Constructors”).

The name for the Canvas object can be chosen freely.

4.4.1. Constructors#

Default Constructor (Canvas)#

The default constructor of the Canvas type is called with the arguments (Width,Height).

It leaves all other properties of the newly created canvas to their default values, as indicated in their corresponding documentation.

4.4.2. Properties#

BackgroundColor#

The color with which the background of the Canvas is filled.

This property defaults to #FFFFFFFF (white, non-transparent).

Height, Width#

The height/width of the Canvas, as a Number Value in millimeters.

These properties have no default value, they are always set using the constructor.

Their values must be positive and nonzero.

It is permitted to set the width and/or height to infinity.

For more information about the unit used, please refer to Section 1.5, “Units and Coordinate System”.

4.5. Point#

Point objects mark a point in the diagram that is used for other Objects to refer to. Points are not visible in the rendered diagram, but they are modifiable by the user. Point is an abstract object type, its concrete manifestations are Section 4.6, “PointAbsolute” and Section 4.7, “PointDerived”.

4.6. PointAbsolute#

A PointAbsolute object is a Point (see Section 4.5, “Point”) of which the position is not derived from another object, but fixed to a set of X/Y coordinates.

4.6.1. Constructors#

Default Constructor (PointAbsolute)#

The default constructor of the PointAbsolute type is called with the arguments (X,Y).

4.6.2. Properties#

X, Y#

The X, Y coordinate of the point, as a Number Value in millimeters.

These properties have no default value, it is initialized using the constructor.

For more information about units and coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

4.7. PointDerived#

A PointDerived object is a Point (see Section 4.5, “Point”) of which the position is derived from another object’s position and dimensions.

4.7.1. Constructors#

Default Constructor (PointDerived)#

The default constructor of the PointDerived type is called with the arguments (ParentID, Side).

It leaves all other properties of the newly created PointDerived object to their default values, as indicated in their corresponding documentation.

4.7.2. Properties#

ParentID#

The ID of the parent object of which the position of this point is derived, as a String Value.

This property has no default value, it is initialized using the constructor.

Side#

The side of the parent object, at the center of which the point shall be placed.

Valid values are one of "Bottom", "Left", "Right", "Top".

This property has no default value, it is initialized using the constructor.

OffsetX, OffsetY#

The offset from the center of the Parent Object’s side, in X/Y direction, as a Number Value in millimeters.

These properties default to 0mm.

For more information about units and coordinate system used, please refer to Section 1.5, “Units and Coordinate System”.

4.8. Common Properties#

This section contains properties that are shared by multiple object types.

4.8.1. TextProperties#

TextProperties are used by object types that can contain text. They control the rendering and spacing of text.

FontName#

A String Value containing the name of the font used to render the text, in the format specified by the FontConfig library (for details, please see https://www.freedesktop.org/software/fontconfig/fontconfig-user.html).

FontSize#

The font size, in points.

This property defaults to 12pt.

For more information about the unit used, please refer to Section 1.5, “Units and Coordinate System”.

LineHeight#

The line height is expressed a factor of the normal line height, as a Number Value.

This property defaults to 1.0, the normal line height.

Text#

The text contained in the object, as a String Value.

Text may contain line breaks, which must be rendered accordingly.

If the text’s size exceeds the size of the object, it shall be clipped by removing the overlapping text in accordance to the text’s alignment. This means that for top-aligned text, the bottom shall be clipped, for left-aligned text the right, for center-aligned text both top and bottom / left and right and so on. The padding of the object, if any, must be respected. Text is not allowed to render into the padding space, even if it could otherwise avoid clipping.

This property’s default value is an empty string.

TextColor#

The color with which the text is filled.

This property defaults to #000000FF (black, non-transparent).

TextHAlignment#

The horizontal alignment of the text, as a String Value.

Valid values are one of "Left", "Center" and "Right".

This property defaults to "Center".

TextVAlignment#

The vertical alignment of the text, as a String Value.

Valid values are one of "Top", "Center" and "Bottom".

This property defaults to "Center".

5. Examples#

5.1. An Empty Diagram#

# Copyright 2022 John Doe and Contributors <noreply@gradis-project.org>
# SPDX-License-Identifier: CC0-1.0

GRADIFF v0.1

5.2. A Blank Canvas#

# Copyright 2022 John Doe and Contributors <noreply@gradis-project.org>
# SPDX-License-Identifier: CC0-1.0

GRADIFF v0.1


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T17:30:00Z

CREATE canvas: Canvas(2100, 2970)

5.3. A "Hello World" Example#

# Copyright 2022 John Doe and Contributors <noreply@gradis-project.org>
# SPDX-License-Identifier: CC0-1.0

GRADIFF v0.1


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T17:30:00Z

CREATE canvas: Canvas(1000, 1000)
CREATE boxHello: Box(300, 300, 400, 400)
SET boxHello.Text = "Hello World!"

5.4. Two boxes, connected with a labelled Arrow#

# Copyright 2022 John Doe and Contributors <noreply@gradis-project.org>
# SPDX-License-Identifier: CC0-1.0

GRADIFF v0.1


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T17:30:00Z

CREATE canvas: Canvas(1000, 1000)
CREATE boxHello: Box(300, 300, 400, 400)
SET boxHello.Text = "Hello World!"


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T17:45:00Z

SET boxHello.Height = 200
SET boxHello.Y = 750
CREATE boxBonjour: Box(300, 450, 400, 200)
SET boxBonjour.Text = "Bonjour Le Monde!"


[Chunk]
Author: "John Doe <noreply@gradis-project.org>"
Timestamp: @2022-08-30T17:50:00Z

CREATE ptArrowSrc: PointDerived("boxHello", "Bottom")
CREATE ptArrowDest: PointDerived("boxBonjour", "Top")
CREATE arrow: Arrow("ptArrowSrc", "ptArrowDest")
CREATE lblTranslatesTo: ArrowLabel("arrow", 0, "translates to")