From d40259681fd4711f25d364571a497def207ec473 Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Tue, 19 May 2026 11:37:48 -0500
Subject: [PATCH 1/6] imrpove language of gallery landing page
---
docs/gallery.md | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/docs/gallery.md b/docs/gallery.md
index c14dfa8a4..961d8d394 100644
--- a/docs/gallery.md
+++ b/docs/gallery.md
@@ -4,9 +4,17 @@
Examples of napari usage.
-All examples in this gallery can be downloaded as Python scripts or Jupyter
-notebooks to be executed locally. Check out [](launch-jupyter) for more details
-on using napari in Jupyter notebooks.
+Each example page includes downloads for both the source `.py` file and a
+generated Jupyter notebook. If you download the Python script, you can run it
+with `napari path/to/my_example.py` or drag the `.py` file onto a running napari viewer
+to execute it there. Some examples may require additional dependencies beyond
+napari itself, so be sure to check the example's source code for any additional
+requirements if you see an error when trying to run it.
+Check out [](launch-jupyter) for more details on using
+napari in Jupyter notebooks.
+
+Use the tag index below to browse examples by topic, or jump straight into the
+gallery grid.
```{note}
From 431c86946be733389e7995c45e8e0c2bd8056f18 Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Tue, 19 May 2026 11:38:13 -0500
Subject: [PATCH 2/6] WIP initial LLM working strategy
---
docs/_static/custom.css | 27 +++++++++++++++++
docs/conf.py | 64 +++++++++++++++++++++++++++++++++++------
2 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index e5c50e450..918057251 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -44,6 +44,33 @@ html[data-theme="dark"] div.sphx-glr-download a:hover {
background-color: #222832 !important;
}
+.napari-gallery-downloads {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin: 0 0 1.25rem;
+}
+
+.napari-gallery-downloads .sphx-glr-download {
+ margin: 0;
+}
+
+html[data-theme="light"] .napari-gallery-downloads div.sphx-glr-download a {
+ border-color: #d7deea !important;
+}
+
+html[data-theme="dark"] .napari-gallery-downloads div.sphx-glr-download a {
+ border-color: #4f5f79 !important;
+ color: #fff;
+}
+
+.sphx-glr-download-link-note,
+.sphx-glr-download-jupyter,
+.sphx-glr-download-python,
+.sphx-glr-download-zip {
+ display: none;
+}
+
/* Version warning banner color */
#bd-header-version-warning {
background-color: color-mix(in srgb, var(--pst-color-secondary-bg), transparent 30%);
diff --git a/docs/conf.py b/docs/conf.py
index 569b5b0da..362b9bf76 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -396,6 +396,60 @@ def napari_scraper(block, block_vars, gallery_conf):
return scrapers.figure_rst(img_paths, gallery_conf['src_dir'])
+GALLERY_DOWNLOAD_NOTE_RE = re.compile(
+ r'\n\.\. only:: html\n\n'
+ r' \.\. note::\n'
+ r' :class: sphx-glr-download-link-note\n\n'
+ r' :ref:`Go to the end ]+>`\n'
+ r' to download the full example as a Python script or as a\n'
+ r' Jupyter notebook\.\.?\n',
+ re.MULTILINE,
+)
+GALLERY_TITLE_RE = re.compile(r'^(?P.+\n=+\n)', re.MULTILINE)
+
+
+def add_gallery_download_buttons(app, docname, source):
+ """Add compact top-of-page download links to generated gallery examples."""
+ if not docname.startswith('gallery/'):
+ return
+ if docname.endswith('/index') or docname.endswith('sg_execution_times'):
+ return
+
+ content = source[0]
+ if 'THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.' not in content:
+ return
+
+ content = GALLERY_DOWNLOAD_NOTE_RE.sub('\n', content, count=1)
+ if 'napari-gallery-downloads' in content:
+ source[0] = content
+ return
+
+ example_name = Path(docname).name
+ title_match = GALLERY_TITLE_RE.search(content)
+ if title_match is None:
+ source[0] = content
+ return
+
+ download_block = f"""
+.. only:: html
+
+ .. container:: napari-gallery-downloads
+
+ .. container:: sphx-glr-download
+
+ :download:`Python (.py) <{example_name}.py>`
+
+ .. container:: sphx-glr-download
+
+ :download:`Notebook (.ipynb) <{example_name}.ipynb>`
+"""
+ source[0] = (
+ content[: title_match.end()]
+ + download_block
+ + content[title_match.end() :]
+ )
+
+
gen_rst.EXAMPLE_HEADER = """
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
@@ -403,15 +457,6 @@ def napari_scraper(block, block_vars, gallery_conf):
.. "{0}"
.. LINE NUMBERS ARE GIVEN BELOW.
-.. only:: html
-
- .. note::
- :class: sphx-glr-download-link-note
-
- :ref:`Go to the end `
- to download the full example as a Python script or as a
- Jupyter notebook.{2}
-
.. rst-class:: sphx-glr-example-title
.. _sphx_glr_{1}:
@@ -549,6 +594,7 @@ def setup(app):
"""
app.registry.source_suffix.pop('.ipynb', None)
app.connect('source-read', add_google_calendar_secrets)
+ app.connect('source-read', add_gallery_download_buttons)
app.connect('linkcheck-process-uri', rewrite_github_anchor)
app.connect('autodoc-process-docstring', qt_docstrings)
From fc1477b4f50d9d120329e7389d4c873b2f1ce27f Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Tue, 19 May 2026 12:13:29 -0500
Subject: [PATCH 3/6] simplify imlpementation and css
---
docs/_static/custom.css | 9 ---------
docs/conf.py | 24 +++++++-----------------
2 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index 918057251..0eed907b2 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -55,15 +55,6 @@ html[data-theme="dark"] div.sphx-glr-download a:hover {
margin: 0;
}
-html[data-theme="light"] .napari-gallery-downloads div.sphx-glr-download a {
- border-color: #d7deea !important;
-}
-
-html[data-theme="dark"] .napari-gallery-downloads div.sphx-glr-download a {
- border-color: #4f5f79 !important;
- color: #fff;
-}
-
.sphx-glr-download-link-note,
.sphx-glr-download-jupyter,
.sphx-glr-download-python,
diff --git a/docs/conf.py b/docs/conf.py
index 362b9bf76..43b7cdf72 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -396,20 +396,16 @@ def napari_scraper(block, block_vars, gallery_conf):
return scrapers.figure_rst(img_paths, gallery_conf['src_dir'])
-GALLERY_DOWNLOAD_NOTE_RE = re.compile(
- r'\n\.\. only:: html\n\n'
- r' \.\. note::\n'
- r' :class: sphx-glr-download-link-note\n\n'
- r' :ref:`Go to the end ]+>`\n'
- r' to download the full example as a Python script or as a\n'
- r' Jupyter notebook\.\.?\n',
- re.MULTILINE,
-)
-GALLERY_TITLE_RE = re.compile(r'^(?P.+\n=+\n)', re.MULTILINE)
+GALLERY_TITLE_RE = re.compile(r'^.+\n=+\n', re.MULTILINE)
def add_gallery_download_buttons(app, docname, source):
- """Add compact top-of-page download links to generated gallery examples."""
+ """Add compact top-of-page download links to generated gallery examples.
+
+ The title of the example is used to determine where to insert the download links,
+ which are only added to generated gallery examples.
+ The links are added after the title.
+ """
if not docname.startswith('gallery/'):
return
if docname.endswith('/index') or docname.endswith('sg_execution_times'):
@@ -419,15 +415,9 @@ def add_gallery_download_buttons(app, docname, source):
if 'THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.' not in content:
return
- content = GALLERY_DOWNLOAD_NOTE_RE.sub('\n', content, count=1)
- if 'napari-gallery-downloads' in content:
- source[0] = content
- return
-
example_name = Path(docname).name
title_match = GALLERY_TITLE_RE.search(content)
if title_match is None:
- source[0] = content
return
download_block = f"""
From a036fec20b538863db370b43dab3c93516057351 Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Wed, 20 May 2026 15:00:03 -0500
Subject: [PATCH 4/6] update with #1026 css logic
---
docs/_static/custom.css | 135 +++++++++++++++++++++-------------------
docs/index.md | 6 +-
2 files changed, 74 insertions(+), 67 deletions(-)
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index 0eed907b2..87a94abb8 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -1,60 +1,45 @@
-/*
-Sphinx-Gallery has compatible CSS to fix default sphinx themes
-Tested for Sphinx 1.3.1 for all themes: default, alabaster, sphinxdoc,
-scrolls, agogo, traditional, nature, haiku, pyramid
-Tested for Read the Docs theme 0.1.7 */
-
-html[data-theme="light"] div.sphx-glr-download a {
- background-color: rgb(255, 255, 255) !important;
- background-image: linear-gradient(to bottom, rgb(255, 255, 255), #ffffff) !important;
+/* ── Buttons for homepage and gallery ───────────────────────────────────── */
+
+.button-primary,
+.button-alt,
+.napari-gallery-downloads .sphx-glr-download a {
+ background-image: none !important;
border-radius: 4px;
- border: 1px solid #ffffff !important;
- color: #000;
- display: inline-block;
- font-weight: bold;
- padding: 1ex;
text-align: center;
+ text-decoration: none;
}
-html[data-theme="light"] div.sphx-glr-download a:hover {
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
- 0 1px 5px rgba(0, 0, 0, 0.25);
- text-decoration: none;
- background-image: none;
- background-color: #ffffff !important;
+/* makes homepage button take up width of column */
+.button-primary {
+ display: block;
}
-html[data-theme="dark"] div.sphx-glr-download a {
- background-color: #222832 !important;
- background-image: linear-gradient(to bottom, #222832, #222832) !important;
- border-radius: 4px;
- border: 1px solid #222832 !important;
- color: #000;
+/* Allow border override to show through on example buttons */
+.napari-gallery-downloads .sphx-glr-download a {
+ border: 1px solid transparent;
display: inline-block;
- font-weight: bold;
- padding: 1ex;
- text-align: center;
+ padding: 0.45rem 0.8rem;
}
-html[data-theme="dark"] div.sphx-glr-download a:hover {
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
- 0 1px 5px rgba(0, 0, 0, 0.25);
- text-decoration: none;
- background-image: none;
- background-color: #222832 !important;
+/* force sphinx-gallery download code to inherit text color */
+.napari-gallery-downloads .sphx-glr-download a code.download {
+ color: inherit !important;
}
+/* horizontally align and reduce lower margin of container */
.napari-gallery-downloads {
display: flex;
flex-wrap: wrap;
- gap: 0.5rem;
- margin: 0 0 1.25rem;
+ gap: 0.375rem;
+ margin: 0 0 0.35rem;
}
+/* remove spacing around download buttons */
.napari-gallery-downloads .sphx-glr-download {
margin: 0;
}
+/* Remove the sphinx-gallery downloads note and buttons */
.sphx-glr-download-link-note,
.sphx-glr-download-jupyter,
.sphx-glr-download-python,
@@ -62,53 +47,75 @@ html[data-theme="dark"] div.sphx-glr-download a:hover {
display: none;
}
-/* Version warning banner color */
-#bd-header-version-warning {
- background-color: color-mix(in srgb, var(--pst-color-secondary-bg), transparent 30%);
+html[data-theme="light"] .button-primary,
+html[data-theme="light"] .napari-gallery-downloads .sphx-glr-download a {
+ background-color: var(--napari-primary-blue) !important;
+ border-color: var(--napari-primary-blue) !important;
+ color: var(--napari-color-text-base) !important;
}
-#bd-header-version-warning .pst-button-link-to-stable-version {
- background-color: color-mix(in srgb, var(--pst-color-secondary-bg), transparent 0%);
- border-color: var(--pst-color-secondary-bg);
- color: var(--napari-color-text-base);
- font-weight: 700;
+html[data-theme="dark"] .button-primary,
+html[data-theme="dark"] .napari-gallery-downloads .sphx-glr-download a {
+ background-color: var(--napari-purple) !important;
+ border-color: var(--napari-purple) !important;
+ color: var(--napari-color-text-base) !important;
}
-#bd-header-version-warning .pst-button-link-to-stable-version:hover {
- background-color: var(--pst-color-secondary-bg);
- border-color: var(--pst-color-secondary-bg);
- color: var(--napari-color-text-base);
- font-weight: 700;
+html[data-theme="light"] .button-primary:hover,
+html[data-theme="light"] .napari-gallery-downloads .sphx-glr-download a:hover {
+ background-color: color-mix(in srgb, var(--napari-primary-blue), transparent 25%) !important;
+ text-decoration: underline;
}
-/* ── Homepage accent cards ───────────────────────────────────────────
- Install, Download cards with theme-aware napari blue.
- sphinx-design marks every property !important, so we must too. */
-
-.homepage-button {
- display: block;
+html[data-theme="dark"] .button-primary:hover,
+html[data-theme="dark"] .napari-gallery-downloads .sphx-glr-download a:hover {
+ background-color: color-mix(in srgb, var(--napari-purple), transparent 25%) !important;
+ text-decoration: underline;
}
-html[data-theme="light"] .homepage-button {
- background-color: var(--napari-primary-blue) !important;
+html[data-theme="light"] .button-alt {
+ background-color: var(--pst-color-background) !important;
border-color: var(--napari-primary-blue) !important;
color: var(--napari-color-text-base) !important;
}
-html[data-theme="dark"] .homepage-button {
- background-color: var(--napari-purple) !important;
+html[data-theme="dark"] .button-alt {
+ background-color: var(--pst-color-background) !important;
border-color: var(--napari-purple) !important;
color: var(--napari-color-text-base) !important;
}
-html[data-theme="light"] .homepage-button:hover {
+html[data-theme="light"] .button-alt:hover {
+ background-color: var(--pst-color-background) !important;
+ border-color: var(--napari-primary-blue) !important;
+ color: var(--napari-color-text-base) !important;
text-decoration: underline;
- background-color: color-mix(in srgb, var(--napari-primary-blue), transparent 25%) !important;
}
-html[data-theme="dark"] .homepage-button:hover {
+html[data-theme="dark"] .button-alt:hover {
+ background-color: var(--pst-color-background) !important;
+ border-color: var(--napari-purple) !important;
+ color: var(--napari-color-text-base) !important;
text-decoration: underline;
- background-color: color-mix(in srgb, var(--napari-purple), transparent 25%) !important;
+}
+
+/* Version warning banner color */
+#bd-header-version-warning {
+ background-color: color-mix(in srgb, var(--pst-color-secondary-bg), transparent 30%);
+}
+
+#bd-header-version-warning .pst-button-link-to-stable-version {
+ background-color: color-mix(in srgb, var(--pst-color-secondary-bg), transparent 0%);
+ border-color: var(--pst-color-secondary-bg);
+ color: var(--napari-color-text-base);
+ font-weight: 700;
+}
+
+#bd-header-version-warning .pst-button-link-to-stable-version:hover {
+ background-color: var(--pst-color-secondary-bg);
+ border-color: var(--pst-color-secondary-bg);
+ color: var(--napari-color-text-base);
+ font-weight: 700;
}
/* ── Homepage quicklinks (icon columns) ──────────────────────────────── */
diff --git a/docs/index.md b/docs/index.md
index b775ffabb..aa3935234 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -64,7 +64,7 @@ theme:
:color: primary
:ref-type: myst
:shadow:
-:class: homepage-button
+:class: button-primary
{material-regular}`arrow_forward;1.2em` **Get started**
```
@@ -133,8 +133,8 @@ A standalone installer for when you want napari without setting up Python first.
Display an image in napari and explore the viewer with a minimal example.
-
Examples gallery
-
+
Examples gallery
+
From fb920a52f73c0d60cee93ca70094ef492363274e Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Wed, 20 May 2026 15:15:37 -0500
Subject: [PATCH 5/6] remove vestigial css
---
docs/_static/custom.css | 5 -----
1 file changed, 5 deletions(-)
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index 87a94abb8..0070f87e3 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -248,8 +248,3 @@ html[data-theme="dark"] .homepage-quicklinks a {
html[data-theme="dark"] img#homepage-featured-example-image {
background-color: var(--pst-color-background) !important;
}
-
-.homepage-example-button:hover {
- background-color: var(--pst-color-background) !important;
- color: var(--napari-color-text-base) !important;
-}
\ No newline at end of file
From ad0639dd1f9854a13b540e2cc1dfc106db4928d7 Mon Sep 17 00:00:00 2001
From: Tim Monko
Date: Tue, 26 May 2026 23:26:24 -0500
Subject: [PATCH 6/6] add buttons just before python script
---
docs/conf.py | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/docs/conf.py b/docs/conf.py
index 43b7cdf72..581ae0907 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -396,15 +396,18 @@ def napari_scraper(block, block_vars, gallery_conf):
return scrapers.figure_rst(img_paths, gallery_conf['src_dir'])
-GALLERY_TITLE_RE = re.compile(r'^.+\n=+\n', re.MULTILINE)
+GALLERY_METADATA_END_RE = re.compile(
+ r'^\.\. GENERATED FROM PYTHON SOURCE LINES \d+-\d+\s*$', re.MULTILINE
+)
def add_gallery_download_buttons(app, docname, source):
- """Add compact top-of-page download links to generated gallery examples.
-
- The title of the example is used to determine where to insert the download links,
- which are only added to generated gallery examples.
- The links are added after the title.
+ """Add compact download links near the top of generated gallery examples.
+
+ Sphinx-Gallery emits the example title first, followed by the short
+ description and tags, and only then the ``GENERATED FROM PYTHON SOURCE``
+ marker. Insert the links just before that first marker so they stay below
+ the description metadata without overriding Sphinx-Gallery templates.
"""
if not docname.startswith('gallery/'):
return
@@ -416,8 +419,8 @@ def add_gallery_download_buttons(app, docname, source):
return
example_name = Path(docname).name
- title_match = GALLERY_TITLE_RE.search(content)
- if title_match is None:
+ metadata_end_match = GALLERY_METADATA_END_RE.search(content)
+ if metadata_end_match is None:
return
download_block = f"""
@@ -434,9 +437,9 @@ def add_gallery_download_buttons(app, docname, source):
:download:`Notebook (.ipynb) <{example_name}.ipynb>`
"""
source[0] = (
- content[: title_match.end()]
+ content[: metadata_end_match.start()]
+ download_block
- + content[title_match.end() :]
+ + content[metadata_end_match.start() :]
)