The .vd format
A vDesign document is one file with the extension .vd. It is plain UTF-8 text, in two
parts: a head, which is the design, and an optional payload, which carries the bytes
of any images the design uses.
The head
The head is the design, written in the vDesign DSL, one statement per line: the header
(version, kind, title), then tokens, fonts and assets, then the nodes, and after the last
page an optional motion section. An indented line belongs to the line above it: a node’s
children, the quoted runs of a text node, a font’s fallback.
versionis the format version, andkindsays what sort of document this is. Both are always written, on the first two lines, so a reader knows before anything else whether it can read the rest. Today there is one kind,design.titlenames the document.- Lines starting
$are tokens: named values the rest of the document reads. fontandassetlines declare the fonts and images the design uses; Expressions covers both.- A line that opens with a node type is a node:
frame,rect,textand the rest, each with an id and its properties. The quoted lines indented under atextnode are its words. Nodes lists every type. - Top-level frames play, and export, in the order they are written; the app’s thumbnail strip shows and changes that order.
- A
motionsection after the last page says how Play presents the document; see Motion.
A property holds a number or an expression, and an expression is kept as written. In the
example, w=(100% - $gap * 2) stays that formula in the file. Change $gap and everything
that reads it moves, in the file as well as on the canvas.
Expressions covers the language.
The payload
Pictures are bytes, not text, so they go after the design. The head declares each image as
an asset line with its media type, size and content hash; below the head, a line reading
--- payload base64 --- begins the payload, which is one line per asset: its hash, a space,
and its bytes in base64.
asset logo = image/png hash=sha256-9f2c… bytes=24567
frame page w=1280 h=720
image page.logo x=40 y=32 w=160 h=48 src=logo fit=contain
--- payload base64 ---
sha256-9f2c… iVBORw0KGgoAAAANSUhEUgAA…
A document with no images has no payload.
Why it is shaped this way
- It streams. A finished line is a finished node, so a design can be drawn while a model is still writing it, or while the file is still downloading. The head declares every asset’s size before any bytes arrive, so the layout can reserve room for a picture that has not loaded yet.
- It stays a text file.
diff,grepand version control work on it. A change to the design is a change of a few lines, even in a file carrying large images, because each image is one line at the end. - Edits are small. A model changes a document with
statements such as
set $gap = 40rather than writing the file again. One line where regenerating would be forty, and the relationships in the document survive the change. - Truncation costs pictures, not the design. A file cut short in its payload still has its whole head.
The cost, accepted: the payload is not for editing by hand, and saving rewrites the whole file.
Reading and writing it yourself
Anyone may implement the format, free of charge; see the licence. These pages, with the examples, are the specification.