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.
---
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.
| Key | Used for |
|---|---|
title | Browser <title> + H1 if the body's first H1 differs. |
eyebrow | Small all-caps label above the H1. |
lede | One-sentence summary under the H1; also fills <meta description>. |
see_also | Array of related links rendered as a card at the bottom — each entry needs href, optional label + meta. |
prev / next | Manual navigation arrows. Object with href + label. |
---
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' }
---
Callouts
Highlight a note, tip, warning, danger or success block.
variant defaults to note; title is optional.
@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
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.
@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:
Call gpio_mode($pin, GPIO_OUTPUT) before writing — the direction is explicit.
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 … -->).
@method name="gpio_write" returns="void" visibility="public" /
Renders as:
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.
@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:
pin
value
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.
@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.
@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.
@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:
-
01
Scaffold
Scaffold a project with
phpflash init my-project. -
02
Write
Write your sketch — define
setup()andloop(). -
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.
@divider eyebrow="Advanced"
For the curious — the bits below are not required for everyday usage.
@enddivider
Renders as:
Advanced
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.
@version-badge type="added" version="0.15.0" date="2026-04-12" /
The mem_* store keeps values across requests, in RAM.
<!-- @version-badge type="changed" version="0.15.0" -->
Renders as:
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.
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.
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