From 3303d22b0c8bf64e25f11046c380c022f07dfbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20E=2E=20S=C3=B8rensen?= Date: Sat, 11 Mar 2023 11:53:06 +0100 Subject: [PATCH 01/10] Introduce `navigation_startdepth` parameter Allows users to start the sidebar Toc at level 0 Addresses issue #1181 --- docs/conf.py | 1 + src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html | 1 + src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf | 1 + 3 files changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index be25b184c..fda1120b5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -145,6 +145,7 @@ "navbar_align": "left", # [left, content, right] For testing that the navbar items align properly "navbar_center": ["version-switcher", "navbar-nav"], "announcement": "https://raw.githubusercontent.com/pydata/pydata-sphinx-theme/main/docs/_templates/custom-template.html", + "navigation_startdepth": 0, # "show_nav_level": 2, # "navbar_start": ["navbar-logo"], # "navbar_end": ["theme-switcher", "navbar-icon-links"], diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html index ca3b36876..d133439c8 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html @@ -10,6 +10,7 @@ {# Create the sidebar links HTML here to re-use in a few places #} {# If we have no sidebar links, pop the links component from the sidebar list #} {%- set sidebar_nav_html = generate_toctree_html("sidebar", +startdepth=theme_navigation_startdepth|int, show_nav_level=theme_show_nav_level|int, maxdepth=theme_navigation_depth|int, collapse=theme_collapse_navigation|tobool, diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf index 7105d124e..9d05244cf 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf @@ -25,6 +25,7 @@ search_bar_text = Search the docs ... search_bar_position = sidebar navigation_with_keys = True collapse_navigation = False +navigation_startdepth = 1 navigation_depth = 4 show_nav_level = 1 show_toc_level = 1 From f45c66ecbc763201802e5e07d8790b2021c07959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20E=2E=20S=C3=B8rensen?= Date: Sat, 11 Mar 2023 12:15:57 +0100 Subject: [PATCH 02/10] Make copy of `toctree.resolve` from Sphinx Copy function from toctree.py that needs to be modified (as-is for prettier diffs in future commits) --- src/pydata_sphinx_theme/__init__.py | 241 +++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 2 deletions(-) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 3633f20cf..cf77504cb 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -1,6 +1,7 @@ """ Bootstrap-based sphinx theme from the PyData community """ +from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Tuple, cast import os from pathlib import Path from functools import lru_cache @@ -11,14 +12,17 @@ import jinja2 from bs4 import BeautifulSoup as bs from docutils import nodes +from docutils.nodes import Element from sphinx import addnodes +from sphinx.locale import __ from sphinx.application import Sphinx from sphinx.environment.adapters.toctree import TocTree from sphinx.addnodes import toctree as toctree_node from sphinx.transforms.post_transforms import SphinxPostTransform -from sphinx.util.nodes import NodeMatcher +from sphinx.util.nodes import NodeMatcher, clean_astext, process_only_nodes +from sphinx.util.matching import Matcher from sphinx.errors import ExtensionError -from sphinx.util import logging, isurl +from sphinx.util import logging, isurl, url_re from sphinx.util.fileutil import copy_asset_file from pygments.formatters import HtmlFormatter from pygments.styles import get_all_styles @@ -27,6 +31,9 @@ from .translator import BootstrapHTML5TranslatorMixin +if TYPE_CHECKING: + from sphinx.builders import Builder + __version__ = "0.13.2dev0" logger = logging.getLogger(__name__) @@ -797,7 +804,237 @@ def extract_level_recursive(ul, navs_list): return navs +def resolve(self, docname: str, builder: "Builder", toctree: addnodes.toctree, + prune: bool = True, maxdepth: int = 0, titles_only: bool = False, + collapse: bool = False, includehidden: bool = False) -> Optional[Element]: + """Resolve a *toctree* node into individual bullet lists with titles + as items, returning None (if no containing titles are found) or + a new node. + + If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0, + to the value of the *maxdepth* option on the *toctree* node. + If *titles_only* is True, only toplevel document titles will be in the + resulting tree. + If *collapse* is True, all branches not containing docname will + be collapsed. + """ + if toctree.get('hidden', False) and not includehidden: + return None + generated_docnames: Dict[str, Tuple[str, str, str]] = self.env.domains['std'].initial_data['labels'].copy() # NoQA: E501 + + # For reading the following two helper function, it is useful to keep + # in mind the node structure of a toctree (using HTML-like node names + # for brevity): + # + # + # + # The transformation is made in two passes in order to avoid + # interactions between marking and pruning the tree (see bug #1046). + + toctree_ancestors = self.get_toctree_ancestors(docname) + included = Matcher(self.env.config.include_patterns) + excluded = Matcher(self.env.config.exclude_patterns) + + def _toctree_add_classes(node: Element, depth: int) -> None: + """Add 'toctree-l%d' and 'current' classes to the toctree.""" + for subnode in node.children: + if isinstance(subnode, (addnodes.compact_paragraph, + nodes.list_item)): + # for

and

  • , indicate the depth level and recurse + subnode['classes'].append('toctree-l%d' % (depth - 1)) + _toctree_add_classes(subnode, depth) + elif isinstance(subnode, nodes.bullet_list): + # for