Skip to content

ci: Document with a patched roxygen2 that keeps the sentence gap - #67

Open
krlmlr wants to merge 3 commits into
claude/readme-goalsfrom
claude/roxygen2-fork
Open

krlmlr wants to merge 3 commits into
claude/readme-goalsfrom
claude/roxygen2-fork

Conversation

@krlmlr

@krlmlr krlmlr commented Sep 13, 2026

Copy link
Copy Markdown
Member

Replaces #63, which had its head on a fork and so could not join the pull request stack. Same branch, same commits.

Top of the documentation chain, on top of #61. This existed only as krlmlr#4, in the fork, where reviewers here could not see it; this is the same branch, opened against r-lib so the whole stack is reviewable in one place. The fork pull request is now redundant.

The problem

commonmark discards the whitespace a line break stands for. roxygen2 turns every softbreak into a bare newline, so the .Rd carries a line break with nothing after it and Rd2txt() renders it as a single space. Prose written one sentence per line therefore comes out single-spaced, while the same words wrapped to a fixed width with two spaces after the period keep the gap.

Only the text renderer is affected. Rd2HTML() and Rd2latex() differ by whitespace that HTML and TeX collapse, and LaTeX applies its own sentence spacing regardless. But text is what ?topic shows.

For this package the effect is small and worth stating plainly: R/ carried no double-spaced sentence pairs at all, and the one in README.Rmd is markdown rather than rendered help. So this does not restore a gap the author wrote here — it introduces two-space sentence spacing in the rendered help, consistently with the rest of the fleet.

The change

A composite action, .github/workflows/roxygen2-fork, installs roxygen2 from upstream with the R/ part of krlmlr/roxygen2@f-sentence-spacing applied on top, and R-CMD-check.yaml runs it immediately before the Roxygenize step. It shallow-clones upstream, fetches the branch, computes the diff against their merge base restricted to R/, and applies it with git apply --3way. Restricting to R/ means an unrelated upstream change to a test fixture cannot fail the documentation step.

Config/roxygen2/version becomes 8.1.0.9100. The .9100 suffix distinguishes a patched build from upstream's own .9000 development builds. DESCRIPTION is DCF and cannot carry a comment line, so the explanation lives in a Config/cynkra/roxygen2 field.

Known defects, not yet fixed

This is filed for review, not for merging as it stands. A review round across the fleet found two blocking problems in this action, both of which apply here:

  • The version stamp uses "\1" as a regex backreference. In R that is the octal escape for \001, so DESCRIPTION gets a malformed version and R CMD INSTALL aborts. Confirmed by real CI runs in three other repositories.
  • The new step carries no continue-on-error: true and no entry in the CHECKS summary, contrary to the stated invariant of the block it sits in, so a failure takes down R CMD check and pkgdown with it and the summary reports nothing.

Both fixes are known; they are being handled as a fleet-wide pass rather than repo by repo.

Upstream

The roxygen2 side is krlmlr/roxygen2#8, on a fork, not yet filed with r-lib. It is deliberately narrow — one line in R/markdown.R plus a new R/sentence-spacing.R — with three guards: an abbreviation list, a single-letter-initial guard so M.E.J. before Newman does not gain a gap mid-name, and a fix for a determinism bug where a line starting with \doi{} or \code{} gained or lost its gap at random, because the test was reading roxygen2's own random placeholder for protected Rd tags.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WWhverMTZZKgEpUuTK117m


Generated by Claude Code

krlmlr and others added 3 commits September 14, 2026 05:58
commonmark discards the whitespace a line break stands for, so roxygen prose written
one sentence per line loses the gap between sentences in the rendered help.
Only the text renderer is affected, which is what `?topic` shows.

A new composite action installs roxygen2 from upstream with the R/ part of
krlmlr/roxygen2@f-sentence-spacing applied on top, and runs just before the
Roxygenize step. It shallow-clones upstream, fetches the branch, applies the diff
restricted to R/ so conflicts in the test files cannot fail it, and aborts rather
than silently installing an unpatched build. It then asserts that what it installed
really carries the patch.

Config/roxygen2/version becomes 8.1.0.9100. The .9100 suffix distinguishes a patched
build from upstream's own .9000 development builds; if upstream moves, the x.y.z part
follows it and the suffix stays. DESCRIPTION is DCF and cannot carry a comment, so the
explanation lives in a Config/cynkra/roxygen2 field.

This is a separate decision from the line-break reformatting below it, and is kept in
its own pull request so it can be taken or left on its own. Without it, the
reformatting simply renders as it does today, with one space between sentences.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWhverMTZZKgEpUuTK117m
The version stamp passed "\1" to `sub()` as the replacement,
meaning it as a backreference to the captured `x.y.z`.
R parses `"\1"` in a string literal as the octal escape for `\001`,
so the stamped version became a control character followed by `.9100`,
and `DESCRIPTION` was left with a malformed version.
`R CMD INSTALL` aborted on it,
which is what turned this action red across every pull request that runs it.
The replacement is now `"\\1"`, verified to stamp 8.1.0.9000 to 8.1.0.9100.

The post-install guard asserted only the `.9100` suffix,
and the corrupt `"\001.9100"` ends in `.9100` as well,
so the guard passed and the bug survived unnoticed.
It now asserts the whole `x.y.z.9100` shape,
and passes `inherits = FALSE` to `exists()` so the patch check cannot be satisfied from a parent environment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWhverMTZZKgEpUuTK117m
@krlmlr
krlmlr force-pushed the claude/roxygen2-fork branch from 1440e2b to ffe6a80 Compare September 14, 2026 05:58
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.

2 participants