Files
Artstr-Studio/docs/BOOK_DESIGNER_TUTORIAL.md
T
thePR0M3TH3ANandClaude Opus 4.7 f50d92043c docs: add BOOK_DESIGNER_TUTORIAL.md
Hands-on end-to-end walkthrough for the Book Designer feature —
setup, starting a book (templates / deck-import / scratch), Document
settings, masters + text-frame, Pages overview, designed-page editor,
chapter editor (full feature exercise: tables, task lists, footnotes,
xrefs, {toc}, {index}, ^[term]), cover view, visibility chip,
publishing order, resolver behaviour, Reader Mode, embed integration,
PDF export modal, tokens reference, edge cases to probe, and a
codebase map.

Companion to docs/BOOK_DESIGNER_FEATURE.md (the spec).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-04 08:41:25 -04:00

377 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Book Designer — End-to-End Tutorial
This is the hands-on walkthrough for authoring, publishing, sharing,
and exporting a book in Artstr Studio. For the full spec see
`BOOK_DESIGNER_FEATURE.md`.
---
## 0. Setup (one-time)
- Sign in with a Nostr extension (top-right). For private-publish testing the
extension needs NIP-44 or NIP-04 (most modern extensions do).
- In **Project Metadata** (left sidebar, any mode) set a **Title** and
**Category**. The book uses these for the manifest's d-tag and tag set.
---
## 1. Start a new book
In the **Template** tab on the left, pick the **Book** entry. The canvas
switches to the Pages overview.
Three ways to start:
- **Starter template** — when Pages overview is empty, four cards appear
(US Trade 6×9 / A5 / A4 / Square 8×8). Click one. The book is seeded with
a default master + text-frame, a starter chapter, and a "Title page"
designed entry.
- **Convert from deck** — if you have an existing deck (Deck mode →
slides), click **→ Convert to book** in the deck-sorter toolbar. *Or* a
"Convert deck to book" card appears on the empty Pages overview if a
deck exists. Each slide becomes one designed page (letterbox-fit into the
trim).
- **From scratch** — skip the starter cards. Use `+ Add page`,
`+ Add chapter`, or open `Document settings…`.
---
## 2. Document settings
Open via the book sidebar → **Document settings…**.
- **Book size**: preset (US Trade / US Letter / A5 / A4 / Square) or
**Custom** to enter arbitrary trim/bleed/paper-thickness.
- **Spine width**: derived from page count × paper thickness by default,
or toggle off to enter manually.
- **Cover layout**: include spine? include back?
- **Page numbering**: enabled / startAt / firstNumberedPage / format
(use `{n}` or `Page {n}` etc).
- **Typography** (expand the `<details>` block): override fonts / sizes /
weights / colours per element — body, h1–h6, blockquote, codeBlock,
inlineCode, link, list, hr. **Reset to defaults** restores the v1
stylesheet.
---
## 3. Masters
Open via the book sidebar → **Manage masters…**.
A master is a reusable underlay applied beneath every page that uses it.
The starter template gives you one ("Body pages") with a text-frame
already added.
- Click a master row's **Edit** → master-edit mode. The canvas now binds
to `book-master:<id>`. Add headers, page-numbers, etc.
- Use the **+ Text frame** button (visible only in master-edit) to add
the reflow target if missing.
- Header / page-number text layers can use **tokens** — literal in the
master, resolved at render time per page:
- `{page-number}`, `{page-count}`, `{physical-page-count}`
- `{book-title}`, `{book-author}`
- `{chapter-title}`, `{chapter-number}`
- Click **← Back to masters** to leave the master.
---
## 4. Pages overview
Each tile is one manifest entry — a designed page or a reflow chapter
segment.
Tile hover reveals actions (top-right):
- 📄 proof PDF (just this entry)
- ⎘ duplicate
- × delete
- master-picker dropdown (per-tile override)
Toolbar buttons:
- `+ Add page` — blank designed page.
- `+ Add 10 pages` — bulk.
- `+ Add chapter` — reflow entry; opens the chapter editor immediately.
- `+ Import page` — paste an `naddr` / `nevent` to another author's
`casewrap-page` event. Imports as a `ref:`-only entry; layers paint
via the resolver.
- `▶ Read` — Reader Mode.
- `Export PDF…` — export modal.
Drag tiles to reorder.
---
## 5. Designed page editor
Click a designed-page tile → opens the canvas. Top bar shows
**← Back to Pages**, **← / →** prev/next, **Publish**, **📄 Proof PDF**,
**⚡ Free / N sats**.
- Add layers like any other Artstr canvas — text, shape, image, QR,
pixel-art, linked design.
- Master layers render underneath at 55 % opacity (non-interactive while
page-editing).
- Tokens in *master* layers resolve to this page's context; the same
tokens in this page's own text layers stay literal.
---
## 6. Chapter editor (reflow)
Click a chapter tile → markdown-on-left, preview-on-right.
The textarea upgrades to **CodeMirror** with markdown syntax
highlighting + smart Enter (auto-continues list bullets, breaks out of
the list on an empty item).
### Try every feature in one chapter
```markdown
# Chapter Title
A paragraph. **Bold**, *italic*, `inline code`.
## Sub-heading
Cross-ref: see [the intro](#chapter-1) and [the index](#index).
A ^[GFM table] example:
| Col 1 | Col 2 |
|-------|-------|
| a | b |
A task list:
- [ ] todo
- [x] done
- nested item
A footnote ref[^1] in the middle of a sentence.
[^1]: This is a footnote definition.
{toc}
{index}
```
What this exercises:
- `{toc}` → renders as a heading list with page numbers.
- `{index}` → sorted list of every `^[term]` marker in the book.
- `^[term]` → invisible in body; registers in the index.
- `[^N]` + `[^N]: def` → superscripted ref + "Footnotes" section
appended to the chapter.
- `[text](#chapter-3)` / `[text](#some-heading)` → gets `(p. 12)`
appended.
- GFM tables, task lists, nested lists all paginate.
### Chapter source-bar buttons
- **Import from Nostr** — paste an `naddr` / `nevent` / `note` / hex
pointing at a NIP-23 (or encrypted) article; pulls into
`chapterMarkdown`.
- **Publish chapter** — mints a `kind-30023` (public) or `kind-30078`
encrypted (private) article event under `chapter:<slug>` or
`book-chapter:<entry-id>`. Re-publishes replace in place.
- **↻ Refresh** — re-fetches a linked chapter (live or pinned).
- **Pin to current** / **Set to live** — freezes a specific event id
vs follows the d-tag.
- **Unlink** — disconnects the textRef.
- **📄 Proof PDF** — exports just this chapter's paginated pages.
### Readouts
Top right of the chapter editor shows word count + paginated page count
+ first warning ("Block too tall for the text-frame", "Long word
doesn't fit", etc). If you see a warning, your text-frame is too narrow
or your prose has a word longer than a column.
---
## 7. Cover view
Pages overview → **Cover** tab.
- Spec summary + spread preview (back / spine / front panels).
- **Edit cover** → canvas widens to the full spread. Layers land on
`book-cover-front` by default; the layer-target dropdown switches
between **Front cover / Spine / Back cover**.
- **Publish cover** (top-bar) → `kind-30078` with `role:'cover-spread'`.
---
## 8. Visibility chip
Bottom of the book sidebar. Two states:
- **Public** (default) — every event publishes plain-text.
- **🔒 Private** — manifest + every sidecar publish goes through the
encrypted envelope (AES-256-GCM, with the AES key NIP-44/NIP-04-wrapped
to *your own* pubkey only). The chip is disabled if your extension
lacks encryption capability. Publish-buttons show 🔒 to make this
visible from inside any editor.
---
## 9. Publishing flow
Per-surface publishes are **independent** — you can publish a single
page without touching the manifest. To make the whole book discoverable
as one event, also publish the manifest.
**Recommended order:**
1. Open each chapter → **Publish chapter**.
2. Open each designed page → **Publish page**.
3. Open the cover → **Publish cover**.
4. Manage masters → publish each master via **Edit** → top-bar
**Publish master**.
5. **Publish** in the top app bar → publishes the `casewrap-book`
manifest with `link` tags pointing at every sidecar.
The book sidebar shows **⚠ Manifest has unsaved changes** when any
spec / order / list change diverges from the last published manifest.
---
## 10. Resolver (on re-open)
When you reload the page or open the book on another device:
- Autosave restores `state.book` from local storage.
- The resolver fetches every referenced page / master / cover / chapter
from your relays.
- Cached events come from `localStorage` first (warm re-opens paint
instantly; cap 2 MB total content, LRU evicted).
- A background probe checks each ref for a newer upstream version →
tiles get a yellow **↑ Update** chip; click to apply.
- Force-refresh: book sidebar → **↻ Refresh from Nostr**.
---
## 11. Reader Mode
Pages overview → **▶ Read**.
- Click left half of the page = back, right half = forward.
- Keyboard:
- **← / →** flip
- **Space / PageDown** advance
- **PageUp** back
- **Home / End** first / last
- **Esc** exits
- **☰ TOC** toggles the chapter-heading sidebar.
- Page counter + progress bar in the footer.
- Pages cache as you flip; forward flips prefetch the next two.
---
## 12. Embed (share publicly)
Once the manifest is publicly published, the resulting `naddr` works in
the embed iframe:
```html
<iframe
src="https://your-host/#/embed/<naddr-here>"
width="600" height="900"></iframe>
```
URL params:
- `?page=N` — deep-link to a starting page (1-based)
- `?controls=0` — hide prev/next/fullscreen
- `?attr=0` — hide the author chip
- `?open=0` — hide the "Open in Artstr ↗" link
The embed renders a cut-down Reader Mode (no TOC).
---
## 13. PDF export
Pages overview → **Export PDF…** opens the modal:
- **Pages**: All, custom range (from–to), or current.
- **Include cover spread**: yes/no.
- **Include bleed**: extends each PDF page to trim + 2×bleed (centered).
- **Crop marks**: L-shaped marks at each trim corner (printer guidance).
- **Output**: single file vs `<name>-interior.pdf` + `<name>-cover.pdf`
split.
- **Filename pattern**.
Reflowed prose using **Georgia / Times / Helvetica / Arial / Courier /
monospace** families emits as real PDF text (vector, selectable,
searchable). Other fonts fall back to vector raster, and the warning
summary lists which families fell back.
**Proof one page** (📄 button on any tile or in any editor toolbar) →
one-click PDF of just that entry. No modal.
---
## 14. Tokens reference
Resolve at render time using the manifest's context.
| Token | Where it resolves |
|-------------------------|-----------------------------------------------------------|
| `{page-number}` | This page's number under `spec.pageNumbering` rules. |
| `{page-count}` | Total numbered pages in the book. |
| `{physical-page-count}` | Total physical pages (including skipped-number entries). |
| `{book-title}` | `state.meta.title`. |
| `{book-author}` | Cached profile display name, falling back to short npub. |
| `{chapter-title}` | The chapter this page belongs to. |
| `{chapter-number}` | The chapter's ordinal. |
| `{toc}` *(standalone)* | Auto-generated TOC with page numbers. |
| `{index}` *(standalone)*| Auto-generated alphabetical index with page numbers. |
Inline markers (in chapter markdown):
- `[^N]` … `[^N]: definition` → footnote ref + chapter-end definition.
- `^[term]` → invisible index marker; appears in `{index}`.
- `[text](#anchor)` → cross-reference; rewritten to `[text (p. N)]`.
---
## 15. Edge cases worth probing
- **Private round-trip** — switch to 🔒 Private, publish a chapter,
reload the page. The resolver should decrypt + repaint.
- **Cross-device** — publish the manifest publicly, paste the `naddr`
into the embed route on a different browser → it should resolve and
render.
- **Spec change → spine shift** — open Document settings, change paper
thickness or page count, look at the cover panel — spine width
should re-derive immediately.
- **TOC accuracy** — TOC page numbers are computed pre-expansion
(chapter-start granularity). Expect a 1–2 page offset for the TOC
chapter itself once expanded.
- **Reflow overflow** — drop a `# Heading` near the end of a chapter
that doesn't have room. The `keepWithNext` rule should push it to
the next page.
- **Imported chapter from someone else** — import an existing NIP-23
article, then click **Publish chapter** — should confirm before
clobbering and mint your own d-tag.
- **Token resolution** — put `{page-number} of {page-count}` in a
master text layer; verify the rendered numbers update as you add /
remove pages.
---
## 16. Where to find things in the codebase
Single file: `src/index.html`.
- Pagination engine: `function paginateChapter`
- Reader Mode: `function openBookReader`
- PDF export: `async function exportBookToPdf`
- Resolver: `async function resolveBookSidecars`
- Disk cache: `BOOK_SIDECAR_CACHE_KEY`
- Manifest payload: `function bookManifestPayload`
- Token substitution: `function substituteBookTokens`
- TOC builder: `function _computeBookTocEntries`
- Index builder: `function _computeBookIndexEntries`
- Cross-refs: `function _computeBookSlugToPageMap`
- Footnotes: `function _processBookFootnotes`
Spec: `docs/BOOK_DESIGNER_FEATURE.md`.