Scrivener direct formatting (fonts and the Format menu)
You help the writer apply direct formatting to the text they edit in Scrivener —
the things on the Format menu (Manual Ch. 15): font family and size,
bold/italic/underline/strikethrough, text and highlight color, paragraph alignment,
line and paragraph spacing, indents and tab stops, lists, tables, and hyperlinks.
This formatting lives inline in each document's content.rtf, independent of named
styles.
Before doing anything, settle two questions: which font are they actually asking
about (editing vs compile), and what scope the change should cover (project /
subtree / specific docs). Get these wrong and you either edit the wrong layer or
rewrite far more than the writer intended.
Editing font vs compile font — ask first
This is the most common confusion and you must resolve it explicitly:
- Editing font (this skill). The font, size, and formatting you see while writing
in the editor. "Change the font for the whole project" almost always means this — make
the on-screen text easier to read. It rewrites direct formatting inside each
content.rtf.
- Compile font (scrivener-compile). The font of the exported/printed manuscript.
Scrivener deliberately separates the two: a writer drafts in Courier and compiles to
Times New Roman without touching their editing text. If the user wants "the manuscript
in 12pt Times" or "the final PDF font", that is the compile Format's override, not
this skill — hand off to scrivener-compile.
- Override-formatting note. Many compile Formats override editing formatting anyway,
so changing the editing font may have no effect on the output. Say so when it
matters, then confirm which layer the writer means.
When a request is ambiguous ("change the font everywhere"), ask: "Do you mean the font
you write in, or the font of the exported manuscript?"
Direct formatting vs named styles
- Direct formatting (this skill) is applied straight to a text range — ad-hoc, not
named, not reusable.
- Named styles (scrivener-styles) are reusable definitions (e.g. "Block Quote") that
update everywhere when redefined. If the writer wants one consistent, re-editable look
across the project, prefer a named style and point them to scrivener-styles.
Use direct formatting for one-off changes and for project-wide normalization
(e.g. "make all the body text 12pt Times"); use styles for semantic, reusable looks.
Scope: project / subtree / selected docs
Every formatting change is scoped. Be explicit about which one applies:
| Scope |
Means |
Planned flag |
| Selection / single doc |
One document (and, when supported, a range within it) |
--scope docs:<id> |
| Subtree |
A folder/container and all its descendants |
--scope subtree:<id> |
| Project |
Every text document in the binder |
--scope project |
A "change the font for the whole project" request is project scope — a bulk rewrite
of every content.rtf. Confirm the scope and warn that it touches many documents.
CRITICAL: project-wide rewrites must preserve RTF and skip script docs
Two hard rules for any bulk font/format rewrite:
- Token-preserving only. Direct formatting lives inline in
content.rtf, alongside
linked comment/footnote anchors (scrivcmt:// HYPERLINK fields), applied-style markers
(<$Scr_H::n>…), embedded images (\pict/pngblip), and internal Scrivener Links.
A bulk format change must edit the RTF token tree in place, never regenerate
"minimal RTF from text" — naïve regex/regeneration silently orphans comments, drops
style ranges, breaks links, and deletes images. This is the same token-preserving
contract set-text uses (see scrivener-format / the RTF strategy).
- Warn about and exclude script-mode documents. In script mode, screenplay elements
(Scene Heading, Action, Character, Dialogue, …) are recognized by their paragraph
formatting — indents, alignment, spacing. Bulk-reformatting a script document
destroys that recognition and breaks the script. A project-wide format op must detect
script-mode docs, warn, and exclude them by default (script formatting belongs to
scrivener-scriptwriting). Never silently reformat a script doc.
What you can do today
Direct formatting is a 🔜 planned layer — the format … commands are not in the CLI
yet. What exists now lets you inspect formatting and prepare changes safely:
# See whether a document carries styles/links/images/lists/tables before any rewrite
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py read <id> --project "<path.scriv>"
# The constructs flags (styles/comments/images/tables/links/lists) tell you what a
# bulk reformat would have to preserve — and hint where a doc may be script-formatted.
For brand-new text you author, set-text writes minimal valid RTF; for existing rich
documents it is token-preserving and refuses a destructive regenerate without
--allow-destructive. Use that as the model for how format will behave.
Planned commands (roadmap — not yet in the CLI)
Describe the workflow, set scope, then note these are planned and suggest the closest
available step (inspect with read, hand off to scrivener-styles for reusable looks):
| Planned command |
Does |
format set-font --scope … |
Set font family across the scope |
format set-size --scope … |
Set point size (e.g. "make this 12pt") |
format bold|italic|underline|strike --scope … |
Toggle character formatting |
format color|highlight --scope … |
Text color / highlight color |
format align --scope … |
Left / center / right / justified |
format spacing|indent --scope … |
Line/paragraph spacing, indents, tab stops |
format list --scope … |
Bulleted / numbered lists |
format convert-default <id|subtree|project> |
Strip direct formatting back to the project's default editing format |
All take --scope project | subtree:<id> | docs:<ids> and the usual mutating flags
(--dry-run, --no-backup, --no-snapshot). Deeper construct detail
(fonts/\fs, color tables, alignment, spacing, lists, tables, hyperlinks) is in
references/formatting-model.md.
Safety
Restate before any write (planned or otherwise):
- Close the project in Scrivener and let cloud sync (Dropbox/iCloud) finish first.
- Writes auto-backup (zip) and auto-snapshot a document before overwriting its text.
- Titles are not unique — use a UUID for any mutating command when a title is ambiguous.
- Never regenerate a rich document (comments/styles/images/tables/links) from plain text —
edit token-preserving, or snapshot and pass
--allow-destructive.
- A bulk format op warns about and excludes script-mode documents by default.
Toolkit support
- ✅
read <id> — inspect a document's text + constructs flags (styles/comments/images/tables/links/lists) so you know what a reformat must preserve.
- ✅
set-text <id> — token-preserving text write; the model the planned format ops follow.
- 🔜
format set-font / set-size / bold / italic / underline / strike — character & font formatting.
- 🔜
format color / highlight / align / spacing / indent / list — color, alignment, paragraph & list formatting.
- 🔜
format convert-default — strip direct formatting back to the project default editing format.
All format … commands are roadmap (v0.1.0), not yet in the CLI. Be honest about this and
suggest inspecting with read or using a named style (scrivener-styles) in the meantime.
Related skills
- scrivener-styles — named Styles & Stylesheets: reusable, re-editable looks. Prefer over direct formatting when the writer wants one consistent look project-wide.
- scrivener-compile — the output/compile font and Format overrides. This is where "the manuscript in 12pt Times" belongs.
- scrivener-scriptwriting — script mode. Bulk formatting must not break script docs; their elements are recognized by paragraph formatting.
- scrivener-format — the package/RTF reference hub: what lives inside
content.rtf and why edits must be token-preserving.
- scrivener-edit — text writes (
set-text) that share the token-preserving contract.
1---2name: scrivener-formatting3description: When the user wants to apply direct formatting to a Scrivener 3 project's editing text — fonts, size, bold/italic/underline/strikethrough, text or highlight color, alignment, line/paragraph spacing, indents, tab stops, lists, tables, or hyperlinks (Manual Ch.15 / the Format menu). Use when the user says "change the font for the whole project", "make this 12pt", "bold this", "italicize", "highlight this", "align center", or "convert to default formatting". This is the editing-font layer, NOT the compile output font. For named, reusable styles, see scrivener-styles. For the font of the exported/compiled manuscript, see scrivener-compile. For script-mode documents, see scrivener-scriptwriting.4---56# Scrivener direct formatting (fonts and the Format menu)78You help the writer apply **direct formatting** to the text they edit in Scrivener —9the things on the **Format menu** (Manual Ch. 15): font family and size,10bold/italic/underline/strikethrough, text and highlight color, paragraph alignment,11line and paragraph spacing, indents and tab stops, lists, tables, and hyperlinks.12This formatting lives inline in each document's `content.rtf`, independent of named13styles.1415Before doing anything, settle two questions: **which font are they actually asking16about** (editing vs compile), and **what scope** the change should cover (project /17subtree / specific docs). Get these wrong and you either edit the wrong layer or18rewrite far more than the writer intended.1920## Editing font vs compile font — ask first2122This is the most common confusion and you must resolve it explicitly:2324- **Editing font (this skill).** The font, size, and formatting you see *while writing*25 in the editor. "Change the font for the whole project" almost always means this — make26 the on-screen text easier to read. It rewrites direct formatting inside each27 `content.rtf`.28- **Compile font (scrivener-compile).** The font of the **exported/printed manuscript**.29 Scrivener deliberately separates the two: a writer drafts in Courier and compiles to30 Times New Roman without touching their editing text. If the user wants "the manuscript31 in 12pt Times" or "the final PDF font", that is the **compile Format's** override, not32 this skill — hand off to **scrivener-compile**.33- **Override-formatting note.** Many compile Formats override editing formatting anyway,34 so changing the editing font may have **no effect on the output**. Say so when it35 matters, then confirm which layer the writer means.3637When a request is ambiguous ("change the font everywhere"), ask: *"Do you mean the font38you write in, or the font of the exported manuscript?"*3940## Direct formatting vs named styles4142- **Direct formatting (this skill)** is applied straight to a text range — ad-hoc, not43 named, not reusable.44- **Named styles (scrivener-styles)** are reusable definitions (e.g. "Block Quote") that45 update everywhere when redefined. If the writer wants one consistent, re-editable look46 across the project, prefer a named style and point them to **scrivener-styles**.4748Use direct formatting for one-off changes and for project-wide *normalization*49(e.g. "make all the body text 12pt Times"); use styles for semantic, reusable looks.5051## Scope: project / subtree / selected docs5253Every formatting change is **scoped**. Be explicit about which one applies:5455| Scope | Means | Planned flag |56|---|---|---|57| **Selection / single doc** | One document (and, when supported, a range within it) | `--scope docs:<id>` |58| **Subtree** | A folder/container and all its descendants | `--scope subtree:<id>` |59| **Project** | Every text document in the binder | `--scope project` |6061A "change the font for the whole project" request is **project scope** — a bulk rewrite62of every `content.rtf`. Confirm the scope and warn that it touches many documents.6364## CRITICAL: project-wide rewrites must preserve RTF and skip script docs6566Two hard rules for any bulk font/format rewrite:67681. **Token-preserving only.** Direct formatting lives inline in `content.rtf`, alongside69 linked comment/footnote anchors (`scrivcmt://` HYPERLINK fields), applied-style markers70 (`<$Scr_H::n>…`), embedded images (`\pict`/`pngblip`), and internal Scrivener Links.71 A bulk format change must edit the RTF token tree **in place**, never regenerate72 "minimal RTF from text" — naïve regex/regeneration silently orphans comments, drops73 style ranges, breaks links, and deletes images. This is the same token-preserving74 contract `set-text` uses (see scrivener-format / the RTF strategy).752. **Warn about and exclude script-mode documents.** In script mode, screenplay elements76 (Scene Heading, Action, Character, Dialogue, …) are **recognized by their paragraph77 formatting** — indents, alignment, spacing. Bulk-reformatting a script document78 destroys that recognition and breaks the script. A project-wide format op must **detect79 script-mode docs, warn, and exclude them by default** (script formatting belongs to80 **scrivener-scriptwriting**). Never silently reformat a script doc.8182## What you can do today8384Direct formatting is a **🔜 planned** layer — the `format …` commands are not in the CLI85yet. What exists now lets you *inspect* formatting and *prepare* changes safely:8687```bash88# See whether a document carries styles/links/images/lists/tables before any rewrite89python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py read <id> --project "<path.scriv>"9091# The constructs flags (styles/comments/images/tables/links/lists) tell you what a92# bulk reformat would have to preserve — and hint where a doc may be script-formatted.93```9495For brand-new text you author, `set-text` writes minimal valid RTF; for existing rich96documents it is token-preserving and refuses a destructive regenerate without97`--allow-destructive`. Use that as the model for how `format` will behave.9899## Planned commands (roadmap — not yet in the CLI)100101Describe the workflow, set scope, then note these are planned and suggest the closest102available step (inspect with `read`, hand off to `scrivener-styles` for reusable looks):103104| Planned command | Does |105|---|---|106| `format set-font --scope …` | Set font family across the scope |107| `format set-size --scope …` | Set point size (e.g. "make this 12pt") |108| `format bold\|italic\|underline\|strike --scope …` | Toggle character formatting |109| `format color\|highlight --scope …` | Text color / highlight color |110| `format align --scope …` | Left / center / right / justified |111| `format spacing\|indent --scope …` | Line/paragraph spacing, indents, tab stops |112| `format list --scope …` | Bulleted / numbered lists |113| `format convert-default <id\|subtree\|project>` | Strip direct formatting back to the project's default editing format |114115All take `--scope project | subtree:<id> | docs:<ids>` and the usual mutating flags116(`--dry-run`, `--no-backup`, `--no-snapshot`). Deeper construct detail117(fonts/`\fs`, color tables, alignment, spacing, lists, tables, hyperlinks) is in118**[references/formatting-model.md](references/formatting-model.md)**.119120## Safety121122Restate before any write (planned or otherwise):123124- **Close the project in Scrivener** and let **cloud sync (Dropbox/iCloud) finish** first.125- Writes **auto-backup** (zip) and **auto-snapshot** a document before overwriting its text.126- **Titles are not unique** — use a **UUID** for any mutating command when a title is ambiguous.127- Never regenerate a rich document (comments/styles/images/tables/links) from plain text —128 edit token-preserving, or snapshot and pass `--allow-destructive`.129- A bulk format op **warns about and excludes script-mode documents** by default.130131## Toolkit support132133- ✅ `read <id>` — inspect a document's text + `constructs` flags (styles/comments/images/tables/links/lists) so you know what a reformat must preserve.134- ✅ `set-text <id>` — token-preserving text write; the model the planned `format` ops follow.135- 🔜 `format set-font` / `set-size` / `bold` / `italic` / `underline` / `strike` — character & font formatting.136- 🔜 `format color` / `highlight` / `align` / `spacing` / `indent` / `list` — color, alignment, paragraph & list formatting.137- 🔜 `format convert-default` — strip direct formatting back to the project default editing format.138139All `format …` commands are roadmap (v0.1.0), not yet in the CLI. Be honest about this and140suggest inspecting with `read` or using a named style (scrivener-styles) in the meantime.141142## Related skills143144- **scrivener-styles** — named **Styles & Stylesheets**: reusable, re-editable looks. Prefer over direct formatting when the writer wants one consistent look project-wide.145- **scrivener-compile** — the **output/compile font** and Format overrides. This is where "the manuscript in 12pt Times" belongs.146- **scrivener-scriptwriting** — script mode. Bulk formatting must **not** break script docs; their elements are recognized by paragraph formatting.147- **scrivener-format** — the package/RTF reference hub: what lives inside `content.rtf` and why edits must be token-preserving.148- **scrivener-edit** — text writes (`set-text`) that share the token-preserving contract.