Ghost Nodes: The Complete Reference
Introduction
This is a self-documenting reference for ox-ghost, the Emacs org-mode export backend that converts .org files to Ghost's Lexical JSON format.
Every section shows:
- The rendered resultas it appears in Ghost
- An Org Sourcetoggle below (click to see the org-mode code)
At the end, you can download this very document and its Lexical JSON output.
Text Fundamentals
Paragraphs
The simplest element. Just write text with blank lines between paragraphs.
This is the first paragraph. It can span multiple lines in your org file - they'll be joined.
This is a second paragraph, separated by a blank line.
Org Source
This is the first paragraph. It can span multiplelines in your org file - they'll be joined.
This is a second paragraph, separated by a blank line.
Text Formatting
Org-mode formatting maps to Lexical's text format bitmask:
| Format | Org Syntax | Bitmask |
|---|---|---|
| Bold | *bold* |
1 |
| Italic | /italic/ |
2 |
| Strikethrough | +struck+ |
4 |
| Underline | _underline_ |
8 |
| Code | ==code== |
16 |
Table Org Source
| Format | Org Syntax | Bitmask ||---------------+-----------------+---------|| Bold | *bold* | 1 || Italic | /italic/ | 2 |
Format text with bold, italic, strikethrough, underline, and code.
Combine them: bold-italic, bold-underline, all three.
Org Source
Format text with bold, italic, strikethrough, underline, and code.Combine them: /bold-italic/, _bold-underline_, /+all three+/.
Links
External link: Ghost CMS
Plain URL auto-links: https://ii.coop
Email: Contact us
Org Source
External link: Ghost CMSPlain URL auto-links: https://ii.coopEmail: Contact us
Line Breaks
Force line breaks with double backslash.
Line one
Line two
Line three
Org Source
Line one\\Line two\\
Line three
Headings
Org headlines become Lexical headings. The post title is H1, so content starts at H2.
| Org Stars | Lexical Tag | Typical Use |
|---|---|---|
* |
H2 | Major sections |
** |
H3 | Subsections |
*** |
H4 | Deep structure |
**** |
H5 | Rarely needed |
***** |
H6 | Almost never |
Org Source
βΌ H2 - Major Section (one star)*β½ H3 - Subsection (two stars)**β― H4 - Sub-subsection (three stars)***βΏ H5 - Rarely needed (four stars)****βΎ H6 - Avoid this deep (five stars)
Lists
Unordered Lists
- First item
- Second item with bold
- Third item with link
Org Source
β First itemβ Second item with boldβ Third item with link
Ordered Lists
- First step
- Second step
- Third step
Org Source
1. First step2. Second step3. Third step
Nested Lists
- Parent item
- Child item
- Another child
- Grandchild
- Back to parent
- Numbered parent
- Numbered child
- Another child
- Back to parent
Org Source
β Parent item β Child item β Another child β Grandchildβ Back to parent1. Numbered parent 1. Numbered child 2. Another child2. Back to parent
Checkbox Lists
- Unchecked task
- Completed task
- In progress
Org Source
β β‘ Unchecked taskβ β‘x Completed taskβ β‘β In progress
Blockquotes
The best way to predict the future is to invent it. β Alan Kay
Org Source
QUOTE
The best way to predict the future is to invent it.
β Alan KayQUOTE
Horizontal Rules
Content above.
Content below.
Org Source
Content above.
-----
Content below.
Code Blocks
Code blocks support syntax highlighting via Prism.js.
def hello(name):
return f"Hello, {name}!"
print(hello("Ghost"))
NoneOrg Source
SRC pythondef hello(name): return f"Hello, {name}!"print(hello("Ghost"))SRC
More Languages
// JavaScript
const greet = (name) => `Hello, ${name}!`;
console.log(greet("World"));
Hello, World!
undefined#!/bin/bash
echo "Hello from $(hostname)"
Hello from nextral.sharing.io
;; Emacs Lisp
(defun greet (name)
(message "Hello, %s!" name))
greetCallout Blocks
Callouts highlight important information with color-coded backgrounds.
Org Source
CALLOUT :emoji "π‘" :color blueYour message here. Supports formatting.CALLOUT
All Seven Colors
Common Emoji Names
| Emoji | Name | Use Case |
|---|---|---|
| π‘ | bulb |
Tips, ideas |
| β | white_check_mark |
Success, do this |
| β οΈ | warning |
Caution |
| β | x |
Error, don’t |
| π | rocket |
Launch, deploy |
| π | memo |
Notes |
| β¨ | sparkles |
Special |
Toggle Blocks
Toggles hide content behind a clickable heading. They support rich HTML content!
Click to expand
Hidden content here. Supports formatting, lists, and code:
print("Code inside a toggle!")
None
Org Source
TOGGLE :heading "Click to expand"Hidden content here. Supports formatting, lists, and code:SRC pythonprint("Code inside a toggle!")SRCTOGGLE
Toggle with a list
Toggles are great for:
- FAQs
- Technical details
- Optional deep-dives
- Spoiler warnings
Aside Blocks
Asides provide tangential information with distinct styling.
Tangential content here. Supports formatting and links.
Org Source
ASIDETangential content here. Supports formatting and links.ASIDE
Button Blocks
Buttons create prominent call-to-action links.
Org Source
BUTTON :url "https://example.com" :alignment centerButton TextBUTTON
Header Cards
Full-width banners with text overlay.
Small Header
Medium Header
Large Header
Org Source
HEADER :size smallHeader TextHEADER
Signup Forms
Capture email subscribers.
Regular layout:
Wide layout:
Split layout:
Org Source
SIGNUP :layout regular :buttonText "Subscribe"SIGNUP
Email-Only Content
Content that only appears in newsletter emails, not on the web post.
Org Source
EMAIL<p>Thanks for being a subscriber!</p><p>This only appears in the <strong>email version</strong>.</p>EMAIL
Call to Action (CTA)
Prominent sections to drive reader action.
Simple and clean. Great for subtle prompts.
Bold and attention-grabbing. For important conversions.
Branded styling. Shows site identity.
Org Source
CTA :layout minimal :buttonText "Learn More" :url "https://example.com"Compelling message here.CTA
Bookmark Cards
Rich link previews with metadata.

Org Source
BOOKMARK :url "URL" :title "Title" :description "Desc" :thumbnail "IMG" :icon "ICO"Fallback textBOOKMARK
Product Cards
Showcase products with optional buy buttons.
Premium Widget Pro
Advanced Course (no button)
Org Source
PRODUCT :url "https://shop.example.com/item" :buttonText "Buy Now"Product TitlePRODUCT
Images
| Width | Attribute | Use Case |
|---|---|---|
| Regular | :cardWidth regular |
Inline with text |
| Wide | :cardWidth wide |
Break out of column |
| Full | :cardWidth full |
Edge to edge |
Regular width (default):
Wide width:
Full width:
Org Source
ATTR_LEXICAL: :cardWidth wideAlt text description
Video Blocks
| Attribute | Description | Example |
|---|---|---|
:src |
Video URL (required) | https://.../v.mp4 |
:width |
Width in pixels | 1920 |
:height |
Height in pixels | 1080 |
:duration |
Duration in seconds | 30 |
:mimeType |
MIME type | video/mp4 |
:thumbnailSrc |
Poster image URL | https://.../t.jpg |
Org Source
VIDEO :src "URL" :width 1920 :height 1080 :duration 30 :mimeType "video/mp4"Caption textVIDEO
Audio Blocks
| Attribute | Description | Example |
|---|---|---|
:src |
Audio URL (required) | https://... |
:duration |
Duration in seconds | 120 |
:mimeType |
MIME type | audio/mpeg |
Org Source
AUDIO :src "URL" :duration 120 :mimeType "audio/mpeg"Track titleAUDIO
File Downloads
Org Source
FILE :src "URL" :fileName "document.pdf"Download descriptionFILE
Gallery Blocks
Embed Blocks
Embed external content (YouTube, Twitter, etc.).
Org Source
EMBED :url "https://youtube.com/watch?v=..." :html "<iframe>...</iframe>"Fallback titleEMBED
Asciinema Player
Embed terminal recordings with the asciinema player. Perfect for demos, tutorials, and documentation.
Star Wars Demo
The classic ASCII Star Wars animation via telnet:
Star Wars Episode IV (ASCII)
Org Source
ASCIINEMA :src https://asciinema.org/a/8.cast :speed 1 :theme monokai :title "Star Wars Episode IV (ASCII)" :idle-time-limit 2ASCIINEMA
Player Options
| Attribute | Description | Example |
|---|---|---|
:src |
Cast file URL or path | https://.../a.cast |
:speed |
Playback speed | 1.5 |
:theme |
Player theme | solarized-dark |
:poster |
Poster frame | npt:0:30 |
:cols / :rows |
Terminal size | 80 / 24 |
:autoplay |
Auto-play on load | true |
:loop |
Loop playback | true |
:start-at |
Start time (seconds) | 10 |
:idle-time-limit |
Max idle between frames | 2 |
:fit |
Fit mode | width |
:controls |
Show controls | true |
:title |
Title above player | Demo Recording |
Org Source
ASCIINEMA :src https://asciinema.org/a/8.cast :speed 1.5 :theme solarized-dark :poster "npt:0:10" :autoplay true :loop true :start-at 5 :idle-time-limit 2 :fit width :controls true :title "Full Options Example"ASCIINEMA
Available Themes
With Custom Settings
Org Source
ASCIINEMA :src https://asciinema.org/a/8.cast :speed 2 :theme dracula :autoplay true :loop true :start-at 5 :fit widthASCIINEMA
Local Cast Files
When using local files, they're tracked for upload:
Org Source for Local Files
ASCIINEMA :src ./recordings/demo.cast :speed 1.5 :theme github-darkASCIINEMA
This adds to metadata.json:
{ "media_files": [
{ "local": "/full/path/to/recordings/demo.cast", "dest": "/content/media/casts/demo.cast"
}
]
}
Tables
Tables export as HTML blocks (Lexical lacks native table support).
| Feature | Status | Notes |
|---|---|---|
| Headings | Done | H2-H6 supported |
| Lists | Done | Nested too |
| Callouts | Done | 7 colors |
| Tables | Done | Via HTML export |
Org Source
| Column A | Column B | Column C ||----------+----------+----------|| Value 1 | Value 2 | Value 3 |
| Value 4 | Value 5 | Value 6 |
REPL Blocks
REPL blocks combine code with output in styled presentations.
Simple (default)
2 + 2
4Labeled
for i in range(3):
print(f"Item {i}")
Output:
Item 0
Item 1
Item 2Callout
echo "Build succeeded!"
Org Source
REPL :style callout :emoji "β
" :color greenSRC pythonprint("hello")SRCRESULTS:
: helloREPL
Toggle
Show implementation
def fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b list(fibonacci(8))
[0, 1, 1, 2, 3, 5, 8, 13]Aside
Raw HTML
When Lexical nodes aren't enough, embed raw HTML.
Custom HTML Block
Any HTML, CSS, or embedded widgets.
Org Source
EXPORT html<div style="background: #667eea; padding: 2rem; color: white;">
Custom HTML content</div>EXPORT
Raw Lexical JSON
Insert raw Lexical JSON directly (advanced).
This is useful for nodes ox-ghost doesn't yet support.
Org Source
EXPORT lexical
{"type":"paragraph","version":1,"children":[...]}EXPORT
The Export Pipeline
Step 1: Write Your Org File
Create your content using the patterns shown above.
Step 2: Export to Lexical JSON
cd /path/to/ox-ghost
./org-to-lexical.sh input.org output.json
Step 3: Validate the Output
node validate-lexical.js output.json
# With HTML preview:
node validate-lexical.js output.json --html preview.html
Step 4: Create Ghost Post
cd /srv/ii.coop
node ghost.js post create "Post Title" output.json --format lexical
Step 5: Upload Media (Optional)
For video/audio/files, upload first then update the org with URLs:
# Upload media file
node ghost.js upload /path/to/video.mp4
# Returns: https://coop.ghost.io/content/media/2026/01/video.mp4
# Add this URL to your :src attribute
Step 6: Enrich Media Metadata
Auto-populate width/height/duration from uploaded files:
;; In Emacs, with ghost-publish.el loaded:
M-x ghost-publish-enrich-buffer
This probes each media URL and adds the metadata attributes.
Membership Paywall
The PAYWALL block marks where free content ends and members-only content begins.
π Secret Members-Only Content
Congratulations! You've unlocked the exclusive members-only section.
Here's what free readers are missing:
- The meaning of life: 42
- The best programming language: the one that pays your bills
- The secret to happiness: good coffee and clean code
Org Source
PAYWALLPAYWALL
Content after the paywall is members-only.
Download This Document
This post is self-documenting. Download the source files:
Summary: All Node Types
| Category | Nodes |
|---|---|
| Text | Paragraph, Heading (H2-H6), Line Break |
| Format | Bold, Italic, Strikethrough, Underline, Code, Link |
| Structure | Blockquote, Horizontal Rule, Table (as HTML) |
| Lists | Ordered, Unordered, Nested, Checkbox |
| Code | Code Block (syntax highlighted) |
| Cards | Callout (7 colors), Toggle, Aside, Button, Bookmark |
| Media | Image (3 widths), Video, Audio, Gallery, File, Embed |
| Terminal | Asciinema (9 themes, full player options) |
| Ghost | Header (3 sizes), Signup (3 layouts), CTA (3 layouts) |
| Product | Product Card |
| Newsletter | Email (email-only content), Paywall (members-only) |
| Special | REPL (5 styles), Raw HTML, Raw Lexical |
ox-ghost is open source. Contributions welcome!