The first non-empty lines before any heading are treated as metadata. Tome looks for:
VE.# is captured as the document version| Markdown | Tome uses it as |
|---|---|
# Heading 1 |
Navigation group (collapsible section header) |
## Heading 2 |
Page — each H2 becomes a separately viewable page |
### – ##### |
In-page headings (auto-generates a table of contents) |
#section-heading-page-titleBlockquotes with a special tag on the first line are rendered as styled callout boxes. The tag is stripped from the output.
| Syntax | Type | Appearance |
|---|---|---|
> [!WARNING] text |
Warning | Yellow accent, ⚠ icon |
> [!INFO] text |
Info | Blue accent, ℹ icon |
> [!TIP] text |
Tip | Green accent, ✎ icon |
> [!DANGER] text |
Danger | Red accent, ✕ icon |
> [!NOTE] text |
Note | Purple accent, ✱ icon |
Multi-line callouts work normally — just keep the > prefix on each line. The tag only needs to appear on the first line.
Every book Tome knows about is declared in one central file: Books/books.json. It is an ordered array; the first entry is the default book on first load and entries appear in the sidebar dropdown in order.
Books/
books.json <-- the one file you edit to add/remove books
my-monolithic-book.md <-- a monolithic book (one .md file)
my-directory-book/ <-- a directory book (folder of files)
Section One/
page-1.md
page-2.md
Diagrams/
chart.png
A monolithic book is a single markdown file. Drop the .md into Books/ (or a sub-folder) and add one entry:
{
"file": "Books/my-book.md",
"title": "My Book"
}
A directory book is a folder of markdown files organised into sub-folders. Declare it inline in books.json with directory, title, and sections:
{
"directory": "Books/my-directory-book",
"title": "My Directory Book",
"sections": [
{
"title": "Section One",
"pages": [
"page-1.md",
"page-2.md"
]
},
{
"title": "Section Two",
"pages": [
{ "file": "intro.md", "title": "Introduction" },
"details.md"
]
}
]
}
See the Directory-Format Books section for the full manifest schema (folder overrides, page title overrides, optional metadata, etc.).
Delete its entry from books.json. The book’s files on disk are left alone — removing the entry just hides it from the viewer. Delete the files too if you no longer need them.
The order of entries in books.json is the order shown in the sidebar dropdown. Reorder the array to reorder the list. The first entry is loaded by default when a new user visits for the first time.
Tome opens whichever book was loaded last (per-browser, via localStorage). On first visit, or after clearing site data, it loads the first entry in books.json. To change the default for new users, move that entry to position 0.
[
{
"file": "Books/quick-start.md",
"title": "Quick Start Guide"
},
{
"directory": "Books/Governance",
"title": "Helpdesk Operations Manual - Governance",
"sections": [
{
"title": "Overview",
"pages": [ "intro.md", "scope.md" ]
},
{
"title": "Policies",
"pages": [ "policy-1.md", "policy-2.md" ]
}
]
}
]
After editing books.json, refresh the page in the browser. There is no build step.
A book can live either as a single monolithic .md file or as a folder of files. Both formats are fully supported and mix freely in the same Books/books.json (see Managing Books for add/remove instructions).
| Format | Good for |
|---|---|
Monolithic .md |
Small books, single-author documents, when you want one file to edit and ship |
| Directory | Large manuals, multi-author content, when sections/pages are worked on independently |
The root folder is the book. Each sub-folder you list in the manifest is a section (equivalent to an H1 in a monolithic book). Each .md file inside a section folder is a page (equivalent to an H2 in a monolithic book). Asset folders (like Diagrams/) are ignored unless referenced by a page.
Books/
my-book/
Section One/
page-1.md
page-2.md
Section Two/
overview.md
details.md
Diagrams/
flowchart.png
Inside each page file, author the body as you would any markdown document:
# heading in the file becomes the page title in the sidebar. The original H1 is stripped from the rendered view and replaced by the title.## subsections render as H3 inside the page — they stay in the page, they do not become new pages).Every directory book is declared with a manifest. The recommended place is inline in Books/books.json (edit one file to manage everything). Tome also accepts a book.json at the directory root as a fallback, which is useful when distributing a book as a portable self-contained folder.
{
"directory": "Books/my-book", // only at the books.json level
"title": "My Book", // optional; defaults to folder name
"version": "1.0", // optional metadata
"date": "2026-04-21", // optional
"classification": "Internal", // optional
"sections": [
{
"title": "Section One", // shown as the section header
"folder": "Section One", // optional; defaults to title; use "" for book root
"pages": [
"page-1.md", // shorthand - title taken from file's first H1
"page-2.md",
{ "file": "page-3.md", "title": "Explicit Page Title" }
]
},
{
"title": "Section Two",
"pages": [ "overview.md", "details.md" ]
}
]
}
 in a page in Section One/ loads Section One/chart.png.../ to reference files in sibling folders (e.g. ../Diagrams/flow.png)..md file inside the same book are rewritten automatically to navigate within the viewer — clicking jumps to that page, it does not download the raw file.You can link from any page in one book to a specific page in another book. When clicked, Tome switches to the target book and shows a floating “Back to …” button so the reader can return to where they were.
Use an HTML anchor with the tome:// protocol:
<a href="tome://book-folder#policy-slug">Link text</a>
| Part | Where to find it |
|---|---|
book-folder |
The folder name inside Books/ that contains the target book’s .md file (e.g. operationsmanual-governance-ve16) |
policy-slug |
Navigate to the target page in Tome and copy the text after # in the browser URL bar |
Books/books.json, in any direction<a href="tome://operationsmanual-governance-ve16#non-critical-ticket-handling-escalation-policy">Escalation Policy</a>
All branding is configured through tome.json. No source code changes are needed.
| Key | What it controls |
|---|---|
branding.defaultTitle |
The title shown in the sidebar and browser tab before a book loads (or as a fallback if the markdown has no title) |
branding.classification |
The label beneath the title, e.g. “Internal Use Only” or “Confidential” |
branding.favicon |
Path to the browser tab icon (SVG, PNG, or ICO) |
On load, Tome shows a full-screen splash with the “TOME” wordmark. Control how long it stays visible:
| Key | What it controls |
|---|---|
splash.minDurationMs |
Minimum splash duration in milliseconds (default: 2000) |
The splash always waits for the book manifest to load. If loading takes longer than the minimum, the splash stays until loading completes.
PDF export branding is configured through brand profiles in export-branding/. See the
Export Branding section for details.
For backwards compatibility, tome.json still supports pdf.logo and
pdf.footer as a fallback when no brand profiles are configured.
{
"branding": {
"defaultTitle": "Company Handbook",
"classification": "Internal Use Only",
"favicon": "brand-icon.svg"
},
"pdf": {
"logo": "company-logo.png",
"footer": [
"example.com | hello@example.com | 01onal 123 456",
"Example Ltd, 1 High Street, London, EC1A 1BB",
"Registered in England 12345678"
]
},
"splash": {
"minDurationMs": 2500
}
}
Tome automatically resolves image paths relative to the book’s directory. Keep images alongside your markdown files.
Books/
my-manual/
manual.md
diagram.png
screenshot.png
another-book/
guide.md
photo.jpg
Just use the filename — no path prefix needed:

Tome detects that the book lives at Books/my-manual/manual.md and resolves the image to
Books/my-manual/diagram.png.
src and link href attributes are resolved after renderingIf a book file sits directly in the root (not in a subfolder), image paths are not modified. Place images
alongside index.html in that case.
The single source of truth for which books appear in the viewer. An ordered array — the first entry is loaded by default on first visit, and entries appear in the sidebar dropdown in order. A file entry is a monolithic book; a directory entry with a sections array is a directory-format book declared inline. See Managing Books for step-by-step add/remove instructions.
[
{
"file": "Books/my-guide.md",
"title": "My Guide"
},
{
"directory": "Books/my-directory-book",
"title": "Multi-File Book",
"sections": [
{ "title": "Intro", "pages": [ "01-welcome.md", "02-setup.md" ] },
{ "title": "Policies", "pages": [ "p1.md", "p2.md" ] }
]
}
]
Controls platform branding and behaviour. All fields are optional.
{
"branding": {
"defaultTitle": "My Documentation",
"classification": "Internal Use Only",
"favicon": "my-icon.svg"
},
"pdf": {
"logo": "logo.png",
"footer": ["Line 1", "Line 2", "Line 3"]
},
"splash": {
"minDurationMs": 2000
}
}
| Key | Purpose |
|---|---|
branding.defaultTitle |
Fallback title if the markdown has none |
branding.classification |
Label shown below the title |
branding.favicon |
Path to the browser tab icon |
pdf.logo |
Fallback letterhead image (used when no brand profiles exist) |
pdf.footer |
Fallback footer text (used when no brand profiles exist) |
splash.minDurationMs |
Minimum splash screen duration in milliseconds |
Exports the currently viewed page as a PDF at 2× resolution with letterhead and footer.
Stitches every page into a single PDF with a cover page. A progress indicator shows pages processed.
Downloads the raw .md source — either the current page’s markdown or the entire
book file.
PDF exports use brand profiles stored in export-branding/. Each brand has its own directory
with a configuration file and media assets.
export-branding/
brands.json
default/
brand.json
media/
letterhead_logo.png
client-a/
brand.json
media/
logo.png
watermark.png
An array of brand directory names. The first entry is the default.
["default", "client-a"]
Each brand’s configuration file. All fields are optional and fall back to sensible defaults.
{
"label": "Client A Branded",
"pageSize": "a4",
"orientation": "portrait",
"margins": {
"top": 20, "right": 10,
"bottom": 15, "left": 10
},
"header": {
"logo": "media/logo.png",
"logoWidth": 40,
"logoAspect": 4.04,
"x": 15, "y": 8
},
"footer": {
"lines": [
"Client A Corp",
"123 Main Street",
"Confidential"
],
"fontSize": 9,
"color": 80
},
"coverPage": true,
"coverTitle": "Operations Manual"
}
| Key | Purpose |
|---|---|
label |
Display name in the brand picker dropdown |
pageSize |
PDF page size: a4, letter, or legal |
orientation |
portrait or landscape |
margins |
Page margins in mm (top, right, bottom, left) |
header.logo |
Path to logo image, relative to the brand directory |
header.logoWidth |
Logo width in mm (default: 40) |
header.logoAspect |
Logo width-to-height ratio (default: 4.04) |
header.x / header.y |
Logo position in mm from the top-left corner |
footer.lines |
Array of up to 3 strings, centred at the bottom of each page |
footer.fontSize |
Footer text size in points (default: 9) |
footer.color |
Footer text colour as a greyscale value 0–255 (default: 80) |
coverPage |
Whether to include a cover page in full-manual export (default: true) |
coverTitle |
Override the cover page title (defaults to the document title) |
When two or more brands are defined in brands.json, a dropdown appears in the Settings
→ Export section. Select a brand before exporting to apply its letterhead, footer, and page settings.
If export-branding/brands.json is missing or fails to load, Tome falls back to the PDF
settings in tome.json (the pdf.logo and pdf.footer keys).
| Key | Action |
|---|---|
/ |
Focus the search box |
n |
Go to the next page |
p |
Go to the previous page |
Escape |
Clear search / close settings panel |
| Tome | |
| markdown-it | |
| markdown-it-anchor | |
| html2pdf.js | |
| html2canvas |
.md. The root folder is the book, each sub-folder is a section (H1 equivalent), and each .md file within a section is a page (H2 equivalent)Books/books.json: directory books declare their sections and pages inline alongside monolithic books, so there is one file to edit to add, remove, or reorder any bookfile, directory entries use directory + sections. Existing file-only entries (including paths without .md) keep working for backwards compatibilitybook.json at the root as a fallback — useful for distributing a book as a portable self-contained folder — but it’s no longer required../ supported for cross-folder asset references.md file within the same directory book are rewritten automatically to navigate within the viewer instead of fetching the raw filecache: "no-store" to cache: "default" for faster navigation[!WARNING], [!INFO], [!TIP], [!DANGER], or [!NOTE] tags render as styled callout boxes with coloured accents and icons (compatible with GitHub alert syntax)tome:// protocol allows linking between books with automatic “Back to…” return button; return button pulses every 20s and has a dismiss optionavoid-all mode from html2pdf configversion.json at startup — single source of truth, no more duplicate version stringsupdate.sh (bash) and update.ps1 (PowerShell) for one-click updates from GitHubbooks.json manifest into the Books/ directory alongside user contentREADME.md with project documentation, quick start, and configuration referencetome.md)TOME md/ directory so all files live at the
repository rootsuper-gill.github.io/tome.md/
export-branding/
brand.json config and a media/ folder
for logos and assetstome.json PDF settings when no brand profiles are present (backwards
compatible)version.json from the canonical published URL
and compares it to the running versionversion.json to the platform project for deployed instances to check againstpre) now use theme tokens (--bg, --text,
--border) instead of hardcoded colours
--h1bg, --border) instead of hardcoded
colours--h1bg theme token.doc blockquote base style: left border in heading colour, tinted background, rounded
right corners.doc ol base style to match existing ul margin and spacingmargin-left instead of
padding-left to preserve borders and number gutters
pre): margin-left override so
padding: 12px no longer silently cancels the indent
hr): switched to margin-left since
padding has no effect on void elementsmargin-left to shift the entire element (including
left border) to the indent positiondata-tone system for clean light/dark CSS overrides/ to search, n/p to move between pagestome.json configuration file for branding, PDF settings, favicon, and splash durationtome.json
books.json rather than hardcoded filenamebooks.json manifest with dropdown book pickerindex.html, index.js, styles.css