# Scrivener Styles

> When the user wants to work with named Styles and Stylesheets in a Scrivener 3 project — apply a style to text, create or redefine a style, remove styling, or import styles from another project. Use when the user says "apply the Block Quote style", "create a style", "redefine Heading 1", "remove styles from this text", "make this a named style", or "import styles from another project". This is named STYLES (a project stylesheet), distinct from direct FORMATTING (fonts/color/alignment applied inline) — for that, see scrivener-formatting. For how styles turn into headings/markup on output, see scrivener-compile. For where styles serialize on disk, see scrivener-format.

- Skill: `donnfelker/scrivener-styles` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add donnfelker/scrivener-styles`
- Raw SKILL.md: https://api.skillmd.com/api/skills/donnfelker/scrivener-styles/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: donnfelker (https://skillmd.com/u/donnfelker)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/donnfelker/scrivener-styles

---


# Scrivener named Styles & Stylesheets

You help the writer work with **named styles** — the project stylesheet from the
manual's Ch.17 "Styles and Stylesheets." A named style ("Heading 1", "Block
Quote", "Code Block") is a *reusable, named* bundle of formatting stored once in
the project and applied to ranges of text. Redefine the style once and every
range that uses it updates everywhere.

This is **not** the same as direct formatting (making one paragraph 14pt bold by
hand). Direct formatting is inline and one-off; a named style is referenced by
name and centrally editable. Knowing which one the writer means is the first job
of this skill.

> **Honesty note.** The style **write** commands (`style apply/create/redefine/
> remove/select/import`) are **🔜 planned roadmap**, not in the CLI today. What
> works now is **detection**: `read <id>` reports whether a document contains
> style markers. The rest of this skill explains the model so an agent can read,
> reason about, and (later) safely mutate styles. Be upfront with the writer
> about what is available vs. planned.

## STYLES vs. FORMATTING — pick the right skill

| | Named **STYLE** (this skill) | Direct **FORMATTING** (scrivener-formatting) |
|---|---|---|
| What it is | A named, reusable rule ("Heading 1") | Inline attributes on a range (this text is bold) |
| Stored | Once in `styles.xml`; applied refs in `content.styles` + RTF markers | Inline in `content.rtf` only |
| Editable centrally | Yes — redefine once, all uses update | No — each range edited separately |
| On compile | Can map to markup (heading level, prefix/suffix) | Travels as literal formatting |
| Triggers | "apply the X style", "redefine Heading 1" | "make this bold", "change the font", "highlight this" |

If the request names a style ("Block Quote", "Heading 2") or says "create/redefine
a style" → **this skill**. If it's a raw attribute ("bold", "12pt", "center",
"red") with no style name → **scrivener-formatting**.

## How named styles are stored

Three pieces work together (full detail in
**[references/styles-model.md](references/styles-model.md)**):

- **`styles.xml`** (project-level) — the **stylesheet**: every style's Name, ID,
  Type (`Para` / `Char` / `Para+Char`), an RTF `<Format>` block defining its look,
  and attributes (keyboard shortcut, next-style, highlight box, whether it
  includes font family/size).
- **`content.styles`** (per document) — which named styles are *applied* inside
  that document (the doc's link back to `styles.xml`).
- **`<$Scr_H::n>…<!$Scr_H::n>` markers** *inside* `content.rtf` — the actual
  in-text spans that carry style `n`. This is why a style is real text data, not
  just a side file, and why writes must be token-preserving (see
  scrivener-format / the RTF strategy in the spec).

## Paragraph vs. character styles

- **Paragraph style** (`Para`) — applies to whole paragraphs (Heading 1, Block
  Quote, Code Block). Setting it affects the entire paragraph.
- **Character style** (`Char`) — applies to a run *within* a paragraph (Emphasis,
  Code Inline) without disturbing the paragraph's own style.
- **`Para+Char`** — a paragraph style that also pins character attributes.

A paragraph and a character style can coexist on the same text. This matters when
redefining: redefining a paragraph style won't touch character runs layered on
top, and vice versa. See the reference for the interaction rules.

## What works today

Use `read` to discover whether a document uses styles before reasoning about it:

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py read <id> \
  --project "<path.scriv>" --format json
```

The `constructs` block in the output flags `styles: true` when the document
contains `<$Scr_H::n>` markers. Pair it with `outline` to find document IDs:

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py outline --project "<path.scriv>"
```

When `styles` is true, tell the writer the document has named-style spans, and
that applying/redefining/removing them is on the roadmap (below). When it's
false, the text is direct-formatted only — point them at scrivener-formatting.

## Planned style commands (roadmap)

These describe the intended workflow; none are in the CLI yet. Suggest the
closest available action (usually `read` to inspect, or scrivener-formatting for
direct attributes).

| Planned command | What it will do |
|---|---|
| `style list` | List the project's styles (name, ID, type, shortcut, next-style) |
| `style apply <id> --style <name> [--range …]` | Apply a named style to text |
| `style create --name … --type para\|char\|para+char [--from <id> --range …]` | Define a new style (optionally from a selection) |
| `style redefine <name> [--from <id> --range …]` | Change a style's definition; all uses update |
| `style remove <id> [--style <name>]` | Strip style markers from text, leaving the resolved formatting (distinct from deleting the style) |
| `style select <name>` | Find every range that uses a style |
| `style import <other.scriv> [--mode keep\|replace\|add]` | Merge another project's stylesheet (see merge modes in the reference) |

**Remove vs. delete:** *removing* a style from text un-marks the range (the look
stays as direct formatting); *deleting* a style from the stylesheet removes the
definition project-wide. The planned `remove` un-marks text; deleting a definition
is a separate concern. The reference covers both.

## Styles on compile

Named styles are the bridge to clean output. On compile, a style can be mapped to
markup — e.g. a "Heading 1" paragraph style becomes an actual `#` heading, and a
"do-nothing"/markup style can wrap its text in a prefix/suffix (like `>` for a
block quote or fenced code). This is why styling with named styles (not direct
formatting) is the recommended path for anything that should become structure on
export. The mapping itself lives in the compile Format — see scrivener-compile.

## Safety (restate before any write)

The write commands are planned, but when they land they follow the toolkit's
rules:

- **Close the project in Scrivener** *and* let cloud sync (Dropbox/iCloud) finish
  before writing — editing mid-sync can corrupt or conflict.
- Writes **auto-backup** (zip) and **auto-snapshot** a document before changing
  its `content.rtf`.
- `docs.checksum` mismatches are **advisory**, never corruption.
- **Titles are not unique** — address documents by **UUID** for mutating commands
  when a title is ambiguous.
- Style spans live *inside* `content.rtf`; edits are **token-preserving** and must
  never regenerate a rich document from plain text (that would orphan markers,
  comments, links, and images).

## Toolkit support

- ✅ `read <id>` — reports `constructs.styles` (whether the doc has style markers) — available now
- 🔜 `style list` — list project styles — planned
- 🔜 `style apply` — apply a named style to text — planned
- 🔜 `style create` — define a new style — planned
- 🔜 `style redefine` — change a style definition (all uses update) — planned
- 🔜 `style remove` — un-mark styled text (distinct from deleting a style) — planned
- 🔜 `style select` — find ranges that use a style — planned
- 🔜 `style import` — merge another project's stylesheet (keep/replace/add) — planned

## Related skills

- **scrivener-formatting** — direct, inline formatting (fonts, color, alignment,
  lists, tables, highlight). Use this when there is no named style involved.
- **scrivener-compile** — how named styles map to markup (headings, prefix/suffix)
  on output; the style→layout/markup binding lives in the compile Format.
- **scrivener-format** — where `styles.xml`, `content.styles`, and the
  `<$Scr_H::n>` markers serialize on disk; the format-fact hub.
- **scrivener-inspect** — `outline` and `read` to locate documents and detect
  style markers.

