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="0.15.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: 'GPIO'
eyebrow: 'Docs · Hardware'
lede: 'Drive pins straight from PHP with the built-in gpio extension.'

see_also:
  - { href: './setup-loop.md', meta: '5 min' }
  - { href: 'https://github.com/php-baremetal/php-esp32', label: 'php-esp32', meta: 'external' }

prev: { label: 'Storage', href: './storage.md' }
next: { label: 'Custom extensions',  href: './custom-extensions.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)
- Hardware
  - [GPIO](./hardware/gpio.md)
  - [Storage](./hardware/storage.md)
  - Custom extensions  (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"
The persistent `store_*` writes to flash — don't call `store_set()` on the
hot path, or you'll wear the NVS. Use the in-RAM `mem_*` for per-request state.
@endcallout

Renders as:

Heads up

The persistent store_* writes to flash — don't call store_set() on the hot path, or you'll wear the NVS. Use the in-RAM mem_* for per-request state.

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
  Call `gpio_mode($pin, GPIO_OUTPUT)` before writing — the direction is explicit.
  @enddo
  @dont
  Write to a pin you never configured; it may float, and readers of your
  code can't see what the pin is for.
  @enddont
@enddo-dont

Renders as:

Do

Call gpio_mode($pin, GPIO_OUTPUT) before writing — the direction is explicit.

Don't

Write to a pin you never configured; it may float, and readers of your code can't see what the pin is for.

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="gpio_write" returns="void" visibility="public" /

Renders as:

method · public
returns void
gpio_write

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="pin" type="int" required="true"
  The GPIO number to drive, as printed on the board header.
  @endparam
  @param name="value" type="int" default="0"
  `1` for high, `0` for low.
  @endparam
@endparams

Renders as:

Arguments
pin
int required
The GPIO number to drive, as printed on the board header.
value
int optional default 0
1 for high, 0 for low.

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="index.php"
```php
gpio_mode(2, GPIO_OUTPUT);
gpio_write(2, 1);
```
@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="init-loop, event-driven, web-server"
  @tab index="0"
  The script runs once, top to bottom.
  @endtab
  @tab index="1"
  Define `setup()` and `loop()` — Arduino-style.
  @endtab
  @tab index="2"
  Each HTTP request runs `index.php` fresh.
  @endtab
@endtabs

Renders as:

The script runs once, top to bottom.

Define setup() and loop() — Arduino-style.

Each HTTP request runs index.php fresh.

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
- **Scaffold** a project with `phpflash init my-project`.
- **Write** your sketch.

    ```php
    function loop(): void { gpio_write(2, 1); delay(500); }
    ```

- **Flash** it to the board with `phpflash flash`.
@endsteps

Renders as:

  1. 01

    Scaffold

    Scaffold a project with phpflash init my-project.

  2. 02

    Write

    Write your sketch — define setup() and loop().

  3. 03

    Flash

    Flash it to the board with phpflash flash.

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="0.15.0" date="2026-04-12" /
md inline form

The mem_* store keeps values across requests, in RAM.
<!-- @version-badge type="changed" version="0.15.0" -->

Renders as:

Added in 0.15.0 · 2026-04-12 Changed in 0.15.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 [the overview](./overview.md) for the simpler case.
Anchors are preserved: [the gpio extension](../hardware/gpio.md#pins).
External URLs pass through unchanged: [php.net](https://www.php.net).

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.