Skip to content

Sandbox

Ignacio Ferro Picón edited this page Apr 22, 2026 · 1 revision

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.

Interface layout

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.

Activity bar

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 (FileCode icon) — Opens the markdown editing panel
  • Configuration (Settings2 icon) — Opens the layout configuration panel
  • Resources (FolderOpen icon) — 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

Sidebar panels

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.

Configuration panel

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.

Markdown editor

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.

Resources panel

Coming in a future version. This panel will manage the resources (images, tables, figures, pull quotes) referenced from the markdown content.

Main viewport

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.

Canvas tab

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.

HTML tab

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.

PDF tab

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 (RefreshCw icon) — 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 (Download icon) — Saves the current PDF to disk. The filename is derived from the document's first H1 heading (falling back to document.pdf).
  • Print (Printer icon) — 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.

Persistence

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

Export and import

For transferring your work between devices or sharing configurations:

  • Export (Download icon in the activity bar) — Downloads a postext-sandbox.json file containing both the markdown content and the full configuration
  • Import (Upload icon in the activity bar) — Opens a file picker to load a previously exported .json file

The export format is versioned for forward compatibility:

{
  "version": 1,
  "config": { ... },
  "markdown": "# Your content..."
}

Standalone usage

The Sandbox is available as a standalone React package (postext-sandbox) that can be embedded in any React application:

npm install postext-sandbox postext
import { 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)}
    />
  );
}

Props

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

CSS requirements

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)

Roadmap

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

Clone this wiki locally