Skip to content

Normalize line endings to LF; add .gitattributes#165

Open
MMenninger wants to merge 1 commit into
masterfrom
chore/normalize-line-endings
Open

Normalize line endings to LF; add .gitattributes#165
MMenninger wants to merge 1 commit into
masterfrom
chore/normalize-line-endings

Conversation

@MMenninger

Copy link
Copy Markdown
Collaborator

From AI -- Problem. The whole working tree currently shows as modified in git, but git diff --ignore-all-space shows zero real changes — it is pure CRLF↔LF line-ending noise. Without fixing this first, every later PR diff is buried under thousands of phantom line-ending changes and nothing reviews cleanly.

Change.

Add a .gitattributes that forces LF for text files (* text=auto eol=lf plus explicit entries for .R, .Rmd, .Rd, .md, .yaml/.yml, DESCRIPTION, NAMESPACE, .Rproj) and marks binaries (.rda, .png, .ico, .svg) as binary.
Set the RStudio project to write LF (LineEndingConversion: Posix in cmapplot.Rproj) so RStudio doesn't re-introduce CRLF on save. Run git add --renormalize . in the same commit.

Files. .gitattributes (new), cmapplot.Rproj.

Review note. The diff looks huge but is mechanical — "line endings only."

From AI -- Problem. The whole working tree currently shows as modified in git, but git diff --ignore-all-space shows zero real changes — it is pure CRLF↔LF line-ending noise. Without fixing this first, every later PR diff is buried under thousands of phantom line-ending changes and nothing reviews cleanly.

Change.

Add a .gitattributes that forces LF for text files (* text=auto eol=lf
plus explicit entries for .R, .Rmd, .Rd, .md, .yaml/.yml,
DESCRIPTION, NAMESPACE, .Rproj) and marks binaries (.rda, .png,
.ico, .svg) as binary.
Set the RStudio project to write LF (LineEndingConversion: Posix in
cmapplot.Rproj) so RStudio doesn't re-introduce CRLF on save.
Run git add --renormalize . in the same commit.

Files. .gitattributes (new), cmapplot.Rproj.

Review note. The diff looks huge but is mechanical — "line endings only."
@MMenninger

MMenninger commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

AI generated cmapplot modernization — status & roadmap

A sequence of small, independent pull requests to modernize the package — especially to make it Positron-friendly and resilient to current ggplot2. Each PR is self-contained and safe to merge on its own.

Convention: the package uses the magrittr %>% pipe. Keep it — do not migrate to native |>.

Issue links refer to https://github.com/CMAP-REPOS/cmapplot/issues


Progress at a glance

PR Title Issues Status
1 Normalize line endings + .gitattributes done, committed
2 Positron-aware .onLoad() done, committed
2.5 Fix gridtext
 error on indented captions
rel. #152 done, committed
3 Drop unused Rcpp dependency done, committed
4 Cross-platform font fallback done / committing
5 Modernize GitHub Actions + ggplot2 release/devel matrix guards #164 next
6 Replace deprecated size with linewidth #164 not started
7 theme_cmap() / theme_set() compatibility rel. #164, #162 not started
8 Install docs: drop Rtools, add Positron not started
9 Fix margins image missing in pkgdown docs #148 not started
10 Discrete palette: overflow warning + interpolation control + color-count docs #149, #138 not started
11 Good/Fair/Poor (condition) palette #155, #138 not started
12 Default ggplot annotations to Whitney #162 not started
13 Resolve the testthat gap (add tests) not started
14 Trim Suggests: tidyverse not started
15 Document / wrap ggplotly() interaction not started
16 De-risk ggrepel internals (larger) not started

Stack, in order: master <- PR1 <- PR2 <- PR2.5 <- PR3 <- PR4

The numbering below is the recommended order: CI + ggplot2 fixes first (they guard everything and address active breakage), then docs, then palette work, then infra/quality, then the big ggrepel refactor last.


Completed — details

PR 1 — Normalize line endings + .gitattributes

Added .gitattributes (force LF, mark binaries) and set cmapplot.Rproj to LineEndingConversion: Posix. HEAD was already LF; this only stops the local CRLF working-tree churn from polluting future diffs.

PR 2 — Positron-aware .onLoad()

R/cmapplot.R: replaced rstudioapi::isAvailable()/getVersion() gating with env-var detection (RSTUDIO, POSITRON_VERSION). Removes the load-time error risk in Positron; RStudio behavior unchanged; adds a Positron branch and fixes the misleading plain-R message.

PR 2.5 — gridtext <pre> fix (the CI-breaker)

R/finalize_plot.R: collapse newline + indentation in title/caption to a single space before gridtext parses them as markdown (indented lines were read as <pre> code blocks, which newer gridtext rejects — this is what broke the finalize.Rmd vignette build in CI). <br> still works for explicit breaks. Related: #152 (superscript/LaTeX in captions) is the same gridtext limited-tag constraint — not fixed here, but same subsystem.

PR 3 — Drop Rcpp

Removed Rcpp from Imports: (DESCRIPTION), the @import tag (R/cmapplot.R), and import(Rcpp) (NAMESPACE). Nothing used it — the compiled routines behind geom_text_lastonly_repel() are ggrepel's, called via base .Call(). Also means Rtools was never actually needed to install cmapplot (see PR 8).

PR 4 — Cross-platform font fallback

R/cmapplot.R: the manual Whitney fallback now searches user font dirs on macOS (~/Library/Fonts), Windows (%LOCALAPPDATA%/Microsoft/Windows/Fonts), and Linux (~/.local/share/fonts, ~/.fonts), filtered by dir.exists(). macOS behavior unchanged.


Remaining — the plan (do in this order)

PR 5 — Modernize GitHub Actions + ggplot2 release/devel matrix (START HERE)

.github/workflows/check-standard.yaml and pkgdown.yaml use actions/checkout@v3, actions/cache@v3, and actions/upload-artifact@main (a floating tag) and skip Linux.

  • Bump to current pinned action versions; replace @main.
  • Add an Ubuntu runner.
  • Add a ggplot2 release + devel matrix (the r-lib/actions/check-r-package template supports this) so ggplot2 breakage is caught before it reaches a user mid-render.

Do this first: it is the guardrail that would have caught both the theme_set() break and #164 early, and it will keep PRs 6 and 7 honest.

PR 6 — Replace deprecated size with linewidth (#164)

Mechanical ggplot2 deprecation fix across geoms/themes (line/border sizing moved from size to linewidth in ggplot2 3.4.0). Small and self-contained; PR 5's devel matrix will confirm it. Closes #164.

PR 7 — theme_cmap() / theme_set() compatibility (HIGH — broke a render outright)

theme_cmap() returns a plain list() — it bundles a base theme with data-dependent extras (axis labels, optional reference lines, legend guides) rather than an S3 <theme> object. So theme_set(theme_cmap()) fails ggplot2's is_theme() check (added ~ggplot2 3.5.0) — the single most natural thing anyone touching ggplot2 will try.

  • Best fix: split into an actual theme object (e.g. theme_cmap_base(), exported, usable with theme_set()) separate from the plot-specific layer bundle added per-chart with +.
  • Minimum fix: document loudly in ?theme_cmap that it cannot go through theme_set(). Nothing currently warns against it.
  • Related: use linewidth instead of deprecated size #164 (same "untested against current ggplot2" root cause) and ggplot annotation not in Whitney by default #162 (annotation font, see PR 12). Sequence after PR 5 so the matrix guards it.

PR 8 — Install docs: drop Rtools, add Positron

vignettes/installation.Rmd: remove the Rtools step (cmapplot compiles nothing, per PR 3) and add a Positron install path alongside RStudio. Check README.Rmd/README.md for duplicated steps.

PR 9 — Fix margins image missing in pkgdown docs (#148)

#148: the margins reference image doesn't render in the built documentation. Likely a pkgdown asset-path / build-config issue; pairs naturally with the CI and docs work above. Closes #148.

PR 10 — Discrete palette: overflow warning + interpolation control (#149, #138)

Two related discrete-palette problems seen in a live report: cmap_fill_discrete("prosperity") silently left 2 of 7 pie wedges colorless, and cmap_color_discrete("community") did similar on a 7-county line chart (both needing a manual switch to scale_*_viridis_d()).

  • When factor levels exceed the palette's defined colors, emit a cli::cli_warn() naming the palette, its color count, and the data's level count — turns a silent visual bug into a legible warning.
  • Address Prevent palette interpolation for some cases #149 (prevent palette interpolation for some cases): let callers opt out of interpolation and get the exact defined colors.
  • Document each palette's color count on the reference page (simple table: "prosperity: N colors", etc.) so people can self-check for high-cardinality data.
  • Follow up with Comms about discrete color scales #138 (follow up with Comms about discrete color scales) is the design context for what the "right" behavior should be.

PR 11 — Good/Fair/Poor (condition) palette (#155, #138)

Reports repeatedly hand-roll c(Good="#1a9850", Fair="#fee08b", Poor="#d73027") because cmapplot has no condition palette. CMAP reports condition data often (bridges, pavement, transit assets) on a Good/Fair/Poor red-amber-green scale. Add cmap_fill_condition() / cmap_color_condition() (or a documented palette name). Check the ramp against #155 (digital accessibility) — the naive RAG scale is not colorblind-safe, so pick accessible hues. Relates to #138.

PR 12 — Default ggplot annotations to Whitney (#162)

#162: annotate() / geom_text layers don't pick up Whitney by default. Extend the package's default-aes handling (R/default_aes.R) so annotation geoms inherit the CMAP font like other text does. Closes #162.

PR 13 — Resolve the testthat gap (add tests)

Config/testthat/edition: 3 is set but there's no tests/ dir. Add a minimal tests/testthat/ suite. Good first targets that also lock in the work above: fetch_pal, abbr_years, the palette color counts and overflow warning from PR 10, and the theme_cmap_base() object from PR 7.

PR 14 — Trim Suggests: tidyverse

Replace the tidyverse meta-package with the specific packages the vignettes use.

PR 15 — Document / wrap ggplotly() interaction (partly outside cmapplot)

Not cmapplot's bug, but hit twice: a geom_line() with a fixed color = "#hex" parameter rendered completely invisible under plotly::ggplotly(), while the same chart with color mapped via aes() (even to a constant) worked. Since CMAP reports commonly go to interactive HTML via cmap-html + plotly:

  • Add a short "gotchas when wrapping cmapplot charts in ggplotly()" note to a vignette, or
  • Export a cmap_ggplotly() convenience wrapper that handles this by default.

PR 16 — De-risk ggrepel internals (larger, optional)

R/geom_text_lastonly_repel.R calls ggrepel's unexported compiled routines by hardcoded symbol name (.Call('_ggrepel_...', PACKAGE = 'ggrepel', ...)). A ggrepel release could rename/remove these and silently break the geom. Bigger design change (vendor the C++ into src/, or rebuild on ggrepel's public API). Keep last and separate.


Backlog — existing feature-request issues (not scheduled in this pass)

These are open issues worth tracking but outside the modernization scope above. Left as-is so the critical path stays focused; promote into the numbered plan if priorities change.


Notes for whoever picks this up

  • Verify each PR in R before relying on green CI: devtools::load_all() to confirm parsing, devtools::build_vignettes() for the finalize/gridtext fix, and ideally devtools::check().
  • CI is currently red due to the pre-existing gridtext <pre> issue (fixed in PR 2.5) and aging GitHub Actions (PR 5). Don't read red as "my change broke it" until PR 2.5 + PR 5 are in.
  • Pipe convention: keep %>%.

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