DMD reference
Authoring guide · DMD

DMD — Docs Markdown Directives

Write your package documentation as Markdown files under docs/ at the root of your repo. This page is a complete reference of the directives available on top of plain CommonMark — each section shows the source you would write next to the result that ends up on the docs site.

Introduction

DMD is plain CommonMark plus a small set of block directives that start with @. If your file doesn't use any of them, it renders exactly as CommonMark. Directives are additive — pick the ones that fit the page you're writing, ignore the rest.

Three shapes show up in this reference:

  • Block directives open and close on their own lines (@callout … @endcallout).
  • Inline directives are HTML comments (<!-- @version-badge … -->) that flow with the surrounding text.
  • Self-closing directives have no body and end with a slash (@version-badge type="added" version="v4.3.0" /).

Page structure

Each docs page is a single .md file. The first # heading becomes the page title; every ## heading appears in the right-side "On this page" navigation. Subdirectories under docs/ become URL segments.

md docs/connection/opening-and-closing.md

---
title: 'Opening and closing'
eyebrow: 'Docs · Connection'
lede: 'How to open a session and tear it down cleanly.'
---

# Opening and closing

## Open

Plain CommonMark goes here.

## Close

More CommonMark.

Frontmatter

Optional YAML block at the top of the file. Use it to set the page title, summary, related-links footer and prev/next arrows. Every key is optional — leave the block out entirely if you don't need it.

KeyUsed for
titleBrowser <title> + H1 if the body's first H1 differs.
eyebrowSmall all-caps label above the H1.
ledeOne-sentence summary under the H1; also fills <meta description>.
see_alsoArray of related links rendered as a card at the bottom — each entry needs href, optional label + meta.
prev / nextManual navigation arrows. Object with href + label.
yaml frontmatter example

---
title: 'Subscriptions'
eyebrow: 'Docs · Operations'
lede: 'Open a subscription, attach monitored items, consume notifications.'

see_also:
  - { href: './monitored-items.md', meta: '5 min' }
  - { href: 'https://opcfoundation.org/specs/part4', label: 'OPC UA Part 4', meta: 'external' }

prev: { label: 'Calling methods', href: './calling-methods.md' }
next: { label: 'Monitored items',  href: './monitored-items.md' }
---

index.md & sidebar

The file docs/index.md defines the left-side navigation of your documentation. Write it as a nested bullet list: top-level bullets become group titles; nested bullets become page entries. A plain-text entry is a placeholder (not yet written); [Label](./path.md) turns into a real link.

md docs/index.md

- Getting started
  - [Overview](./overview.md)
  - [Installation](./getting-started/installation.md)
  - [Quick start](./getting-started/quick-start.md)
- Operations
  - [Reading](./operations/reading.md)
  - [Writing](./operations/writing.md)
  - Subscriptions  (placeholder, not yet written)

Callouts

Highlight a note, tip, warning, danger or success block. variant defaults to note; title is optional.

md source

@callout variant="warning" title="Heads up"
Subscriptions hold server resources — always close them
in a `finally` block or via the session destructor.
@endcallout

Renders as:

Heads up

Subscriptions hold server resources — always close them in a finally block or via the session destructor.

Available variants: note · info · tip · success · warning · danger.

Do / Don't

Side-by-side good/bad example. Body must contain exactly one @do and one @dont block.

md source

@do-dont
  @do
  Use `NodeId::numeric(0, 2259)` — namespace + identifier are explicit.
  @enddo
  @dont
  Pass `'i=2259'` as a string; the encoder will still accept it,
  but readers of your code can't see the namespace.
  @enddont
@enddo-dont

Renders as:

Do

Use NodeId::numeric(0, 2259) — namespace + identifier are explicit.

Don't

Pass 'i=2259' as a string; the encoder will still accept it, but readers of your code can't see the namespace.

Method signatures

Compact pill that introduces a function or method. Often pairs with a following @params block. Available as block (@method … /) and inline (<!-- @method … -->).

md source

@method name="Client::read" returns="DataValue" visibility="public" /

Renders as:

method · public
returns DataValue
Client::read

Parameter lists

Structured argument reference. @params wraps one or more @param children; each child supports name, type, required, default attributes plus a free-form description in the body.

md source

@params heading="Arguments"
  @param name="nodeId" type="NodeId" required="true"
  The node to read. Construct with `NodeId::numeric()` or `NodeId::string()`.
  @endparam
  @param name="attribute" type="int" default="13"
  OPC UA attribute id — `13` (`Value`) is the most common.
  @endparam
@endparams

Renders as:

Arguments
nodeId
NodeId required
The node to read. Construct with NodeId::numeric() or NodeId::string().
attribute
int optional default 13
OPC UA attribute id — 13 (Value) is the most common.

Code blocks

@code-block wraps a fenced code block with the docs chrome: terminal-style header, language pill, optional label, and a copy-to-clipboard button. Body must contain exactly one fenced block.

md source

@code-block language="php" label="examples/read.php"
```php
$client = ClientBuilder::create()->connect('opc.tcp://localhost:4840');
$value = $client->read(NodeId::numeric(0, 2259));
```
@endcode-block

Supported languages: php, bash, text, yml, cs, blade.php. Other languages get rendered without syntax highlighting — write them as plain CommonMark fenced code blocks instead.

Tabs

Switch between alternative views of the same content (often per-language code samples). labels is a comma-separated list; the number of labels must match the number of @tab children, indexed from zero.

md source

@tabs labels="Laravel, Symfony, Plain PHP"
  @tab index="0"
  Use the `Opcua` facade — `Opcua::read(...)`.
  @endtab
  @tab index="1"
  Inject `OpcuaManager` from the container.
  @endtab
  @tab index="2"
  Build the client by hand via `ClientBuilder::create()`.
  @endtab
@endtabs

Renders as:

Use the Opcua facade — Opcua::read(...).

Inject OpcuaManager from the container.

Build the client by hand via ClientBuilder::create().

Steps

Numbered walkthrough. The body MUST be a single Markdown list (bulleted or ordered); each item becomes a numbered step. A leading **title** on the item becomes the step heading; the rest is the body.

md source

@steps
- **Install** the package with `composer require php-opcua/opcua-client`.
- **Connect** to your server.

    ```php
    $client = ClientBuilder::create()->connect('opc.tcp://localhost:4840');
    ```

- **Read** a node and inspect the data value.
@endsteps

Renders as:

  1. 01

    Install

    Install the package with composer require php-opcua/opcua-client.

  2. 02

    Connect

    Connect to your server with ClientBuilder::create()->connect(...).

  3. 03

    Read

    Read a node and inspect the data value.

Section divider

Visual break between major topical groups inside a page. eyebrow is the small all-caps label; the body is a one-line description.

md source

@divider eyebrow="Advanced"
For the curious — the bits below are not required for everyday usage.
@enddivider

Renders as:

Advanced

For the curious — the bits below are not required for everyday usage.

Version badge

Marker for "Added in vX.Y", "Changed in vX.Y" or "Deprecated since vX.Y". Block form (@version-badge … /) renders as a standalone pill; inline form (<!-- @version-badge … -->) flows with surrounding text.

md block form

@version-badge type="added" version="v4.3.0" date="2026-04-12" /
md inline form

Subscriptions reuse the same session token across reconnects.
<!-- @version-badge type="changed" version="v4.3.0" -->

Renders as:

Added in v4.3.0 · 2026-04-12 Changed in v4.3.0 Deprecated in v4.2.0

Supported type values: added · changed · deprecated.

Keyboard keys

Use the standard HTML <kbd> element inline. It's restyled to look like a physical keyboard key — no DMD directive needed.

md source

Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to stop the daemon.

Renders as:

Press Ctrl + C to stop the daemon.

Cross-references

Use relative Markdown links to point at other pages in your docs — the same way you would in any GitHub README. Links to .md files are turned into the correct version-pinned URL automatically, anchors are preserved, and external URLs pass through unchanged.

md source

See [Reading values](./reading.md) for the simpler case.
Anchors are preserved: [security policies](../security/policies.md#ecc).
External URLs pass through unchanged: [OPC Foundation](https://opcfoundation.org).

Authoring tip

Always write relative links — never hard-code absolute paths into the docs site. The same file then works on every release tag of your package without edits.