Skip to content

API review: group sheet view settings, tidy docs and argument order - #127

Merged
billdenney merged 3 commits into
masterfrom
claude/api-usability-review
Jul 28, 2026
Merged

API review: group sheet view settings, tidy docs and argument order#127
billdenney merged 3 commits into
masterfrom
claude/api-usability-review

Conversation

@billdenney

Copy link
Copy Markdown
Collaborator

An API review before Phase 6 widens things further. All pre-release, so no user
code breaks.

1. xl_sheet(): 23 arguments → 15

Phase 4's nine view settings went in flat, while page = xl_page_setup() had
already established the pattern for exactly this kind of cluster. They now
follow it: view = xl_sheet_view(...).

freeze deliberately stays on xl_sheet() — it is the single most common
worksheet option, and making the common case wordier to tidy the rare ones would
be a poor trade. split, its rarely-used divider variant, moves; the two stay
mutually exclusive and the error now names both spellings.

Done now so Phase 6's validation = lands in a function that isn't already
overloaded.

2. A stale documentation claim

write_xlsx(format_headers) still said the header would be "centered and bold".
That stopped being true when the header format became configurable via
xl_properties(header_format = ). It now describes what the argument does and
points at the setting; xl_workbook() @inheritParams it rather than carrying
its own paraphrase.

3. One concept, three argument names

xl_hyperlink(name =), xl_hyperlink_cell(value =) and
xl_cell_general(value =) all mean the text displayed instead of a URL. The
names differ only because xl_hyperlink() mirrors Excel's HYPERLINK()
argument. name is released API so it stays; the docs now state the
equivalence.

4. Duplicated coercion

if (is.factor(x)) x <- as.character(x); stopifnot(is.character(x)) appeared
verbatim in all three cell shorthands. Now .as_character_arg(), which also
reports the argument name and the class it got instead of stopifnot()'s
expression dump.

5. Most-probable-first argument order

  • xl_font() leads with bold, italic, color, size, name rather than
    name, size, color, bold, italic
  • xl_comment() leads with author before format

Every call site names its arguments past the first, so nothing positional
depended on the old order — verified by grep before changing them.

Correction to the review

I initially flagged the format argument as documented seven times with
inconsistent wording. On inspection that is mostly legitimate variation, not
duplication: xl_comment() uses a fill-and-font subset, xl_rich_run() a
font-only subset, and the others a full format. Unifying them would have lost
the distinction. Only col_names / format_headers were genuinely the same
argument described twice, and those are now inherited.

billdenney and others added 3 commits July 27, 2026 19:20
xl_sheet() had grown to 23 arguments, nine of them the tab and opening-view
settings added in Phase 4. xl_page_setup() already established the pattern for
this kind of cluster, so the view settings now follow it: xl_sheet(view =
xl_sheet_view(...)). The signature drops to 15 arguments.

freeze deliberately stays on xl_sheet(). It is the single most common worksheet
option -- keeping the header row visible -- and making the common case wordier
in order to tidy the rare ones would be a poor trade. split, its rarely-used
divider variant, does move, and the two remain mutually exclusive with an error
that now names both spellings.

Done before adding data validation, so that argument lands in a function that
is not already overloaded. Nothing here has been released, so no user code
breaks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…uments

Follow-up to the xl_sheet_view() regrouping, from an API review before the next
phase widens things further.

The three cell shorthands each repeated the same factor-to-character coercion
and a stopifnot() whose failure printed an expression rather than a name. They
now share .as_character_arg(), which reports the argument and the class it got.

write_xlsx()'s format_headers documentation still described the header as
"centered and bold". That stopped being true when the header format became
configurable through xl_properties(header_format =), so it now says what the
argument actually does and points at the setting. xl_workbook() inherits both
that and col_names rather than carrying its own paraphrase.

xl_hyperlink(name =), xl_hyperlink_cell(value =) and xl_cell_general(value =)
all mean the display text shown instead of a URL; the docs now say so, since
the differing names are only an accident of xl_hyperlink() mirroring Excel's
HYPERLINK() argument.

Two signatures now lead with their most probable argument: xl_font() with bold
and italic rather than name and size, and xl_comment() with author before
format. Every call site names its arguments past the first, so nothing
positional depended on the old order.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…sistency

xl_hyperlink() called its display-text argument `name` while
xl_hyperlink_cell() and xl_cell_general() called the same thing `value`. It is
now `value`, taking the argument position `name` used to occupy, so code that
passed the display text positionally is unaffected. `name` is retained, warns
and points at `value`, and giving both is an error since they mean the same
thing.

Reverts the xl_comment() reorder from the previous commit. Shared arguments
should keep the same relative order across functions so that reading one
signature teaches the others, and that outranks putting each function's most
probable argument first. Across xl_formula(), xl_rich_run(), xl_merge() and
xl_hyperlink_cell(), `format` immediately follows the content arguments;
putting `author` in between broke that idiom. xl_font() keeps its reordering,
whose arguments are shared with nothing.

The rule now has a mechanical gate rather than living in prose, since prose is
what just failed: test-api-consistency.R enumerates every exported function and
fails on any pair of functions whose shared arguments disagree on relative
order, pins where `format` sits relative to the content arguments, and pins
data-first. Two pairs are allow-listed with the reason -- a comment box's pixel
width and a column's character width share a name but not a concept.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@billdenney
billdenney merged commit 3c29b82 into master Jul 28, 2026
12 checks passed
@billdenney
billdenney deleted the claude/api-usability-review branch July 29, 2026 11:06
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.

1 participant