Code Monkey home page Code Monkey logo

sphinx-immaterial's Introduction

Sphinx-Immaterial Theme

MIT License PyPI Package CI status

This theme is an adaptation of the popular mkdocs-material theme for the Sphinx documentation tool.

This theme is regularly maintained to stay up to date with the upstream mkdocs-material repository. The HTML templates, JavaScript, and styles from the mkdocs-material theme are incoroprated directly with mostly minor modifications.

This theme is a fork of the sphinx-material theme, which proved the concept of a Sphinx theme based on an earlier version of the mkdocs-material theme, but has now significantly diverged from the upstream mkdocs-material repository.

See this theme's own documentation for a demonstration.

WARNING: This theme is still in beta. While it is already very usable, breaking changes will still be made prior to the 1.0 release.

Installation

Install via pip:

$ pip install sphinx-immaterial

or if you have the code checked out locally:

$ pip install -e .

Configuration

In your conf.py add sphinx_immaterial as an extension:

extensions = [
    ...,
    "sphinx_immaterial"
]

and add the following:

html_theme = 'sphinx_immaterial'

to set the theme.

Customizing the layout

You can customize the theme by overriding Jinja template blocks. For example, 'layout.html' contains several blocks that can be overridden or extended.

Place a 'layout.html' file in your project's '/_templates' directory.

mkdir source/_templates
touch source/_templates/layout.html

Then, configure your 'conf.py':

templates_path = ['_templates']

Finally, edit your override file 'source/_templates/layout.html':

{# Import the theme's layout. #}
{% extends '!layout.html' %}

{%- block extrahead %}
{# Add custom things to the head HTML tag #}
{# Call the parent block #}
{{ super() }}
{%- endblock %}

Differences from mkdocs-material

This theme closely follows the upstream mkdocs-material repository, but there are a few differences, primarily due to differences between Sphinx and MkDocs:

  • This theme adds styles for Sphinx object descriptions, commonly used for API documentation (e.g. class and function documentation). This is a core element of Sphinx for which there is no corresponding feature in MkDocs.
  • mkdocs-material uses lunr.js for searching, and has custom UI components for displaying search results in a drop-down menu as you type the search query. This theme uses a separate search implementation based on the custom index format used by Sphinx, which fully integrates with the search UI provided by mkdocs-material.

sphinx-immaterial's People

Contributors

12rambau avatar 2bndy5 avatar antonymayi avatar bizordec avatar danwos avatar dependabot[bot] avatar duncanmmacleod avatar funkyfuture avatar glatosinski avatar hugoshaka avatar jan-matejka avatar jbms avatar kamiazya avatar kartben avatar matthias-colt avatar mhostetter avatar n-wouda avatar ruslo avatar simonboothroyd avatar tim-nordell-nimbelink avatar umarcor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sphinx-immaterial's Issues

Tabs require first item to be a page header

I also noticed that a tab item in which the toc entry is just RST links will forward to only the first link in the list. This is exemplified in my CirPy_nRF24 docs' "other links" tab.
image

RST source code:

.. toctree::
    :caption: Other Links
    :hidden:

    Download <https://github.com/2bndy5/CircuitPython_nRF24L01/releases/latest>
    CircuitPython Reference Documentation <https://circuitpython.readthedocs.io>
    CircuitPython Support Forum <https://forums.adafruit.com/viewforum.php?f=60>
    Discord Chat <https://adafru.it/discord>
    Adafruit Learning System <https://learn.adafruit.com>
    Adafruit Blog <https://blog.adafruit.com>
    Adafruit Store <https://www.adafruit.com>

We should probably put a note in the docs that this convention cannot be supported with navigation tabs. Although it is supported in the side navigation menu.
image

Originally posted by @2bndy5 in #31 (comment)

Linked content tabs

Well, it looks like linked content tabs will remain an insiders feature only. Originally, I thought the feature would get included in the public releases when the upstream funding goal hit $5000+, but the linked tabs feature wasn't made public when that goal was recently met.

So, we have to implement linked tabs ourselves.

Implementation

I envision this as a :linked: option to the md-tab-item directive. This could be a flag (option accepts no value) or an option that expects an identifying string.

  • Expecting a string value would align with sphinx-design implementation and allow for linked tabs to have different labels.
  • A flag might be easier from the user's perspective (relying on commonly shared tabs' labels), but that may be error prone. For example, case sensitivity or non-text elements in the linked tabs' labels.

Type annotation CSS was modified

I noticed after merging #60, the CSS styling of type hints (type annotations) has changed. I believe the issue comes from the changes in sphinx_immaterial/apidoc_formatting.py and/or src/assets/stylesheets/main/_api.scss.

It seems this change is where the type hint inherits the --md-typeset-a-color color.

Before:

After:

Before: 8c96b11

image

image

After: d874316

image

image

synopsis is inconsistent with doxygen+breathe

This isn't really a problem with this theme's synopsis feature.

I noticed that sphinx_utils.summarize_element_text() may yeild the wrong text because doxygen's XML tends to use different paragraph structure, and breathe simply attempts to output a node tree based on the doxygen XML output (1:1).

So, I'm suggesting a note about synopsis compatibility with other sphinx extensions that don't use nodes.paragraph exactly like sphinx/docutils does.

Example

expected results

useing the RST code

    .. cpp:function:: RF24::RF24(uint32_t _spi_speed=RF24_SPI_SPEED)

        :param _spi_speed: The SPI speed in Hz ie: 1000000 == 1Mhz

            - Users can specify default SPI speed by modifying :c:macro:`RF24_SPI_SPEED` in :file:`RF24_config.h`
        
              - For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS
              - Older/Unsupported Arduino devices will use a default clock divider & settings configuration
              - For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7
parameter's pformat() output
<definition>
    <paragraph>
        <inline translatable="True">
            The SPI speed in Hz ie: 1000000 == 1Mhz
            <bullet_list>
                <list_item>
                    <paragraph>
                        Users can specify default SPI speed by modifying
                        <pending_xref refdomain="std" refexplicit="True" refid="RF24__config_8h_1a63ef6fd21b0b83db10e95c0da126d1e2" reftarget="RF24__config_8h_1a63ef6fd21b0b83db10e95c0da126d1e2" reftype="ref">
                            RF24_SPI_SPEED
                         in
                        <pending_xref refdomain="std" refexplicit="True" refid="RF24__config_8h" reftarget="RF24__config_8h" reftype="ref">
                            RF24_config.h
                        <bullet_list>
                            <list_item>
                                <paragraph>
                                    For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS
                            <list_item>
                                <paragraph>
                                    Older/Unsupported Arduino devices will use a default clock divider & settings configuration
                            <list_item>
                                <paragraph>
                                    For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7

Resulting synopsis for the parameter:

RF24::RF24::RF24::_spi_speed (C++ function parameter) — The SPI speed in Hz ie: 1000000 == 1Mhz

unexpected results (using doxygen+breathe)

using the documented prototype in a header file:

    /**
     * @param _spi_speed The SPI speed in Hz ie: 1000000 == 1Mhz
     * - Users can specify default SPI speed by modifying @ref RF24_SPI_SPEED in @ref RF24_config.h
     *     - For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS
     *     - Older/Unsupported Arduino devices will use a default clock divider & settings configuration
     *     - For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7
     */
    RF24(uint32_t _spi_speed = RF24_SPI_SPEED);
parameter's pformat() output
<definition>
    <paragraph>
        <inline translatable="True">
            <paragraph>
                The SPI speed in Hz ie: 1000000 == 1Mhz
            <bullet_list bullet="-">
                <list_item>
                    <paragraph>
                        Users can specify default SPI speed by modifying
                        <pending_xref cpp:parent_key="<sphinx.domains.cpp.LookupKey object at 0x000001D18B4A8CA0>" refdoc="classRF24" refdomain="c" refexplicit="False" reftarget="RF24_SPI_SPEED" reftype="macro" refwarn="False">
                            <literal classes="xref c c-macro">
                                RF24_SPI_SPEED
                         in
                        <literal classes="file" role="file">
                            RF24_config.h
                    <bullet_list bullet="-">
                        <list_item>
                            <paragraph>
                                For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS
                        <list_item>
                            <paragraph>
                                Older/Unsupported Arduino devices will use a default clock divider & settings configuration
                        <list_item>
                            <paragraph>
                                For Linux: The old way of setting SPI speeds using BCM2835 driver enums has been removed as of v1.3.7

Resulting synopsis for the parameter:

RF24::RF24::RF24::_spi_speed (C++ function parameter) — For Arduino, the default SPI speed will only be properly configured this way on devices supporting SPI TRANSACTIONS

add option to disable cross-linking C++ parameters

There are 2 reasons why I think this would be useful.

  1. If a documented API uses a lot of parameters, then the ToC gets very long and visually complex (despite the include_object_description_fields_in_toc config value).
  2. When writing new documentation for API, it can be annoying to see a warning related to missing parameter descriptions.
    • I wouldn't do this myself, but some might consider a parameter's name/type as "self-descriptive enough." Thus, they would deliberately neglect adding parameter description(s).

The only objection I can think of is: If disabling cross-linked parameters, would it affect other C++ domain customization options, namely synopses?

I imagine that the option's name would be cpp_cross_link_parameters (defaults to True). This way it can be used independently from similar implementations for other domains (like Java or JS) - thinking optimistically about future additions 😃 .

Navigation tabs

Hey guys, really love what you've done here! I'm working to port over my open source project to this theme.

I know it's new and still being developed / polished. I was wondering if the navigation tabs feature from Material for Mkdocs is possible here with Sphinx?

line numbers could use better visual distinction

At first, this felt like a personal style choice, but I've been adding custom CSS to all my docs that use this theme.

.linenos {
  background-color: var(--md-default-bg-color--light);
  margin-right: 0.5rem;
}

which transforms
image
into something a little more "legible" like so
image


I was wondering if this CSS change should be considered for this theme. Additionally, I kinda like how line numbers look in the mkdocs-material upstream
image

CSS for details/summary html tags is tied to admonitions' CSS

Sphinx and rST directives don't support HTML's details and summary tags, This theme has some css specifically for these tags which collides with other sphinx extensions that implement custom directives to enumerate the details & summary tags. Example using sphinx-panels (same result from using sphinx-design):

closed

image

open

image

Notice that the theme's css also assume any generic .. admonition:: is a .. note:: which impedes user-defined admonitions.

code to reproduce

Enable the extension in docs' conf.py

extensions = [
    "spinx_immaterial",
    "sphinx_panels",
]

Use the extension's introduced directives

.. dropdown:: Settings used in this documentation

    .. literalinclude:: ./conf.py
        :start-at: # -- HTML theme settings ------------------------------------------------
        :end-before: # ---- Other documentation options -------------------------

Updating the docs

I have been looking into what the docs need and don't need. Much of what is there seems like it was copied from the sphinx-material theme's docs.

  1. I don't think using numpy as an example API is a "simple" demonstration of the theme's capabilities. Furthermore, numpy-doc is not PEP517 compliant (as reported by pip), which complicates building the docs on different platforms.
  2. Using to a Jupyter notebook also seems to further complicate what should be a "simple" demonstration (& even simpler docs build process). It requires pandoc (a 3rd party utility not available via pypi only) to convert the notebook into a sample doc.

My concern here is that if someone looks at the sphinx-immaterial docs, then finds API docs for an entirely separate library, they might get overwhelmed/confused.

ps - I'm under the impression that completed/revised docs are 1 of the last few things preventing a release (or pre-release) to pypi. I have been using a locally copied wheel to try this theme with readthedocs.org... Found another issue with compatibility there (it isn't a deal-breaking issue).

allow consecutive builds

Due to the altered search system in this theme, any consecutive attempt to build docs results in the following error:

Exception occurred:
  File "/path/to/env/lib/python3.10/site-packages/sphinx/search/__init__.py", line 283, in load
    index2fn = frozen['docnames']
KeyError: 'docnames'

The current workaround is delete any previously built docs (specific to the project being worked on), then re-build the docs.

This affects IDE extensions designed to generate previews of documentation. I don't see a way to workaround this error in the vscode restructuredtext extension, so it would be nice to have this theme cooperate better with sphinx in this scenario.

typo in docs/cppreference.rst

According to the new doc, users are instructed to

extensions = [
    # other extensions...
    "sphinx_immaterial.cppreferences",
]

But there is no module named sphinx_immaterial.cppreferences, rather it is the singular form (no trailing "s") sphinx_immaterial.cppreference.

Monospace code with box characters

I noticed that box drawing characters in sphinx-immaterial don't print with the same width. I tried several different fonts, even ones I know to "work" elsewhere, but can't seem to get uniform spacing. I've been digging into the CSS to try to determine what parameters could affect this (ligatures, etc). I was curious if anything in squidfunk/mkdocs-material#323 was related. Given my very limited HTML/CSS knowledge, this has proved difficult.

Any thoughts?

sphinx-immaterial

image

sphinx_rtd_theme

image

VS Code

image

'NoneType' object has no attribute 'walk'

I get the following error if I try to use sphinx-immaterial with a fresh sphinx project, created by sphinx-quickstart.

Extension error (sphinx_immaterial.nav_adapt):
Handler <function _html_page_context at 0x7f47a41e1c60> for event 'html-page-context' threw an exception (exception: 'NoneType' object has no attribute 'walk')

The reason is, that you need a toctree directive and at least one additional rst-file, which must be mentioned in the toctree directive.

So this does not work (index.rst):

Project
=======
Test me

This does also not work:

Project
=======
Test me

.. toctree::

but this works:

Project
=======
Test me

.. toctree::

   page.rst

The problematic code is inside nav_adapt.py:

def _get_mkdocs_toc(
    toc_node: docutils.nodes.Node, builder: sphinx.builders.Builder
) -> List[MkdocsNavEntry]:
    """Converts a docutils toc node into a mkdocs-format JSON toc."""
    visitor = _TocVisitor(sphinx.util.docutils.new_document(""), builder)
    toc_node.walk(visitor)
    return visitor._children

and there toc_node can be None for small documentation projects.

use of Mapping in __init__.py incompatible with py3.10

I just updated my local version of python to v3.10, rebuilt a new venv, and then tried to build some docs with this theme. The build failed saying

Running Sphinx v4.2.0
loading translations [en]... done

Exception occurred:
  File "C:\Users\ytreh\Documents\GitHub\venv\lib\site-packages\sphinx_immaterial\__init__.py", line 187, in <module>
    def dict_merge(*dicts: List[collections.Mapping]):
AttributeError: module 'collections' has no attribute 'Mapping'
The full traceback has been saved in C:\Users\ytreh\AppData\Local\Temp\sphinx-err-u29qe6xq.log, if you want to report the issue to the developers.

So, I took a look at where Mapping was really defined, and found it in CPython's Lib/typing.py

Mapping = _alias(collections.abc.Mapping, 2)

The code in this theme's __init__.py is

import collections
import os
import sys
from typing import List, Optional, Union, Type, Dict, Sequence, Tuple

def dict_merge(*dicts: List[collections.Mapping]):
"""Recursively merges the members of one or more dicts."""
result = dict()
for d in dicts:
for k, v in d.items():
if (isinstance(v, collections.Mapping) and k in result

Solution

Change where Mapping is imported from, then remove the collections namespaces

from typing import List, Optional, Union, Type, Dict, Sequence, Tuple, Mapping
# ...
def dict_merge(*dicts: List[Mapping]): 
     """Recursively merges the members of one or more dicts.""" 
     result = dict() 
     for d in dicts: 
         for k, v in d.items(): 
             if (isinstance(v, Mapping) and k in result 

I haven't gone back to an older version of python to make sure this is backward compatible, but I imagine that this repo's build CI workflow (which uses py v3.9) would error out if there's any problems.

`html_wrap_signatures_with_css` default value treated as a list

I went to play with the new features from #64 on my personal project and found this error when letting html_wrap_signatures_with_css be it's default value (which is None and interpreted as True).

Extension error (sphinx_immaterial.apidoc_formatting):
Handler <function _wrap_signatures at 0x000001AC357BACB0> for event 'object-description-transform' threw an exception (exception: argument of type 'NoneType' is not iterable)

The fix for this is to modify


into

    if isinstance(enabled, list) and domain not in enabled:

Just now discovering this because I assume only the list form of the option's value was last tested. Our docs is using

html_wrap_signatures_with_css = ["py"]

can't render docs with built/installed theme on windows

I keep running into a problem when using npm on windows to build the theme. It installs fine, but any docs built from the install doesn't properly link to the correct names of compiled CSS files in the installed theme's base.html template.

The generated docs try linking to files named main.css and pallete.css. However, they should be named main.<sha>.min.css and pallete.<sha>.min.css. I suspect it has something to do with the tools/build JS module.

Looking for JS advice again...

(venv) PS C:\path\to\sphinx-immaterial> npm -v
8.1.2

I have resorted to using WSL ubuntu bash (& related npm v8.1.2) to build a wheel and install to a Windows venv. Note that sphinx (& python in general) runs faster in Windows PS than it does in WSL terminal for some reason.

Google Analytics search query support

I am receiving no search queries in Google Analytics from my webpage using sphinx-immaterial. Full disclosure, I wasn't receiving them using sphinx_rtd_theme either. I was, however, able to see the search terms on the readthedocs.org Admin tab. I don't believe I get any search terms in the Admin tab with sphinx-immaterial.

My question still stands, though. It seems that it should be possible to receive Google Analytics search results as is discussed here with sphinx-immaterial.

I believe I'm configuring Google Analytics the correct way. And I can see that the JS is loaded and is emitting page references (which I can see in my GA dashboard).

html_theme_options = {
    "google_analytics": ["G-***********", "auto"],
}

However, the webpage is not emitting anything when search terms are typed or selected. I did some investigating and comparison with what the Material for Mkdocs webpage does. I found the Material for Mkdocs website does invoke analytics.js when searching and sphinx-immaterial does not, see below.

Thoughts on this? Can we add some JS to invoke the analytics.js after typing a search query (begin scrolling through results) or when clicking on a search result?

Material for Mkdocs

On https://squidfunk.github.io/mkdocs-material/, I typed the search term and nothing was emitted on the network. Once I scrolled down onto the first result, or clicked somewhere, the analytics.js was triggered (see the last line).

image

Examining the last packet, we see the ?q=a custom search query.

image

Google Analytics uses the q to parse the search result.

image

Sphinx Immaterial

I noticed no such ?q= emitted from my website https://galois.readthedocs.io/en/v0.0.25/index.html using sphinx-immaterial.

When arriving on a page, there is a analytics.js trigger just saying where we are.

image

However, after typing a search query, scrolling down through the results, and then clicking a page there is no additional analytics.js trigger with a ?q= included.

production lists rendered incorrectly

I noticed this a long time ago, but keep forgetting to file this issue.

An erroneous example can be seen in our hosted docs

I think the expected behavior is something that resembles a typical code-block but with cross-referencing links in certain parts of the code. I generally don't use the productionlist directive, but I figured I should say something.

The directive's docs are at the Sphinx docs

An expected behavior can be observed from the attached simple project (uses furo theme)
prod-list-proper.zip

image

getting WARNING: Invalid parameter name

I'm now getting warnings saying

GitHub\RF24\docs\sphinx\classRF24.rst:6: WARNING: Invalid parameter name: '_cepin'
GitHub\RF24\docs\sphinx\classRF24.rst:6: WARNING: Invalid parameter name: '_cspin'
GitHub\RF24\docs\sphinx\classRF24.rst:6: WARNING: Invalid parameter name: '_spi_speed'
GitHub\RF24\docs\sphinx\classRF24.rst:7: WARNING: Invalid parameter name: '_spi_speed'

The only commonality that these parameters have is that they're used as verbatim parameter names in multiple functions ( in overloaded c'tor and Arduino style begin()), and each name begins with a _. I might be misunderstanding the problem here, but I doubt that the _ is the culprit (removing the _ didn't prevent the warning).

EDITED: better diagnosis in first comment below

I'm guessing this warning should be saying "Non-unique parameter name" given that it is generated from

# Determine the number of unique declarations of this parameter
unique_decls: Dict[str, Tuple[int, docutils.nodes.Element]] = {}
for i, sig_param_nodes in enumerate(sig_param_nodes_for_signature):
desc_param_node = sig_param_nodes.get(param_name)
if desc_param_node is None:
continue
decl_text = desc_param_node.astext().strip()
unique_decls.setdefault(decl_text, (i, desc_param_node))
if not unique_decls:
logger.warning(
"Invalid parameter name: %r", param_name, location=param_node
)
continue

However, I would argue that re-using parameter names for multiple functions is an accepted practice. So, we shouldn't raise warnings about it (which would cause RTD builds to fail fast).

`jinja2.Markup` no longer exists as of `3.1.0`

As of this morning, I get a failing build on RTD with this error. Upon investigation, the latest jinja2 (released today) does not support jinja2.Markup, see here. Instead, it states Markup should be imported from markupsafe.

I can submit a PR to either:

  • Pin jinja < 3.1.0, or
  • Add the markupsafe dependency (I believe it's already required by jinja2) and change the code to import Markup accordingly

Thoughts?

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/events.py", line 101, in emit
    results.append(listener.handler(self.app, *args))
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx_immaterial/nav_adapt.py", line 410, in _html_page_context
    page_title = jinja2.Markup.escape(jinja2.Markup(context.get("title")).striptags())
AttributeError: module 'jinja2' has no attribute 'Markup'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/cmd/build.py", line 284, in build_main
    app.build(args.force_all, filenames)
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/application.py", line 337, in build
    self.builder.build_update()
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 294, in build_update
    self.build(to_build,
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 358, in build
    self.write(docnames, list(updated_docnames), method)
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 532, in write
    self._write_serial(sorted(docnames))
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 542, in _write_serial
    self.write_doc(docname, doctree)
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/html/__init__.py", line 632, in write_doc
    self.handle_page(docname, ctx, event_arg=doctree)
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/builders/html/__init__.py", line 1033, in handle_page
    newtmpl = self.app.emit_firstresult('html-page-context', pagename,
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/application.py", line 464, in emit_firstresult
    return self.events.emit_firstresult(event, *args,
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/events.py", line 119, in emit_firstresult
    for result in self.emit(name, *args, allowed_exceptions=allowed_exceptions):
  File "/home/docs/checkouts/readthedocs.org/user_builds/galois/envs/312/lib/python3.8/site-packages/sphinx/events.py", line 109, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function _html_page_context at 0x7f03eacd1a60> for event 'html-page-context' threw an exception (exception: module 'jinja2' has no attribute 'Markup')

Extension error (sphinx_immaterial.nav_adapt):
Handler <function _html_page_context at 0x7f03eacd1a60> for event 'html-page-context' threw an exception (exception: module 'jinja2' has no attribute 'Markup')

Hide toc or navigation seems not work

When I try to hide table of contents sidebars or navigation, it did not work. I add the following line in markdown files

---
hide:
  - navigation
  - toc
---

Is this the right method to hide table of contents sidebars or navigation? Thanks.

mkdocs edit_url not compatible with sphinx

I've been looking for what features work as expected to determine what config stuff should go into the docs. I happened across this code

<!-- Edit button -->
{% if page.edit_url %}
<a
href="{{ page.edit_url }}"
title="{{ lang.t('edit.link.title') }}"
class="md-content__button md-icon"
>
{% include ".icons/material/pencil.svg" %}
</a>
{% endif %}

but it seems to be unaltered from the original mkdocs-material theme's src/base.html.

Trying to minimize changes to base.html template

Now, I would like to pass the proper edit_url based on config context which is updated from html_page_context(), but I think I need to make the assumption that the document's source file is located in the docs folder. The source file's extension (.rst or any other supported suffix) can be fetched with the template's global variable page_source_suffix. Maybe there's a better way to do this, but this is what I have working so far.

__init__.py changes
--- sphinx_immaterial/__init__.py
+++ sphinx_immaterial/__init__.py
@@ -218,235 +218,241 @@
+    repo_url = theme_options.get("repo_url", None)
     context.update(
         config={
             "theme": theme_options,
             "site_url": theme_options.get("site_url"),
             "site_name": context["docstitle"],
-            "repo_name": theme_options.get("repo_url", None),
+            "repo_url": repo_url,
             "repo_name": theme_options.get("repo_name", None),
+            "edit_url": ""
+            if repo_url is None
+            else "/".join(
+                [repo_url.rstrip("/"), os.path.split(app.srcdir)[1], pagename]
+            ),
             "extra": {
                 "version": version_config,
                 "social": theme_options.get("social"),
                 "disqus": theme_options.get("disqus"),
                 "manifest": theme_options.get("pwa_manifest"),
             },
             "plugins": theme_options.get("plugins"),
             "google_analytics": theme_options.get("google_analytics"),
         },
         base_url=base_url,
    )
template changes
--- src/base.html
+++ src/base.html
@@ -298,306 +298,306 @@
-                {% if page.edit_url %}
+                {% if config.edit_url %}
                   <a
-                    href="{{ page.edit_url }}"
+                    href="{{ config.edit_url ~ page_source_suffix }}"
                     title="{{ lang.t('edit.link.title') }}"
                     class="md-content__button md-icon"
                   >
                     {% include ".icons/material/pencil.svg" %}
                   </a>
                 {% endif %}

You may have noticed that RTD has its own (probably more precise) mechanism that provides links to the document's source (see pictures in #7), but I figured I'd try to tackle this for completion (& people coming from mkdocs who've only ever used gh-pages). Here's a screenshot of the above changes' result:

image

API signature punctuation has modified CSS

A small observation, but...

I noticed that after the changes in #60 through #73 the API signature punctuation color has changed. It used to be var(--md-code-hl-punctuation-color), but now is overridden in some way.

This can be reproduced by adding any function to your docs that has a List[int], or some equivalent type hint. The [ are considered punctuation. Notice they were gray before but are pink now.

8c96b11

image

0e0dcc8

image

multilined cpp function signatures split between param name and datatype

I'm getting ready to start exporting docygen XML to sphinx-immaterial (via breathe ext), and I noticed that function signatures that are wrapped to multiple lines are confusingly split between the parameter's datatype and name. Observe a test I made without doxygen/breathe (using standard sphinx cpp domain directives):
image

.. cpp:function:: const MyType Foo(const MyType bar, uint8_t baz, bool flag, uint16_t foobar, int32_t foobaz, unsigned long barbaz)

   Some function description.

I'm suspecting the fix should be placed in apidoc_formatting.py of this theme, but I still need to research more about how it detects the directive's domain.

How to provide extracopyright

I've just discovered this project, and love it (I have used sphinx-material for a while, but this gets much closer to mkdocs-material), thanks for maintaining it!

But, I can't work out how to provide extracopyright in a way that actually get's built into the rendered docs. I've put together a tiny demo here

https://github.com/duncanmmacleod/test-sphinx-immaterial

but nothing I put in my _templates/layout.html seems to have any effect. Is this possible?

version selector working?

I recently tried the version selector as the docs for this theme instruct, but it didn't work; the JSON file option nor the conf.py dict option made any difference or triggered any unusual build-time output. I know @jbms noted some changes to the version selector dopdown in his initial PR to the sphinx-material theme's repo

I changed the versions.json format to match the "mike" format supported by mkdocs-material.

So, I tried a json in the form that the mike plugin expects: still no joy.

At this point I think its just broken from a change in the HTML template's context variables. However, I'm actually having trouble finding the section of the template that integrates the version selector dropdown. I see the word "version" mentioned in the bottom of base.html about translations, but I have a feeling the mkdocs-material theme supports the mike plugin via added JS (which is where my expertise stops).

On a related note, I think I found the Sphinx alternative to the mkdocs' mike plugin: sphinxcontrib-versioning. It seems that this extension is the key ingredient to versioned docs on RTD as most of the sphinx themes' support it via the extension's html template API.


My initial intention was to try and have a doxygen rendered version and a sphinx/breathe rendered version of a project's docs I'm working on.

`"navigation.tabs"` links to page's first section

I'm in the process of converting my library over to this theme. Thanks for all the hard work creating this fork!!

I noticed when using navigation tabs that after clicking on the tab, the page /the-page.html is loaded with #first-section appended. So the URL is /the-page.html#first-section and not /the-page.html.

This can be observed on @2bndy5's website https://circuitpython-nrf24l01.readthedocs.io/en/latest/index.html.

image

When clicking "Network API Reference", the URL /topology.html#network-levels is loaded and not /topology.html.

image

Desired output:

image

PS: I noticed that when clicking on a navigation tab while currently on that tab (but halfway down the page), it loads the page correctly without the #first-section appended.

Contributing guidelines

I'm ready to start pushing commits in prep for submitting a PR, but I'd like to verify 2 things first (so I don't have to walk some changes back).

  1. Given the use of linting in JS, I'd like to add a .pylintrc for linting selective python sources. Doing so would also instigate the use of pylint in this repo's build.yml.
  2. I tend to use black to format python sources in accordance with PEP8 standards. This would be applied to everything in the sphinx_immaterial folder.
    • I did find a requirement for black==19.10b0 in the requirements-dev.txt
  3. I'm assuming that edits to the package-lock.json & package.json should not be committed. I didn't personally make any changes, but it looks like changes were made in the build process (or setting up nodejs for this project locally).

I raised this issue because I don't see a contributing guidelines in the repo root.

[question] How to change the icon of an admonition?

My intention is to have
image
look like
image

But it looks like the built theme only allows a limited set of options. So, how do I change the icon for admonitions? Usually I'd override the CSS styling to do this, but I don't see the compiled svg I want.

table borders not displayed

hello again! I've already brought this to your attention, but now I have something (a dummy repo) to actually share (as opsosed to building only locally and trying to describe symptoms with words).

In a new project (very early stages - execution is incomplete) I decided to try this theme in the docs because it has a very basic docs' config. However, I'm still not seeing the borders on tables. In this demonstation, the tables listing the functions/classes/modules of the python pkg is not styled correctly (or maybe its something I overlooked).

the docs are built in the repo's github actions workflow. The workflow log (if needed) can be observed also (seen here)

Notice I am using autosummary (with a customized template for better recursion) this time. More info about the docs config can be seen in the docs/config.py. Actually its a copy of the conf.py from my CirPy nRF24L01 lib's docs, but a lot of stuff is commented out.

ps - There are other discrepancies, but I figured 1 issue at a time (try the light and dark color palettes on a page with a code block in it).

Sphinx 4.3 Compatability

Firstly, thanks for making this port available - it works and looks amazing!

It seems the newest version of sphinx (4.3) has a few API changes that leads to some breaks in this package. Namely:

  • sphinx.search.IndexBuilder.get_objects() now returns a list of tuples rather than a dict, where the old dict key has now been included as the last item in the tuple.
  • get_signature_prefix now returns a list of nodes rather than strings.

I'd be happy to contribute a PR with possible fixes if you'd like.

Content tabs

Are content tabs supported in this theme? I searched in the docs here, but didn't find any mention. Thanks!

Resolve roles in navigation

I noticed that Sphinx roles are not applied in the navigation tab or content tab headings. Is there anything we can do about that? Is there a way to run a Sphinx role processor on the the titles or captions?

Content tabs

Here I tried to add an inline literal to a content tab heading. I also tried to add an octicon from the sphinx-design extension.
Potentially the octicon did get converted to a SVG but isn't displaying as such?

    Examples
    --------
    .. md-tab-set::

        .. md-tab-item:: n = 14

            Content one...

        .. md-tab-item:: ``n = 15``

            Content two...

        .. md-tab-item:: :octicon:`graph` Graphs

            Content three...

renders as

image

HTML
<div class="tabbed-labels docutils">
    <label class="tabbed-label" for="__tabbed_1_1">
        n = 14
    </label>
    <label class="tabbed-label" for="__tabbed_1_2">
        &lt;literal&gt;n = 15&lt;/literal&gt;
    </label>
    <label class="tabbed-label" for="__tabbed_1_3">
        &lt;raw format=”html” xml:space=”preserve”&gt;&lt;svg version=”1.1” width=”1.0em” height=”1.0em”
        class=”sd-octicon sd-octicon-graph” viewBox=”0 0 16 16” aria-hidden=”true”&gt;&lt;path fill-rule=”evenodd”
        d=”M1.5 1.75a.75.75 0 00-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 000-1.5H1.5V1.75zm14.28 2.53a.75.75 0
        00-1.06-1.06L10 7.94 7.53 5.47a.75.75 0 00-1.06 0L3.22 8.72a.75.75 0 001.06 1.06L7 7.06l2.47 2.47a.75.75 0
        001.06 0l5.25-5.25z”&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/raw&gt; Graphs
    </label>
</div>

Navigation tabs

Here I tried to add an octicon to a navigation tab, but it didn't render as expected.

.. toctree::
   :caption: Getting Started
   :hidden:

   getting-started.rst

.. toctree::
   :caption: :octicon:`info` Basic Usage
   :hidden:

   basic-usage/galois-field-classes.rst
   basic-usage/compilation-modes.rst
   basic-usage/field-element-representation.rst
   basic-usage/array-creation.rst
   basic-usage/array-arithmetic.rst
   basic-usage/linear-algebra.rst
   basic-usage/poly-creation.rst
   basic-usage/poly-arithmetic.rst

.. toctree::
   :caption: Tutorials
   :hidden:

renders as

image

HTML
<ul class="md-tabs__list">
    <li class="md-tabs__item">
        <a href="getting-started.html" class="md-tabs__link">
            <span class="md-ellipsis">Getting Started</span>
        </a>
    </li>
    <li class="md-tabs__item">
        <a href="basic-usage/galois-field-classes.html" class="md-tabs__link">
            <span class="md-ellipsis">:<wbr>octicon:<wbr>`info` Basic Usage</span>
        </a>
    </li>
    <li class="md-tabs__item">
        <a href="tutorials/intro-to-prime-fields.html" class="md-tabs__link">
            <span class="md-ellipsis">Tutorials</span>
        </a>
    </li>
    ...
</ul>

Autosummary tables have strange line wrapping

I found that sometimes autosummary tables have very strange line wrapping. Below the functions are wrapped across three lines, even though the second column (function summary) hasn't yet reached the end of the table.

I'm willing to help resolve the issue (to the best of my ability). Can @jbms and/or @2bndy5 point me in the right direction? Is this an HTML decision of when to wrap text in each column?

Source file:

.. rubric:: Polynomial tests
.. autosummary::
   :toctree:

   is_monic
   is_irreducible
   is_primitive
   is_square_free

sphinx-immaterial (https://galois.readthedocs.io/en/latest/api/polys.html):

image

sphinx_rtd_theme (https://galois.readthedocs.io/en/v0.0.24/api/polys.html):

image

No article TOC/index scrolling for Python elements

In my testing environment the Sphinx-Immaterial version of docs for our Python API has an issue with the right-side TOC panel: it doesn't scroll and is locked at approx. 1/3rd of the list of available Python methods. As I can see from the template docs in the Customization section, this index scrolls smoothly, when its elements are derived from headings.
Screenshot

Usability issues with long TOCs

For API documentation you can easily end up with a very long table of contents in the left and/or right side panels.

This results in two usability issues:

  • The left TOC does not start out scrolled to have the current page in view, and the right TOC does not automatically keep the current section in view. That makes it challenging to understand the context of the current page/section. This feature is apparently implemented in the insiders-only version of mkdocs-material (squidfunk/mkdocs-material#2155).
  • When scrolling the left or right TOC, if there are multiple levels of nesting, the ancestors of the current page/section may be scrolled out of view and not visible, which also makes it difficult to understand the context of the current page/section. This could be solved by making the section headers "sticky", so that the headers for each nesting level "collect" at the top of the TOC. An implementation of this is explained here: https://stackoverflow.com/a/55941740

Better readthedocs integration

I've made some mock up edits to better integrate into readthedocs hosted docs. All details can be observed at the issue I raised upstream. Unfortunately, the author has no intention to support RTD. I have 1 more use case to consider before I offer a PR here: when the user disables the nav side menu.

version selector not working

Thank you for your efforts on this beautiful theme.

I've met some trouble utilizing the "version selector" function:

  1. when using the "version info" approach, the dropdown menu would always show the top choice(not current version):

截屏2022-03-28 下午5 53 55

截屏2022-03-28 下午5 54 09

截屏2022-03-28 下午5 59 28

  1. the aliases won't work(return 404 on static site with nginx)

  2. I've also tried the "version_json" approach, which has not effect at all. Tried to put the JSON file on over the place yet won't wokring:

    • same directory with conf.py
    • parent directory of conf.py
    • also as mention in docs:
      /versions.json
      /1.0/index.html
      /2.0/index.html
      
    • and all of above places together.

Can anyone please help me with how to achieve this function?


environment:

sphinx==4.4.0
sphinx-immaterial==0.3.1

Left-side TOC collapsed into right-side TOC

I discovered that the changes in 1373cd7 cause issues with the left-side and right-side TOCs. Here is my repo built with two consecutive commits. The individual pages in a navigation tab TOC are combined into subheading of one page.

Also, FWIW, the page title on the left-side TOC is colored differently...

Here is a chunk of index.rst.

.. toctree::
   :caption: Getting Started
   :hidden:

   getting-started.rst

.. toctree::
   :caption: Basic Usage
   :hidden:

   basic-usage/galois-field-classes.rst
   basic-usage/compilation-modes.rst
   basic-usage/field-element-representation.rst
   basic-usage/array-creation.rst
   basic-usage/array-arithmetic.rst
   basic-usage/linear-algebra.rst
   basic-usage/poly-creation.rst
   basic-usage/poly-arithmetic.rst

.. toctree::
   :caption: Tutorials
   :hidden:

   tutorials/intro-to-prime-fields.rst
   tutorials/intro-to-extension-fields.rst

Built with e928b18

image

Built with 1373cd7

image

Extension error

We have a weird error when we try to build our docs.
In most of our computers it works, in some it doesn't, I can't put my fingers on what is different between them.
Same Sphinx version (4.2.0), same Sphinx-immaterial version (0.2.0), similar Python version (3.7+), same code.

The error is:
Extension error (sphinx_immaterial.object_toc):
Handle <bound method _monkey_patch_toc_tree_process_doc.._patched_process_doc of <sphinx.environment.collectors.toctree.TocTreeCollector object at {id}>> for event 'doctree-read' threw an exception (exception: 'desc' object has no attribute '_traverse')

Thanks :)

`font` instead of `fonts` in docs

Found another bug in the theme docs: in the New blocks section there's a description of a block responsible for substituting the default font. But it should read fonts instead of font – I realised that only after reading the code of the default layout.html file here in the repo:

font instead of fonts

When you use the following font block in the /_template/layout.html file that overrides defaults, nothing happens (the text font is still Roboto):

{# Import the theme's layout. #}
{% extends '!layout.html' %}

{% block font %}
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link
          rel="stylesheet"
          href="https://fonts.googleapis.com/css?family=Lato:300,400,400i,700%7CRoboto+Mono&display=fallback"
        />
        <style>
          :root {
            --md-text-font-family: "Lato";
            --md-code-font-family: "Roboto Mono";
          }
        </style>
{% endblock %}

But this code works when you use {% block fonts %}.

"language" parameter missing in docs, build fails when there's none in conf.py

Hi,
Recently I stumbled upon your project while looking for a Sphinx theme that would make our Python API docs (hosted on RTD) similarly looking to the general docs built in Material for MkDocs. A bit disappointed with the sphinx-material theme, I decided to test yours. Unfortunately, my first build attempts were unsuccessful:

writing output... [ 20%] galaxy.api Theme error: An error happened in rendering the page galaxy.api. Reason: TemplateNotFound('partials/languages/None.html')

I figured out it sth related to the language of the project, but in your docs there's nothing about the need to set the language in the conf.py file, otherwise the builder will fail (I guess it takes the None value and looks for the respective None.html file, which simply doesn't exist). In your conf.py file I found language = "en", put it into my conf.py and it worked like a charm.

You should either update the docs with some info regarding this parameter or implement an exception, which handles unspecified language by defaulting to EN, for instance.

Apart from that, it's a fantastic work! I'm impressed how smoothly you integrated the great Material for MkDocs theme with Sphinx.

Support for task lists

Currently sphinx/rst do not provide a way that generates HTML that takes advantage of mkdocs-material's task lists (configured using a md extension again).

Example HTML output from mkdocs-material docs
<ul class="task-list">
  <li class="task-list-item">
    <label class="task-list-control">
      <input type="checkbox" disabled="" checked="">
      <span class="task-list-indicator"></span>
    </label>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit
  </li>
  <li class="task-list-item">
    <label class="task-list-control">
      <input type="checkbox" disabled="">
      <span class="task-list-indicator"></span>
    </label>
    Vestibulum convallis sit amet nisi a tincidunt
    <ul class="task-list">
      <li class="task-list-item">
        <label class="task-list-control">
          <input type="checkbox" disabled="" checked="">
          <span class="task-list-indicator"></span>
        </label>
        In hac habitasse platea dictumst
      </li>
      <li class="task-list-item">
        <label class="task-list-control">
          <input type="checkbox" disabled="" checked="">
          <span class="task-list-indicator"></span>
        </label>
        In scelerisque nibh non dolor mollis congue sed et metus
      </li>
      <li class="task-list-item">
        <label class="task-list-control">
          <input type="checkbox" disabled="">
          <span class="task-list-indicator"></span>
        </label>
        Praesent sed risus massa
      </li>
    </ul>
  </li>
  <li class="task-list-item">
    <label class="task-list-control">
      <input type="checkbox" disabled="">
      <span class="task-list-indicator"></span>
    </label>
    Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque
    </li>
</ul>

I'm not sure how popular the feature is, but I figured I'd discuss the implementation here before submitting a proposal.

About ideal syntax

I would prefer to be able to use the GitHub-flavored MD style of task lists (as used in upstream). This way users migrating from mkdocs to sphinx would be faced with less friction.

.. md-task-list::
    - [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit
    - [ ] Vestibulum convallis sit amet nisi a tincidunt
        .. md-task-list::
            * [x] In hac habitasse platea dictumst
            * [x] In scelerisque nibh non dolor mollis congue sed et metus
            * [ ] Praesent sed risus massa
    - [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque

There may be nothing stopping the user from implementing this on their own, but the styling from upstream (& thus this theme) is desirable.

About persistence

As noted in the upstream's docs, checkbox states aren't persistent. Although this could easily be done with a little extra JS from the user's end.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.