Skip to content

feat(docs): expose heading styles via docs format#615

Open
chrischall wants to merge 2 commits into
openclaw:mainfrom
chrischall:feat/605-docs-format-headings
Open

feat(docs): expose heading styles via docs format#615
chrischall wants to merge 2 commits into
openclaw:mainfrom
chrischall:feat/605-docs-format-headings

Conversation

@chrischall
Copy link
Copy Markdown

Closes #605.

Summary

`docs format` covered text attributes and a couple of paragraph attributes (alignment, line spacing) but had no way to set a paragraph's named style — the Docs API field that drives the outline view / navigation pane and is the difference between a flat doc and a structured one. The markdown writer can produce HEADING_N on fresh content via leading `#`s, but offered no way to restyle existing paragraphs.

New flags

  • `--heading-level N` (1..6): shortcut for `HEADING_N`.
  • `--named-style NAME`: full enum — `NORMAL_TEXT`, `TITLE`, `SUBTITLE`, `HEADING_1`..`HEADING_6` (case-insensitive).

Mutually exclusive. Either path sets `paragraphStyle.namedStyleType` on the existing `UpdateParagraphStyle` request, so they compose cleanly with `--alignment` and `--line-spacing` without an extra round-trip.

```
gog docs format --match=Title --heading-level=1
gog docs format --match=Title --named-style=HEADING_1
gog docs format --match="Day-by-Day" --heading-level=2 --alignment=center
```

Tests

  • `TestDocsFormatFlags_HeadingLevelEmitsNamedStyleType` — H1/H2/H6 → correct enum + Fields includes `namedStyleType`.
  • `TestDocsFormatFlags_NamedStyleAcceptsAllValidEnums` — round-trips every legal value.
  • `TestDocsFormatFlags_NamedStyleIsCaseInsensitive` — `heading_3` → `HEADING_3`.
  • `TestDocsFormatFlags_HeadingLevelAndNamedStyleMutuallyExclusive` — combining the two errors out.
  • `TestDocsFormatFlags_HeadingLevelOutOfRangeRejected` — -1, 7, 99 all rejected with a precise message.
  • `TestDocsFormatFlags_UnknownNamedStyleRejected` — `BANNER` → enum error.
  • `TestDocsFormatFlags_HeadingComposesWithAlignment` — single paragraph request carries both `alignment` and `namedStyleType` Fields, with `TabId` preserved.
  • `TestDocsFormatFlags_AnyDetectsHeadingFlags` — `any()` sees the new fields so the "no formatting flags provided" guard stays correct.

`go test ./internal/cmd/ -count=1` → ok 23.6s.

chrischall and others added 2 commits May 19, 2026 20:17
Closes openclaw#605.

`docs format` covered text attributes and a couple of paragraph
attributes (alignment, line spacing) but had no way to set a paragraph's
named style — the Docs API field that drives outline view / navigation
pane and is the difference between a flat doc and a structured one. The
markdown writer can produce HEADING_N on fresh content via leading `#`s,
but offered no way to restyle existing paragraphs.

Adds two new DocsFormatFlags:

- `--heading-level N` (1..6): shortcut for HEADING_N.
- `--named-style NAME`: full enum — NORMAL_TEXT, TITLE, SUBTITLE,
  HEADING_1..HEADING_6 (case-insensitive).

The two are mutually exclusive. Either sets
paragraphStyle.namedStyleType on the existing UpdateParagraphStyle
request, so the new flags compose cleanly with --alignment and
--line-spacing without an extra round-trip.

Helper docsFormatNamedStyle does the validation + enum resolution. Tests
cover all six heading levels, the full enum, case-insensitivity,
mutual-exclusion, range-rejection, unknown-enum rejection, composition
with alignment, and the any() detection used by the no-flags guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(docs): expose heading styles (H1–H6) via docs format

1 participant