-
Notifications
You must be signed in to change notification settings - Fork 0
Sandbox
An interactive playground for the Postext layout engine.
The Sandbox provides a VS Code-like interface where you can write markdown, adjust layout configuration, and see the results rendered in real time through three synchronized output modes — canvas, HTML and PDF. It is designed for experimentation: tweak typography settings, change column counts, test resource placement strategies, and watch how the engine responds.
The Sandbox follows a familiar IDE paradigm with three main areas: a narrow activity bar for switching panels, a resizable sidebar hosting the editor or configuration, and a viewport on the right with the three output tabs.
A narrow strip on the left edge (48px wide) contains icon buttons for navigating between panels. The top section holds three panel toggles:
-
Markdown Editor (
FileCodeicon) — Opens the markdown editing panel -
Configuration (
Settings2icon) — Opens the layout configuration panel -
Resources (
FolderOpenicon) — Opens the resource management panel (coming soon)
Clicking the active panel's icon collapses the sidebar. Clicking a different icon switches to that panel.
The bottom section of the activity bar contains:
- Export — Downloads the current sandbox state (markdown + config) as a JSON file
- Import — Loads a previously exported JSON file
- Theme toggle — Switches between dark and light mode
- Language switcher — Changes the interface language
The sidebar is resizable: drag the separator between the sidebar and the viewport to adjust its width (240px–480px range). The sidebar collapses entirely when no panel is active.
A form-based editor for PostextConfig. Settings are grouped into collapsible sections, each with a reset button to restore defaults:
| Section | Settings |
|---|---|
| Page | Background color, size preset (or custom width/height), margins (top, bottom, left, right), DPI, cut lines, baseline grid (with color and line width) |
| Layout | Layout type (single, double, column-and-a-half), gutter width, side column percentage |
| Body Text | Font family (with Google Fonts search), font size, line height, text color, text alignment, font weight, bold font weight, hyphenation (toggle + locale) |
| Headings | General defaults (font family, line height, color, alignment, weight, margins) plus per-level overrides (H1–H6) for font size, line height, font family, weight, color, and margins |
Controls are context-aware: gutter width only appears for multi-column layouts, hyphenation settings only appear when text is justified, and side column percentage only shows for the column-and-a-half layout. Changes take effect immediately in the viewport preview. For a full reference of all configuration options and their defaults, see the Configuration page.
A CodeMirror 6-based editor with:
- Syntax highlighting — Headings, emphasis, links, code blocks, and blockquotes are visually distinct
- Line numbers and active line highlighting
- Line wrapping for long paragraphs
-
Toolbar with buttons for common markdown actions:
- Bold, Italic
- Heading levels 1–3
- Link, Inline code
- Blockquote
- Ordered and unordered lists
The toolbar is extensible: custom actions can be added for postext-specific micro-formats as the enriched markdown specification evolves.
Coming in a future version. This panel will manage the resources (images, tables, figures, pull quotes) referenced from the markdown content.
The right side of the interface displays the rendered output. Three tabs are available, one per rendering mode — Canvas, HTML and PDF. Switching tabs does not re-run layout: the same VDT feeds every backend, so the content you see is consistent across modes.
Each viewport runs the layout pipeline inside a dedicated Web Worker (postext/worker). A per-viewport useLayoutWorker hook owns the worker handle, ships fonts into it as transferable ArrayBuffers, and drives builds with last-wins cancellation — a keystroke or slider drag aborts the previous build's AbortSignal before the next one starts, so fast typing never queues up stale work on the main thread. Unmounting a viewport disposes its worker and rejects any pending build. See Configuration → Running layout in a Web Worker for the integration pattern used here.
Renders a rasterized preview of the document on an HTML5 <canvas> element. This provides a pixel-accurate representation of how the final typeset document will look, including precise text positioning, column layout, and resource placement.
A toolbar at the top of the canvas viewport provides:
- Zoom controls — Zoom in and out (1.25x per step, range 0.25x–4x). Manual zooming disables fit mode.
- Fit modes — Fit to page width or fit to page height. Toggles on/off; fitting recalculates automatically on window resize.
- View modes — Single page (one page per row) or double-page spread (book-like layout where the first page appears on the right as a recto, and subsequent pages are paired as spreads).
Pages render lazily via IntersectionObserver — only visible pages (plus a 200px margin) are drawn to canvas, keeping GPU memory usage low for long documents.
Renders the postext output inside a Shadow DOM container, ensuring complete style isolation from the host page. The editorial CSS (typography, spacing, column rules) is injected inside the shadow root so it cannot be affected by or leak into the surrounding application styles.
A toolbar at the top of the viewport provides:
- Font-scale controls — Shrink or grow body text while preserving every relative measurement in the configuration.
- Column modes — Single (one tall scrollable column) or multi (as many columns as the viewport fits at the configured measure, with horizontal scroll-snap between them).
Column geometry is driven by the HTML Viewer section of the configuration sidebar: maxCharsPerLine sets the target measure in characters of the body font, columnGap the horizontal gap between columns in multi mode, and optimalLineBreaking toggles Knuth–Plass inside the viewer. See the HTML Viewer configuration reference and the end-to-end integration example for the same pattern used internally by the sandbox.
Generates a real PDF of the current document via the postext-pdf package and displays it inside an embedded browser PDF viewer. The PDF is rebuilt automatically on first mount and on every subsequent regeneration, using the same VDT that feeds the canvas and HTML tabs — so line breaks, page boundaries, and resource placement match pixel-for-pixel across the three backends.
A floating toolbar at the bottom-right of the viewport provides:
-
Regenerate (
RefreshCwicon) — Rebuilds the PDF from the current markdown and configuration. Useful after changing a setting that does not auto-trigger a rebuild, or when fonts have finished loading. -
Download (
Downloadicon) — Saves the current PDF to disk. The filename is derived from the document's first H1 heading (falling back todocument.pdf). -
Print (
Printericon) — Opens the browser's print dialog against the embedded PDF viewer, which in most browsers lets you either print or save as PDF again.
Under the hood the sandbox uses a createPdfFontProvider() helper that fetches per-weight static WOFF2 files from the Fontsource jsdelivr CDN, decompresses them to TTF in the browser, and hands the bytes to pdf-lib via renderToPdf. Per-weight static fonts (rather than a single variable font) are required so that bold text actually embeds at the bold weight. See Generating PDFs for the same pattern used outside the sandbox.
The Sandbox automatically saves your work to the browser's localStorage:
- Auto-save — Markdown content and configuration are saved after 1 second of inactivity
- Auto-load — On page load, the previous session's content is restored automatically
- Viewport state — Canvas view mode (single/spread) and fit mode (none/width/height) are persisted between sessions
- Section state — Which configuration sections are expanded or collapsed is remembered
For transferring your work between devices or sharing configurations:
-
Export (
Downloadicon in the activity bar) — Downloads apostext-sandbox.jsonfile containing both the markdown content and the full configuration -
Import (
Uploadicon in the activity bar) — Opens a file picker to load a previously exported.jsonfile
The export format is versioned for forward compatibility:
{
"version": 1,
"config": { ... },
"markdown": "# Your content..."
}The Sandbox is available as a standalone React package (postext-sandbox) that can be embedded in any React application:
npm install postext-sandbox postextimport { PostextSandbox } from 'postext-sandbox';
function App() {
return (
<PostextSandbox
initialMarkdown="# Hello World"
initialConfig={{ layout: { layoutType: 'double' } }}
onMarkdownChange={(md) => console.log(md)}
onConfigChange={(cfg) => console.log(cfg)}
/>
);
}| Prop | Type | Description |
|---|---|---|
initialMarkdown |
string |
Starting markdown content |
initialConfig |
PostextConfig |
Starting layout configuration |
className |
string |
CSS class for the root container |
labels |
Partial<SandboxLabels> |
i18n label overrides (defaults to English) |
onConfigChange |
(config) => void |
Callback when config changes |
onMarkdownChange |
(markdown) => void |
Callback when markdown changes |
themeToggle |
ReactNode |
Custom theme toggle component |
languageSwitcher |
ReactNode |
Custom language switcher component |
The package uses Tailwind CSS utility classes that reference CSS custom properties. Your host application must provide these variables:
-
--background,--foreground— Base colors -
--surface— Elevated surface color -
--gilt— Accent color (gold) -
--slate— Muted text color -
--rule— Border/divider color -
--accent-blue— Link/accent color -
--font-mono— Monospace font family (for the code editor)
The following features are planned for future versions:
- Resource management — Upload, manage, and reference images, tables, and figures from the markdown editor
- Collaborative editing — Share sandbox sessions via URL
- Preset configurations — Quick-start templates for common layout scenarios (newspaper, academic paper, book chapter)
- Custom micro-format toolbar extensions — Add buttons for postext-specific enriched markdown syntax as the specification evolves
Postext is MIT-licensed. Maintained by Ignacio Ferro and community contributors. See the live documentation for the most up-to-date reference.
Overview
Authoring
Internals
Community
External