From b8422236be0673b867919bc215fb2450652d0afe Mon Sep 17 00:00:00 2001 From: Revathy Venugopal <104772255+Revathyvenugopal162@users.noreply.github.com> Date: Wed, 13 Mar 2024 16:02:16 +0100 Subject: [PATCH] feat: Add theme options for cheatsheet (#346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jorge Martínez <28702884+jorgepiloto@users.noreply.github.com> Co-authored-by: Kerry McAdams <58492561+klmcadams@users.noreply.github.com> Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com> --- .pre-commit-config.yaml | 20 ++--- LICENSE | 2 +- doc/source/user_guide/options.rst | 62 ++++++++++++- doc/styles/Vocab/ANSYS/accept.txt | 2 +- src/ansys_sphinx_theme/__init__.py | 90 ++++++++++++++++++- .../components/cheatsheet_sidebar.html | 19 ++++ .../static/css/ansys_sphinx_theme.css | 28 ++++++ .../theme/ansys_sphinx_theme/theme.conf | 1 + 8 files changed, 210 insertions(+), 14 deletions(-) create mode 100644 src/ansys_sphinx_theme/theme/ansys_sphinx_theme/components/cheatsheet_sidebar.html diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 29d6eb62..b3e243ca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,21 +1,21 @@ repos: - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 24.2.0 hooks: - id: black - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/codespell-project/codespell - rev: v2.2.2 + rev: v2.2.6 hooks: - id: codespell @@ -26,13 +26,13 @@ repos: additional_dependencies: [toml] - repo: https://github.com/pre-commit/mirrors-prettier - rev: 'v3.0.0-alpha.9-for-vscode' + rev: 'v4.0.0-alpha.8' hooks: - id: prettier - types_or: [css, javascript, html] + types_or: [css, javascript] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-merge-conflict - id: debug-statements @@ -40,20 +40,20 @@ repos: # this validates our github workflow files - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.21.0 + rev: 0.28.0 hooks: - id: check-github-workflows - repo: https://github.com/adamchainz/blacken-docs - rev: 1.15.0 + rev: 1.16.0 hooks: - id: blacken-docs additional_dependencies: [black==23.7.0] exclude: 'src/ansys_sphinx_theme/theme/ansys_sphinx_theme/_templates/' - repo: https://github.com/ansys/pre-commit-hooks - rev: v0.2.8 + rev: v0.2.9 hooks: - id: add-license-headers args: diff --git a/LICENSE b/LICENSE index 764c83ee..fd96df5f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022-2023 ANSYS, Inc. and/or its affiliates. +Copyright (c) 2022-2024 ANSYS, Inc. and/or its affiliates. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/doc/source/user_guide/options.rst b/doc/source/user_guide/options.rst index e9a01e3d..04b6bb8f 100644 --- a/doc/source/user_guide/options.rst +++ b/doc/source/user_guide/options.rst @@ -59,7 +59,7 @@ GitHub repository. in the *PyData Theme* documentation. - For comprehensive information on `Font Awesome `_, an icon library and toolkit, see its `documentation `_, - particularly `How To Add Icons `_. + particularly `How To Add Icons `_. The following sections explain how you can add icons and hide icons. @@ -188,3 +188,63 @@ to provide search functionality for your documentation. If you do not set the "use_meilisearch" option, ``ansys-sphinx-theme`` uses the default search functionality inherited from the PyData Sphinx Theme. + +Cheat sheets +------------ + +The ``cheatsheet`` HTML theme option can be used to enable a cheat sheet in the Ansys Sphinx theme. + +To enable a cheatsheet, in the ``conf.py`` file for your PyAnsys +library, you can add a child dictionary named ``cheatsheet`` to +the ``html_theme_options`` dictionary. + +This dictionary should contain these keys, in the order given: + +#. ``url``: URL of the cheat sheet for downloading. +#. ``title``: Title of the cheat sheet. +#. ``thumbnail``: Thumbnail image for the cheat sheet. +#. ``needs_download``: Whether to download the cheat sheet locally during the build. The default is ``False``, in which case the cheat sheet is accessed directly from the provided URL. If ``True``, the cheat sheet is downloaded to the ``_build/html/_static/`` directory. +#. ``pages``: List of pages to include in the cheat sheet (optional). If no list is provided, the cheat sheet includes the index page of the documentation. + +.. code-block:: python + + html_theme_options = ( + { + "cheatsheet": { + "url": "", + "title": "", + "thumbnail": "<image URL>", + "needs_download": True, # True if you want to download the cheatsheet locally in the ``_build/html/_static/`` directory. + "pages": "<list of pages to include the cheat sheet on>", # Optional + }, + }, + ) + +Here is an example configuration of using cheatsheet in +``conf.py`` file of ``PyMAPDL``: + + .. code-block:: python + + html_theme_options = ( + { + "cheatsheet": { + "url": "https://cheatsheets.docs.pyansys.com/pymapdl_cheat_sheet.pdf", + "title": "PyMAPDL cheatsheet", + "thumbnail": "https://cheatsheets.docs.pyansys.com/pymapdl_cheat_sheet.png", + "needs_download": True, + "pages": ["index", "getting_started/learning"], + }, + }, + ) + +.. note:: + + if you set the "needs_download" option, you should provide the "html_static_path" option + in the ``conf.py`` file to specify the location of the cheat sheet. + + for example, if you need to download cheat sheet in the ``_build/html/_static/`` directory, + you should add the following line in the ``conf.py`` file: + + .. code-block:: pycon + + html_static_path = ["_static"] diff --git a/doc/styles/Vocab/ANSYS/accept.txt b/doc/styles/Vocab/ANSYS/accept.txt index 7853ced9..4e68e6c8 100644 --- a/doc/styles/Vocab/ANSYS/accept.txt +++ b/doc/styles/Vocab/ANSYS/accept.txt @@ -10,6 +10,6 @@ link_code_library link_code_source link_code_branch html_context -HTML +(?!)HTML CSS PDF \ No newline at end of file diff --git a/src/ansys_sphinx_theme/__init__.py b/src/ansys_sphinx_theme/__init__.py index 4bcaf5b7..eba5cd4b 100644 --- a/src/ansys_sphinx_theme/__init__.py +++ b/src/ansys_sphinx_theme/__init__.py @@ -27,6 +27,7 @@ from typing import Any, Dict from docutils.nodes import document +import requests from sphinx import addnodes from sphinx.application import Sphinx @@ -285,8 +286,94 @@ def update_footer_theme( context["ansys_sphinx_theme_version"] = __version__ +def add_cheat_sheet( + app: Sphinx, pagename: str, templatename: str, context: Dict[str, Any], doctree: document +) -> None: + """Add a cheat sheet to the left navigation sidebar. + + Parameters + ---------- + app : ~sphinx.application.Sphinx + Application instance for rendering the documentation. + pagename : str + Name of the current page. + templatename : str + Name of the template being used. + context : dict + Context dictionary for the page. + doctree : ~docutils.nodes.document + The doctree. + """ + cheatsheet_options = app.config.html_theme_options.get("cheatsheet", {}) + pages = cheatsheet_options.get("pages", ["index"]) + pages = [pages] if isinstance(pages, str) else pages + if cheatsheet_options and any(pagename == page for page in pages): + if cheatsheet_options.get("needs_download"): + static_folder = app.config.html_static_path or ["static"] + download_cheatsheet_to_static(app, cheatsheet_options, static_folder, context) + sidebar = context.get("sidebars", []) + sidebar.append("cheatsheet_sidebar.html") + context["sidebars"] = sidebar + + +def download_cheatsheet_to_static( + app: Sphinx, + cheatsheet_options: Dict[str, Any], + static_folder: pathlib.Path, + context: Dict[str, Any], +) -> None: + """Download the cheatsheet to the static directory. + + Parameters + ---------- + app : ~sphinx.application.Sphinx + Application instance for rendering the documentation. + cheatsheet_options : dict + Dictionary containing the cheat sheet options. + static_folder : pathlib.Path + Path containing the static folder. + context : dict + Dictionary containing the context for the page. + """ + cheatsheet_url = cheatsheet_options.get("url", "") + cheatsheet_thumbnail = cheatsheet_options.get("thumbnail", "") + static_path = pathlib.Path(app.outdir) / static_folder[0] + context["cheatsheet_static_path"] = str(static_folder[0]) + + # Download cheat sheet file if URL is provided + if cheatsheet_url: + download_file(cheatsheet_url, static_path) + + # Download cheat sheet image if thumbnail URL is provided + if cheatsheet_thumbnail: + download_file(cheatsheet_thumbnail, static_path) + + +def download_file(url: str, directory: pathlib.Path) -> None: + """ + Download a file from the given URL and save it to a given directory. + + Parameters + ---------- + url : str + URL of the file to download. + directory : pathlib.Path + Directory to save the file to. + """ + filename = url.split("/")[-1] + if not directory.exists(): + directory.mkdir(parents=True, exist_ok=True) + if not (directory / filename).exists(): + file_path = directory / filename + with open(file_path, "wb") as file: + response = requests.get(url) + if response.status_code != 200: + raise FileNotFoundError(f"Failed to download file from {url}.") + file.write(response.content) + + def setup(app: Sphinx) -> Dict: - """Connect to the sphinx theme app. + """Connect to the Sphinx theme app. Parameters ---------- @@ -316,6 +403,7 @@ def setup(app: Sphinx) -> Dict: app.add_css_file("https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css") app.connect("html-page-context", update_footer_theme) app.connect("html-page-context", fix_edit_html_page_context) + app.connect("html-page-context", add_cheat_sheet) app.config.templates_path.append(str(TEMPLATES_PATH)) return { "version": __version__, diff --git a/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/components/cheatsheet_sidebar.html b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/components/cheatsheet_sidebar.html new file mode 100644 index 00000000..8b492854 --- /dev/null +++ b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/components/cheatsheet_sidebar.html @@ -0,0 +1,19 @@ +{% if theme_cheatsheet %} + {% set theme_cheatsheet_title = theme_cheatsheet.get('title', 'Cheatsheet') %} + <div class="sidebar-cheatsheets"> + <h4>{{ theme_cheatsheet_title }}</h4> + {% if theme_cheatsheet.get('needs_download') == true %} + {% set static_path = cheatsheet_static_path + '/' | default('') %} + {% set theme_cheatsheet_url = theme_cheatsheet.get('url').split('/')[-1] %} + {% set theme_cheatsheet_thumbnail = theme_cheatsheet.get('thumbnail').split('/')[-1] %} + {% set theme_cheatsheet_thumbnail = pathto(static_path ~ theme_cheatsheet_thumbnail, 1) %} + {% set theme_cheatsheet_url = pathto(static_path ~ theme_cheatsheet_url, 1) %} + {% else %} + {% set theme_cheatsheet_url = theme_cheatsheet.get('url') %} + {% set theme_cheatsheet_thumbnail = theme_cheatsheet.get('thumbnail') %} + {% endif %} + <a href="{{ theme_cheatsheet_url }}"> + <img src="{{ theme_cheatsheet_thumbnail }}" alt="{{ theme_cheatsheet_title }}" /> + </a> + </div> +{% endif %} diff --git a/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/static/css/ansys_sphinx_theme.css b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/static/css/ansys_sphinx_theme.css index 6c413752..98198159 100644 --- a/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/static/css/ansys_sphinx_theme.css +++ b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/static/css/ansys_sphinx_theme.css @@ -1133,3 +1133,31 @@ a:visited, a:visited:hover { color: var(--pst-color-link-visted); } + +/* Cheat sheet sidebar */ + +.sidebar-cheatsheets h4 { + font-weight: var(--pst-sidebar-header-font-weight) !important; + font-size: var(--pst-sidebar-header-font-size) !important; + margin-bottom: 0.5rem; +} + +.sidebar-cheatsheets a { + display: inline-flex; + border: 0.5px solid var(--pst-color-border); + padding: 0.25rem; + max-width: 80%; +} + +.sidebar-cheatsheets a:hover { + background-color: var(--pst-color-border); + color: var(--pst-color-text-base); +} + +.sidebar-cheatsheets img { + padding: 0rem; +} + +.bd-sidebar-primary { + padding: 0.5rem; +} diff --git a/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/theme.conf b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/theme.conf index 99b42dea..c85cfe5b 100644 --- a/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/theme.conf +++ b/src/ansys_sphinx_theme/theme/ansys_sphinx_theme/theme.conf @@ -16,3 +16,4 @@ article_header_start = breadcrumbs.html footer_end = theme-version.html pygment_light_style = friendly pygment_dark_style = monokai +cheatsheet =