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](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.