Authoring Guide (Template)
How to regenerate the kbox-stack documentation for a new version or add a new platform section using this template.
This documentation set is a template. Every page is written so a future maintainer can regenerate it for a new stack version, or extend it for a new hardware platform, by following a small set of rules. This page is those rules.
How the docs are organised
The docs separate the portable core from platform-specific content on purpose:
- Core pages (version root, e.g.
content/docs/v1.0.0/) describe the MCU-agnostic API and design. They never assume a specific chip — they use interface types (IBusDriver&,IFlash&) and defer hardware details to a platform section. - Platform sections (subfolders, e.g.
platform-stm32-hal/) hold everything hardware-specific: concrete drivers, build/flash steps, and board details.
The rule of thumb: if a sentence names a chip, a toolchain, a linker address, or a HAL type, it belongs in a platform section — not in a core page.
The fill-in markers
Every page carries invisible JSX comment markers ({/* … */}). They never render, and they
are greppable so you can tell, mechanically, when a page is finished. There are three kinds:
| Marker | Meaning | What to do |
|---|---|---|
{/* TEMPLATE: … */} | Guidance for the author of a section | Follow it, then delete the marker |
{/* FILL:<field> — … */} | A value that must be supplied this version | Replace with the real value, delete the marker |
{/* VERIFY:<source> — … */} | A fact that may drift between versions | Re-check it against the named header/source, then delete the marker |
Use JSX comments {/* … */}, never HTML comments <!-- … -->. HTML comments break the Fumadocs
MDX parser and the page will fail to build. Also, never put the two-character sequence */ inside
a marker (for example a glob path like Peripheral/*/Foo) — it closes the comment early and breaks the
page. Reword to avoid it (say "under Peripheral" instead of Peripheral/*/).
Finished-page gate — before publishing a filled version, no markers may remain:
grep -rn "TEMPLATE:\|FILL:\|VERIFY:" content/docs/<version>/
# must print nothing for a shipped versionCutting a new version
Copy the latest version folder to the new version number (MAJOR.MINOR.PATCH):
cp -r content/docs/v1.0.0 content/docs/v1.1.0Register the version so the site knows about it — update three places:
// lib/docs-versions.ts — newest first
export const DOC_VERSIONS = ['v1.1.0', 'v1.0.0'] as const
export const LATEST_VERSION = DOC_VERSIONS[0]// content/docs/meta.json — version ordering
{ "pages": ["v1.1.0", "v1.0.0"] }Update the new folder's content/docs/v1.1.0/meta.json title / description to the new version.
Resolve every marker. Walk each page and replace FILL values, re-check VERIFY facts against the
current dist/include/Stack/** headers, and delete TEMPLATE guidance as you complete sections.
Fix all internal links to the new version path (/docs/v1.1.0/<slug>/).
Run the marker gate and preview:
grep -rn "TEMPLATE:\|FILL:\|VERIFY:" content/docs/v1.1.0/ # expect empty
npm run dev # open http://localhost:3000/docs/v1.1.0/Adding a new platform
kbox-stack is portable. When a new platform is supported (a new MCU family, a new HAL, a non-STM32 board), it becomes its own sibling section — the core pages do not change.
Create a platform subfolder under the current version, mirroring platform-stm32-hal/:
mkdir content/docs/v1.0.0/platform-esp32Give it a meta.json (a folder group, not a version root — no "root": true):
{
"title": "ESP32 (IDF)",
"description": "ESP32 platform support: build, flash, and peripherals.",
"pages": ["overview", "getting-started", "project-setup", "first-application", "peripherals", "flashing"]
}Add the folder name to the version root meta.json, under the ---Platforms--- section header:
"---Platforms---",
"platform-stm32-hal",
"platform-esp32"Author the platform pages. Reuse the platform-stm32-hal/ pages as the structural template:
each platform documents its concrete implementations of the core
Peripheral Interfaces, its toolchain, and its flashing flow.
See Porting to a New Platform for the code side.
Anything that is the same on every platform (the KNX API, group objects, the DPT helper, security) stays in the core pages. A platform section only adds the parts that differ.
Source-of-truth map
Each page is generated from real repository sources. When updating, re-read these:
| Page(s) | Source of truth |
|---|---|
value-encoding-dpt | kbox-stack/Docs/DPT_HELPER_API.md + dist/include/Stack/Helpers/Dpt/* |
stack-construction, integration-contract | kbox-stack/README.md + Logic/IKnxStack.h + Models/StackParameters.h |
architecture | kbox-stack/src/Stack/ARCHITECTURE.md (public-safe subset) |
group-objects, first-application | example led-indicator/** (main.cpp, stackevents.cpp, LedIndicatorLogic.cpp) |
api-reference, enums-reference, configuration, peripheral-interfaces | dist/include/Stack/** headers |
versioning-compatibility, index, changelog | dist/include/Stack/StackVersion.h |
certification | kbox-stack/Docs/certification/CERTIFICATION_PICS_PIXIT.md (omit internal lab notes) |
platform-stm32-hal/* | example STM32F103-HAL/led-indicator/** + dist/include/Stack/Peripheral/**/STM32/HAL/* |
Conventions checklist
Before publishing, confirm every page:
- Frontmatter has only
title+description. - Body starts at
##— there is no H1 in the body (the title renders it). - All internal links are full, versioned, and end with a slash:
/docs/<version>/<slug>/. - Code fences carry a language tag (
```cpp,```cmake,```bash). - Any new Fumadocs component (
Tabs,Steps,Accordions,Cards) is registered inapp/docs/[...slug]/page.tsx's components map, or the page will not render. - No
TEMPLATE:/FILL:/VERIFY:markers remain. - Core pages contain no chip/toolchain/HAL specifics — those live in a platform section.