The .kmd File Format
Technical details about Korppi's native document format.
Overview
The .kmd (Korppi Markdown Document) format is a
ZIP-based container that stores:
- Markdown content with cross-reference support
- Version history (timeline)
- Comments and annotations
- Document metadata
- Collaborative editing state
File Structure
A .kmd file is a ZIP archive with this structure:
document.kmd (ZIP archive)
├── content.md # Main markdown content
├── format.json # Format version info
├── meta.json # Document metadata
├── patches/ # Timeline patches
│ ├── index.json # Patch list
│ └── *.json # Individual patches
├── comments.json # Comments and threads
└── ystate.bin # Yjs CRDT state (binary)
format.json
Format version information for compatibility:
{
"kmd_version": "0.1.0",
"min_reader_version": "0.1.0"
}| Field | Description |
|---|---|
kmd_version |
Version of Korppi that created this file |
min_reader_version |
Minimum version required to read this file |
content.md
The main document content in Markdown format with support for cross-references.
Basic Markdown
# My Document
This is the actual markdown content of your document.Cross-References
Korppi supports Pandoc-compatible cross-reference syntax for figures, sections, and tables.
Section Labels
Add {#sec:label} at the end of any heading:
# Introduction {#sec:intro}
## Methods {#sec:methods}
As described in @sec:intro, we use certain methods.Figure Labels
Add {#fig:label} after an image to create a numbered
figure:
{#fig:sales}
As shown in @fig:sales, revenue increased.Table Labels
Add {#tbl:label} on a new line after a table:
| Quarter | Revenue |
|---------|---------|
| Q1 | $1.2M |
| Q2 | $1.4M |
{#tbl:quarterly}
See @tbl:quarterly for the data.Reference Syntax Summary
| Type | Label Syntax | Reference Syntax | Output |
|---|---|---|---|
| Section | {#sec:label} |
@sec:label |
Section N |
| Figure | {#fig:label} |
@fig:label |
Figure N |
| Table | {#tbl:label} |
@tbl:label |
Table N |
meta.json
Document metadata:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Document",
"created_at": "2024-12-07T12:00:00Z",
"modified_at": "2024-12-07T15:30:00Z",
"authors": [
{
"id": "author-uuid",
"name": "Jane Doe",
"email": "jane@example.com",
"joined_at": "2024-12-07T12:00:00Z",
"role": "owner"
}
],
"settings": {
"language": "en-US",
"spell_check": true
},
"sync_state": {
"last_export": "2024-12-07T14:00:00Z",
"pending_patches": 0
}
}Fields
| Field | Type | Description |
|---|---|---|
uuid |
string | Unique document identifier |
title |
string | Document title |
created_at |
string | ISO 8601 creation timestamp |
modified_at |
string | ISO 8601 last modified timestamp |
authors |
array | List of document authors |
settings |
object | Document settings |
sync_state |
object | Synchronization state |
Author Object
| Field | Type | Description |
|---|---|---|
id |
string | Unique author identifier |
name |
string | Display name |
email |
string? | Email address (optional) |
joined_at |
string? | When author joined (optional) |
role |
string? | Role: "owner", "editor", "viewer" (optional) |
Settings Object
| Field | Type | Default | Description |
|---|---|---|---|
language |
string | "en-US" | Document language |
spell_check |
boolean | true | Enable spell checking |
Sync State Object
| Field | Type | Description |
|---|---|---|
last_export |
string? | Last export timestamp (optional) |
pending_patches |
number | Number of unsynced patches |
patches/
The timeline patches directory contains version history:
index.json
List of all patches:
{
"patches": [
"patch-001.json",
"patch-002.json"
]
}patch-*.json
Individual patch files:
{
"id": "patch-001",
"timestamp": "2024-12-07T12:00:00Z",
"author": "Jane Doe",
"description": "Added introduction section",
"status": "approved",
"lines": {
"start": 1,
"end": 15
},
"diff": {
"added": 10,
"removed": 0,
"modified": 5
}
}comments.json
All comments and threads:
{
"comments": [
{
"id": "comment-001",
"author": {
"name": "Jane Doe",
"color": "#ff5733"
},
"content": "This needs clarification",
"created_at": "2024-12-07T12:00:00Z",
"status": "unresolved",
"anchor": {
"start": 100,
"end": 150
},
"replies": []
}
]
}ystate.bin
Binary Yjs CRDT state for real-time sync.
This file enables:
- Conflict-free editing
- State synchronization
- Undo/redo history
- Collaborative editing
⚠️ This file is binary and not human-readable.
Export Formats
Korppi can export to several formats:
DOCX Export
Export to Microsoft Word format with:
- Headings preserved with proper styles
- Bold, italic, and strikethrough formatting
- Ordered and unordered lists
- Tables with headers
- Code blocks with monospace font
- Block quotes
- Cross-references resolved (e.g.,
@fig:sales→ "Figure 1") - Figure labels stripped from output
Markdown Export
Plain markdown with all cross-reference syntax preserved.
Working with .kmd Files
Extracting Content
To extract just the markdown:
unzip -p document.kmd content.md > output.mdInspecting Metadata
unzip -p document.kmd meta.json | jq .Full Extraction
unzip document.kmd -d extracted/Compatibility
Version Compatibility
.kmdfiles note their version informat.json- Newer Korppi versions read older formats
- Format upgrades happen automatically on save
- Version checks prevent data loss from incompatible readers
Markdown Compatibility
The content.md file is extended GitHub Flavored
Markdown:
- Standard GFM features work in any markdown renderer
- Cross-references (
@type:label) are Korppi/Pandoc-specific - Labels (
{#type:label}) are stripped on export to other formats
Creating .kmd Programmatically
You can create a .kmd file with minimal structure:
# Create minimal structure
mkdir mydoc
echo "# Hello" > mydoc/content.md
echo '{"kmd_version":"0.1.0","min_reader_version":"0.1.0"}' > mydoc/format.json
echo '{"uuid":"123","title":"Hello","created_at":"2024-01-01T00:00:00Z","modified_at":"2024-01-01T00:00:00Z","authors":[]}' > mydoc/meta.json
# Package as .kmd
cd mydoc && zip -r ../hello.kmd . && cd ..Related
- Export Options - Exporting to other formats
- Timeline - Understanding patches
- Cross-References - Using figures, sections, and tables