Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
# Author(s):
# - Markus Braun, :em engineering methods AG (contracted by Robert Bosch GmbH)
# - Aniket Salve, Robert Bosch GmbH
# =====================================================================================
"""sphinx configuration file."""

Expand Down Expand Up @@ -66,9 +67,8 @@
html_theme_options = theme_options(html_theme)
html_static_path = ["docs/_static/"]
html_title = project
html_css_files = [f"{html_theme.replace('_', '-')}-custom.css"]
html_logo = "docs/resources/doxysphinx_logo.svg"
html_last_updated_fmt = last_updated_from_git(html_theme_options["repository_url"])
html_last_updated_fmt = last_updated_from_git()

github_username = "anyone" # these just need to be set that the sphinx toolbox extension will work
github_repository = "any"
Expand All @@ -93,6 +93,7 @@
"sphinx_design",
# in-repo sphinx extensions:
"sphinx_extensions.replacer",
"sphinx_extensions.doxysphinx_theme",
]

# Plantuml
Expand Down
5 changes: 1 addition & 4 deletions conf_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ def multi_glob(*glob_patterns: str) -> List[str]:
return result


def last_updated_from_git(repo_url: str) -> str:
def last_updated_from_git() -> str:
"""Get the last updated string from git command (needs a git repository!).

:return: The last updated string
:rtype: str
"""
git_cmd_timestamp = ["git", "log", "--pretty=format:'%ad'", "--date=local", "-n1"]
git_cmd_commit = ["git", "log", "--pretty=format:'%h'", "--date=local", "-n1"]
Expand Down Expand Up @@ -80,8 +79,6 @@ def theme_options(theme: str) -> Dict[str, Any]:

elif theme == "sphinx_rtd_theme":
return {
"show_nav_level": 1,
"collapse_navigation": True,
"github_url": "https://github.com/boschglobal/doxysphinx",
"repository_url": "https://github.com/boschglobal/doxysphinx",
"logo_only": False,
Expand Down
5 changes: 5 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ this:
### Recommended Setup

* To link from sphinx documentation directly to doxygen documented symbols -> see our [setting up doxylink](doxylink_setup.md) guide.(__Strongly recommended.__)
* Add Doxysphinx Theme extension to get support for navbar bugfix with loosing focus on opening Doxygen files.

### Notes

* Doxysphinx is supporting incremental behavior from V3.2.1 (Will work properly with Doxygen V1.9.7 and above)

### Related Reading

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ classifiers = [
"Topic :: Documentation :: Sphinx",
"Topic :: Documentation",
]
packages = [{ include = "doxysphinx" }]
packages = [{ include = "doxysphinx" }, { include = "sphinx_extensions" }]

[tool.poetry.dependencies]
python = ">=3.8,<3.11"
Expand Down
48 changes: 48 additions & 0 deletions sphinx_extensions/doxysphinx_theme/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# =====================================================================================
# C O P Y R I G H T
# -------------------------------------------------------------------------------------
# Copyright (c) 2023 by Robert Bosch GmbH. All rights reserved.
#
# Author(s):
# - Aniket Salve, Robert Bosch GmbH
# =====================================================================================

"""Doxysphinx themes extension.

This extensions add custom javascript files depending on theme.
Currently only supporting Book and RTD theme.
"""

import logging
import pathlib

from sphinx.application import Sphinx
from sphinx.config import Config


def setup(app: Sphinx):
"""Setups up the doxysphinx themes extension."""
app.connect("config-inited", doxysphinx_theme_extension)
return {"parallel_read_safe": True, "parallel_write_safe": True, "version": "0.1.0"}


def doxysphinx_theme_extension(app: Sphinx, config: Config):
"""Add custom javascript files specific to theme and set theme options.

:param app: Sphinx app
:param config: Sphinx config
"""
current_file_path = pathlib.Path(__file__).parent.resolve()

config.html_static_path.append(str(current_file_path) + "/_static/")

if config.html_theme == "sphinx_book_theme":
app.add_js_file("js/customize-navbar-book.js")
app.add_css_file("css/sphinx-book-theme-custom.css")

elif config.html_theme == "sphinx_rtd_theme":
app.add_js_file("js/customize-navbar-rtd.js")
app.add_css_file("css/sphinx-rtd-theme-custom.css")
if config.html_theme_options["collapse_navigation"]:
logging.warning("We are forcefully setting 'collapse_navigation' flag to 'False' in RTD theme options")
config.html_theme_options["collapse_navigation"] = False
Comment thread
aniketsalve22 marked this conversation as resolved.
Comment on lines +38 to +

@Maetveis Maetveis Apr 14, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being nosey here, but could there be some kind of explicit option to get these files?

For ROCm documentation our theme is a slightly modified version of the Sphinx Book Theme (custom headers and footers), and I'm certain the js file for that theme would work for us as well, so it would be nice if we could enable this fix somehow.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are planning to provide these files as part of an extension which will be part of Doxysphinx. So hopefully you won't need to add anything manually.

@Maetveis Maetveis Apr 20, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is the current logic wouldn't work for us because config.html_theme wouldn't be sphinx_rtd_theme, so it would be good to have another way to enable this.

@mb-emag mb-emag Apr 20, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Maetveis So you have an own version of the sphinx book theme with a different name, e.g. "sphinx-book-theme-custom" right? In that case as you said his extension won't do anything for you.

But you could still use the jsfile as it's in the doxysphinx-theme package directory.
Maybe a little bit cumbersome to reference though, however here's a rough sketch of the idea (untested!):

#<conf.py>
from pathlib import Path
from importlib.resources import files
# ...
patch_js_path = Path(files("doxysphinx_theme")) / "_static/js/customize-navbar-book.js"
html_theme_options = {
  'extra_scripts': [str(patch_js_path)]
}

But this might be only working in python 3.11+.

@Maetveis Maetveis Apr 21, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's exactly what we have.

I think I'll be able to make something like that work, the only slight issue with it is that I need to "know" implementation details of doxysphinx, I guess that is a price for having "forked" a theme.

I'll try this out and maybe do a PR if I come up with a way to have less coupling. Thank you for the help.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

/**
=====================================================================================
C O P Y R I G H T
-------------------------------------------------------------------------------------
Copyright (c) 2023 by Robert Bosch GmbH. All rights reserved.

Author(s):
- Aniket Salve, Robert Bosch Gmbh
=====================================================================================
*/


/**
* This function stores and updates the session store with active href
* If href is not present in nav bar then last state for session storage
* is shown as active state in navbar
*
* The classes are customized for sphinx-book-theme
*/
function findCurrentRoute() {

if (window.sessionStorage.getItem("href") == null) {
window.sessionStorage.setItem("href", window.location.href);
}

if (document.querySelector("li.active")) {
window.sessionStorage.setItem("href", window.location.href);
return;
} else {
var lastActiveNav = window.sessionStorage.getItem("href");
var allTags = document.querySelectorAll("li");
for (let i = 0; i < allTags.length; i++) {
if (allTags[i].getElementsByTagName("a")[0].href == lastActiveNav) {
allTags[i].getElementsByTagName("a")[0].classList.add("current");
allTags[i].classList.add("current");
allTags[i].classList.add("active");
recursiveParentClassAppend(allTags[i].parentNode, false);
return;
}
}
}
}

/**
* This function recursively parses the parent nodes
* Adds current class to UL tags
* Adds current and active classes to LI tags
*
* For all 2nd level and about parent UL nodes, the corresponding
* input tag is checked so that the navbar is expanded. This is achieved using flag
*
* @param {ParentNode | null} element Parent node of last active LI tag
* @param {Boolean} flag flag to check if input should be checked or not
*/
function recursiveParentClassAppend(element, flag) {
if (element.nodeName == "UL") {
if (flag && element.getElementsByTagName("input")) {
element.getElementsByTagName("input")[0].setAttribute("checked", "");
}
element.classList.add("current")
if (element.parentNode.nodeName == "LI") {
element.parentNode.classList.add("current");
element.parentNode.classList.add("active");
recursiveParentClassAppend(element.parentNode.parentNode, true);
}
else {
return;
}
}
}

$(document).ready(function () {
findCurrentRoute();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@

/**
=====================================================================================
C O P Y R I G H T
-------------------------------------------------------------------------------------
Copyright (c) 2023 by Robert Bosch GmbH. All rights reserved.

Author(s):
- Aniket Salve, Robert Bosch Gmbh
=====================================================================================
*/


/**
* This function stores and updates the session store with active href
* If href is not present in nav bar then last state for session storage
* is shown as active state in navbar
*
* The classes are customized for sphinx-rtd-theme
*/
function findCurrentRoute() {

if (window.sessionStorage.getItem("href") == null) {
window.sessionStorage.setItem("href", window.location.href);
}

if (document.querySelector("li.current")) {
window.sessionStorage.setItem("href", window.location.href);
return;
} else {
var lastActiveNav = window.sessionStorage.getItem("href");
var allTags = document.querySelectorAll("li");
for (let i = 0; i < allTags.length; i++) {
console.log(allTags[i].getElementsByTagName("a")[0].href);
if (allTags[i].getElementsByTagName("a")[0].href == lastActiveNav) {
allTags[i].getElementsByTagName("a")[0].classList.add("current");
allTags[i].getElementsByTagName("a")[0].setAttribute("aria-expanded", "true")
allTags[i].classList.add("current");
allTags[i].setAttribute("aria-expanded", "true")
recursiveParentClassAppend(allTags[i].parentNode, true);
return;
}
}
}
}

/**
* This function recursively parses the parent nodes
* Adds current class to UL tags
* Adds current class to LI tags
* Adds aria-expanded attribute to UL and LI tags
*
* For all 2nd level and about parent UL nodes, the corresponding
* input tag is checked so that the navbar is expanded. This is achieved using flag
*
* @param {ParentNode | null} element Parent node of last active LI tag
* @param {Boolean} flag flag to check if input should be checked or not
*/
function recursiveParentClassAppend(element, flag) {
if (element.nodeName == "UL") {
element.classList.add("current")
element.setAttribute("aria-expanded", "true")
if (element.parentNode.nodeName == "LI") {
element.parentNode.classList.add("current");
element.parentNode.setAttribute("aria-expanded", "true")
recursiveParentClassAppend(element.parentNode.parentNode, true);
}
else {
return;
}
}
}

$(document).ready(function () {
findCurrentRoute();
});