From 75909b3f301b73948346352d8cac1521243b5b76 Mon Sep 17 00:00:00 2001 From: Rambaud Pierrick <12rambau@users.noreply.github.com> Date: Tue, 1 Aug 2023 07:11:49 +0200 Subject: [PATCH] docs: change rational of the gallery grid (#1390) * docs: change name of the gallery grid * docs: create a gallery list directive * docs: split the list in 2 categories, images and no images * refactor: simplify the witting of GalleryList * refactor: clean gallery grid * docs: edit documentation of the projectst * refactor: clean * test: remove unraised warnings * fix: generate galleries with the corect keywords * comments/docstrings * fix option name * alphabetize featured projects & remove pyvista * bigger card size for featured; smaller for others * wording * alphabetize "other projects" list (and add pyvista there) * test: pyvista has been moved to other --------- Co-authored-by: Daniel McCloy --- docs/_extension/gallery_directive.py | 107 ++++++++---------- docs/_static/contributors.yaml | 18 +-- docs/_static/gallery.yaml | 75 +++++------- docs/examples/gallery.md | 34 +++++- .../scripts/generate_collaborators_gallery.py | 2 +- docs/scripts/generate_gallery_images.py | 4 +- tests/warning_list.txt | 6 - 7 files changed, 115 insertions(+), 131 deletions(-) diff --git a/docs/_extension/gallery_directive.py b/docs/_extension/gallery_directive.py index e80d2c8e7..b5c1223d4 100644 --- a/docs/_extension/gallery_directive.py +++ b/docs/_extension/gallery_directive.py @@ -22,8 +22,8 @@ TEMPLATE_GRID = """ -`````{{grid}} {grid_columns} -{container_options} +`````{{grid}} {columns} +{options} {content} @@ -32,15 +32,26 @@ GRID_CARD = """ ````{{grid-item-card}} {title} -{card_options} +{options} {content} ```` """ -class GalleryDirective(SphinxDirective): - """A directive to show a gallery of images and links in a grid.""" +class GalleryGridDirective(SphinxDirective): + """A directive to show a gallery of images and links in a Bootstrap grid. + + The grid can be generated from a YAML file that contains a list of items, or + from the content of the directive (also formatted in YAML). Use the parameter + "class-card" to add an additional CSS class to all cards. When specifying the grid + items, you can use all parameters from "grid-item-card" directive to customize + individual cards + ["image", "header", "content", "title"]. + + Danger: + This directive can only be used in the context of a Myst documentation page as + the templates use Markdown flavored formatting. + """ name = "gallery-grid" has_content = True @@ -55,6 +66,7 @@ class GalleryDirective(SphinxDirective): } def run(self) -> List[nodes.Node]: + """Create the gallery grid.""" if self.arguments: # If an argument is given, assume it's a path to a YAML file # Parse it and load it into the directive content @@ -70,79 +82,49 @@ def run(self) -> List[nodes.Node]: else: yaml_string = "\n".join(self.content) - # Read in YAML so we can generate the gallery - grid_data = safe_load(yaml_string) - + # Use all the element with an img-bottom key as sites to show + # and generate a card item for each of them grid_items = [] - for item in grid_data: - # Grid card parameters - options = {} - if "website" in item: - options["link"] = item["website"] - - if "class-card" in self.options: - options["class-card"] = self.options["class-card"] - - if "img-background" in item: - options["img-background"] = item["img-background"] - - if "img-top" in item: - options["img-top"] = item["img-top"] - - if "img-bottom" in item: - options["img-bottom"] = item["img-bottom"] + for item in safe_load(yaml_string): - options_str = "\n".join(f":{k}: {v}" for k, v in options.items()) + "\n\n" + # remove parameters that are not needed for the card options + title = item.pop("title", "") - # Grid card content - content_str = "" - if "header" in item: - content_str += f"{item['header']}\n\n^^^\n\n" + # build the content of the card using some extra parameters + header = f"{item.pop('header')} \n^^^ \n" if "header" in item else "" + image = f"![image]({item.pop('image')}) \n" if "image" in item else "" + content = f"{item.pop('content')} \n" if "content" in item else "" - if "image" in item: - content_str += f"![Gallery image]({item['image']})\n\n" - - if "content" in item: - content_str += f"{item['content']}\n\n" + # optional parameter that influence all cards + if "class-card" in self.options: + item["class-card"] = self.options["class-card"] - if "footer" in item: - content_str += f"+++\n\n{item['footer']}\n\n" + loc_options_str = "\n".join(f":{k}: {v}" for k, v in item.items()) + " \n" - title = item.get("title", "") - content_str += "\n" - grid_items.append( - GRID_CARD.format( - card_options=options_str, content=content_str, title=title - ) + card = GRID_CARD.format( + options=loc_options_str, content=header + image + content, title=title ) + grid_items.append(card) - # Parse the template with Sphinx Design to create an output - container = nodes.container() + # Parse the template with Sphinx Design to create an output container # Prep the options for the template grid - container_options = {"gutter": 2, "class-container": "gallery-directive"} - if "class-container" in self.options: - container_options[ - "class-container" - ] += f' {self.options["class-container"]}' - container_options_str = "\n".join( - f":{k}: {v}" for k, v in container_options.items() - ) + class_ = "gallery-directive" + f' {self.options.get("class-container", "")}' + options = {"gutter": 2, "class-container": class_} + options_str = "\n".join(f":{k}: {v}" for k, v in options.items()) # Create the directive string for the grid grid_directive = TEMPLATE_GRID.format( - grid_columns=self.options.get("grid-columns", "1 2 3 4"), - container_options=container_options_str, + columns=self.options.get("grid-columns", "1 2 3 4"), + options=options_str, content="\n".join(grid_items), ) + # Parse content as a directive so Sphinx Design processes it + container = nodes.container() self.state.nested_parse([grid_directive], 0, container) - # Sphinx Design outputs a container too, so just use that - container = container.children[0] - # Add extra classes - if self.options.get("container-class", []): - container.attributes["classes"] += self.options.get("class", []) - return [container] + # Sphinx Design outputs a container too, so just use that + return [container.children[0]] def setup(app: Sphinx) -> Dict[str, Any]: @@ -150,10 +132,11 @@ def setup(app: Sphinx) -> Dict[str, Any]: Args: app: the Sphinx application + Returns: the 2 parallel parameters set to ``True``. """ - app.add_directive("gallery-grid", GalleryDirective) + app.add_directive("gallery-grid", GalleryGridDirective) return { "parallel_read_safe": True, diff --git a/docs/_static/contributors.yaml b/docs/_static/contributors.yaml index 115e3b959..c3d2eef3a 100644 --- a/docs/_static/contributors.yaml +++ b/docs/_static/contributors.yaml @@ -1,27 +1,27 @@ - header: "@bollwyvl" image: https://avatars.githubusercontent.com/u/45380 - website: https://github.com/bollwyvl + link: https://github.com/bollwyvl - header: "@jarrodmillman" image: https://avatars.githubusercontent.com/u/123428 - website: https://github.com/jarrodmillman + link: https://github.com/jarrodmillman - header: "@hoetmaaiers" image: https://avatars.githubusercontent.com/u/468045 - website: https://github.com/hoetmaaiers + link: https://github.com/hoetmaaiers - header: "@jorisvandenbossche" image: https://avatars.githubusercontent.com/u/1020496 - website: https://github.com/jorisvandenbossche + link: https://github.com/jorisvandenbossche - header: "@damianavila" image: https://avatars.githubusercontent.com/u/1640669 - website: https://github.com/damianavila + link: https://github.com/damianavila - header: "@drammock" image: https://avatars.githubusercontent.com/u/1810515 - website: https://github.com/drammock + link: https://github.com/drammock - header: "@choldgraf" image: https://avatars.githubusercontent.com/u/1839645 - website: https://github.com/choldgraf + link: https://github.com/choldgraf - header: "@12rambau" image: https://avatars.githubusercontent.com/u/12596392 - website: https://github.com/12rambau + link: https://github.com/12rambau - header: "@trallard" image: https://avatars.githubusercontent.com/u/23552331 - website: https://github.com/trallard + link: https://github.com/trallard diff --git a/docs/_static/gallery.yaml b/docs/_static/gallery.yaml index 11a349af7..f821315d2 100644 --- a/docs/_static/gallery.yaml +++ b/docs/_static/gallery.yaml @@ -3,59 +3,38 @@ # 1. Used by `generate_gallery_images.py` to take snapshots of each item and place an image in `gallery`. # 2. Used by our Gallery Grid directive to create the grid on our `examples/gallery.md` page. # -# title: The title of each gallery item -# website: The website that will be used to create a snapshot of this item. -# An image will be placed in docs/_static/gallery/{sanitized_title}.png -# img-bottom: The location where img-bottoms will be placed for each entry by generate_gallery_img-bottoms.py -# This should follow the form shown above and is roughly the same for all items. -- title: Pandas - website: https://pandas.pydata.org/docs/ - img-bottom: ../_static/gallery/pandas.png -- title: NumPy - website: https://numpy.org/doc/stable/ - img-bottom: ../_static/gallery/numpy.png -- title: SciPy - website: https://docs.scipy.org/doc/scipy/ - img-bottom: ../_static/gallery/scipy.png +# This file should only be modified by maintainer, contributors should add their project +# to the list of `gallery.md`. +- title: ArviZ + link: https://python.arviz.org/ + img-bottom: ../_static/gallery/arviz.png - title: Bokeh - website: https://docs.bokeh.org/en/latest/ + link: https://docs.bokeh.org/en/latest/ img-bottom: ../_static/gallery/bokeh.png -- title: CuPy - website: https://docs.cupy.dev/en/stable/index.html - img-bottom: ../_static/gallery/cupy.png -- title: PyVista - website: https://docs.pyvista.org - img-bottom: ../_static/gallery/pyvista.png +- title: Jupyter + link: https://docs.jupyter.org/en/latest/ + img-bottom: ../_static/gallery/jupyter.png +- title: Jupyter Book + link: https://jupyterbook.org/en/stable/intro.html + img-bottom: ../_static/gallery/jupyter_book.png +- title: Matplotlib + link: https://matplotlib.org/stable/ + img-bottom: ../_static/gallery/matplotlib.png - title: MNE-Python - website: https://mne.tools/stable/index.html + link: https://mne.tools/stable/index.html img-bottom: ../_static/gallery/mne-python.png - title: NetworkX - website: https://networkx.org/documentation/stable/ + link: https://networkx.org/documentation/stable/ img-bottom: ../_static/gallery/networkx.png -- title: Fairlearn - website: https://fairlearn.org/main/about/ - img-bottom: ../_static/gallery/fairlearn.png -- title: Jupyter Book - website: https://jupyterbook.org/en/stable/intro.html - img-bottom: ../_static/gallery/jupyter_book.png -- title: Binder - website: https://mybinder.readthedocs.io/en/latest/index.html - img-bottom: ../_static/gallery/binder.png -- title: Jupyter - website: https://docs.jupyter.org/en/latest/ - img-bottom: ../_static/gallery/jupyter.png -- title: MegEngine - website: https://www.megengine.org.cn/doc/stable/en/index.html - img-bottom: ../_static/gallery/megengine.png -- title: Feature-engine - website: https://feature-engine.readthedocs.io/ - img-bottom: ../_static/gallery/feature-engine.png -- title: ArviZ - website: https://python.arviz.org/ - img-bottom: ../_static/gallery/arviz.png +- title: NumPy + link: https://numpy.org/doc/stable/ + img-bottom: ../_static/gallery/numpy.png +- title: Pandas + link: https://pandas.pydata.org/docs/ + img-bottom: ../_static/gallery/pandas.png +- title: SciPy + link: https://docs.scipy.org/doc/scipy/ + img-bottom: ../_static/gallery/scipy.png - title: SEPAL - website: https://docs.sepal.io/en/latest/index.html + link: https://docs.sepal.io/en/latest/index.html img-bottom: ../_static/gallery/sepal.png -- title: Matplotlib - website: https://matplotlib.org/stable/ - img-bottom: ../_static/gallery/matplotlib.png diff --git a/docs/examples/gallery.md b/docs/examples/gallery.md index 447c10e7a..a79133863 100644 --- a/docs/examples/gallery.md +++ b/docs/examples/gallery.md @@ -1,9 +1,37 @@ # Gallery of sites using this theme -This is a gallery of documentation built on top of the `pydata-sphinx-theme`. -If you'd like to add your documentation to this list, simply add an entry to [this gallery.yaml file](https://github.com/pydata/pydata-sphinx-theme/blob/main/docs/_static/gallery.yaml) and open a Pull Request to add it. +This is a gallery of documentation sites built with `pydata-sphinx-theme`. If you'd like +to add your documentation to this list, add an entry (in alphabetical order) to the list +at the end of [this page](https://github.com/pydata/pydata-sphinx-theme/blob/main/docs/examples/gallery.md) +and open a Pull Request to add it. + +## Featured projects + +These projects are our earliest adopters and/or present some interesting customization. +Check their repositories for more information. ```{gallery-grid} ../_static/gallery.yaml -:grid-columns: "1 2 2 3" +:grid-columns: "1 1 2 2" +``` + +## Other projects using this theme + +Here are some other projects using `pydata-sphinx-theme` for their documentation. +Thanks for your support! + +```{gallery-grid} +:grid-columns: "1 2 3 4" +- title: Binder + link: https://mybinder.readthedocs.io/en/latest/index.html +- title: CuPy + link: https://docs.cupy.dev/en/stable/index.html +- title: Fairlearn + link: https://fairlearn.org/main/about/ +- title: Feature-engine + link: https://feature-engine.readthedocs.io/ +- title: MegEngine + link: https://www.megengine.org.cn/doc/stable/en/index.html +- title: PyVista + link: https://docs.pyvista.org ``` diff --git a/docs/scripts/generate_collaborators_gallery.py b/docs/scripts/generate_collaborators_gallery.py index 064098efd..110abfb0f 100644 --- a/docs/scripts/generate_collaborators_gallery.py +++ b/docs/scripts/generate_collaborators_gallery.py @@ -21,7 +21,7 @@ { "header": f"@{collaborator['login']}", "image": f"https://avatars.githubusercontent.com/u/{collaborator['id']}", - "website": collaborator["html_url"], + "link": collaborator["html_url"], } ) diff --git a/docs/scripts/generate_gallery_images.py b/docs/scripts/generate_gallery_images.py index d2de76188..b30173313 100644 --- a/docs/scripts/generate_gallery_images.py +++ b/docs/scripts/generate_gallery_images.py @@ -44,11 +44,11 @@ def regenerate_gallery() -> None: # Visit the page and take a screenshot for ii in range(3): try: - page.goto(item["website"]) + page.goto(item["link"]) page.screenshot(path=screenshot) break except TimeoutError: - print(f"Page visit start timed out for: {item['website']}") + print(f"Page visit start timed out for: {item['link']}") print(f"Trying again (attempt {ii+2}/3)") # copy the 404 only if the screenshot file was not manually diff --git a/tests/warning_list.txt b/tests/warning_list.txt index ef61a29d5..b1d89e3f8 100644 --- a/tests/warning_list.txt +++ b/tests/warning_list.txt @@ -2,16 +2,10 @@ WARNING: image file not readable: _static/gallery/pandas.png WARNING: image file not readable: _static/gallery/numpy.png WARNING: image file not readable: _static/gallery/scipy.png WARNING: image file not readable: _static/gallery/bokeh.png -WARNING: image file not readable: _static/gallery/cupy.png -WARNING: image file not readable: _static/gallery/pyvista.png WARNING: image file not readable: _static/gallery/mne-python.png WARNING: image file not readable: _static/gallery/networkx.png -WARNING: image file not readable: _static/gallery/fairlearn.png WARNING: image file not readable: _static/gallery/jupyter_book.png -WARNING: image file not readable: _static/gallery/binder.png WARNING: image file not readable: _static/gallery/jupyter.png -WARNING: image file not readable: _static/gallery/megengine.png -WARNING: image file not readable: _static/gallery/feature-engine.png WARNING: image file not readable: _static/gallery/arviz.png WARNING: image file not readable: _static/gallery/sepal.png WARNING: image file not readable: _static/gallery/matplotlib.png