Skip to content

Named documents and shared syntax ​

Layup 0.4 implements Layup's shared document language and scoped graph, sequence and state-machine grammars. A file can start directly with a named diagram. An optional layup 1 header asserts the supported source revision; it does not select a dialect. Unknown revisions and non-integer revision numbers are errors. Source files written for 0.3 need migration to this grammar.

The shared language owns comments, values, annotations, names, references and diagram envelopes. type selects a diagram's body grammar. Graph, sequence and state-machine bodies are implemented, including views and presentation steps. Unavailable types are preserved as opaque source with a warning. The replacement grammar is the only source entry point; title-only headers, implicit IDs, bare styling flags and typed arrow lexemes are rejected.

Try a graph ​

Service calls{"languageVersion":1,"diagramId":"services","diagrams":["services"],"manifest":[{"id":"services","diagramType":"graph","status":"selected","reason":null,"annotations":[],"span":{"start":0,"end":381,"line":1,"column":1,"endLine":9,"endColumn":2}}],"targets":[{"diagramId":"services","category":"object","span":{"start":165,"end":213,"line":4,"column":3,"endLine":4,"endColumn":51},"annotations":[{"name":"source","raw":"@source(uri=\"src/worker.rs\", symbol=\"Worker::run\")","arguments":{"symbol":{"value":{"type":"string","value":"Worker::run"},"span":{"start":141,"end":161,"line":3,"column":32,"endLine":3,"endColumn":52},"valueSpan":{"start":148,"end":161,"line":3,"column":39,"endLine":3,"endColumn":52},"nameSpan":{"start":141,"end":147,"line":3,"column":32,"endLine":3,"endColumn":38}},"uri":{"value":{"type":"string","value":"src/worker.rs"},"span":{"start":120,"end":139,"line":3,"column":11,"endLine":3,"endColumn":30},"valueSpan":{"start":124,"end":139,"line":3,"column":15,"endLine":3,"endColumn":30},"nameSpan":{"start":120,"end":123,"line":3,"column":11,"endLine":3,"endColumn":14}}},"span":{"start":112,"end":162,"line":3,"column":3,"endLine":3,"endColumn":53}}]}],"diagnostics":[],"diagram":{"declaration":"diagram","attributes":{"flow-direction":{"value":{"type":"choice","value":"right"},"span":{"start":56,"end":76,"line":1,"column":57,"endLine":1,"endColumn":77},"valueSpan":{"start":71,"end":76,"line":1,"column":72,"endLine":1,"endColumn":77},"nameSpan":{"start":56,"end":70,"line":1,"column":57,"endLine":1,"endColumn":71}},"layout":{"value":{"type":"choice","value":"auto"},"span":{"start":44,"end":55,"line":1,"column":45,"endLine":1,"endColumn":56},"valueSpan":{"start":51,"end":55,"line":1,"column":52,"endLine":1,"endColumn":56},"nameSpan":{"start":44,"end":50,"line":1,"column":45,"endLine":1,"endColumn":51}},"type":{"value":{"type":"choice","value":"graph"},"span":{"start":33,"end":43,"line":1,"column":34,"endLine":1,"endColumn":44},"valueSpan":{"start":38,"end":43,"line":1,"column":39,"endLine":1,"endColumn":44},"nameSpan":{"start":33,"end":37,"line":1,"column":34,"endLine":1,"endColumn":38}}},"path":null,"authoredId":null,"documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"objects":{"object:[\"Worker::run(&self)\"]":{"declaration":"node","attributes":{"style":{"value":{"type":"choice","value":"service"},"span":{"start":200,"end":213,"line":4,"column":38,"endLine":4,"endColumn":51},"valueSpan":{"start":206,"end":213,"line":4,"column":44,"endLine":4,"endColumn":51},"nameSpan":{"start":200,"end":205,"line":4,"column":38,"endLine":4,"endColumn":43}}},"path":["Worker::run(&self)"],"authoredId":"Worker::run(&self)","documentation":null,"sourceLocations":[{"uri":"src/worker.rs","range":null,"symbol":"Worker::run"}],"metadata":{},"annotations":[{"name":"source","raw":"@source(uri=\"src/worker.rs\", symbol=\"Worker::run\")","arguments":{"symbol":{"value":{"type":"string","value":"Worker::run"},"span":{"start":141,"end":161,"line":3,"column":32,"endLine":3,"endColumn":52},"valueSpan":{"start":148,"end":161,"line":3,"column":39,"endLine":3,"endColumn":52},"nameSpan":{"start":141,"end":147,"line":3,"column":32,"endLine":3,"endColumn":38}},"uri":{"value":{"type":"string","value":"src/worker.rs"},"span":{"start":120,"end":139,"line":3,"column":11,"endLine":3,"endColumn":30},"valueSpan":{"start":124,"end":139,"line":3,"column":15,"endLine":3,"endColumn":30},"nameSpan":{"start":120,"end":123,"line":3,"column":11,"endLine":3,"endColumn":14}}},"span":{"start":112,"end":162,"line":3,"column":3,"endLine":3,"endColumn":53}}],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"object:[\"red\"]":{"declaration":"node","attributes":{"style":{"value":{"type":"choice","value":"service"},"span":{"start":96,"end":109,"line":2,"column":18,"endLine":2,"endColumn":31},"valueSpan":{"start":102,"end":109,"line":2,"column":24,"endLine":2,"endColumn":31},"nameSpan":{"start":96,"end":101,"line":2,"column":18,"endLine":2,"endColumn":23}}},"path":["red"],"authoredId":"red","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}}},"relationships":{"relationship:\"dispatch\"":{"declaration":"edge","attributes":{"palette":{"value":{"type":"choice","value":"purple"},"span":{"start":365,"end":379,"line":8,"column":40,"endLine":8,"endColumn":54},"valueSpan":{"start":373,"end":379,"line":8,"column":48,"endLine":8,"endColumn":54},"nameSpan":{"start":365,"end":372,"line":8,"column":40,"endLine":8,"endColumn":47}},"stroke-style":{"value":{"type":"choice","value":"dashed"},"span":{"start":345,"end":364,"line":8,"column":20,"endLine":8,"endColumn":39},"valueSpan":{"start":358,"end":364,"line":8,"column":33,"endLine":8,"endColumn":39},"nameSpan":{"start":345,"end":357,"line":8,"column":20,"endLine":8,"endColumn":32}},"style":{"value":{"type":"choice","value":"calls"},"span":{"start":269,"end":280,"line":5,"column":56,"endLine":5,"endColumn":67},"valueSpan":{"start":275,"end":280,"line":5,"column":62,"endLine":5,"endColumn":67},"nameSpan":{"start":269,"end":274,"line":5,"column":56,"endLine":5,"endColumn":61}}},"path":null,"authoredId":"dispatch","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":"dashed","strokeWidth":null}}}}Copyright © 2017 IBM Corp. with Reserved Font Name "Plex" This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.Service callscallsAPIWorkerDispatch
text
diagram services "Service calls" type=graph layout=auto flow-direction=right {
  node red "API" style=service
  @source(uri="src/worker.rs", symbol="Worker::run")
  node "Worker::run(&self)" "Worker" style=service
  edge dispatch red -> "Worker::run(&self)" "Dispatch" style=calls

  node-style service palette=blue base=node
  edge-style calls stroke-style=dashed palette=purple
}

The first name after diagram, node, group, package, or crate is its required ID. A second quoted string is the display label; otherwise it defaults to the ID. Quoted first names remain IDs. IDs cannot be empty or contain control characters. Keywords and palette names such as node, row and red are contextual and can be IDs. Quote literal true, false and null names.

Styles use attributes such as palette=blue, font-family=mono, text-align=center and stroke-style=dashed. Style declarations belong at diagram level. Bases may refer forward; cycles and duplicates are errors. Attribute order never changes meaning. Use fill-color, stroke-color, text-color, background-color (canvas), and stroke-width for direct paint. Colors can be literal, theme tokens, or {light: COLOR, dark: COLOR} pairs. auto clears a channel override; none removes shape/line paint. Obsolete spellings such as kind, tone, node-kind and edge-kind are rejected.

A named edge ID ... can be referenced by views or steps. Anonymous connections use the endpoints directly. Both accept ->, <-, <-> and -- and one optional quoted caption. source-side and target-side refer to semantic endpoints; for a <- b, the source is b. route-side sets the preferred route side. Text direction and flow direction are separate properties.

Scopes and names ​

Named objects introduce semantic scopes. Rows arrange content without creating a scope:

Scoped caches{"languageVersion":1,"diagramId":"caches","diagrams":["caches"],"manifest":[{"id":"caches","diagramType":"graph","status":"selected","reason":null,"annotations":[],"span":{"start":0,"end":280,"line":1,"column":1,"endLine":7,"endColumn":2}}],"targets":[],"diagnostics":[],"diagram":{"declaration":"diagram","attributes":{"type":{"value":{"type":"choice","value":"graph"},"span":{"start":31,"end":41,"line":1,"column":32,"endLine":1,"endColumn":42},"valueSpan":{"start":36,"end":41,"line":1,"column":37,"endLine":1,"endColumn":42},"nameSpan":{"start":31,"end":35,"line":1,"column":32,"endLine":1,"endColumn":36}}},"path":null,"authoredId":null,"documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"objects":{"object:[\"backend\",\"cache\"]":{"declaration":"node","attributes":{"palette":{"value":{"type":"choice","value":"green"},"span":{"start":124,"end":137,"line":3,"column":58,"endLine":3,"endColumn":71},"valueSpan":{"start":132,"end":137,"line":3,"column":66,"endLine":3,"endColumn":71},"nameSpan":{"start":124,"end":131,"line":3,"column":58,"endLine":3,"endColumn":65}}},"path":["backend","cache"],"authoredId":"cache","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"object:[\"backend\"]":{"declaration":"group","attributes":{},"path":["backend"],"authoredId":"backend","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"object:[\"frontend\",\"cache\"]":{"declaration":"node","attributes":{"palette":{"value":{"type":"choice","value":"blue"},"span":{"start":200,"end":212,"line":4,"column":61,"endLine":4,"endColumn":73},"valueSpan":{"start":208,"end":212,"line":4,"column":69,"endLine":4,"endColumn":73},"nameSpan":{"start":200,"end":207,"line":4,"column":61,"endLine":4,"endColumn":68}}},"path":["frontend","cache"],"authoredId":"cache","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}},"object:[\"frontend\"]":{"declaration":"group","attributes":{},"path":["frontend"],"authoredId":"frontend","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}}},"relationships":{"relationship:\"sync\"":{"declaration":"edge","attributes":{},"path":null,"authoredId":"sync","documentation":null,"sourceLocations":[],"metadata":{},"annotations":[],"paint":{"paletteOrigin":null,"fillColor":null,"strokeColor":null,"textColor":null,"backgroundColor":null,"strokeStyle":null,"strokeWidth":null}}}}Copyright © 2017 IBM Corp. with Reserved Font Name "Plex" This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.Scoped cachesBackendBackend cacheFrontendFrontend cacheSynchronize
text
diagram caches "Scoped caches" type=graph {
  row weights=[1, 1] {
    group backend "Backend" { node cache "Backend cache" palette=green }
    group frontend "Frontend" { node cache "Frontend cache" palette=blue }
  }
  edge sync frontend.cache -> ::backend.cache "Synchronize"
}

backend.cache has two path segments. backend."worker.v2" has a literal second segment containing a dot. "backend.cache" is one literal name. :: starts at the diagram root. Relative lookup searches the current scope and ancestors; once a prefix matches, lookup stays with that object. Siblings can reuse local names. Duplicate names in a scope and ancestor-name shadowing are rejected, including forward declarations.

Bare names use Unicode identifiers with internal single hyphens. Quote dots, slashes, ::, spaces and code punctuation. Case and Unicode spelling are exact.

Comments and values ​

Newlines and semicolons separate statements; a closing brace ends the final statement. // comments work after declarations and /* … */ comments can span lines and nest to 128 levels. Newlines inside block comments do not end statements. Comments never carry annotation semantics. Strings keep comment markers literally and support multiline content and \", \\, \n, \t, \r escapes. Unsupported escapes and unclosed comments/strings are errors.

Values distinguish choices, strings, integers, floats, booleans, null, lists, records and syntactic references. Bare blue is a choice; "blue" is a string. 1 is an integer; 1.0 and 1e0 are floats. Integers preserve exact signed 64-bit negative and unsigned 64-bit nonnegative values. Overflow is an error; quote larger identifiers. Floats must be finite. Geometry validates its own ranges and converts numeric values only when building the renderer model.

Collections allow newlines around separators and trailing commas. Record keys are data strings, can be empty, and do not introduce object IDs. Record keys and attributes cannot repeat. The shared nesting limit is 128, and each annotation is limited to 1 MiB. Formatting preserves numeric spelling, comments, string content, references and statement/event order.

Annotations and extensions ​

Annotations use @name(key=value, ...), with parentheses even when empty. Names may be dotted, such as @company.analysis(...). They attach to the next construct in the same block, including styles, layout and content items. Blank lines and comments preserve attachment; a closing brace does not. Annotations can appear on the same line as their target and never inherit.

text
@source(uri="src/api.rs", symbol="API::run",
  range={start-line: 8, start-column: 1, end-line: 12, end-column: 2})
@source(uri="src/lib.rs", symbol="exports::API")
@doc(text="Accepts a request.")
@company.analysis(confidence=0.92, generated=true, count=9007199254740993)
@meta(namespace="analysis", value={public: true, tags: [entry, "HTTP"], extra: null})
node "API::run(&self)" "API"

@source, @doc and @meta retain strict argument and cardinality checks. Source evidence is repeatable and targets diagrams, objects or relationships; ranges use 1-based lines/scalar columns and an exclusive end. @doc is a singleton and @meta is unique per namespace. These locations describe original code, separately from the declaration's DSL span.

Unknown annotations preserve their name, raw spelling, arguments, repeated occurrences, attachment and spans. They have no rendering effect. A strong unqualified typo such as @sorce receives a warning without being interpreted as @source. Namespaced extensions do not warn merely for being unknown. Opaque reference values in extension arguments are preserved without lookup. A public host schema-registration API remains a separate checkpoint.

Unavailable diagram types ​

text
@company.owner(team=design)
diagram roadmap "Roadmap" type=company.timeline {
  launch => 2027-01-01 ? extension-specific punctuation
}
diagram services "Services" type=graph { node api "API" }

The unavailable diagram retains its envelope and balanced raw body. Braces inside quoted strings or comments do not end the body. Shared quoting/comment boundaries still apply, and malformed boundaries are document errors. Formatting preserves the entire opaque block byte-for-byte. Its ID participates in duplicate checks, and registered envelope annotations still validate.

Rendering defaults to the first supported diagram and warns about all skipped entries. Explicitly selecting an unavailable diagram is an error. Supported siblings are validated before selection, so selecting one cannot hide another supported diagram's errors. --strict makes skip warnings fail CI. A document with no supported diagram can be inspected and formatted but cannot render. Typo hints only use a unique strong match in the same namespace.

Inspect, select and export ​

sh
layup inspect document.layup
layup render document.layup --diagram services --theme auto
layup compile document.layup --diagram services -o services.json
layup lint document.layup --json
layup fmt document.layup --check
js
const inspection = engine.inspect(source);
const scene = engine.compile(source, { diagram: 'services' });
const { output, warnings } = engine.render(source, { diagram: 'services', format: 'html' });

Inspection returns {document, diagnostics} without layout. It exposes the original source, typed diagrams, raw opaque bodies, annotations and value spans. Recovery retains valid siblings and reports independent syntax/lexical errors; the returned partial document does not make erroneous source renderable. CLI inspection writes JSON and exits unsuccessfully if errors are present. Formatting requires valid shared syntax but does not require an available body renderer or successful semantic resolution.

Tagged values in inspection and annotation exports use forms such as {type: "choice", value: "blue"}, {type: "integer", value: "9007199254740993"} and {type: "float", value: 1.0}. Integer strings prevent JavaScript Number rounding; use BigInt(value.value) when arithmetic is needed. Convenience @meta JSON remains ordinary JSON, so use the authoritative tagged annotation values for integers outside JavaScript's exact range. Reference tags distinguish unresolved paths from strings and records.

Scene JSON retains version-1 geometry and adds document metadata: a manifest of supported/selected/skipped diagrams, diagnostics, ordered annotations and annotated non-rendered targets. SVG and HTML carry the same document metadata. Full unavailable bodies are available through inspection, not embedded in rendered exports. Renderer IDs remain opaque; use document.diagramId, objectPath segments and authoredId for authored identity.

Markdown fences accept diagram=services. The playground renders the default supported diagram. Try the scoped example.

Diagram-specific syntax ​

The common grammar dispatches to graph, sequence or state-machine rules. Sequence bodies use participant, actor, named message declarations, loop, optional, alternatives/branch, and participant notes. Message type=call|reply is separate from call delivery=sync|async.

State bodies use state, initial, final, choice, and named transition declarations. Composite states introduce scopes; layout rows/sections do not. Transition event, guard and action are display text.

All supported bodies own views, ordered presentation steps and slide configuration. Graph/state bodies additionally support explicit legends. Use show objects=[...] connections=[...], highlight with the same lists, and speaker-note. A view can override shared slide settings with its own slide size=... declaration.

See the complete syntax reference, sequence guide, state guide, and presentation guide.

Remaining extensions ​

ER bodies, member-port geometry, public annotation-schema registration and structured document JSON input remain separate work. Current analyzer graph JSON and compileModel/renderModel retain their version-one contract. The inspection API exposes the typed body, declaration/property/reference spans and preserved extension data. Rendered document metadata also retains object/connection declaration categories, attributes, source evidence and resolved paint without embedding opaque foreign bodies.

MIT OR Apache-2.0 · Bundled fonts: SIL OFL 1.1