From 1e4e755b23cc7bf8bfa9a9cadd4e17ceaadf88a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Canouil?= <8896044+mcanouil@users.noreply.github.com> Date: Wed, 12 Aug 2026 15:50:02 +0200 Subject: [PATCH 1/3] feat(gallery): redesign gallery with intent-driven landing Replace the single carousel gallery with an intent-driven landing and six category spoke pages. The landing offers a category chooser, a section rail, and curated featured examples with animated hover previews; each spoke page lists its examples with keyboard-operable category filters and working sort and search. Drive every card from YAML under docs/gallery/data/, with a curated featured.yml and per-category lists, and single-source the feature links and browse chips from that data. Consolidate thumbnails under thumbnails/ and add capture tooling for still, PDF, and video previews, documented in READMEs. Meet WCAG AA on the interactive chips and heading order, keep the legacy implementation for reference, and skip the freeze check for the intentionally deleted freeze entry. --- .githooks/check-freeze.sh | 13 + .github/workflows/preview.yml | 11 +- .../gallery/index/execute-results/html.json | 15 - _quarto.yml | 17 +- _tools/screenshots/README.md | 44 +++ _tools/screenshots/SETUP.md | 6 + _tools/screenshots/package-lock.json | 29 ++ _tools/screenshots/package.json | 7 + _tools/screenshots/scripts/PREVIEWS.md | 88 +++++ .../scripts/capture-card-thumbs.mjs | 143 ++++++++ .../scripts/capture-pdf-thumbs.mjs | 170 ++++++++++ .../screenshots/scripts/capture-previews.mjs | 267 +++++++++++++++ _tools/screenshots/scripts/help.js | 7 +- docs/gallery/README.md | 65 ++++ docs/gallery/_metadata.yml | 15 + docs/gallery/articles/advanced-layout-pdf.png | Bin 191186 -> 0 bytes docs/gallery/articles/articles-pdf.png | Bin 259104 -> 0 bytes docs/gallery/assets/_browse-chips.ejs.md | 19 ++ docs/gallery/assets/_caps.ejs.md | 9 + docs/gallery/assets/_card.ejs.md | 35 ++ docs/gallery/assets/_chooser.ejs.md | 15 + docs/gallery/assets/_featured.ejs.md | 110 +++++++ docs/gallery/assets/_gallery.scss | 300 +++++++++++++++++ docs/gallery/assets/_jumpnav.ejs.md | 109 +++++++ docs/gallery/assets/_preview.html | 188 +++++++++++ docs/gallery/browse.qmd | 26 ++ docs/gallery/carousel.R | 64 ---- docs/gallery/carousel.yml | 25 -- docs/gallery/dashboards-monitoring.qmd | 28 ++ .../gallery/dashboards/ggplotly-dashboard.png | Bin 283166 -> 0 bytes docs/gallery/dashboards/ojs-flights.jpg | Bin 75812 -> 0 bytes .../dashboards/waste-sites-dashboard.png | Bin 1455706 -> 0 bytes docs/gallery/data/dashboards-monitoring.yml | 191 +++++++++++ docs/gallery/data/featured.yml | 293 +++++++++++++++++ docs/gallery/data/personal-community.yml | 211 ++++++++++++ docs/gallery/data/reports-analytics.yml | 97 ++++++ docs/gallery/data/research-scholarship.yml | 104 ++++++ docs/gallery/data/software-documentation.yml | 127 ++++++++ docs/gallery/data/teaching-learning.yml | 304 ++++++++++++++++++ docs/gallery/index.qmd | 142 ++------ docs/gallery/legacy/README.md | 8 + docs/gallery/{ => legacy}/gallery.ejs | 0 docs/gallery/{ => legacy}/gallery.yml | 180 +++++------ docs/gallery/personal-community.qmd | 28 ++ .../presentations/presentations-beamer.png | Bin 92547 -> 0 bytes docs/gallery/presentations/presentations.png | Bin 148515 -> 0 bytes docs/gallery/reports-analytics.qmd | 28 ++ docs/gallery/research-scholarship.qmd | 28 ++ docs/gallery/software-documentation.qmd | 28 ++ docs/gallery/teaching-learning.qmd | 28 ++ .../customer-churn-dashboard.png | Bin .../dashing-through-snow.png | Bin .../diamonds-dashboard.png | Bin .../gapminder-dashboard.png | Bin .../dashboards-monitoring/gh-dashboard.png | Bin 0 -> 151508 bytes .../housing-market-dashboard.png | Bin .../dashboards-monitoring}/ld-dashboard.png | Bin .../dashboards-monitoring/mynorfolk.png | Bin 0 -> 147256 bytes .../nfl-injuries-dashboard.png | Bin .../nz-quakes-dashboard.png | Bin .../dashboards-monitoring}/ojs-flights.png | Bin .../ojs-penguins-dashboard.png | Bin .../dashboards-monitoring}/olympics-game.png | Bin .../penguins-dashboard.png | Bin .../pyopensci-software-review.png | Bin 0 -> 149662 bytes .../restaurant-dashboard.png | Bin .../retirement-gallery.png | Bin .../dashboards-monitoring/stock-explorer.png | Bin 0 -> 156911 bytes .../weather-ojs-dashboard.jpg | Bin .../personal-community-isabelizimm.mp4 | Bin 0 -> 118470 bytes .../personal-community-isabelizimm.webm | Bin 0 -> 112587 bytes .../personal-community-noahweidig.mp4 | Bin 0 -> 415835 bytes .../personal-community-noahweidig.webm | Bin 0 -> 296078 bytes .../featured/personal-community-rainbowr.mp4 | Bin 0 -> 88253 bytes .../featured/personal-community-rainbowr.webm | Bin 0 -> 90667 bytes .../featured/reports-analytics-closeread.mp4 | Bin 0 -> 332789 bytes .../featured/reports-analytics-closeread.webm | Bin 0 -> 274459 bytes .../featured/research-scholarship-affcom.mp4 | Bin 0 -> 48668 bytes .../featured/research-scholarship-affcom.webm | Bin 0 -> 51849 bytes .../research-scholarship-causal-inference.mp4 | Bin 0 -> 480786 bytes ...research-scholarship-causal-inference.webm | Bin 0 -> 342597 bytes .../software-documentation-great-docs.mp4 | Bin 0 -> 447249 bytes .../software-documentation-great-docs.webm | Bin 0 -> 390077 bytes .../software-documentation-gribouille.mp4 | Bin 0 -> 205050 bytes .../software-documentation-gribouille.webm | Bin 0 -> 158290 bytes .../software-documentation-positron.mp4 | Bin 0 -> 90783 bytes .../software-documentation-positron.webm | Bin 0 -> 93289 bytes .../teaching-learning-dataviz-course.mp4 | Bin 0 -> 215498 bytes .../teaching-learning-dataviz-course.webm | Bin 0 -> 192722 bytes .../teaching-learning-feature-eng.mp4 | Bin 0 -> 48931 bytes .../teaching-learning-feature-eng.webm | Bin 0 -> 54288 bytes .../teaching-learning-textrecipes.mp4 | Bin 0 -> 110071 bytes .../teaching-learning-textrecipes.webm | Bin 0 -> 108576 bytes .../legacy}/books-telling-stories.png | Bin .../{books => thumbnails/legacy}/ci-in-r.png | Bin .../legacy}/mynorfolk-dash.png | Bin .../legacy}/presentations-textrecipes.png | Bin .../legacy}/stock-explorer-dashboard.png | Bin .../legacy}/websites-rainbowr.png | Bin .../personal-community/bea-milz.png} | Bin .../chris-von-csefalvay.png} | Bin .../personal-community/dkapitan.png} | Bin .../personal-community/fluidsyndicate.png} | Bin .../personal-community/forbo7-landing.png} | Bin .../personal-community/hamel.png} | Bin .../personal-community/ipardalis.png} | Bin .../personal-community/isabelizimm.png | Bin 0 -> 402446 bytes .../personal-community/masiello-group.png} | Bin .../personal-community/mcanouil.png | Bin 0 -> 172247 bytes .../personal-community/mike-mahoney.png} | Bin .../personal-community/mockup.png} | Bin .../personal-community/nasa-openscapes.png} | Bin .../personal-community/nascent-peru.png | Bin 0 -> 332092 bytes .../personal-community}/nhs-r-website.png | Bin .../personal-community/noahweidig.png | Bin 0 -> 350019 bytes .../personal-community/quartotip.png} | Bin .../personal-community/rainbowr.png | Bin 0 -> 262649 bytes .../real-world-data-science.png} | Bin .../personal-community/vistales.png} | Bin .../personal-community/wannabe-rstats-fu.png} | Bin .../personal-community}/website-ala-labs.png | Bin .../advanced-layout-html.png | Bin .../reports-analytics/advanced-layout-pdf.png | Bin 0 -> 194466 bytes .../reports-analytics/closeread.png | Bin 0 -> 238313 bytes .../reports-analytics/html.png} | Bin .../reports-analytics/jupyter.png} | Bin .../reports-analytics/msword.png} | Bin .../reports-analytics/ojs.png} | Bin .../reports-analytics/shiny.png} | Bin .../thumbnails/reports-analytics/tfff.png | Bin 0 -> 259143 bytes .../thumbnails/reports-analytics/whr.png | Bin 0 -> 430970 bytes .../research-scholarship/affcom.png | Bin 0 -> 129060 bytes .../research-scholarship/causal-inference.png | Bin 0 -> 388420 bytes .../cleaning-bd-in-r.png} | Bin .../heiss-publications.png | Bin 0 -> 297748 bytes .../mcanouil-publications.png | Bin 0 -> 103439 bytes .../thumbnails/research-scholarship/pdf.png | Bin 0 -> 136162 bytes .../research-scholarship/r4csr.png} | Bin .../research-scholarship}/r4pde.png | Bin .../research-scholarship/telling-stories.png | Bin 0 -> 256209 bytes .../research-scholarship}/tsar.png | Bin .../software-documentation/devito.png} | Bin .../software-documentation/great-docs.png | Bin 0 -> 371540 bytes .../software-documentation/gribouille.png | Bin 0 -> 147927 bytes .../software-documentation/ibis.png} | Bin .../software-documentation/mrgsolve.png} | Bin .../software-documentation/nbdev.png} | Bin .../software-documentation/positron.png | Bin 0 -> 222772 bytes .../quarto-extensions.png | Bin 0 -> 149640 bytes .../software-documentation/quarto.png} | Bin .../r-development-guide.png} | Bin .../software-documentation/r-manuals.png} | Bin .../software-documentation/r-pkgs.png} | Bin .../software-documentation}/utilitr.png | Bin .../2021-cloud-hackathon.png} | Bin .../anthology-experimental-designs.png} | Bin .../teaching-learning/arrow-dplyr.png} | Bin .../teaching-learning/arrow-workshop.png} | Bin .../thumbnails/teaching-learning/beamer.png | Bin 0 -> 61502 bytes .../book-analyse-conceptions-french.png | Bin .../teaching-learning}/books_lsj.png | Bin .../teaching-learning/cookbook-rpolars.png} | Bin .../teaching-learning/datascienceinabox.png} | Bin .../teaching-learning/dataviz-course.png | Bin 0 -> 291575 bytes .../teaching-learning/des-rap-book.png | Bin 0 -> 829291 bytes .../educators-perspective-tidyverse.png} | Bin .../teaching-learning/feature-eng.png | Bin 0 -> 113745 bytes .../teaching-learning}/geocompy.png | Bin .../teaching-learning/hertie-coding-club.png} | Bin .../teaching-learning/hopr.png} | Bin .../teaching-learning/julia-workshop.png} | Bin .../teaching-learning/jupyter.png} | Bin .../teaching-learning/linogaliana.png} | Bin .../teaching-learning/mlr3book.png} | Bin .../teaching-learning}/modern-polars.png | Bin .../nfl-analytics-with-r.PNG | Bin .../opescapes-quarto-tutorial.png} | Bin .../teaching-learning/penguins-story.png} | Bin .../teaching-learning/powerpoint.png} | Bin .../practical-deep-learning.png} | Bin .../teaching-learning/python-for-data.png} | Bin .../quarto-the-practical-guide.png | Bin 0 -> 411524 bytes .../teaching-learning/r4ds.png} | Bin .../teaching-learning/revealjs.png} | Bin .../teaching-learning/sta210.png} | Bin .../streamlining-with-r.png} | Bin .../teaching-learning/textrecipes.png | Bin 0 -> 147278 bytes ...ebsite-m.canouil.dev_quarto-extensions.png | Bin 653636 -> 0 bytes .../websites/website-mickael.canouil.fr.png | Bin 993538 -> 0 bytes docs/websites/website-listings-custom.qmd | 6 +- 190 files changed, 3309 insertions(+), 319 deletions(-) delete mode 100644 _freeze/docs/gallery/index/execute-results/html.json create mode 100644 _tools/screenshots/README.md create mode 100644 _tools/screenshots/scripts/PREVIEWS.md create mode 100644 _tools/screenshots/scripts/capture-card-thumbs.mjs create mode 100644 _tools/screenshots/scripts/capture-pdf-thumbs.mjs create mode 100644 _tools/screenshots/scripts/capture-previews.mjs create mode 100644 docs/gallery/README.md create mode 100644 docs/gallery/_metadata.yml delete mode 100644 docs/gallery/articles/advanced-layout-pdf.png delete mode 100644 docs/gallery/articles/articles-pdf.png create mode 100644 docs/gallery/assets/_browse-chips.ejs.md create mode 100644 docs/gallery/assets/_caps.ejs.md create mode 100644 docs/gallery/assets/_card.ejs.md create mode 100644 docs/gallery/assets/_chooser.ejs.md create mode 100644 docs/gallery/assets/_featured.ejs.md create mode 100644 docs/gallery/assets/_gallery.scss create mode 100644 docs/gallery/assets/_jumpnav.ejs.md create mode 100644 docs/gallery/assets/_preview.html create mode 100644 docs/gallery/browse.qmd delete mode 100644 docs/gallery/carousel.R delete mode 100644 docs/gallery/carousel.yml create mode 100644 docs/gallery/dashboards-monitoring.qmd delete mode 100644 docs/gallery/dashboards/ggplotly-dashboard.png delete mode 100644 docs/gallery/dashboards/ojs-flights.jpg delete mode 100644 docs/gallery/dashboards/waste-sites-dashboard.png create mode 100644 docs/gallery/data/dashboards-monitoring.yml create mode 100644 docs/gallery/data/featured.yml create mode 100644 docs/gallery/data/personal-community.yml create mode 100644 docs/gallery/data/reports-analytics.yml create mode 100644 docs/gallery/data/research-scholarship.yml create mode 100644 docs/gallery/data/software-documentation.yml create mode 100644 docs/gallery/data/teaching-learning.yml create mode 100644 docs/gallery/legacy/README.md rename docs/gallery/{ => legacy}/gallery.ejs (100%) rename docs/gallery/{ => legacy}/gallery.yml (81%) create mode 100644 docs/gallery/personal-community.qmd delete mode 100644 docs/gallery/presentations/presentations-beamer.png delete mode 100644 docs/gallery/presentations/presentations.png create mode 100644 docs/gallery/reports-analytics.qmd create mode 100644 docs/gallery/research-scholarship.qmd create mode 100644 docs/gallery/software-documentation.qmd create mode 100644 docs/gallery/teaching-learning.qmd rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/customer-churn-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/dashing-through-snow.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/diamonds-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/gapminder-dashboard.png (100%) create mode 100644 docs/gallery/thumbnails/dashboards-monitoring/gh-dashboard.png rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/housing-market-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/ld-dashboard.png (100%) create mode 100644 docs/gallery/thumbnails/dashboards-monitoring/mynorfolk.png rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/nfl-injuries-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/nz-quakes-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/ojs-flights.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/ojs-penguins-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/olympics-game.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/penguins-dashboard.png (100%) create mode 100644 docs/gallery/thumbnails/dashboards-monitoring/pyopensci-software-review.png rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/restaurant-dashboard.png (100%) rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/retirement-gallery.png (100%) create mode 100644 docs/gallery/thumbnails/dashboards-monitoring/stock-explorer.png rename docs/gallery/{dashboards => thumbnails/dashboards-monitoring}/weather-ojs-dashboard.jpg (100%) create mode 100644 docs/gallery/thumbnails/featured/personal-community-isabelizimm.mp4 create mode 100644 docs/gallery/thumbnails/featured/personal-community-isabelizimm.webm create mode 100644 docs/gallery/thumbnails/featured/personal-community-noahweidig.mp4 create mode 100644 docs/gallery/thumbnails/featured/personal-community-noahweidig.webm create mode 100644 docs/gallery/thumbnails/featured/personal-community-rainbowr.mp4 create mode 100644 docs/gallery/thumbnails/featured/personal-community-rainbowr.webm create mode 100644 docs/gallery/thumbnails/featured/reports-analytics-closeread.mp4 create mode 100644 docs/gallery/thumbnails/featured/reports-analytics-closeread.webm create mode 100644 docs/gallery/thumbnails/featured/research-scholarship-affcom.mp4 create mode 100644 docs/gallery/thumbnails/featured/research-scholarship-affcom.webm create mode 100644 docs/gallery/thumbnails/featured/research-scholarship-causal-inference.mp4 create mode 100644 docs/gallery/thumbnails/featured/research-scholarship-causal-inference.webm create mode 100644 docs/gallery/thumbnails/featured/software-documentation-great-docs.mp4 create mode 100644 docs/gallery/thumbnails/featured/software-documentation-great-docs.webm create mode 100644 docs/gallery/thumbnails/featured/software-documentation-gribouille.mp4 create mode 100644 docs/gallery/thumbnails/featured/software-documentation-gribouille.webm create mode 100644 docs/gallery/thumbnails/featured/software-documentation-positron.mp4 create mode 100644 docs/gallery/thumbnails/featured/software-documentation-positron.webm create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-dataviz-course.mp4 create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-dataviz-course.webm create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-feature-eng.mp4 create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-feature-eng.webm create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-textrecipes.mp4 create mode 100644 docs/gallery/thumbnails/featured/teaching-learning-textrecipes.webm rename docs/gallery/{books => thumbnails/legacy}/books-telling-stories.png (100%) rename docs/gallery/{books => thumbnails/legacy}/ci-in-r.png (100%) rename docs/gallery/{dashboards => thumbnails/legacy}/mynorfolk-dash.png (100%) rename docs/gallery/{presentations => thumbnails/legacy}/presentations-textrecipes.png (100%) rename docs/gallery/{dashboards => thumbnails/legacy}/stock-explorer-dashboard.png (100%) rename docs/gallery/{websites => thumbnails/legacy}/websites-rainbowr.png (100%) rename docs/gallery/{websites/websites-bea-milz.png => thumbnails/personal-community/bea-milz.png} (100%) rename docs/gallery/{websites/websites-chris-von-csefalvay.png => thumbnails/personal-community/chris-von-csefalvay.png} (100%) rename docs/gallery/{websites/websites-dkapitan.png => thumbnails/personal-community/dkapitan.png} (100%) rename docs/gallery/{websites/websites-fluidsyndicate.png => thumbnails/personal-community/fluidsyndicate.png} (100%) rename docs/gallery/{websites/websites-forbo7-landing.png => thumbnails/personal-community/forbo7-landing.png} (100%) rename docs/gallery/{websites/websites-hamel.png => thumbnails/personal-community/hamel.png} (100%) rename docs/gallery/{websites/websites-ipardalis.png => thumbnails/personal-community/ipardalis.png} (100%) create mode 100644 docs/gallery/thumbnails/personal-community/isabelizimm.png rename docs/gallery/{websites/websites-masiello-group.png => thumbnails/personal-community/masiello-group.png} (100%) create mode 100644 docs/gallery/thumbnails/personal-community/mcanouil.png rename docs/gallery/{websites/websites-mike-mahoney.png => thumbnails/personal-community/mike-mahoney.png} (100%) rename docs/gallery/{websites/websites-mockup.png => thumbnails/personal-community/mockup.png} (100%) rename docs/gallery/{websites/websites-nasa-openscapes.png => thumbnails/personal-community/nasa-openscapes.png} (100%) create mode 100644 docs/gallery/thumbnails/personal-community/nascent-peru.png rename docs/gallery/{websites => thumbnails/personal-community}/nhs-r-website.png (100%) create mode 100644 docs/gallery/thumbnails/personal-community/noahweidig.png rename docs/gallery/{websites/websites-quartotip.png => thumbnails/personal-community/quartotip.png} (100%) create mode 100644 docs/gallery/thumbnails/personal-community/rainbowr.png rename docs/gallery/{websites/websites-real-world-data-science.png => thumbnails/personal-community/real-world-data-science.png} (100%) rename docs/gallery/{websites/websites-vistales.png => thumbnails/personal-community/vistales.png} (100%) rename docs/gallery/{websites/websites-wannabe-rstats-fu.png => thumbnails/personal-community/wannabe-rstats-fu.png} (100%) rename docs/gallery/{websites => thumbnails/personal-community}/website-ala-labs.png (100%) rename docs/gallery/{articles => thumbnails/reports-analytics}/advanced-layout-html.png (100%) create mode 100644 docs/gallery/thumbnails/reports-analytics/advanced-layout-pdf.png create mode 100644 docs/gallery/thumbnails/reports-analytics/closeread.png rename docs/gallery/{articles/articles-html.png => thumbnails/reports-analytics/html.png} (100%) rename docs/gallery/{interactive/interactive-jupyter.png => thumbnails/reports-analytics/jupyter.png} (100%) rename docs/gallery/{articles/articles-msword.png => thumbnails/reports-analytics/msword.png} (100%) rename docs/gallery/{interactive/interactive-ojs.png => thumbnails/reports-analytics/ojs.png} (100%) rename docs/gallery/{interactive/interactive-shiny.png => thumbnails/reports-analytics/shiny.png} (100%) create mode 100644 docs/gallery/thumbnails/reports-analytics/tfff.png create mode 100644 docs/gallery/thumbnails/reports-analytics/whr.png create mode 100644 docs/gallery/thumbnails/research-scholarship/affcom.png create mode 100644 docs/gallery/thumbnails/research-scholarship/causal-inference.png rename docs/gallery/{books/books-cleaning-bd-in-r.png => thumbnails/research-scholarship/cleaning-bd-in-r.png} (100%) create mode 100644 docs/gallery/thumbnails/research-scholarship/heiss-publications.png create mode 100644 docs/gallery/thumbnails/research-scholarship/mcanouil-publications.png create mode 100644 docs/gallery/thumbnails/research-scholarship/pdf.png rename docs/gallery/{books/books-r4csr.png => thumbnails/research-scholarship/r4csr.png} (100%) rename docs/gallery/{books => thumbnails/research-scholarship}/r4pde.png (100%) create mode 100644 docs/gallery/thumbnails/research-scholarship/telling-stories.png rename docs/gallery/{books => thumbnails/research-scholarship}/tsar.png (100%) rename docs/gallery/{websites/websites-devito.png => thumbnails/software-documentation/devito.png} (100%) create mode 100644 docs/gallery/thumbnails/software-documentation/great-docs.png create mode 100644 docs/gallery/thumbnails/software-documentation/gribouille.png rename docs/gallery/{websites/websites-ibis.png => thumbnails/software-documentation/ibis.png} (100%) rename docs/gallery/{websites/websites-mrgsolve.png => thumbnails/software-documentation/mrgsolve.png} (100%) rename docs/gallery/{websites/websites-nbdev.png => thumbnails/software-documentation/nbdev.png} (100%) create mode 100644 docs/gallery/thumbnails/software-documentation/positron.png create mode 100644 docs/gallery/thumbnails/software-documentation/quarto-extensions.png rename docs/gallery/{websites/websites-quarto.png => thumbnails/software-documentation/quarto.png} (100%) rename docs/gallery/{books/books-r-development-guide.png => thumbnails/software-documentation/r-development-guide.png} (100%) rename docs/gallery/{websites/websites-r-manuals.png => thumbnails/software-documentation/r-manuals.png} (100%) rename docs/gallery/{books/books-r-pkgs.png => thumbnails/software-documentation/r-pkgs.png} (100%) rename docs/gallery/{books => thumbnails/software-documentation}/utilitr.png (100%) rename docs/gallery/{websites/websites-2021-cloud-hackathon.png => thumbnails/teaching-learning/2021-cloud-hackathon.png} (100%) rename docs/gallery/{presentations/presentations-anthology-experimental-designs.png => thumbnails/teaching-learning/anthology-experimental-designs.png} (100%) rename docs/gallery/{presentations/presentations-arrow-dplyr.png => thumbnails/teaching-learning/arrow-dplyr.png} (100%) rename docs/gallery/{websites/websites-arrow-workshop.png => thumbnails/teaching-learning/arrow-workshop.png} (100%) create mode 100644 docs/gallery/thumbnails/teaching-learning/beamer.png rename docs/gallery/{books => thumbnails/teaching-learning}/book-analyse-conceptions-french.png (100%) rename docs/gallery/{books => thumbnails/teaching-learning}/books_lsj.png (100%) rename docs/gallery/{books/books-cookbook-rpolars.png => thumbnails/teaching-learning/cookbook-rpolars.png} (100%) rename docs/gallery/{websites/websites-datascienceinabox.png => thumbnails/teaching-learning/datascienceinabox.png} (100%) create mode 100644 docs/gallery/thumbnails/teaching-learning/dataviz-course.png create mode 100644 docs/gallery/thumbnails/teaching-learning/des-rap-book.png rename docs/gallery/{presentations/presentations-educators-perspective-tidyverse.png => thumbnails/teaching-learning/educators-perspective-tidyverse.png} (100%) create mode 100644 docs/gallery/thumbnails/teaching-learning/feature-eng.png rename docs/gallery/{books => thumbnails/teaching-learning}/geocompy.png (100%) rename docs/gallery/{websites/websites-hertie-coding-club.png => thumbnails/teaching-learning/hertie-coding-club.png} (100%) rename docs/gallery/{websites/websites-hopr.png => thumbnails/teaching-learning/hopr.png} (100%) rename docs/gallery/{websites/websites-julia-workshop.png => thumbnails/teaching-learning/julia-workshop.png} (100%) rename docs/gallery/{websites/websites-jupyter.png => thumbnails/teaching-learning/jupyter.png} (100%) rename docs/gallery/{websites/websites-linogaliana.png => thumbnails/teaching-learning/linogaliana.png} (100%) rename docs/gallery/{books/books-mlr3book.png => thumbnails/teaching-learning/mlr3book.png} (100%) rename docs/gallery/{books => thumbnails/teaching-learning}/modern-polars.png (100%) rename docs/gallery/{books => thumbnails/teaching-learning}/nfl-analytics-with-r.PNG (100%) rename docs/gallery/{websites/websites-opescapes-quarto-tutorial.png => thumbnails/teaching-learning/opescapes-quarto-tutorial.png} (100%) rename docs/gallery/{presentations/presentations-penguins-story.png => thumbnails/teaching-learning/penguins-story.png} (100%) rename docs/gallery/{presentations/presentations-powerpoint.png => thumbnails/teaching-learning/powerpoint.png} (100%) rename docs/gallery/{websites/websites-practical-deep-learning.png => thumbnails/teaching-learning/practical-deep-learning.png} (100%) rename docs/gallery/{books/books-python-for-data.png => thumbnails/teaching-learning/python-for-data.png} (100%) create mode 100644 docs/gallery/thumbnails/teaching-learning/quarto-the-practical-guide.png rename docs/gallery/{books/books-r4ds.png => thumbnails/teaching-learning/r4ds.png} (100%) rename docs/gallery/{presentations/presentations-revealjs.png => thumbnails/teaching-learning/revealjs.png} (100%) rename docs/gallery/{websites/websites-sta210.png => thumbnails/teaching-learning/sta210.png} (100%) rename docs/gallery/{presentations/presentations-streamlining-with-r.png => thumbnails/teaching-learning/streamlining-with-r.png} (100%) create mode 100644 docs/gallery/thumbnails/teaching-learning/textrecipes.png delete mode 100644 docs/gallery/websites/website-m.canouil.dev_quarto-extensions.png delete mode 100644 docs/gallery/websites/website-mickael.canouil.fr.png diff --git a/.githooks/check-freeze.sh b/.githooks/check-freeze.sh index a5ddd16231..6c39d76895 100755 --- a/.githooks/check-freeze.sh +++ b/.githooks/check-freeze.sh @@ -39,6 +39,19 @@ while IFS= read -r qmd; do [ -n "$qmd" ] || continue freeze_rel="_freeze/${qmd%.qmd}/execute-results/html.json" + # Skip when the freeze file is intentionally removed in this change: the + # page no longer executes code (e.g. converted to the markdown engine), so + # its freeze entry is vestigial and correctly deleted, not stale. + if [ "$MODE" = "commit" ]; then + if git diff --cached --diff-filter=D --name-only 2>/dev/null | grep -Fxq "$freeze_rel"; then + continue + fi + else + if git diff "${REMOTE}..HEAD" --diff-filter=D --name-only 2>/dev/null | grep -Fxq "$freeze_rel"; then + continue + fi + fi + # Read freeze JSON from git objects, not working tree, to avoid false passes # when the freeze file is updated on disk but not yet staged. if [ "$MODE" = "commit" ]; then diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 3c617d6488..20be8f3b66 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -210,9 +210,14 @@ jobs: 'docs/extensions/listings/custom-formats.yml': 'docs/extensions/index.html', 'docs/extensions/listings/revealjs-formats.yml': 'docs/extensions/index.html', 'docs/extensions/listings/revealjs.yml': 'docs/extensions/index.html', - // Gallery data files → gallery index - 'docs/gallery/carousel.yml': 'docs/gallery/index.html', - 'docs/gallery/gallery.yml': 'docs/gallery/index.html', + // Gallery data files → gallery pages + 'docs/gallery/data/featured.yml': 'docs/gallery/index.html', + 'docs/gallery/data/reports-analytics.yml': 'docs/gallery/reports-analytics.html', + 'docs/gallery/data/dashboards-monitoring.yml': 'docs/gallery/dashboards-monitoring.html', + 'docs/gallery/data/research-scholarship.yml': 'docs/gallery/research-scholarship.html', + 'docs/gallery/data/teaching-learning.yml': 'docs/gallery/teaching-learning.html', + 'docs/gallery/data/software-documentation.yml': 'docs/gallery/software-documentation.html', + 'docs/gallery/data/personal-community.yml': 'docs/gallery/personal-community.html', // Guide listing → guide index 'docs/guide/guide.yml': 'docs/guide/index.html', // Download data → download index diff --git a/_freeze/docs/gallery/index/execute-results/html.json b/_freeze/docs/gallery/index/execute-results/html.json deleted file mode 100644 index f9f6bfda06..0000000000 --- a/_freeze/docs/gallery/index/execute-results/html.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hash": "838b86bcdf1e147ddbf3ace68d6405b8", - "result": { - "engine": "knitr", - "markdown": "---\npagetitle: \"Gallery\"\nformat:\n html:\n toc: false\nimage: articles/advanced-layout-pdf.png\nsearch: false\nexecute:\n echo: false\nlisting:\n - id: gallery\n template: gallery.ejs\n contents: gallery.yml\ndescription: |\n A gallery of example documents, websites, books, and presentations created with Quarto.\naliases:\n - /docs/dashboards/examples/index.html\n - /docs/dashboards/examples/\n---\n\n::: {#hero-banner .column-screen}\n::: {.grid .column-page}\n::: {.headline .g-col-lg-6 .g-col-12 .g-col-md-12}\n::: {.h1 role=\"heading\" aria-level=\"1\"}\nGallery\n:::\n\n\nQuarto can produce a wide variety of output formats. Here are some examples:\n\n- [Articles & Reports](#articles-reports)\n- [Presentations](#presentations)\n- [Dashboards](#dashboards)\n- [Websites](#websites)\n- [Books](#books)\n- [Interactive Docs](#interactive-docs)\n:::\n\n\n::: {.cell .g-col-lg-6 .g-col-12 .g-col-md-12}\n::: {.cell-output-display}\n\n```{=html}\n
\n
\n\n\n\n\n\n
\n
\n
\n\n\"A\n\n
\n

Articles and reports with Python and R

\n
\n
\n
\n\n\"A\n\n
\n

Create data-driven presentations

\n
\n
\n
\n\n\"A\n\n
\n

Engage readers with interactivity

\n
\n
\n
\n\n\"Documentation\n\n
\n

Publish collections of articles as a website

\n
\n
\n
\n\n\"A\n\n
\n

Create multi-format books

\n
\n
\n
\n\n\n
\n```\n\n:::\n:::\n\n:::\n:::\n\n::: {#gallery .column-page}\n:::\n\n```{=html}\n\n```\n", - "supporting": [], - "filters": [ - "rmarkdown/pagebreak.lua" - ], - "includes": {}, - "engineDependencies": {}, - "preserve": {}, - "postProcess": true - } -} \ No newline at end of file diff --git a/_quarto.yml b/_quarto.yml index b52f28767d..dd66373bca 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -111,6 +111,19 @@ website: - text: "Tutorial: Authoring" href: docs/get-started/authoring/ + - id: gallery + contents: + - section: "Gallery" + href: docs/gallery/index.qmd + contents: + - docs/gallery/reports-analytics.qmd + - docs/gallery/dashboards-monitoring.qmd + - docs/gallery/research-scholarship.qmd + - docs/gallery/teaching-learning.qmd + - docs/gallery/software-documentation.qmd + - docs/gallery/personal-community.qmd + - docs/gallery/browse.qmd + - id: guide collapse-level: 1 contents: @@ -684,8 +697,8 @@ format: respect-user-color-scheme: true toc: true theme: - light: [cosmo, theme.scss] - dark: [cosmo, theme-dark.scss] + light: [cosmo, theme.scss, docs/gallery/assets/_gallery.scss] + dark: [cosmo, theme-dark.scss, docs/gallery/assets/_gallery.scss] code-copy: true code-overflow: wrap css: styles.css diff --git a/_tools/screenshots/README.md b/_tools/screenshots/README.md new file mode 100644 index 0000000000..2a575e43ca --- /dev/null +++ b/_tools/screenshots/README.md @@ -0,0 +1,44 @@ +# Screenshot and preview tooling + +Scripts to capture and update quarto-web's documentation images and gallery media. + +There are two families. +Doc screenshots come from `manifest.json` through `capture.js`. +Gallery assets come from `docs/gallery/data/*.yml` through the `scripts/capture-*.mjs` scripts. + +Run every command from `_tools/screenshots/`. + +## Which tool makes what + +| Asset | Command | Script | Output | +| ----------------------------------------- | ----------------------------- | ---------------------------------- | ----------------------------------------------- | +| Doc screenshots (PNG, light and dark) | `npm run capture` | `capture.js` (manifest) | `docs/**/images/*.png` | +| Gallery hover previews (webm and mp4) | `npm run capture:previews` | `scripts/capture-previews.mjs` | `docs/gallery/thumbnails/featured/*.{webm,mp4}` | +| Gallery PDF card thumbnails (PNG) | `npm run capture:pdf-thumbs` | `scripts/capture-pdf-thumbs.mjs` | `docs/gallery/thumbnails/**/*.png` | +| Gallery card thumbnails, image-less (PNG) | `npm run capture:card-thumbs` | `scripts/capture-card-thumbs.mjs` | `docs/gallery/thumbnails//.png` | +| axe DevTools console (PNG, manual, macOS) | see script header | `scripts/capture-axe-devtools.mjs` | `docs/output-formats/images/axe-console.png` | + +Only `npm run capture:previews` makes the mp4 and webm hover clips. + +Each `capture:*` gallery command takes `-- --name ` to match a subset. +Each also takes `-- --limit ` to stage the first `n` matches. + +## Prerequisites at a glance + +All commands need Node.js 18+ and this tool's dependencies (`npm install`, then `npx playwright install chromium`). + +`capture:previews` also needs ffmpeg on `PATH` and a full Playwright Chromium; set `PREVIEW_CHROME` to point at it because the headless shell cannot record video. + +`capture:pdf-thumbs` also needs poppler (`pdfinfo`, `pdftoppm`) and ImageMagick (`magick`). + +Full setup steps are in `SETUP.md`. +The gallery prerequisites are detailed in `scripts/PREVIEWS.md`. + +## Where to read next + +`SETUP.md` covers install steps and the still-screenshot workflow. +`scripts/PREVIEWS.md` covers gallery video previews plus PDF and card thumbnails in detail. +`docs/gallery/README.md` covers how to add the gallery entries these thumbnails serve. +`CLAUDE.md` covers the AI-assisted workflow and the `manifest.json` field reference. +`DECISIONS.md` covers why the tooling is built the way it is. +`npm run help` prints the full command list. diff --git a/_tools/screenshots/SETUP.md b/_tools/screenshots/SETUP.md index de12eb4bcd..20c8aced2f 100644 --- a/_tools/screenshots/SETUP.md +++ b/_tools/screenshots/SETUP.md @@ -61,6 +61,12 @@ playwright-cli -s=screenshot screenshot --filename=docs/websites/images/about-jo playwright-cli -s=screenshot close ``` +## Gallery featured video previews + +`scripts/capture-previews.mjs` (`npm run capture:previews`) records the animated preview +clips for featured gallery cards. It is separate from the still-screenshot manifest and +needs ffmpeg plus a full Playwright Chromium. See **`scripts/PREVIEWS.md`** for details. + ## Optional: PNG Compression ```bash diff --git a/_tools/screenshots/package-lock.json b/_tools/screenshots/package-lock.json index ce19c156c7..92534f5647 100644 --- a/_tools/screenshots/package-lock.json +++ b/_tools/screenshots/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "ajv": "^8.18.0", + "js-yaml": "^5.2.3", "open": "^10.0.0", "playwright": "^1.50.0", "sharp": "^0.33.0" @@ -398,6 +399,12 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -593,6 +600,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/js-yaml": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.3.tgz", + "integrity": "sha512-n+mUVyUX5bVv7G/G2zyIHOhdxfuU1dY2NOFzTQUWiMUbFss8b57NFlgCCaggU78wSw5KVS9cllzeLyzyR+n5nw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", diff --git a/_tools/screenshots/package.json b/_tools/screenshots/package.json index 770a0cbfdf..d14dbc1243 100644 --- a/_tools/screenshots/package.json +++ b/_tools/screenshots/package.json @@ -8,14 +8,21 @@ "serve": "node scripts/serve.js", "compress": "node scripts/compress.js", "capture": "node capture.js", + "capture:previews": "node scripts/capture-previews.mjs", + "capture:pdf-thumbs": "node scripts/capture-pdf-thumbs.mjs", + "capture:card-thumbs": "node scripts/capture-card-thumbs.mjs", "open": "node scripts/open.js", "validate": "node scripts/validate.js", "update-demo": "bash scripts/update-demo.sh" }, "dependencies": { "ajv": "^8.18.0", + "js-yaml": "^5.2.3", "open": "^10.0.0", "playwright": "^1.50.0", "sharp": "^0.33.0" + }, + "allowScripts": { + "sharp@0.33.5": true } } diff --git a/_tools/screenshots/scripts/PREVIEWS.md b/_tools/screenshots/scripts/PREVIEWS.md new file mode 100644 index 0000000000..10885f324a --- /dev/null +++ b/_tools/screenshots/scripts/PREVIEWS.md @@ -0,0 +1,88 @@ +# Gallery featured video previews + +`capture-previews.mjs` generates the short, muted, looping clips that featured +gallery cards play on hover or keyboard focus. The rendering, +interaction, and reduced-motion handling live in the gallery, not here: +`docs/gallery/assets/_featured.ejs.md` and `docs/gallery/assets/_gallery.scss`. + +This script is separate from the still-screenshot manifest (`capture.js`): it +records motion rather than a single frame, and is driven by gallery data rather +than `manifest.json`. + +## How it works + +- Driven by `docs/gallery/data/featured.yml`: every card with both a `live` URL + and a `preview` base path gets a clip. `preview:` is the output path without + extension, e.g. `thumbnails/featured/software-documentation-gribouille`. +- Optional `preview-url:` overrides the page that is recorded when the card's + `live` link is not the best source (e.g. a landing page vs a richer subpage). The + card's `live` link is unchanged; only the capture source differs. +- Output: `.webm` (VP9) and `.mp4` (H.264) under + `docs/gallery/thumbnails/featured/` (animated previews are a featured-only + asset), beside the still PNG (`image:`), which stays the `