Plugin ABI v1
A Markup Poet plugin is a WebAssembly module executed by the Chasm runtime. No imports are allowed — modules requiring WASI or host functions are rejected at load; a plugin is pure compute over JSON envelopes (no filesystem, no network, no clock). This page is the normative ABI; for a walkthrough see Write a WASM plugin.
Required exports
| Export | Signature | Purpose |
|---|---|---|
|
linear memory |
Shared data buffer |
|
|
Host asks the plugin to reserve memory |
|
|
Host returns memory to the plugin |
|
|
Returns the descriptor payload |
|
|
Handles one invocation; |
|
|
Optional init hook |
|
|
Optional shutdown hook |
Payload protocol
Every payload crossing the boundary is a 4-byte little-endian length prefix
followed by UTF-8 JSON. Payloads are capped at 1 MB (64 KB for the
descriptor); PluginEngine(PluginLimits(…)) customizes the caps. The host
writes an invocation via plugin_alloc + memory writes, calls
process(ptr, len), reads the length-prefixed response at the returned
pointer, then returns both buffers via plugin_dealloc. A plugin whose
invocation fails is poisoned and refuses further calls.
Descriptor (plugin_info)
{
"abiVersion": 1,
"id": "shout-plugin",
"name": "Shout",
"version": "0.1.0",
"description": "Uppercases the content of [shout] blocks",
"capabilities": [ { "type": "block", "name": "shout" } ],
"metadata": {}
}
Capability type is one of block, blockMacro, inlineMacro, converter.
Invocation (host → plugin)
{
"abiVersion": 1,
"extensionPoint": "block",
"name": "shout",
"attributes": { "1": "shout" },
"content": "raw block body or macro target",
"documentAttributes": { "toc": "" },
"location": { "line": 12, "column": 1 }
}
-
attributescarries the construct’s own attributes: positional attributes keyed by their 1-based index plus the named attributes. -
For
blockMacroandinlineMacro, the macro target is additionally available asattributes["target"], andcontentis the target. -
For
converter,contentis the claimed node serialized as official ASG node JSON (see below).
Response (plugin → host)
{
"ok": true,
"replacement": { "contentType": "html", "value": "<div class=\"shout\">…</div>" },
"warnings": []
}
contentType |
Host behavior |
|---|---|
|
The host re-parses |
|
Spliced as a raw passthrough block |
|
Official ASG node JSON: |
ok: false + error: the host leaves the original construct untouched and
surfaces the error as a processing warning.
Converter invocations
A converter capability plugs into HTML rendering, not document processing.
The host registers it as a custom renderer under its capability name
(block style, e.g. gallery, or ASG node kind, e.g. ListBlock — style
wins). The invocation’s content is the claimed node as official ASG node
JSON (the node-level encoding of asciidoc-asg’s
`AsgDocumentJsonSerializer), and documentAttributes carries the resolved
document attributes.
The response must be { "contentType": "html", "value": "…" }; the value
is emitted verbatim in the node’s place. Any failure — ok: false, another
content type, or a node with no official ASG form — renders as nothing plus a
rendering warning.