From b793e0947ba78c36a384e7ecc99e9de2286e27b3 Mon Sep 17 00:00:00 2001 From: Mathieu Scheltienne Date: Mon, 30 Oct 2023 11:10:57 +0100 Subject: [PATCH] fix documentation build and version selection --- doc/_static/js/copybutton.js | 63 --- doc/_static/style.css | 389 +++++++++++++++++- doc/_static/versions.json | 27 ++ doc/_templates/autosummary/class.rst | 8 +- doc/_templates/autosummary/function.rst | 10 +- doc/_templates/docs-navbar.html | 20 - doc/_templates/docs-toc.html | 13 - doc/_templates/layout.html | 19 - doc/_templates/version-switcher.html | 11 - doc/api.rst | 12 +- doc/conf.py | 370 +++++++++-------- doc/index.rst | 8 +- ...abel_automatic_artifact_correction_ica.py} | 0 ...l_components.py => 10_label_components.py} | 0 pyproject.toml | 3 +- 15 files changed, 620 insertions(+), 333 deletions(-) delete mode 100644 doc/_static/js/copybutton.js create mode 100644 doc/_static/versions.json delete mode 100644 doc/_templates/docs-navbar.html delete mode 100644 doc/_templates/docs-toc.html delete mode 100755 doc/_templates/layout.html delete mode 100644 doc/_templates/version-switcher.html rename examples/{iclabel_automatic_artifact_correction_ica.py => 00_iclabel_automatic_artifact_correction_ica.py} (100%) rename examples/{label_components.py => 10_label_components.py} (100%) diff --git a/doc/_static/js/copybutton.js b/doc/_static/js/copybutton.js deleted file mode 100644 index d87f56998..000000000 --- a/doc/_static/js/copybutton.js +++ /dev/null @@ -1,63 +0,0 @@ -$(document).ready(function() { - /* Add a [>>>] button on the top-right corner of code samples to hide - * the >>> and ... prompts and the output and thus make the code - * copyable. */ - var div = $('.highlight-python .highlight,' + - '.highlight-python3 .highlight,' + - '.highlight-pycon .highlight,' + - '.highlight-default .highlight') - var pre = div.find('pre'); - - // get the styles from the current theme - pre.parent().parent().css('position', 'relative'); - var hide_text = 'Hide the prompts and output'; - var show_text = 'Show the prompts and output'; - var border_width = pre.css('border-top-width'); - var border_style = pre.css('border-top-style'); - var border_color = pre.css('border-top-color'); - var button_styles = { - 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0', - 'border-color': border_color, 'border-style': border_style, - 'border-width': border_width, 'color': border_color, 'text-size': '75%', - 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em', - 'border-radius': '0 3px 0 0' - } - - // create and add the button to all the code blocks that contain >>> - div.each(function(index) { - var jthis = $(this); - if (jthis.find('.gp').length > 0) { - var button = $('>>>'); - button.css(button_styles) - button.attr('title', hide_text); - button.data('hidden', 'false'); - jthis.prepend(button); - } - // tracebacks (.gt) contain bare text elements that need to be - // wrapped in a span to work with .nextUntil() (see later) - jthis.find('pre:has(.gt)').contents().filter(function() { - return ((this.nodeType == 3) && (this.data.trim().length > 0)); - }).wrap(''); - }); - - // define the behavior of the button when it's clicked - $('.copybutton').click(function(e){ - e.preventDefault(); - var button = $(this); - if (button.data('hidden') === 'false') { - // hide the code output - button.parent().find('.go, .gp, .gt').hide(); - button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden'); - button.css('text-decoration', 'line-through'); - button.attr('title', show_text); - button.data('hidden', 'true'); - } else { - // show the code output - button.parent().find('.go, .gp, .gt').show(); - button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible'); - button.css('text-decoration', 'none'); - button.attr('title', hide_text); - button.data('hidden', 'false'); - } - }); -}); diff --git a/doc/_static/style.css b/doc/_static/style.css index ef38f57ac..b10216ddc 100644 --- a/doc/_static/style.css +++ b/doc/_static/style.css @@ -1,26 +1,381 @@ -a[class^="sphx-glr-backref-module-mne_hfo"] { - /* make all MNE-BIDS backrefs bold */ - font-weight: 800; +:root { + + --pst-font-size-base: 16px; + --pst-font-size-milli: 13px; + --pst-font-family-base: 'Source Sans Pro', var(--pst-font-family-base-system); + --pst-font-family-heading: var(--pst-font-family-base); + --pst-font-family-monospace: 'Source Code Pro', var(--pst-font-family-monospace-system); + /* colors that aren't responsive to light/dark mode */ + --mne-color-discord: #5865F2; + --mne-color-primary: #007bff; + --mne-color-primary-highlight: #0063cc; + /* font weight */ + --mne-font-weight-semibold: 600; +} + + +html[data-theme="light"] { + /* topbar logo links */ + --mne-color-github: #000; + --mne-color-discourse: #000; + --mne-color-mastodon: #2F0C7A; + /* code block copy button */ + --copybtn-opacity: 0.75; + /* card header bg color */ + --mne-color-card-header: rgba(0, 0, 0, 0.05); + /* section headings */ + --mne-color-heading: #003e80; + /* pydata-sphinx-theme overrides */ + --pst-color-primary: var(--mne-color-primary); + --pst-color-primary-highlight: var(--mne-color-primary-highlight); + --pst-color-info: var(--pst-color-primary); + --pst-color-border: #ccc; + --pst-color-background: #fff; + --pst-color-link: var(--pst-color-primary-highlight); + /* sphinx-gallery overrides */ + --sg-download-a-background-color: var(--pst-color-primary); + --sg-download-a-background-image: unset; + --sg-download-a-border-color: var(--pst-color-border); + --sg-download-a-color: #fff; + --sg-download-a-hover-background-color: var(--pst-color-primary-highlight); + --sg-download-a-hover-box-shadow-1: none; + --sg-download-a-hover-box-shadow-2: none; +} +html[data-theme="dark"] { + /* topbar logo links */ + --mne-color-github: rgb(240, 246, 252); /* from their logo SVG */ + --mne-color-discourse: #FFF9AE; /* from their logo SVG */ + --mne-color-mastodon: #858AFA; /* www.joinmastodon.org/en/branding */ + /* code block copy button */ + --copybtn-opacity: 0.25; + /* card header bg color */ + --mne-color-card-header: rgba(255, 255, 255, 0.2); + /* section headings */ + --mne-color-heading: #b8cbe0; + /* pydata-sphinx-theme overrides */ + --pst-color-primary: var(--mne-color-primary); + --pst-color-primary-highlight: var(--mne-color-primary-highlight); + --pst-color-info: var(--pst-color-primary); + --pst-color-border: #333; + --pst-color-background: #000; + --pst-color-link: #66b0ff; + /* sphinx-gallery overrides */ + --sg-download-a-background-color: var(--pst-color-primary); + --sg-download-a-background-image: unset; + --sg-download-a-border-color: var(--pst-color-border); + --sg-download-a-color: #000; + --sg-download-a-hover-background-color: var(--pst-color-primary-highlight); + --sg-download-a-hover-box-shadow-1: none; + --sg-download-a-hover-box-shadow-2: none; +} +h1, h2, h3, h4, h5, h6 { + color: var(--mne-color-heading); +} + +/* ************************************************************ Sphinx fixes */ + +/* API docs parameter lists */ +dl.field-list { + grid-template-columns: auto 1fr; +} + +/* make HTML'd pandas dataframes scrollable */ +table.dataframe { + display: block; + overflow: auto; } -span.option { - /* avoid breaking lines in our command-line parameters */ - white-space: nowrap; +/* Long API titles need to wrap for mobile */ +div[id^="mne-"] h1, +div[id^="examples-using-"] h2 { + word-break: break-word; } -/* gallery thumbnail size */ -.sphx-glr-thumbcontainer { - min-width: 160px; - height: 250px; +/* *********************************************** pydata-sphinx-theme fixes */ + +/* this is most critical for the homepage logos, but affects all images */ +html[data-theme="dark"] img { + filter: none; +} + +/* prev/next links */ +.prev-next-area a p.prev-next-title { + color: var(--pst-color-link); +} + +/* make versionadded smaller and inline with param name */ +/* don't do for deprecated / versionchanged; they have extra info (too long to fit) */ +div.versionadded > p { + margin-top: 0; + margin-bottom: 0; +} +div.versionadded { + margin: 0; + margin-left: 0.5rem; + display: inline-block; +} +/* when FF supports :has(), change to → dd > p:has(+div.versionadded) */ +dd>p { + display: inline; +} + +/* **************************************************** sphinx-gallery fixes */ + +/* backreference links: restore hover decoration that SG removes */ +a.sphx-glr-backref-instance:hover { + text-decoration: underline; +} +/* backreference links: make non-MNE func/meth calls resemble regular code */ +a[class^="sphx-glr-backref-module"] { + color: rgb(var(--pst-color-text-base)); +} +/* backreference links: make MNE calls bold and colorful */ +a[class^="sphx-glr-backref-module-mne"] { + color: rgb(var(--pst-color-link)); + font-weight: var(--mne-font-weight-semibold); +} +/* suppress redundant note at top of every tutorial and signature at the end */ +div.sphx-glr-download-link-note, +p.sphx-glr-signature { + visibility: hidden; + height: 0; + margin: 0; + padding: 0; +} +/* script/notebook download buttons */ +.sphx-glr-download a.download { + border-radius: 0.5rem; + /* ↓↓↓↓↓↓↓ these two rules copied from sphinx-design */ + box-shadow: 0 .125rem .25rem var(--sd-color-shadow) !important; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; +} +/* Report embedding */ +iframe.sg_report { + width: 95%; + height: 70vh; + margin: 20px auto; + display: block; + border-style: solid; +} +/* Disable thumbnail tooltips on hover */ +.sphx-glr-thumbcontainer[tooltip]:hover::before, +.sphx-glr-thumbcontainer[tooltip]:hover::after { + display: none; +} + +/* Make our external thumbnails (e.g., mne-gui-addons) act like standard SG ones */ +.sphx-glr-thumbcontainer a.external { + bottom: 0; + display: block; + left: 0; + box-sizing: border-box; + padding: 150px 10px 0; + position: absolute; + right: 0; + top: 0; +} + +/* TODO: Either pydata-sphinx-theme (for using Bootstrap) or sphinx-gallery (for adding table formatting) should fix this */ +.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>* { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--pst-color-text-base); +} +.table-hover>tbody>tr:hover>* { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--pst-color-text-base); +} +.rendered_html table { + color: var(--pst-color-text-base); +} + + +/* ***************************************************** sphinx-design fixes */ +p.btn a { + color: unset; +} +/* sphinx-design tabs */ +html .bd-content .sd-tab-set > label:hover, +.bd-content .sd-tab-set > input:not(:checked) + label:hover { + opacity: unset; + color: var(--pst-color-secondary); + border-color: var(--pst-color-secondary); +} + +/* ************************************************************* copy button */ +button.copybtn { + /* always show; https://sphinx-copybutton.readthedocs.io/en/latest/use.html#modify-the-copy-button-s-css */ + opacity: var(--copybtn-opacity); + } + +/* *************************************************** bib reference spacing */ +aside.footnote { + margin-bottom: 0.5rem; +} +aside.footnote:last-child { + margin-bottom: 1rem; +} + +/* ******************************************************** version dropdown */ +.dropdown-toggle { + font-weight: var(--mne-font-weight-semibold); +} + +/* ******************************************************* navbar icon links */ +#navbar-icon-links i.fa-square-github::before { + color: var(--mne-color-github); +} +#navbar-icon-links i.fa-discourse::before { + color: var(--mne-color-discourse); +} +#navbar-icon-links i.fa-discord::before { + color: var(--mne-color-discord); +} +#navbar-icon-links i.fa-mastodon::before { + color: var(--mne-color-mastodon); +} + +/* ************************************************************ nav elements */ +/* topbar nav inactive */ +.bd-header.navbar-light#navbar-main .navbar-nav li a.nav-link { + color: var(--pst-color-text-muted); +} +/* topbar nav active */ +.bd-header.navbar-light#navbar-main .navbar-nav > li.active > .nav-link { + color: var(--pst-color-link); + font-weight: var(--mne-font-weight-semibold); +} +/* topbar nav hover */ +.bd-header.navbar-light#navbar-main .navbar-nav li a.nav-link:focus, +.bd-header.navbar-light#navbar-main .navbar-nav li a.nav-link:hover { + color: var(--pst-color-secondary); +} +/* sidebar nav */ +nav.bd-links .active > a, +nav.bd-links .active:hover > a, +.toc-entry a.nav-link.active, +.toc-entry a.nav-link.active:hover { + color: var(--pst-color-link); +} +/* sidebar nav hover */ +nav.bd-links li > a:hover, +.toc-entry a.nav-link:hover { + color: var(--pst-color-secondary); +} + +/* *********************************************************** homepage logo */ +img.logo { + max-width: 360px; + width: 100%; +} + +/* **************************************************** homepage quick links */ +ul.quicklinks a { + font-weight: var(--mne-font-weight-semibold); + color: var(--pst-color-text-base); +} +ul.quicklinks a:hover { + text-decoration: none; + color: var(--pst-color-secondary); +} +h5.card-header { + margin-top: 0px; + margin-bottom: 0px; + color: var(--pst-color-text-base); +} +h5.card-header::before { + height: 0px; + margin-top: 0px; +} + +/* ******************************************************* homepage carousel */ +div.frontpage-gallery { + overflow: hidden; + height: 180px; + justify-content: center; +} +div.frontpage-gallery a { + text-decoration: none; + color: rgb(var(--pst-color-text-base)); +} +div.frontpage-gallery img.card-img { + transform: scale(1.8); + transform-origin: 40% 20%; + opacity: 0.2; + transition: 400ms ease-out; +} +div.frontpage-gallery:hover img.card-img { + transform: scale(1.2); + opacity: 1.0; + transition: 400ms ease-out; +} +div.frontpage-gallery .fadeout { + opacity: 1.0; + transition: 200ms linear; +} +div.frontpage-gallery:hover .fadeout { + opacity: 0.0; + transition: 200ms linear; +} +/* affects the homepage gallery tiles and the homepage sidebar quicklinks card; + needed for dark mode. */ +div.card { + border: 1px solid var(--pst-color-border); + background-color: rgb(var(--pst-color-background)); +} +.card-header { + border-bottom-color: var(--pst-color-border); + background-color: var(--mne-color-card-header); +} + +/* *************************************** homepage funder/institution logos */ +div#funder-logos div.card, +div#funder-logos div.card img, +div#institution-logos div.card, +div#institution-logos div.card img, +div#contributor-avatars div.card, +div#contributor-avatars div.card img { + background-color: unset; + border: none; + border-radius: unset; +} +div#contributor-avatars div.card img { + width: 3em; +} + +.contributor-avatar { + clip-path: circle(closest-side); +} + +/* ************************************************************ funders page */ +ul.funders li { + margin-left: 36px; + text-indent: -36px; + padding-bottom: 9px; +} +ul.funders li img { + width: 30px; + max-height: 24px; + object-fit: contain; + background-color: unset !important; +} + +/* *********************************************************** contrib guide */ +ul.icon-bullets { + list-style-type: none; + padding-left: 2em; + text-indent: -1.5em; +} +.small-stack { + font-size: 0.5em; } -/* ************************************************* Previous / Next buttons */ -.prev-next-bottom a.left-prev:before { - content:"❮\00A0" +/* *********************************************************** miscellaneous */ +.hidden { + display: none; } -.prev-next-bottom a.right-next:after { - content:"\00A0❯" +img.hidden { + visibility: hidden; } -.prev-next-bottom a.right-next { - text-align: right; +td.justify { + text-align-last: justify; } diff --git a/doc/_static/versions.json b/doc/_static/versions.json new file mode 100644 index 000000000..f31625b00 --- /dev/null +++ b/doc/_static/versions.json @@ -0,0 +1,27 @@ +[ + { + "name": "0.6.0 (dev)", + "version": "dev", + "url": "https://mne.tools/mne-icalabel/dev" + }, + { + "name": "0.5.0 (stable)", + "version": "0.5.0", + "url": "https://mne.tools/mne-icalabel/stable" + }, + { + "name": "0.4", + "version": "0.4", + "url": "https://mne.tools/mne-icalabel/0.4" + }, + { + "name": "0.3.2", + "version": "0.3.2", + "url": "https://mne.tools/mne-icalabel/0.3" + }, + { + "name": "0.2", + "version": "0.2", + "url": "https://mne.tools/mne-icalabel/0.2" + } +] diff --git a/doc/_templates/autosummary/class.rst b/doc/_templates/autosummary/class.rst index 6056ea9c5..3322b321a 100644 --- a/doc/_templates/autosummary/class.rst +++ b/doc/_templates/autosummary/class.rst @@ -1,10 +1,10 @@ -{{ fullname }} -{{ underline }} +{{ fullname | escape | underline }} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} - :special-members: __contains__,__getitem__,__iter__,__len__,__add__,__sub__,__mul__,__div__,__neg__,__hash__ :members: + :inherited-members: -.. include:: {{module}}.{{objname}}.examples +.. minigallery:: {{ fullname }} + :add-heading: diff --git a/doc/_templates/autosummary/function.rst b/doc/_templates/autosummary/function.rst index bdde24208..cdbecc4f6 100644 --- a/doc/_templates/autosummary/function.rst +++ b/doc/_templates/autosummary/function.rst @@ -1,12 +1,8 @@ -{{ fullname }} -{{ underline }} +{{ fullname | escape | underline }} .. currentmodule:: {{ module }} .. autofunction:: {{ objname }} -.. include:: {{module}}.{{objname}}.examples - -.. raw:: html - -
+.. minigallery:: {{ fullname }} + :add-heading: diff --git a/doc/_templates/docs-navbar.html b/doc/_templates/docs-navbar.html deleted file mode 100644 index f32479392..000000000 --- a/doc/_templates/docs-navbar.html +++ /dev/null @@ -1,20 +0,0 @@ -{%- extends "pydata_sphinx_theme/docs-navbar.html" %} - -{%- block icon_links -%} - - - -{%- include "icon-links.html" with context -%} -{%- endblock %} diff --git a/doc/_templates/docs-toc.html b/doc/_templates/docs-toc.html deleted file mode 100644 index 97dc4a69f..000000000 --- a/doc/_templates/docs-toc.html +++ /dev/null @@ -1,13 +0,0 @@ -{% set page_toc = generate_toc_html() %} - -{%- if page_toc | length >= 1 %} -
- On this page -
-{%- endif %} - - - -{% include "edit_this_page.html" %} diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html deleted file mode 100755 index 6b3d45b5b..000000000 --- a/doc/_templates/layout.html +++ /dev/null @@ -1,19 +0,0 @@ -{%- extends "pydata_sphinx_theme/layout.html" %} - -{% block fonts %} - - - - - -{% endblock %} - -{% block extrahead %} - - - -{{ super() }} -{% endblock %} diff --git a/doc/_templates/version-switcher.html b/doc/_templates/version-switcher.html deleted file mode 100644 index add617220..000000000 --- a/doc/_templates/version-switcher.html +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/doc/api.rst b/doc/api.rst index 6fc3f29ae..38d93631e 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -16,7 +16,7 @@ Most-used functions .. currentmodule:: mne_icalabel .. autosummary:: - :toctree: generated/ + :toctree: ./generated/ label_components @@ -39,7 +39,7 @@ are copied to the new image features. Then, the predicted probabilities are aver .. currentmodule:: mne_icalabel.iclabel .. autosummary:: - :toctree: generated/ + :toctree: ./generated/ get_iclabel_features run_iclabel @@ -53,7 +53,7 @@ Contains functions to extract features from `~mne.preprocessing.ICA` instance an .. currentmodule:: mne_icalabel.features .. autosummary:: - :toctree: generated/ + :toctree: ./generated/ get_topomaps @@ -65,7 +65,7 @@ derivative standard of BIDS for EEG data. .. currentmodule:: mne_icalabel.annotation .. autosummary:: - :toctree: generated/ + :toctree: ./generated/ mark_component write_components_tsv @@ -78,6 +78,6 @@ significant bugs still. Please report these in the GH issues tab. .. currentmodule:: mne_icalabel .. autosummary:: - :toctree: generated/ + :toctree: ./generated/ - gui.label_ica_components \ No newline at end of file + gui.label_ica_components diff --git a/doc/conf.py b/doc/conf.py index 601935fc2..95728351d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,31 +1,42 @@ -"""Configure details for documentation with sphinx.""" +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html +import inspect import os import subprocess import sys -import warnings from datetime import date +from importlib import import_module +from typing import Dict, Optional import mne -import sphinx_gallery # noqa: F401 -from mne.fixes import _compare_version -from sphinx_gallery.sorting import ExampleTitleSortKey +from sphinx_gallery.sorting import FileNameSortKey + +import mne_icalabel -sys.path.insert(0, os.path.abspath("..")) -import mne_icalabel # noqa: E402 +# -- project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -curdir = os.path.dirname(__file__) -sys.path.append(os.path.abspath(os.path.join(curdir, ".."))) -sys.path.append(os.path.abspath(os.path.join(curdir, "..", "mne_icalabel"))) +project = "MNE-ICALabel" +author = "Adam Li, Mathieu Scheltienne" +copyright = ( + f"2021-{date.today().year}, MNE Developers. " f"Last updated on {date.today().isoformat()}" +) +release = mne_icalabel.__version__ +package = mne_icalabel.__name__ +gh_url = "https://github.com/mne-tools/mne-icalabel" -# -- General configuration ------------------------------------------------ +# -- general configuration ------------------------------------------------ +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration # If your documentation needs a minimal Sphinx version, state it here. -# -needs_sphinx = "4.0" +needs_sphinx = "5.0" + +# The document name of the “root” document, that is, the document that contains +# the root toctree directive. +root_doc = "index" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -33,140 +44,79 @@ extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosummary", - "sphinx.ext.doctest", "sphinx.ext.intersphinx", + "sphinx.ext.linkcode", "sphinx.ext.mathjax", - "sphinx.ext.viewcode", "numpydoc", "sphinxcontrib.bibtex", "sphinx_copybutton", + "sphinx_design", "sphinx_gallery.gen_gallery", "sphinx_issues", ] -# configure sphinx-copybutton -copybutton_prompt_text = r">>> |\.\.\. |\$ " -copybutton_prompt_is_regexp = True - -# generate autosummary even if no references -# -- sphinx.ext.autosummary -autosummary_generate = True - -autodoc_default_options = {"inherited-members": None} -autodoc_typehints = "none" - -# prevent jupyter notebooks from being run even if empty cell -# nbsphinx_execute = 'never' -# nbsphinx_allow_errors = True - -error_ignores = { # These we do not live by: - "GL01", # docstring should start in the line immediately after the quotes - "EX01", # section 'Examples' not found - "ES01", # no extended summary found - "SA01", # section 'See Also' not found - "RT02", # The first line of the Returns section should contain only the type, unless multiple values are being returned # noqa -} +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] -# -- numpydoc -# Below is needed to prevent errors -numpydoc_xref_param_type = True -numpydoc_class_members_toctree = False -numpydoc_attributes_as_param_list = True -numpydoc_use_blockquotes = True -numpydoc_xref_ignore = { - "of", - "shape", - "n_components", - "n_pixels", - "n_classes", - "instance", - "ICAComponentLabeler", -} -numpydoc_xref_aliases = { - # Python - "Path": "pathlib.Path", - # MNE - "Epochs": "mne.Epochs", - "ICA": "mne.preprocessing.ICA", - "Info": "mne.Info", - "Raw": "mne.io.Raw", -} -numpydoc_validate = True -numpydoc_validation_checks = {"all"} | set(error_ignores) -numpydoc_validation_exclude = { # set of regex - # we currently don't document these properly (probably okay) - r"\.__getitem__", - r"\.__contains__", - r"\.__hash__", - r"\.__mul__", - r"\.__sub__", - r"\.__add__", - r"\.__iter__", - r"\.__div__", - r"\.__neg__", -} +# Sphinx will warn about all references where the target cannot be found. +nitpicky = True +nitpick_ignore = [] +# A list of ignored prefixes for module index sorting. +modindex_common_prefix = [f"{package}."] +# The name of a reST role (builtin or Sphinx extension) to use as the default +# role, that is, for text marked up `like this`. This can be set to 'py:obj' to +# make `filter` a cross-reference to the Python function “filter”. default_role = "py:obj" -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = ".rst" - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = "MNE-ICALabel" -td = date.today() -copyright = "2021-%s, MNE Developers. Last updated on %s" % (td.year, td.isoformat()) - -author = "Adam Li" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = mne_icalabel.__version__ -# The full version, including alpha/beta/rc tags. -release = version - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] +# -- options for HTML output ------------------------------------------------- +html_theme = "pydata_sphinx_theme" +html_title = project # HTML options (e.g., theme) # see: https://sphinx-bootstrap-theme.readthedocs.io/en/latest/README.html # Clean up sidebar: Do not show "Source" link html_show_sourcelink = False html_copy_source = False - -html_theme = "pydata_sphinx_theme" +html_show_sphinx = False # Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] html_static_path = ["_static"] html_css_files = ["style.css"] # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. +switcher_version_match = "dev" if release.endswith("dev0") else release html_theme_options = { + "check_switcher": True, + "external_links": [{"name": "MNE", "url": "https://mne.tools/stable/index.html"}], "icon_links": [ dict( name="GitHub", - url="https://github.com/mne-tools/MNE-ICALabel", + url=gh_url, icon="fab fa-github-square", ), + dict( + name="Forum", + url="https://mne.discourse.group/", + icon="fa-brands fa-discourse", + ), + dict( + name="Discord", + url="https://discord.gg/rKfvxTuATa", + icon="fa-brands fa-discord", + ), ], - "use_edit_page_button": False, + "navbar_end": ["theme-switcher", "version-switcher", "navbar-icon-links"], "navigation_with_keys": False, "show_toc_level": 1, - "navbar_end": ["version-switcher", "navbar-icon-links"], + "use_edit_page_button": False, + "switcher": { + "json_url": "https://mne.tools/mne-icalabel/dev/_static/versions.json", + "version_match": switcher_version_match, + }, } # Custom sidebar templates, maps document names to template names. html_sidebars = { @@ -174,52 +124,98 @@ } html_context = { - "versions_dropdown": { - "dev": "v0.4 (devel)", - "stable": "v0.3", - "v0.2": "v0.2", - "v0.1": "v0.1", - }, + "pygment_light_style": "tango", + "pygment_dark_style": "native", } -# html_sidebars = {'**': ['localtoc.html']} +# -- autosummary ------------------------------------------------------------- +autosummary_generate = True -# Example configuration for intersphinx: refer to the Python standard library. +# -- autosectionlabels ------------------------------------------------------- +autosectionlabel_prefix_document = True + +# -- autodoc ----------------------------------------------------------------- +autoclass_content = "class" +autodoc_typehints = "none" +autodoc_member_order = "groupwise" +autodoc_warningiserror = True + +# -- numpydoc ---------------------------------------------------------------- + +# needed to prevent errors +numpydoc_class_members_toctree = False +numpydoc_attributes_as_param_list = True + +# x-ref +numpydoc_xref_param_type = True +numpydoc_xref_aliases = { + # Python + "Path": "pathlib.Path", + "bool": ":class:`python:bool`", + # MNE + "Epochs": "mne.Epochs", + "ICA": "mne.preprocessing.ICA", + "Info": "mne.Info", + "Raw": "mne.io.Raw", +} +numpydoc_xref_ignore = { + "of", + "shape", + "n_components", + "n_pixels", + "n_classes", + "instance", + "ICAComponentLabeler", +} + +# validation +# https://numpydoc.readthedocs.io/en/latest/validation.html#validation-checks +error_ignores = { + "GL01", # docstring should start in the line immediately after the quotes + "EX01", # section 'Examples' not found + "ES01", # no extended summary found + "SA01", # section 'See Also' not found + "RT02", # The first line of the Returns section should contain only the type, unless multiple values are being returned # noqa +} + +numpydoc_validate = True +numpydoc_validation_checks = {"all"} | set(error_ignores) +numpydoc_validation_exclude = { # set of regex + # we currently don't document these properly (probably okay) + r"\.__getitem__", + r"\.__contains__", + r"\.__hash__", + r"\.__mul__", + r"\.__sub__", + r"\.__add__", + r"\.__iter__", + r"\.__div__", + r"\.__neg__", +} + +# -- sphinx-copybutton ------------------------------------------------------- +copybutton_prompt_text = r">>> |\.\.\. |\$ " +copybutton_prompt_is_regexp = True + +# -- intersphinx ------------------------------------------------------------- intersphinx_mapping = { "joblib": ("https://joblib.readthedocs.io/en/latest", None), "matplotlib": ("https://matplotlib.org/stable", None), "mne": ("https://mne.tools/dev", None), - "numpy": ("https://numpy.org/devdocs", None), + "numpy": ("https://numpy.org/doc/stable", None), "pandas": ("https://pandas.pydata.org/pandas-docs/dev", None), "pooch": ("https://www.fatiando.org/pooch/latest/", None), "python": ("https://docs.python.org/3", None), - "scipy": ("https://scipy.github.io/devdocs", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), "sklearn": ("https://scikit-learn.org/stable", None), "torch": ("https://pytorch.org/docs/stable", None), } intersphinx_timeout = 5 -# Resolve binder filepath_prefix. From the docs: -# "A prefix to append to the filepath in the Binder links. You should use this -# if you will store your built documentation in a sub-folder of a repository, -# instead of in the root." -# we will store dev docs in a `dev` subdirectory and all other docs in a -# directory "v" + version_str. E.g., "v0.3" -if "dev" in version: - filepath_prefix = "dev" -else: - filepath_prefix = "v{}".format(version) - -os.environ["_MNE_BUILDING_DOC"] = "true" +# -- sphinx-gallery ---------------------------------------------------------- scrapers = ("matplotlib",) -try: - import mne_qt_browser - - _min_ver = _compare_version(mne_qt_browser.__version__, ">=", "0.2") - if mne.viz.get_browser_backend() == "qt" and _min_ver: - scrapers += (mne.viz._scraper._MNEQtBrowserScraper(),) -except ImportError: - pass +if mne.viz.get_browser_backend() == "qt": + scrapers += (mne.viz._scraper._MNEQtBrowserScraper(),) compress_images = ("images", "thumbnails") # let's make things easier on Windows users @@ -231,39 +227,77 @@ compress_images = () sphinx_gallery_conf = { + "abort_on_example_error": False, + "backreferences_dir": "generated/backreferences", + "capture_repr": ("_repr_html_",), + "compress_images": compress_images, "doc_module": ("mne_icalabel",), - "reference_url": { - "mne_icalabel": None, - }, "examples_dirs": ["../examples"], - "gallery_dirs": ["auto_examples"], - "backreferences_dir": "generated", - "plot_gallery": "True", # Avoid annoying Unicode/bool default warning - "thumbnail_size": (160, 112), - "remove_config_comments": True, - "min_reported_time": 1.0, - "abort_on_example_error": False, - # 'reset_modules_order': 'both', + "exclude_implicit_doc": {}, # set + "filename_pattern": r"\d{2}_", + "gallery_dirs": ["generated/examples"], "image_scrapers": scrapers, - "show_memory": not sys.platform.startswith(("win", "darwin")), - "line_numbers": False, # messes with style - "within_subsection_order": ExampleTitleSortKey, - "capture_repr": ("_repr_html_",), "junit": os.path.join("..", "test-results", "sphinx-gallery", "junit.xml"), + "line_numbers": False, "matplotlib_animations": True, - "compress_images": compress_images, - "filename_pattern": "^((?!sgskip).)*$", + "min_reported_time": 1.0, + "plot_gallery": "True", + "reference_url": dict(mne_icalabel=None), + "remove_config_comments": True, + "show_memory": sys.platform == "linux", + "thumbnail_size": (160, 112), + "within_subsection_order": FileNameSortKey, } -# sphinxcontrib-bibtex +# -- sphinxcontrib-bibtex ---------------------------------------------------- bibtex_bibfiles = ["./references.bib"] -bibtex_style = "unsrt" -bibtex_footbibliography_header = "" - - -# Enable nitpicky mode - which ensures that all references in the docs resolve. -nitpicky = True -nitpick_ignore = [] # -- Sphinx-issues ----------------------------------------------------------- issues_github_path = "mne-tools/mne-icalabel" + +# -- sphinx.ext.linkcode ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/linkcode.html + + +def linkcode_resolve(domain: str, info: Dict[str, str]) -> Optional[str]: + """Determine the URL corresponding to a Python object. + + Parameters + ---------- + domain : str + One of 'py', 'c', 'cpp', 'javascript'. + info : dict + With keys "module" and "fullname". + + Returns + ------- + url : str | None + The code URL. If None, no link is added. + """ + if domain != "py": + return None # only document python objects + + # retrieve pyobject and file + try: + module = import_module(info["module"]) + pyobject = module + for elt in info["fullname"].split("."): + pyobject = getattr(pyobject, elt) + fname = inspect.getsourcefile(pyobject).replace("\\", "/") + except Exception: + # Either the object could not be loaded or the file was not found. + # For instance, properties will raise. + return None + + # retrieve start/stop lines + source, start_line = inspect.getsourcelines(pyobject) + lines = "L%d-L%d" % (start_line, start_line + len(source) - 1) + + # create URL + if "dev" in release: + branch = "main" + else: + return None # alternatively, link to a maint/version branch + fname = fname.rsplit("/mne_icalabel/")[1] + url = f"{gh_url}/blob/{branch}/mne_icalabel/{fname}#{lines}" + return url diff --git a/doc/index.rst b/doc/index.rst index 2a33c255a..5fdbaca65 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,5 +1,7 @@ -**mne-icalabel** -=================== +:html_theme.sidebar_secondary.remove: + +**MNE-ICALabel** +================ mne-icalabel is a Python package for labeling independent components that stem from an `Independent Component Analysis (ICA) `_. @@ -26,7 +28,7 @@ Contents whats_new install api - auto_examples/index + generated/examples/index .. toctree:: :hidden: diff --git a/examples/iclabel_automatic_artifact_correction_ica.py b/examples/00_iclabel_automatic_artifact_correction_ica.py similarity index 100% rename from examples/iclabel_automatic_artifact_correction_ica.py rename to examples/00_iclabel_automatic_artifact_correction_ica.py diff --git a/examples/label_components.py b/examples/10_label_components.py similarity index 100% rename from examples/label_components.py rename to examples/10_label_components.py diff --git a/pyproject.toml b/pyproject.toml index 86d297c29..41f0765a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,13 +56,12 @@ doc = [ 'mne-icalabel[ica]', 'memory_profiler', 'numpydoc', - 'pydata-sphinx-theme', + 'pydata-sphinx-theme==0.14.1', 'PyQt5', 'sphinx', 'sphinxcontrib-bibtex', 'sphinx-copybutton', 'sphinx-gallery', - 'sphinx_rtd_theme', 'sphinx-issues', ] gui = [