Privacy Diagram Scripting Language. One plain-text document describes everything the diagram maker canvas can produce, and round-trips losslessly through save and load.
v3 • Updated June 2026Paste this into the diagram maker's PDSL import dialog. The pdsl 3 header on the first
line is required: it is how the app recognizes the format.
pdsl 3
canvas 1200x700
theme light
# A card with a title and an arrow pointing away from it
rect card at 100,100 size 240x120 rx 12
fill #dbeafe
stroke #1d4ed8
width 2
text title at 130,140 "Hello PDSL v3"
font Inter 22 bold
color #1e3a8a
arrow a1 from 340,160 to 500,160
Everything compiles to ordinary canvas objects, so after import you can select, move, restyle, and delete every element with the normal tools. Nothing leaves your browser.
Try it NowA PDSL v3 document is plain UTF-8 text, parsed line by line. Indentation creates blocks: two spaces
are recommended, and tabs are not allowed. A line whose first non-space character is # is
a comment. Z-order is document order, so later objects render on top.
pdsl 3 # version header, required, must come first
canvas 1920x1080 # logical canvas size
theme light # light dark corporate vibrant pastel nature
background #ffffff # optional background color
grid 20 snap # optional; grid size, optional snap flag
style myCard # reusable property bundle
fill #f0fdf4
stroke #15803d
# ... objects and flow blocks ...
asset @logo image/png base64 # embedded binary, referenced via src @logo
iVBORw0KGgoAAAANSUhEUgAA...
| Directive | Syntax | Description |
|---|---|---|
pdsl |
pdsl 3 |
Version header. Required for format detection. |
canvas |
canvas WxH |
Logical canvas size in canvas units. |
theme |
theme <name> |
Default palette for flow blocks. See the theme table below. |
background |
background #hex |
Optional canvas background color. |
grid |
grid N [snap] |
Optional grid size; add snap to enable snapping. |
A style block names a reusable bundle of property lines. Apply it to any object with
use <style-name>. You can apply several styles to one object; when they conflict,
the later use line wins, and properties written directly on the object win over both.
style accent
fill #fef3c7
stroke #d97706
width 2
rect r1 at 80,80 size 200x100 rx 10
use accent
ellipse e1 at 340,80 size 160x100
use accent
opacity 80
Use spaces only (two per level is the convention). A tab character anywhere is a syntax error. Unknown keywords or properties produce warnings, not errors: the parser recovers and renders what it understands, and every diagnostic carries a line number.
The general form is <kind> [id] <inline args> followed by an indented block of
property lines (and child objects for group). The id is optional when you write a
document by hand; the serializer always assigns one on save. Coordinates are canvas units with the
origin at the object's top-left corner. size is the object's natural width and height;
resizing done with the selection handles is stored separately in scale.
| Kind | Inline args | Notes |
|---|---|---|
rect |
at x,y size WxH [rx N] |
Rounded corners via rx / ry. |
ellipse |
at x,y size WxH |
Size is the full bounding box. |
triangle |
at x,y size WxH |
|
polygon |
at x,y points <spec> |
Spec is [x y, x y, ...] or a named generator: diamond,
star, hexagon (the toolbar shapes, radius 50). |
line |
from x1,y1 to x2,y2 |
|
arrow |
from x1,y1 to x2,y2 [head N] |
Compiles to the UI's line plus triangle group; head size defaults to 15 plus the stroke width. |
path |
at x,y |
Freehand pencil strokes; the outline goes in a d "<svg path data>" property
line. |
text |
at x,y "content" |
Newlines are escaped as \n. |
sticky |
at x,y [size WxH] [color #hex] "content" |
The UI sticky note (a rect plus text group). |
image |
at x,y size WxH src @asset |
src may also be a quoted data URL. |
icon |
<lib>:<name> at x,y [size N] |
Resolved against the icon manifest. Libraries: tabler, aws,
azure, gcp. |
group |
at x,y |
Children are indented object statements with coordinates relative to the group's top-left. |
mermaid |
at x,y [scale N] |
The indented block is verbatim Mermaid source, re-rendered on load. |
object |
none | Escape hatch with a json "<fabric JSON>" property. Emitted by the
serializer when it meets an object it cannot map, so saving never drops content. |
# A few literal objects side by side
polygon d1 at 600,60 points diamond
fill #fef3c7
stroke #d97706
sticky n1 at 80,80 size 180x180 color #fef08a "Brainstorm:\nship the v3 docs"
icon tabler:bulb at 300,90 size 48
group g1 at 400,80
rect bg at 0,0 size 220x90 rx 8
fill #ffffff
stroke #9ca3af
text t1 at 16,30 "Grouped content"
font Inter 16
mermaid m1 at 650,260 scale 1
graph TD
A[Start] --> B{Decision}
B -->|yes| C[Ship it]
Property lines go in the indented block under an object. All are optional; defaults match the UI
defaults (stroke #000000, fill #ffffff, width 2, opacity 100).
| Property | Syntax | Description |
|---|---|---|
fill |
fill #hex | transparent |
Fill color, or no fill. |
stroke |
stroke #hex |
Outline color. |
width |
width N |
Stroke width, 0 to 20 in the UI. |
opacity |
opacity N |
0 to 100. |
shadow |
shadow #hex blur N offset X,Y |
Drop shadow. |
angle |
angle N |
Rotation in degrees. |
scale |
scale X[,Y] |
Scaling applied via the selection handles. |
skew |
skew X,Y |
Skew transform. |
flip |
flip x | y | xy |
Mirror horizontally, vertically, or both. |
font |
font <family> <size> [bold] [italic] [underline] |
Text font. Quote multiword family names, e.g. font "Courier New" 18. |
align |
align left | center | right |
Text alignment. |
color |
color #hex |
Text fill color. |
rx / ry |
rx N / ry N |
Rect corner radii. |
d |
d "<svg path data>" |
Path outline for path objects. |
src |
src @asset | "<data url>" |
Image source: an embedded asset reference or a quoted data URL. |
points |
points [x y, x y, ...] |
Explicit polygon vertices. |
use |
use <style-name> |
Apply a style block. May repeat; later wins. |
| placement | at x,y / size WxH / from x,y / to x,y |
The inline placement args are also accepted as property lines. |
A flow block declares nodes and edges; the compiler lays them out and emits ordinary
literal objects (groups of rect, text and icon, plus arrow groups). The result is fully editable on
the canvas. Flow blocks are one-way sugar: once compiled and re-saved, the document contains the
literal objects, not the flow block.
flow backend
layout hierarchical gap 60 # hierarchical | flow | grid
theme dark # optional, overrides the document theme
node api "API Gateway" icon aws:api-gateway
node fn "Lambda" icon aws:lambda
node db "Orders" shape database
api -> fn label "invoke"
fn -> db
api <-> fn # bidirectional arrow
fn -- db # plain line, no arrowheads
Each node <id> accepts, in any order: a quoted "label",
icon lib:name, shape rect|ellipse|diamond|database, at x,y
(pins the node and skips layout for it), and size WxH. An indented property block under
the node applies style overrides to the generated shape.
Edges connect node ids with -> (arrow), <-> (bidirectional), or
-- (plain line). Options: label "..." and route straight.
route ortho and route curve are reserved for a future version; today they
fall back to straight with a warning.
Declared with layout <algo> [gap N]. The default is flow with a gap of
60. Default node size is 160x70. Nodes pinned with at x,y keep their position; the
algorithm only places the unpinned ones.
| Algorithm | Behavior |
|---|---|
hierarchical |
Layers nodes top to bottom following edge direction (longest-path layering; cycles are broken by visit order). Each layer is horizontally centered. Best for pipelines and org-chart style diagrams. |
flow |
A single left-to-right row, vertically centered. Best for short linear sequences. |
grid |
A roughly square grid in declaration order. Best for catalogs and unconnected node sets. |
The document theme directive (or a per-flow theme override) sets the palette
used for generated nodes and edges.
| Theme | Palette |
|---|---|
light |
White background, dark gray nodes and text. |
dark |
Near-black background, light text, blue node outlines. |
corporate |
Professional blue palette on off-white. |
vibrant |
Pink and magenta accents on white. |
pastel |
Soft amber and cream tones. |
nature |
Green and earth tones. |
PDSL v3 files are self-contained. Uploaded images embed as base64 asset blocks and are
referenced from image objects via src @<name>. Nothing is fetched
from the network on load except same-origin icons.
image logo at 40,40 size 128x128 src @logo
asset @logo image/png base64
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHL...
...more base64 lines...
The asset body is the base64 payload split across indented lines. When you save from the diagram maker, the serializer writes these blocks for you; you rarely need to author them by hand.
pdsl 3
canvas 1600x900
theme corporate
flow checkout
layout hierarchical gap 60
node web "Web App" icon tabler:browser
node api "API Gateway" icon aws:api-gateway
node pay "Payments" icon aws:lambda
node store "Orders DB" shape database
web -> api label "HTTPS"
api -> pay label "charge"
pay -> store label "persist"
pdsl 3
canvas 1000x600
theme light
grid 20 snap
style card
fill #f0fdf4
stroke #15803d
width 2
rect a at 80,80 size 200x100 rx 10
use card
ellipse b at 360,80 size 160x100
use card
opacity 80
polygon c at 600,60 points diamond
fill #fef3c7
stroke #d97706
arrow a1 from 280,130 to 360,130
arrow a2 from 520,130 to 600,130 head 14
text caption at 80,240 "Rect, ellipse, diamond"
font Inter 18 bold
color #1f2937
pdsl 3
canvas 1200x700
theme pastel
background #fffbeb
text heading at 60,40 "Sprint Retro"
font Inter 32 bold
color #78350f
sticky went at 60,120 size 200x200 color #bbf7d0 "Went well:\nv3 shipped"
sticky meh at 300,120 size 200x200 color #fef08a "Could improve:\ndocs lagged"
sticky next at 540,120 size 200x200 color #fecaca "Action:\nupdate templates"
icon tabler:checklist at 820,140 size 64
pdsl 3
canvas 1400x800
theme dark
background #111827
text title at 60,40 "Order pipeline"
font Inter 28 bold
color #f9fafb
flow pipeline
layout flow gap 80
node in "Intake"
node chk "Validate" shape diamond
node out "Fulfill"
in -> chk
chk -> out label "ok"
rect legend at 60,600 size 320x80 rx 8
fill transparent
stroke #9ca3af
text note at 80,625 "Diamond = decision point"
font Inter 14
color #9ca3af
pdsl 3 on the first line; without it the text is
treated as a legacy format.#4299e1, not blue.\n.at x,y when you need exact placement.PDSL v3 replaces the older PDDSL v6 and PDSL v2 languages. Existing documents in those formats keep
working: the import dialog auto-detects the format, so any text without a pdsl 3 header
is routed through the legacy import path and rendered as before. New documents and everything the app
saves use v3.