Body Shortcodes
Embed diagrams and spreadsheets directly within body text using standard markdown syntax. No special configuration needed — just write fenced blocks or image-style includes in any body field.
Fenced Block Syntax
Use markdown fenced code blocks with a language hint to embed content inline with prose:
Diagrams
Write Mermaid syntax inside a ```mermaid fenced block:
body: |
Here's the system architecture:
```mermaid
graph LR
A[Upload] --> B[Parse]
B --> C[Analyze]
C --> D[Render]
```
The flow above shows how manuscripts are processed.
The diagram renders inline between the surrounding paragraphs, just as it would in GitHub or Obsidian.
Spreadsheets
Use ```spreadsheet or ```csv for interactive tables:
body: |
Here's the production budget:
```spreadsheet
Item,Cost,Quantity,Total
Camera,5000,2,=B2*C2
Lens,2000,3,=B3*C3
Tripod,500,2,=B4*C4
```
All formulas are live — click cells to edit values.
Both spreadsheet and csv aliases work identically. Formulas use standard Excel-style syntax (=SUM, =AVERAGE, etc.).
Mixing Content Types
You can freely mix prose, diagrams, spreadsheets, and regular code blocks in the same body:
body: |
# Project Overview
The system follows this architecture:
```mermaid
graph TD
Frontend --> API
API --> Database
API --> Worker
```
## Budget
```spreadsheet
Department,Budget,Spent,Remaining
Engineering,100000,45000,=B2-C2
Design,50000,22000,=B3-C3
```
## Implementation Notes
```python
# Regular code blocks still render as syntax-highlighted code
def process(data):
return analyze(data)
```
Regular fenced blocks (```python, ```yaml, ```bash, etc.) continue to render as syntax-highlighted code — only mermaid, spreadsheet, and csv are special.
Image-Style Includes
Reference external files using markdown's image syntax. The file extension determines how the content renders:
Diagram Files
body: |
See the full architecture:

The diagram above shows all system components.
Supported extensions: .mermaid, .mmd
Spreadsheet Files
body: |
Full inventory data:

Supported extension: .csv
Regular Images
Normal image files render as images (unchanged behavior):
body: |
Here's a photo from the shoot:

Supported extensions: .jpg, .jpeg, .png, .gif, .svg, .webp, .avif
How It Works
The rendering engine checks the file extension in the image src:
- .mermaid or .mmd → reads the file and renders as a Mermaid diagram
- .csv → reads the file and renders as an interactive spreadsheet
- Everything else → renders as a normal <img> tag
File paths are resolved relative to the codex project directory.
When to Use Body Shortcodes vs Content Arrays
| Feature | Body Shortcodes | Content Array (content:) |
|---|---|---|
| Best for | Prose with embedded visuals | Structured data display |
| Layout control | Full-width within body | width: 1/1, 1/2, 1/3 |
| Mixed with text | Yes — inline with paragraphs | No — separate sections |
| Titles | No automatic titles | name: field renders titles |
| File includes |  |
include: file.mermaid |
| Inline syntax | ```mermaid fenced block |
value: \| in content item |
Rule of thumb: Use body shortcodes when you want diagrams or tables flowing naturally within narrative text. Use content arrays when you want titled, structured sections with layout control.
Dark Mode
All body-embedded diagrams and spreadsheets support dark mode automatically. Diagrams re-render with the appropriate Mermaid theme when the page theme changes.
Limitations
- No width control — Body-embedded content renders full-width within the body column. For side-by-side layouts, use
contentarrays withwidth: 1/2. - No
.spreadsheet.yamlin body — Complex spreadsheet configurations with column types should use content arrays. Body shortcodes support CSV only. - File includes need project context —
requires the codex to be served from a project with a known base path. Fenced blocks (```mermaid) work everywhere.