SQLBI Whiteboard
Reference

The .wimport format

A Markdown recipe that builds image and text containers. It is not a board file. There is no export back to .wimport. After import you rearrange, draw, and save a .wboard.

This page is the public edition of the in-repo contract docs/wimport.md. Authors and agents should treat the two as the same grammar. A sample workshop lives next to that file.

The file must be valid CommonMark so it previews in VS Code and GitHub without a custom renderer. Associate the extension if the editor does not treat it as Markdown:

"files.associations": { "*.wimport": "markdown" }

Produce this

Heading grammar

LineMeaning
# TitleOptional board title. At most one. Not a container. Ignored if it appears after the first ##.
## TitleStarts a container. The heading text is the container title.
### and deeperStay inside the current container body. They do not start a new object.
---, ***, or ___ on its own lineThematic break. Starts a new row of containers. Not a container.
Any other line before the first ##Documentation for the preview. Not imported.

An empty ## heading is titled Text.

How the body becomes a container

Recognizers run in this order. The first match wins. Extra material after the match is ignored.

  1. Markdown image: ![optional alt](relative/path.png). Image container. Title is the ## heading, then the alt text, then the file name. Allowed extensions: .png, .jpg, .jpeg, .bmp, .gif, .svg. An .svg stays vector on the board, so give it a width/height or a viewBox to be sized from; anything it fetches from elsewhere is ignored.
  2. Fenced code whose info-string is a registered language. Text container. Contents of the fence. Language from the tag.
  3. Markdown link to an image extension: same as an image.
  4. Markdown link to a registered language extension: [label](relative/path.dax). Text container. File contents. Language from the extension.
  5. Any remaining text: text container. The Markdown source is stored as plain text. Whiteboard does not render Markdown.
  6. Empty body: the heading is skipped.

Do not put an image and a measure under the same ##. Use two headings.

A fenced block whose tag is unknown (for example python today) is not a language container. The whole body, fence included, becomes plain text.

Languages shipped today

LanguageFence info-stringFile extensions
DAXdax.dax
SQL Serversql, tsql.sql

Further languages will be extra rows in this table. Do not invent fence tags Whiteboard does not list here: they import as plain text. Linked text files larger than 1 000 000 bytes are skipped and reported as missing.

Layout

Whiteboard measures each container, then packs them left to right. A thematic break starts a new row even if the current row is not full. Without a break, a row wraps when the next item would exceed about 2400 world units.

On drop, the group’s top-left is the pointer. On Open or toolbar Import, the group’s top-left is the top-left of the visible view. Do not put coordinates in the file. There is no pos:, no YAML front matter, and no HTML comment layout.

How the file is opened

ActionResult
Drop onto an open boardContainers are added. Pointer is the group top-left. Undo is one step.
Import (toolbar)Containers are added at the visible top-left.
File → Open, or double-clickNew untitled board, then import. Save / Save As writes .wboard only. The .wimport path is used only to resolve relative links.

Missing or unreadable linked files are skipped. Whiteboard then shows a dialog listing the resolved paths, which can be copied.

Template

# Optional board title

Optional notes for the Markdown preview. Not imported.

## Container title for an image
![short alt](./images/diagram.png)

## Container title for notes
- Bullet one
- Bullet two

---

## Container title for embedded DAX
```dax
Total Sales := SUM(Sales[Amount])
```

## Container title for linked SQL
[Top customers](./sql/top-customers.sql)

Checklist

Do not