From 47985bbf82bc1c2485312d2cf91f5abb2a87a052 Mon Sep 17 00:00:00 2001 From: AakashGC Date: Tue, 22 Feb 2022 11:00:06 +1100 Subject: [PATCH 01/28] restructuring html for parts --- src/pydata_sphinx_theme/__init__.py | 74 ++++++++++++++++--- .../theme/pydata_sphinx_theme/theme.conf | 1 + 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index e1b767053..5e0190955 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -106,12 +106,28 @@ def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs): soup = bs(toc_sphinx, "html.parser") + # restructing html to handle part collapsing + partcaptions = soup.find_all("p", attrs={"class": "caption"}) + if len(partcaptions): + new_soup = soup.new_tag("div") + for caption in partcaptions: + for sibling in caption.next_siblings: + if sibling.name == 'ul': + toclist = sibling + break + div = soup.new_tag("div", attrs={"class": "toctree-l0"}) + div.append(caption) + div.append(toclist) + new_soup.append(div) + else: + new_soup = soup + # pair "current" with "active" since that's what we use w/ bootstrap - for li in soup("li", {"class": "current"}): + for li in new_soup("li", {"class": "current"}): li["class"].append("active") # Remove navbar/sidebar links to sub-headers on the page - for li in soup.select("li"): + for li in new_soup.select("li"): # Remove if li.find("a"): href = li.find("a")["href"] @@ -120,30 +136,35 @@ def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs): if kind == "navbar": # Add CSS for bootstrap - for li in soup("li"): + for li in new_soup("li"): li["class"].append("nav-item") li.find("a")["class"].append("nav-link") # only select li items (not eg captions) - out = "\n".join([ii.prettify() for ii in soup.find_all("li")]) + out = "\n".join([ii.prettify() for ii in new_soup.find_all("li")]) elif kind == "sidebar": # Add bootstrap classes for first `ul` items - for ul in soup("ul", recursive=False): + for ul in new_soup("ul", recursive=False): ul.attrs["class"] = ul.attrs.get("class", []) + ["nav", "bd-sidenav"] # Add icons and labels for collapsible nested sections - _add_collapse_checkboxes(soup) + _add_collapse_checkboxes(new_soup, context['theme_collapse_parts']) # Open the navbar to the proper depth + # if not int(show_nav_level): + # for tocl in new_soup.select(".toctree-l0"): + # checkbox = tocl.previous_sibling + # checkbox.attrs["checked"] = None + # else: for ii in range(int(show_nav_level)): - for checkbox in soup.select( + for checkbox in new_soup.select( f"li.toctree-l{ii} > input.toctree-checkbox" ): checkbox.attrs["checked"] = None - out = soup.prettify() + out = new_soup.prettify() elif kind == "raw": - out = soup + out = new_soup return out @@ -255,11 +276,44 @@ def generate_google_analytics_script(id): context["generate_google_analytics_script"] = generate_google_analytics_script -def _add_collapse_checkboxes(soup): +def _add_collapse_checkboxes(soup, collapse_parts): # based on https://github.com/pradyunsg/furo toctree_checkbox_count = 0 + if collapse_parts: + for elem in soup.find_all('p'): + classes = elem.get("class", []) + + if not "caption" in classes: + return + + # Add toctree class + elem["class"] = classes + ["toctree-l0"] + toctree_checkbox_count += 1 + checkbox_name = f"toctree-checkbox-{toctree_checkbox_count}" + + if soup.new_tag is None: + continue + label = soup.new_tag("label", attrs={"for": checkbox_name}) + label.append(soup.new_tag("i", attrs={"class": "fas fa-chevron-down"})) + elem.insert(1, label) + + # Add the checkbox that's used to store expanded/collapsed state. + checkbox = soup.new_tag( + "input", + attrs={ + "type": "checkbox", + "class": ["toctree-checkbox"], + "id": checkbox_name, + "name": checkbox_name, + }, + ) + + if "current" in classes: + checkbox.attrs["checked"] = "" + elem.insert_before(checkbox) + for element in soup.find_all("li", recursive=True): # We check all "li" elements, to add a "current-page" to the correct li. classes = element.get("class", []) 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 140692947..d1801afa7 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf @@ -34,3 +34,4 @@ left_sidebar_end = sidebar-ethical-ads.html footer_items = copyright.html, sphinx-version.html page_sidebar_items = page-toc.html, edit-this-page.html switcher = +collapse_parts = True \ No newline at end of file From cbcc5c337603c958856ad4d7ebb54dda39337123 Mon Sep 17 00:00:00 2001 From: AakashGC Date: Tue, 22 Feb 2022 14:06:09 +1100 Subject: [PATCH 02/28] added styling and restructured bs html --- src/pydata_sphinx_theme/__init__.py | 103 +++++++++--------- .../assets/styles/index.scss | 72 ++++++------ 2 files changed, 87 insertions(+), 88 deletions(-) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 5e0190955..fb90e13d6 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -106,28 +106,12 @@ def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs): soup = bs(toc_sphinx, "html.parser") - # restructing html to handle part collapsing - partcaptions = soup.find_all("p", attrs={"class": "caption"}) - if len(partcaptions): - new_soup = soup.new_tag("div") - for caption in partcaptions: - for sibling in caption.next_siblings: - if sibling.name == 'ul': - toclist = sibling - break - div = soup.new_tag("div", attrs={"class": "toctree-l0"}) - div.append(caption) - div.append(toclist) - new_soup.append(div) - else: - new_soup = soup - # pair "current" with "active" since that's what we use w/ bootstrap - for li in new_soup("li", {"class": "current"}): + for li in soup("li", {"class": "current"}): li["class"].append("active") # Remove navbar/sidebar links to sub-headers on the page - for li in new_soup.select("li"): + for li in soup.select("li"): # Remove if li.find("a"): href = li.find("a")["href"] @@ -136,17 +120,33 @@ def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs): if kind == "navbar": # Add CSS for bootstrap - for li in new_soup("li"): + for li in soup("li"): li["class"].append("nav-item") li.find("a")["class"].append("nav-link") # only select li items (not eg captions) - out = "\n".join([ii.prettify() for ii in new_soup.find_all("li")]) + out = "\n".join([ii.prettify() for ii in soup.find_all("li")]) elif kind == "sidebar": # Add bootstrap classes for first `ul` items - for ul in new_soup("ul", recursive=False): + for ul in soup("ul", recursive=False): ul.attrs["class"] = ul.attrs.get("class", []) + ["nav", "bd-sidenav"] + # restructing html to handle part collapsing + partcaptions = soup.find_all("p", attrs={"class": "caption"}) + if len(partcaptions): + new_soup = bs("", "html.parser") + for caption in partcaptions: + for sibling in caption.next_siblings: + if sibling.name == 'ul': + toclist = sibling + break + li = soup.new_tag("li", attrs={"class": "toctree-l0"}) + li.append(caption) + li.append(toclist) + new_soup.ul.append(li) + else: + new_soup = soup + # Add icons and labels for collapsible nested sections _add_collapse_checkboxes(new_soup, context['theme_collapse_parts']) @@ -281,38 +281,38 @@ def _add_collapse_checkboxes(soup, collapse_parts): toctree_checkbox_count = 0 - if collapse_parts: - for elem in soup.find_all('p'): - classes = elem.get("class", []) + # if collapse_parts: + # for elem in soup.find_all('p'): + # classes = elem.get("class", []) - if not "caption" in classes: - return + # if not "caption" in classes: + # return - # Add toctree class - elem["class"] = classes + ["toctree-l0"] - toctree_checkbox_count += 1 - checkbox_name = f"toctree-checkbox-{toctree_checkbox_count}" - - if soup.new_tag is None: - continue - label = soup.new_tag("label", attrs={"for": checkbox_name}) - label.append(soup.new_tag("i", attrs={"class": "fas fa-chevron-down"})) - elem.insert(1, label) - - # Add the checkbox that's used to store expanded/collapsed state. - checkbox = soup.new_tag( - "input", - attrs={ - "type": "checkbox", - "class": ["toctree-checkbox"], - "id": checkbox_name, - "name": checkbox_name, - }, - ) - - if "current" in classes: - checkbox.attrs["checked"] = "" - elem.insert_before(checkbox) + # # Add toctree class + # elem["class"] = classes + ["toctree-l0"] + # toctree_checkbox_count += 1 + # checkbox_name = f"toctree-checkbox-{toctree_checkbox_count}" + + # if soup.new_tag is None: + # continue + # label = soup.new_tag("label", attrs={"for": checkbox_name}) + # label.append(soup.new_tag("i", attrs={"class": "fas fa-chevron-down"})) + # elem.insert(1, label) + + # # Add the checkbox that's used to store expanded/collapsed state. + # checkbox = soup.new_tag( + # "input", + # attrs={ + # "type": "checkbox", + # "class": ["toctree-checkbox"], + # "id": checkbox_name, + # "name": checkbox_name, + # }, + # ) + + # if "current" in classes: + # checkbox.attrs["checked"] = "" + # elem.insert_before(checkbox) for element in soup.find_all("li", recursive=True): # We check all "li" elements, to add a "current-page" to the correct li. @@ -353,7 +353,6 @@ def _add_collapse_checkboxes(soup, collapse_parts): element.insert(1, checkbox) - def _get_local_toctree_for( self: TocTree, indexname: str, docname: str, builder, collapse: bool, **kwargs ): diff --git a/src/pydata_sphinx_theme/assets/styles/index.scss b/src/pydata_sphinx_theme/assets/styles/index.scss index be386c83f..efc398967 100644 --- a/src/pydata_sphinx_theme/assets/styles/index.scss +++ b/src/pydata_sphinx_theme/assets/styles/index.scss @@ -165,34 +165,6 @@ footer { } } -.bd-sidebar { - padding-top: 1em; - overflow-y: auto; - display: flex; - flex-direction: column; - - @include media-breakpoint-up(md) { - border-right: 1px solid rgba(0, 0, 0, 0.1); - - @supports (position: -webkit-sticky) or (position: sticky) { - position: -webkit-sticky; - position: sticky; - top: var(--pst-header-height); - z-index: 1000; - height: calc(100vh - var(--pst-header-height)); - } - } - - &.no-sidebar { - border-right: 0; - } - - .sidebar-end-items { - margin-top: auto; - margin-bottom: 1em; - } -} - .bd-links { padding-top: 1rem; padding-bottom: 1rem; @@ -522,8 +494,44 @@ nav.bd-links { } .bd-sidebar { + padding-top: 1em; + overflow-y: auto; + display: flex; + flex-direction: column; + + @include media-breakpoint-up(md) { + border-right: 1px solid rgba(0, 0, 0, 0.1); + + @supports (position: -webkit-sticky) or (position: sticky) { + position: -webkit-sticky; + position: sticky; + top: var(--pst-header-height); + z-index: 1000; + height: calc(100vh - var(--pst-header-height)); + } + } + + &.no-sidebar { + border-right: 0; + } + + .sidebar-end-items { + margin-top: auto; + margin-bottom: 1em; + } + .list-caption { + list-style: none; + padding-left: 0px; + } li { position: relative; + // If it has children, add a bit more padding to wrap the content to avoid + // overlapping with the