Repository navigation
Sandbox
The Sandbox's interface: the activity bar and the Text, Books, Chapters, Resources and Fonts panels, and the layout on phones
Generated from docs/sandbox-en.mdx (updated 2026-10-16). Read it on postext.dev, where it is also available in Spanish, Catalan, Portuguese, French, German, Italian, Chinese, Japanese and Arabic. To change this page, edit the MDX and run pnpm wiki in apps/web.
The Sandbox is a free tool on this website for trying Postext without installing anything. You write your text on one side and see the finished pages on the other, and they change as you type. This page explains the parts of the screen and the panels where you write the text, manage books and chapters, add pictures and choose fonts. Other pages cover the design settings, the previews, saving and importing, and putting the Sandbox in your own website.
An interactive playground for the Postext layout engine.
The Sandbox gives you an editor-style interface where you write the text, manage resources and fonts, adjust the design, and see the result in real time in five synchronized views: canvas, PDF, Folio (the printed book in 3D), HTML and EPUB 3. It is built for experimenting. You can change the typography or the number of columns, try different figure placements, and watch how the engine responds. The panels use editorial words (books, figures, boxes, running heads) rather than engine terms, so people from publishing can find their way without knowing the configuration schema. Every control is keyboard- and screen-reader-accessible.
The Sandbox has three main areas: a narrow activity bar for switching panels, a resizable sidebar that holds the active panel, and a viewport on the right with the output tabs. The panel headers, the viewport's tab bar and the logo cell at the top of the activity bar share one height, so the top band reads as a single rule across the window.
Figure: Sandbox interface Activity bar on the left with six labelled panels, resizable sidebar in the middle, and viewport on the right with Canvas, PDF, Folio, HTML and EPUB 3 tabs.
Three areas: activity bar, resizable sidebar, and viewport with output tabs.
A narrow strip on the left edge has one button per panel. Each button shows an icon with a one-word label under it, and a longer hint as its tooltip (the same hint is the button's accessible description). From top to bottom:
-
Books (
Filesicon): your books and the sample books -
Chapters (
BookOpenicon): the open book and its chapters -
Text (
FileCodeicon): write and edit the text of the current chapter -
Resources (
FolderOpenicon): images, SVG drawings and tables used in the book -
Fonts (
Typeicon): the typefaces the book uses, and your own font files -
Design (
Settings2icon): page, typography, headings, figures, boxes and export settings -
Checks (
AlertTriangleicon): typesetting problems found in the layout. The icon carries a live count badge of current warnings, capped at99+.
Clicking the active panel's button collapses the sidebar, and clicking a different button switches to that panel. The bar is a single tab stop: the arrow keys (↑ / ↓, wrapping), Home and End move focus between the buttons, and Enter or Space opens the focused panel.
The host application can add its own items to the bar: an optional home logo link in the top cell (via the homeUrl or homeLink props), and a theme toggle and language switcher at the bottom. Whole books are exchanged as .postext files from the Books panel, and the Text and Design panel headers export their own part (see Export and import).
The bar above the preview starts with a switch between the two ways of working on a book:
- Content: the text is edited, in the Text panel and on the pages. The frames of a composed page stay where their template puts them.
- Design: page templates and styles are edited. The Text panel shows the chapter read only, with a note and an Edit the text button, and its toolbar is off. A click on a frame of a composed page picks that frame for the template editor instead of placing the caret.
Alt+Shift+M (⌥⇧M on a Mac) switches modes from anywhere in the Sandbox. Switching to Design while the Text panel is open opens the Design panel, and switching back opens the Text panel again. The browser remembers the mode. Agents read and set it with sandbox_set_view (mode).
The sidebar is resizable. Drag the separator between the sidebar and the viewport, or focus it with Tab and use the keyboard: ← / → change the width by 2 % (10 % with Shift), and Home / End jump to the narrowest and widest sizes. The separator announces its current value to screen readers, and the viewport always keeps at least 200 px. The sidebar collapses entirely when no panel is active, and its width is remembered between sessions.
Settings rows put their label beside the control, or above it when the sidebar is narrow. This uses container queries, so it follows the sidebar's width rather than the window's.
A CodeMirror 6 editor for the chapter's Markdown. Screen readers announce it as Chapter text. It has:
-
Syntax highlighting: headings, emphasis, links, code blocks and blockquotes are visually distinct, with dedicated highlighting for YAML front matter, LaTeX math regions, inline chips (
:chip[…]: the brackets and attributes are marked and the chip text is tinted), small capitals (:smallcaps[…]: the brackets are marked and the text is shown in small caps), the orientation marks of vertical text (:tcy[…],:upright[…],:sideways[…]: the brackets marked, the text with a dotted underline) and the Chinese annotations (:dots[…],:name[…]and:book[…]with their marks drawn under the text;:ruby[…]{rt="…"}and{紅樓|hóng|lóu};:warichu[…]with the note set smaller). Typing:do,:na,:bo,:ruor:waoffers the directive -
Chip completion: typing
:cat the start of a word offers:chip[…](the caret lands between the brackets). Inside{style="…"}the configured chip style ids are offered. -
Small-caps completion: typing
:smat the start of a word (or right after*/_) offers:smallcaps[…], with the caret between the brackets. -
Tabs:
:taband:tab{…}are highlighted and offered in completion like the other inline directives. The editor's Tab key does not type a tab character, so:tabis how a tab is written in the Sandbox; a tab character pasted with the text is kept, and is a tab in a paragraph whose style sets tab stops. - Line numbers and active-line highlighting
- Line wrapping for long paragraphs
-
Right-to-left lines: a line whose text starts with an Arabic or Hebrew letter runs right to left, and the caret and the arrow keys follow it. The markup inside it (
{…}attributes,[^id]labels, the name of a directive, a whole:ref[fig-1], maths, code, link targets) stays left to right, so it reads as typed. Fences, front matter and lines that start in a Latin word are left to right as before. -
Toolbar: starts with Undo / Redo, followed by bold, italic, heading levels 1–3, link, inline code, chip (wraps the selection in
:chip[…]), small caps (wraps it in:smallcaps[…]), blockquote, ordered and unordered lists, plus five inserters::::pagebreak-
:::space: one line of vertical space (:::space{lines=N}for more) -
Columns: a two-column
:::columns{count=2}group, the caret on its first line, in the text or in a box (since postext 1.25) -
:::numbering{format="decimal" startAt=1}: inserted with example attributes you can adjust -
Composed page: opens a picker with the book's page templates, each drawn as a thumbnail of its empty frames. Choosing one writes a
::::page{template="…"}fence with an empty:::frame{slot="…"}for each frame. A frame that only receives what another frame's text continues with gets none; a frame thattakesa heading gets that heading, with the frame's name selected to type over, and the flow frame gets a blank line for the running text
A code listing (a ``` or ~~~ fence and its lines) is one region in the editor: it gets a code background, and the Postext markup inside it (maths, chips, tabs, index marks) is left uncoloured, as the engine leaves it unread. Host applications can add their own toolbar buttons through extraActions. The editor also reports its cursor and selection to the previews, which enables click-to-caret sync: clicking text in the rendered output moves the caret to the matching Markdown position, and the previews can highlight the current selection.
The panel header is a chapter switcher: previous/next arrows, the chapter's position and title, and a menu listing every chapter of the book with its page range once its pagination is known (see Books and chapters). Each chapter has its own editor instance, so undo history and caret position are kept per chapter. The header then offers five actions:
- Reset (asks for confirmation): reloads the document part of the open sample book. Every chapter and the whole figure set are replaced with the sample's (for the built-in sample, the locale's sample document and example resources). The design is left alone except for the sample's own fonts. See Books panel.
-
Export: downloads the active chapter as a plain
.mdfile, named<book>-<nn>-<chapter>.mdin a multi-chapter book, and otherwise after the open book ordocument.md -
Import: replaces the active chapter with the contents of a
.mdfile -
Import a Word document: opens a
.docxmanuscript and maps its Word styles to Postext styles before anything changes (see Word documents) -
Export to Word: downloads the chapter or the whole book as a
.docxthat comes back with every style when it is imported again
The first panel in the activity bar: the gallery of your books and the sample books, with the New menu, the status of the last operation and the banner of a sample book that has a new version. In code and storage a book is still called a project, and a sample book a preset.
Clicking a book (or one of a sample book's language tags) opens it, and once it is on screen the sidebar moves to the Chapters panel. Clicking the book that is already open goes there straight away. The row menus (rename, duplicate, download, hide, delete) never change panels. The open book stays marked in the list. The panel has two groups:
-
My books: local, editable books stored in the browser (IndexedDB). The open one is marked; its chapters are in the Chapters panel.
While a book of your own is open, the working document is that book. Every edit to the text, design, figures and fonts is saved into it automatically (with the same 1-second debounce as
localStorage), so you can switch books and come back without losing anything. You create books from the header's New menu:- Copy of the open book copies the open book, its figures and fonts into a new book.
- Blank book starts an empty one.
- Open a .postext file… imports a file.
You can also duplicate any row. While you have no books of your own, the group shows an empty state with the same shortcut. Each row has one labelled ⋯ menu (More actions for "…") with Rename…, Duplicate, Download (.postext) and Delete…. Delete asks for confirmation right next to the ⋯ button.
Rename opens inline name and description fields. Enter in either field commits both, and Escape cancels.
A book also carries a cover image, shown where a sample book shows its thumbnail. Making a copy of a sample book (or of another book) adopts its cover. While a row is being renamed, the cover is the control that sets it: click it to choose a PNG, JPEG, WebP, GIF or SVG, or use the X beside it to remove the current one. The cover belongs to the book, not to its figures, and travels with it through export and import.
A book without a cover gets one from its first page (the first page of its first chapter): the first time that page is laid out and painted in the Canvas tab, the Sandbox takes a small picture of it (240 px wide, JPEG) while the browser is idle, once the fonts and the page's pictures are in. It is stored as the book's cover, so a download carries it as the bundle's
thumbnail. A sample book that ships no thumbnail gets one the same way, kept in the browser (thepresetCoversstore of the IndexedDB database, one per sample and language), shown in its row and adopted by a copy or a download of it. An existing cover is never replaced, whether it came with the sample, with an imported file, from your own choice or from an earlier capture. A cover you remove is taken again from the first page on a later visit.Opening a book never asks for confirmation: the book you leave is saved first, whatever it is. While the next one loads, the viewport shows Opening the book… instead of the book you left. Deleting the open book falls back to the built-in sample.
-
Sample books: starting points, listed below your books. The bundle itself is never changed, but your edits to a sample book are kept: the first change saves a copy of it (its draft) in the browser, one per sample and language, and the row shows an Edited tag. Opening that sample again, in that language, brings your version back; a sample you never changed opens as published. The ⋯ menu of each row offers:
- Make my own copy turns the sample into a book of your own that holds its own copies of the bundle's files, so later edits to the bundle on disk never touch it.
-
Download (.postext) saves the sample as a
.postextfile. - Hide from the list removes the sample from the list (the built-in one cannot be hidden).
- Restore the original… discards your changes to the sample (in every language) and, when it is open, loads the published version in its place. It asks first, and only appears on edited samples.
A sample in several languages shows one tag per language, in the order its manifest lists them: 繁 and 简 for Traditional and Simplified Chinese, the language code (EN, ES) for the others; the tooltip names the language in the interface language (Load the Traditional Chinese version). A sample whose original is in another language than the interface (a Chinese novel with an English translation) says which one it opens in (
openLocale, see Preset bundle format), so a click on its row brings up the original.Hidden samples are collected under a Hidden sample books disclosure at the bottom of the group, each with Show in the list. The choice is remembered in
localStorage.
A .postext file opened from the New menu becomes a new, open book. A file in several languages first asks which one to import, starting from the one it is written in (its manifest's locale). Exporting is a per-row action: the open book's row exports what is on screen. A .postext file is a preset bundle directory zipped (see Export and import).
The Reset buttons in the Text and Design panels restore the sample a book was copied from. A blank or imported book has no original, so the buttons are hidden while it is open.
The second panel in the activity bar shows only the open book. At the top, its name, what kind of book it is (Your book, or Sample book with its language and an Edited tag once you change it) and a ⋯ menu with the actions on it: Rename… for your books (a double-click on the name does the same), Duplicate or Make my own copy, Download (.postext), and Restore the original… for an edited sample book.
Below, its chapters fill the rest of the panel and scroll on their own (see Books and chapters). Each chapter row shows its page range and word count, and the active chapter is marked. A Chinese, Japanese or Korean book counts characters instead: each Han character, kana or hangul counts one, and so does each Latin word among them. Add chapter sits in the panel header next to the chapter count, rows reorder by dragging their grip (or with the arrow keys on it), and each chapter's ⋯ menu offers Rename, Move up / down, Split at level-1 headings, Merge into previous chapter and Delete (the last chapter can never be deleted).
A preset bundle is a whole starting point loaded as one unit: the chapters' Markdown, a PostextConfig, the resources (with their bitmap/SVG payloads and table models), and the custom font files the config refers to. The panel lists every preset the Sandbox can reach and marks the open one:
-
Built-in preset: the Postext guide, the default sample book shipped with the package. It is always available, always first in the list, and public. It comes in English, Spanish, Catalan, Arabic, Simplified Chinese, Japanese and Brazilian Portuguese (the row's ES, CA, EN, ع, 简, 日 and PT buttons;
#preset=postext-guide&lang=zh-Hanslinks to the Chinese edition,lang=arto the Arabic one,lang=jato the Japanese one,lang=pt-BRto the Brazilian Portuguese one). The Arabic edition is an Arabic book: right to left, bound on the right, Arabic-Indic digits, Amiri, Noto Kufi Arabic and IBM Plex Sans Arabic, kashida justification and figures drawn in mirror with Arabic labels. The Chinese edition has a design of its own (Noto Serif SC and Noto Sans SC, mainland punctuation and line breaking) and figures drawn with Chinese labels. The Japanese edition is a vertical book too, set by the Japanese rules (JLReq): Noto Serif JP and Noto Sans JP, 9.25 pt type on two tiers of 34 characters, section headings three lines deep (行取り), running heads and Arabic folios across the head and foot, figures with Japanese labels. Each interface opens the guide in its own language. An untouched Chinese, Japanese or Arabic guide opened from another interface (its button or alang=link) stays in its language whatever the interface language; the one the Chinese, Japanese or Arabic interface opened itself changes to the language the Sandbox is next opened in, like the other editions. -
Remote presets: bundles served over HTTP from the base URLs passed in the
presetSourcesprop (see Props). Each source is either public or private. Private presets are tagged Private in the list and are meant for material that must not leave a machine. The public website only lists a private source in local development, where the Next.js app serves the folder named byPOSTEXT_PRIVATE_PRESETS_DIRthrough/api/private-presets. Production never lists it. The website's public source,/presets, serves its sample books: Bioquímica, Deep Sky, Don Quijote, Physics (OpenStax), Spanish Painting and Signals 2020 in Spanish and English, Dream of the Red Chamber in three editions, and Paradise Lost in English, with Verity’s notes as footnotes and Doré’s plates. Each comes with its licence and credits. -
default: true: a private preset flagged as default is loaded automatically the first time a pristine Sandbox (untouched built-in document) opens. When several are flagged, the one whoselocalematches the UI locale wins. Public presets are never loaded automatically.
Each row shows the preset's name, an optional description, its locale tag and its Private / Default tags. Clicking a row loads the preset in full: text, figures, design and fonts. The Sandbox first writes the font files and figure data to IndexedDB, so the viewports never see a half-applied document. Clicking a row opens the sample in the interface language, unless you have only edited it in another language: then your most recent version opens. A bilingual sample's language tags open it in that language (your version there, if you have one).
Live presets. Remote presets are followed automatically. Whenever a preset is applied, the Sandbox records the bundle's fingerprint along with hashes of the Markdown, configuration and resource set it applied. While the page is visible, it polls the fingerprint every 3 seconds, and immediately when the tab becomes visible or the window regains focus. When the fingerprint changes:
- If the book is untouched (Markdown, configuration and resources still hash to what the preset applied), the preset is re-applied in full and a brief notice appears in the panel.
- If there are local changes, they are kept. A banner at the top of the panel (This sample book has a new version. Your changes are kept.) offers Load the new version, which asks before it discards your changes to that language of the sample, and the Books button in the activity bar shows a dot meanwhile. The draft remembers the version it was made from, so the banner comes back each time you open it until you load the new version. Figures of the draft whose files changed in the new version keep the bytes they had: the draft gets its own copy of them before the bundle's are written. Bundles are only followed while a sample book is open. A book copied from one keeps its own copy.
The same check runs on load, so if you edit a bundle and then open the Sandbox, it picks up the new version as long as the book was untouched. The fingerprint comes from <preset-dir>/fingerprint.json. On the development route this is a virtual file that returns a metadata-only hash of the directory (see the Preset bundle format appendix). Sources that do not serve it are not followed.
The open sample book also defines what the other panels' Reset buttons restore:
| Panel | Reset restores |
|---|---|
| Text | The sample's text and its figure set (the document part) |
| Design | The sample's design, its fonts included |
| Books (Restore the original…) | Everything: text, figures, design and fonts |
A preset that was open in an earlier session but is no longer listed by any source (typically a private preset in a build that does not serve it) still appears, greyed out as Not available in this build. The Sandbox keeps the loaded content instead of silently swapping it for the built-in sample. The open preset's id is persisted under the postext-sandbox-preset key (see Persistence). The bundle format is described in the Preset bundle format appendix.
Manages the book's resources: bitmap images, SVG figures, tables and videos. The text refers to them with ::resource{id="…"} blocks and :ref{id="…"} inline references. For the reference syntax and the float model, see Document format → Resources.
List view. The header shows the number of resources. Resources are grouped by their resource-type name, and each group is a counted list. Resources whose typeId no longer matches a configured type fall into an Untyped group so you can still reach them. Each item shows a 36 px thumbnail next to its caption and id: a real preview for bitmaps and SVGs, the poster with a play badge for videos, and a glyph for tables. When the book has more than six resources, a search field (Search resources…) filters the list by caption and id, ignoring accents. When the book has no resources yet, an empty state explains how to add them and place them in the text with :ref{#id}. A New dropdown offers four ways to add one:
- Upload image: PNG, JPEG, WebP or GIF
- Upload SVG
- New table: starts as a 2×2 grid with one header row
- Add video: a YouTube or Vimeo video, a video file, or the address of one (an MP4 or an HLS stream; see Video below). A book whose resource types predate videos gets the built-in Video type when it adds its first one.
You can also drag and drop files from disk onto the panel, video files (MP4, WebM, Ogg, QuickTime) included. They upload in bulk, with ids slugified from their filenames. Unsupported files are skipped, and a short note reports how many were added and how many were skipped.
Detail view. Selecting a resource opens its editor:
- ID: editable and slug-validated. Duplicate ids are flagged and never committed, and an empty id gets a suggestion derived from the caption. Renaming keeps the stored image or SVG file.
- Type: one of the configured resource types
-
Caption: supports inline Markdown (bold, italic, code and
:ref).\\, or a backslash ending a line, starts a new line; a plain line break counts as a space - Note: an optional source line, credit or remark, set in a smaller run under the resource (same inline formatting and line breaks as the caption). It is styled by the Note group of the Captions settings.
- Alt text: accessibility description for the HTML output
-
Table style: for tables, the named style the table is set in (
table.styleId). This is either Document table style (the default) or one of the Table styles declared in the settings. An id that no style declares is listed as missing and renders with the document table style. -
Placement:
-
Position:
auto(the first free slot, the default),top,bottomorhere. -
Span:
column,pageorside. It is disabled when the position ishere. The defaults match the engine's,auto+column. -
Columns: how many adjacent columns a column float takes on a page of several columns (
placement.columns), such as a picture across two of a newspaper's four. As many as the page has makes it page-wide. It shows when the book or one of its sections has more than one column and the span iscolumn, and not for a resource sethereor turned. - Orientation: upright, or turned a quarter turn (top to the left, or to the right). A turned resource takes a page of its own, flush to the spine, so the span select is disabled.
-
Width: a width fraction with an alignment, for floats and inline embeds narrower than their column. The alignment also places a bitmap or SVG narrower than its slot at full width (a bitmap smaller than the column, or a figure
layout.fitFiguresToPageshrank), so it stays enabled for pictures; for a table it needs a width under 100%. A turned resource has neither. -
Caption beside the figure: a toggle for the side column of a column-and-a-half layout. It applies to column floats, so it is hidden when the position is
here. -
Shrink to fit: for a floated picture, Never, On a fresh page or In any slot (
placement.shrink), with Smallest scale (placement.minScale) once it shrinks; and Caption width, Slot or Picture (placement.captionMeasure), for any picture that is not turned. Resource types offer the same three fields in their default placement. -
Head the page that cites it: for a top or automatic float of a column or page span that is not turned (
placement.citingPage): it may take the head of the page or column where the line citing it lands, the text above the reference moving down under it. Resource types offer the same switch in their default placement. -
Text wrap: for a resource set in the text or a one-column float, None or the side of the column it sits on with the text beside it (
placement.wrap), and its Wrap gap (placement.wrapGap) once it wraps; a wrapped resource with no width of its own shows the layout's default share. Resource types offer both in their default placement.
-
Position:
- Payload: uploaders that replace the bitmap or SVG file
-
Size and resolution: for a bitmap, its pixels, the resolution its file states (none stated, or 72 and 96 marked as read as unset), its natural size in mm at the resolution it is laid out at, and the ppi it prints at where the current layout places it (the lowest when it is placed more than once). Under the preflight's minimum it shows in the warning style, under the critical one in the critical style, with Open in Checks for a book set up for print. Resolution sets the picture's own ppi (
bitmap.resolution; see Document format › Bitmap size), and Use the file's … ppi fills it in from the file. An uploaded picture keeps the resolution its file states (bitmap.fileResolution). -
Video: for a video resource (Document format › Videos):
- Source: YouTube, Vimeo or File.
- Video address (YouTube, Vimeo): any link of the video. When it names a new video, its poster, frame size and title are fetched from the platform (the title becomes the alt text when that is empty); Fetch the poster again repeats it. A link that names no video of the platform is flagged under the field.
-
Video file (File): the uploader of an MP4, WebM, Ogg or QuickTime file, with its format, size and length. A first poster is taken a tenth of the way in. Poster frame plays the file: stop or scrub on the frame you want printed and press Use this frame as the poster. Production address: where the published video will be (
https://…), opened by the QR code and the PDF link; without it print gets no QR code or link. -
Video address (File, with no file uploaded): the video plays from its address alone, an MP4 or WebM on a server or an HLS stream (
.m3u8, marked HLS stream above the field). Entering an address reads the video's size and length, and Poster frame plays it from there, HLS included. Picking a frame needs a server that allows cross-origin reads (CORS); otherwise the panel says so, and the poster is uploaded instead. The QR code and the PDF link open this address. - Poster: the printed picture with its size, and an uploader to replace it with a picture of your own.
- Start (s) / End (s): the part that plays; 0 leaves the start or the end as it is.
- Player: this video's switches (controls, download button, full screen, speed menu, picture in picture, autoplay, muted start, loop, play alongside other videos), each Book setting, Yes or No. Only the switches the video's player honours are listed.
-
Safe area: for bitmaps and SVGs, the part of the picture that is always shown (
Resource.safeArea; see Document format › Safe area). The field shows a thumbnail with the area marked and its size in percent, or None when the picture has none, with Mark safe area / Edit safe area and Remove safe area buttons. The dialog shows the picture: drag outside the rectangle to draw a new one, inside it to move it, or from its handles to resize it; with the rectangle focused, the arrow keys move it and Shift with the arrows resizes it. Left, Top, Width and Height fields set it in percent, and two previews show the tallest and the shortest crop the area allows. -
Fonts in the drawing: for SVG figures, the families the drawing's text names (family, weight, style) and what became of each: embedded with its size, declared in the SVG (the file carries its own
@font-face), no font file (the image falls back to another face) or over the size cap. The faces come from the book's custom fonts, then from Google Fonts, and are embedded only when the picture is shown or exported, never in the stored file. Embed the book's fonts turns it off for this figure (svg.inlineFonts: false), for an SVG that carries its own faces or must stay as it is. -
SVG source: for SVG figures, a source editor under the uploader. Only the text nodes accept edits: the content of
<text>/<tspan>elements, tinted in the editor. Typing anywhere else is rejected, and<,>and&typed into a text node are escaped so the file stays well-formed. Each change is saved after a short pause as a new stored file, and the figure re-renders (single-ink recolouring included). The editor notes when the SVG has no text nodes. -
Preview: a live mock-up of how the resource will look, with
#standing in for the number (real numbers depend on where the resource lands in the document). The caption opens with the label the document sets: the type's caption prefix and the number (Figure #.), the prefix alone for a type numbered with an empty template (Do.), and nothing for a type with no caption prefix -
Delete: asks for confirmation first, and warns how many
::resource/:refreferences in the text would be left pointing at nothing
Table editor. Table resources open an interactive grid editor:
-
Toolbar:
- Add or remove rows and columns, and merge or split cells.
- Toggle a header row or a header column.
- Set each cell's horizontal and vertical alignment (top, middle or bottom). The cell content moves as one unit inside a taller row.
- Set each cell's fill: a colour picker, palette-linkable, with a clear button. The fill is written to
TableCell.backgroundand shown in the grid.
-
Column widths: one numeric weight per column under the grid (
2, 1, 1gives the first column half the width; empty means equal widths), written totable.model.columnWidths. Adding or removing a column keeps the weights aligned, and an Equal widths link clears them. - Paste as table: pasting TSV (or simple quoted CSV) fills the grid
- Undo/redo: Cmd/Ctrl+Z and Shift+Cmd/Ctrl+Z
- Keyboard navigation: Tab / Shift-Tab (with row wrap) and the arrow keys move between cells
- Click to edit from the preview: click a table cell, a caption, a note, or a text fragment of an SVG figure on either preview tab. The Resources panel opens on that resource and focuses the matching field, with the caret on the clicked glyph. Dragging selects a range inside the same cell or field, and a double-click selects the word. While the field has focus, its selection is mirrored back onto the page as a highlight (a thin caret when collapsed) on both the Canvas and HTML tabs.
All edits go through pure model functions exported by the postext core (addRow, addColumn, removeRow, removeColumn, mergeCells, unmergeCell, setCellContent, setAlignment and parseTSV), so the same table model behaves identically inside and outside the Sandbox.
Shows the typefaces the book uses and manages your own font files alongside the built-in Google Fonts catalogue:
- Typefaces in this book lists every family the design uses. Each family name is set in its own typeface, with its role (Body text, Headings or Other elements) and its source: Google Fonts, Fontsource (a family Google Fonts does not have), Your file, or Not found for a family no source has. The source appears once the loader knows it. You change the typefaces themselves in Design → Typography and Headings & contents.
-
The files a book is measured with. A family of Google Fonts or of Fontsource is set from Fontsource's static files on jsDelivr (
@fontsource/<family>@5), one per weight, style and subset. They are the files a Cookbook pen loads and the PDF embeds, so a book breaks its lines at the same words in the previews, in its PDF and in a pen. The command line lays out withbodyText.shapingLanguage: 'host', so a line can break at another word there (see Differences from the Sandbox). The previews declare the weights and styles the design and the pages use, and the browser loads each file when the text needs it. Since postext 1.30 the previews also wait, before they first paint a chapter, for every face its laid-out pages name, loaded for the characters of those pages (a family cut into more than 16 files per face, a Chinese or Japanese one, loads them as before). From postext 1.28.3 to 1.29.2 a face only the pages name, set in a script other than Latin (the italic of the summaries of an Arabic contents page), was painted in a fallback face until its file arrived. A weight between two cuts of a variable family (a 450) has no static file: the previews set it from Google's variable file at that weight and the PDF embeds the nearest cut, so choose a weight the family has when the two must agree. A family Fontsource has no files for is taken from Google's style sheet. Every file of a family comes from one version of its package, the one jsDelivr answered its style sheet from:@5names whatever version each address resolves to, and after a release that cuts a family again its files could come from two cuts. - A file that is slow, or that the network does not give. The files of a book's faces are fetched before its first layout, and the layout waits for them as long as they keep arriving: a book of several hundred files (a Chinese or Japanese one) on a slow connection is laid out once, with all of them. The requests are given up only when no font file has received anything for 15 seconds; the chapter is then laid out with the faces that have arrived, the others in the fallback its warnings name. Such a layout is provisional: its page counts are not stored with the book nor written to a bundle. The file is asked for again three times, half a minute apart, and by every later layout; when it arrives, the previews and every chapter laid out without it are laid out again, contents and page references with them, and the PDF and the EPUB are marked out of date.
-
A weight or slant the family does not have. The previews and the PDF set each family in its own files. Where a family has no bold (Bangers, Zen Antique and most display faces ship one weight) or no italic, the bold and the italic are set in its nearest face as it is, without the heavier or slanted letters a browser would draw, and no
fontFallbackis listed for them. A weight another real face of the family answers (a 600 set from the 700) is listed. A family Fontsource carries that Google Fonts does not, such as Commit Mono, is loaded from Fontsource. -
Your font files is where you add, rename and delete custom families.
- Upload variant files per weight (100–900) and style (normal / italic). Accepted formats are WOFF2, WOFF, TTF and OTF, detected by file extension. The files are stored in the browser's IndexedDB.
- Custom families appear in every font picker under a Custom group alongside the Google Fonts results. A custom family takes precedence over a Google Font with the same name.
- In a Chinese document every font picker lists first, under Simplified Chinese or Traditional Chinese, the Google families that hold the document's characters (Fontsource's
chinese-simplified,chinese-traditionalandchinese-hongkongsubsets), then the rest. - In a document in Arabic (or another language written in the Arabic script) every font picker lists first, under Arabic, the Google families with Fontsource's
arabicsubset, the book faces first (Amiri, Noto Naskh Arabic, Scheherazade New, Markazi Text, Lateef, then Noto Kufi Arabic, Reem Kufi, Aref Ruqaa, El Messiri). The previews load each face's Arabic file before the first layout, and the PDF embeds it with the Latin one when the text uses both. - Orphaned font files (uploads no longer used by any family) are removed from IndexedDB automatically.
Below 768 px wide the Sandbox switches to a layout of its own:
- Panels. The panel bar moves to the bottom of the window, with the same buttons in the same order. An open panel covers the preview instead of sitting beside it; the preview stays where it was underneath, out of the tab order, so closing the panel finds it on the same page.
- Top bar. The output tabs, the scope selector (the rendition choice on the EPUB tab) and the host's controls (large targets, theme, language) share the bar above the preview. Below 640 px it takes two rows: the logo, the scope and the controls above, the tabs below, sharing the full width; five tabs fit at 320 px.
- Toolbars. The floating toolbars of the previews dock along the bottom of the preview and wrap onto a second row when they do not fit.
- Folio. The Folio tab is not offered on a phone's screen (see Folio tab).
- PDF. Phones and touch-only tablets cannot show a PDF inside the page (Android has no inline viewer, and iOS draws only its first page), so the PDF tab shows a card with Open PDF instead, which opens the file in a new tab; the toolbar's Download still saves it.
The following features are planned for future versions:
- Collaborative editing — Edit one book together from several browsers
Postext is MIT-licensed. Maintained by Ignacio Ferro and community contributors. See the live documentation for the most up-to-date reference.
Overview
Writing
- Document Format
- Hyphenation and Justification
- Chinese Layout
- Arabic Layout
- Japanese Layout
- Comics
- Composed Pages
- Sandbox
- Agent Skill
- Command Line
- WebMCP
Configuration
- Overview and index
- Page and layout
- Headers and footers
- Body text
- Hyphenation and language
- Headings
- Widows, orphans and balancing
- Lists and maths
- Notes and references
- East Asian typography
- Resources
- Styles and parts
- Callout boxes
- Comics
- Composed pages
- Fonts, colours, viewers
Code
Internals
External