How can the mathjax physics package be used in a sphinx documentation? - python-sphinx

The following section in sphinx
.. math::
\vb{R} = \vb{T} \vb{U}^{-1} = \vb{V}^{-1} \vb{T}
is rendered as
What I actually want is this:
But right now this is only possible if I write
.. math::
\mathbf{R} = \mathbf{T} \mathbf{U}^{-1} = \mathbf{V}^{-1} \mathbf{T}
or by including the \require{physics} tag in the ..math block, which is not ideal since this is also part of a docstring that is being documented with sphinx autodoc.
I have already tried to adopt the solution from this thread by adding
mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-chtml.js"
to my conf.py file, but it did not work. How can I properly display desired latex code on my website?

Adding
mathjax3_config = {
'loader': {'load': ['[tex]/physics']},
'tex': {'packages': {'[+]': ['physics']}},
}
to the conf.py resolves the issue by instructing MathJax to load the physics package.

Related

Bullet list style for single parameter functions in RTD theme using autodoc and Sphinx?

I've noticed that when I use autodoc with the ReadTheDoc theme, if I have multiple arguments in my functions they are listed in a bullet list style:
arg1
arg2
...
but if there is only 1 argument then it is not using the bullet list style which is a bit silly to me since it breaks the continuity of the design.
I've found how to remove the disc via CSS to make things more uniform but I actually want to do the opposite and have the disk for the single argument functions.
At this point, I'm not sure it is a CSS change and I do not know how to do that.
I've also noticed the same thing in different docs.
Here is the rendered html:
Here are the 2 methods:
def add_attribute(self, name, index):
"""
:param name: The name attached to the attribute.
:param index: The position of the attribute within the list of attributes. """
print("")
def delete_attribute(self, name):
"""
:param name: The name of the attribute to delete."""
print("")
Here is the my .rst:
API
----------------
.. automodule:: my_module
:members:
Here is the conf.py
extensions = [
'sphinx_rtd_theme',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.coverage',
'sphinx.ext.autosummary',
]
templates_path = ['_templates']
language = 'python'
exclude_patterns = []
html_theme = "sphinx_rtd_theme"
html_static_path = ['_static']
autosummary_generate = True
Any idea?
Cheers!
After a lot of digging, I've found a partial workaround for this.
My solution involves manually editing the produced HTML files to insert the missing bullet points.
Required conf.py changes:
# Register hook to run when build is complete
def setup(app):
app.connect('build-finished', on_build_finished)
# Hook implementation
def on_build_finished(app, exception):
add_single_param_bullets("_build/html/index.html")
# Function to actually add the bullet points by overwriting the given HTML file
def add_single_param_bullets(file_path):
print('Add single parameter bullets in {:s}'.format(file_path))
if not os.path.exists(file_path):
print(' File not found, skipping...')
return
lines_enc = []
with open(file_path, 'rb') as f:
for l in f.readlines():
# Check for html that indicates single parameter function
if b'<dd class="field-odd"><p><strong>' in l:
# Work out the encoding if not defined
enc = None
if enc is None:
import chardet
enc = chardet.detect(l)['encoding']
# Decode html and get the parameter information that needs adding
l_dec = l.decode(enc)
l_insert = l_dec.replace('<dd class="field-odd">', '').replace('\r\n', '')
# Add new encoded lines to output
lines_enc.append('<dd class="field-odd"><ul class="simple">'.encode('utf=8'))
lines_enc.append('<li>{:s}</li>'.format(l_insert).encode(enc))
lines_enc.append('</ul>'.encode('utf=8'))
else:
lines_enc.append(l)
# Overwrite the original file with the new changes
with open(file_path, 'wb') as f:
for l in lines_enc:
f.write(l)
In my case, I only have single argument functions in index.html. However, you can register additional files in on_build_finished.
A few things to note:
This only edits the produced HTML files, and doesn't actually solve the underlying problem. I dug through the source for a bit but couldn't find why the bullet points aren't added for single parameter function.
The problem is not just for the RTD theme. It seems to occur with the basic theme as well. So I suspect it's a deeper problem with Sphinx rather than the RTD theme.
The code above somewhat deals with different encodings in the original HTML.
This does not work on the RTD website. As the HTML files are edited in place, and the RTD build outputs the HTML files to a different directory, this solution doesn't seem to work on the RTD website. This is quite annoying. A solution would be to somehow change the RTD build process, or tell RTD to use pre-built HTML sources rather than building its own, but I don't know how to do so.
After spending a few hours working all this out, I actually think it looks better without the bullet points...

Sphinx nit-picky mode but only for links I explicitly wrote

I tried turning on Sphinx's nit-picky mode (-n) to catch any broken links I might have accidentally made. However, it spews out errors for all the places where I've documented types. In some cases I've described types semantically (e.g. "3D array"), but it does it even for types extracted from type hints (even with intersphinx set up to pull Python types). For example, for this module
from typing import Callable
def foo(x: Callable[..., int]):
pass
I get the error docstring of myproj.foo:: WARNING: py:class reference target not found: Callable[..., int]. That's with only sphinx.ext.autodoc and sphinx.ext.intersphinx extensions and a freshly-generated conf.py.
Is there some way to prevent Sphinx from trying to generate links for type information, or at least stop it complaining when they don't exist while still telling me about bad links in my hand-written documentation?
I'm using Sphinx 3.0.3.
Perhaps nitpick_ignore will do what you want? In your conf.py, something like this:
nitpick_ignore = [
("py:class", "Callable"),
]
I'm not sure of the exact values in the tuple that should be used, but I got the idea from this issue and a linked commit.
I had success solving a similar problem by writing a custom sphinx transform. I only wanted warnings for cross-references to my own package's python documentation. The following can be saved as a python file and added to extensions in conf.py once it is on the python path.
from sphinx import addnodes
from sphinx.errors import NoUri
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util import logging
logger = logging.getLogger(__name__)
class MyLinkWarner(SphinxPostTransform):
"""
Warns about broken cross-reference links, but only for my_package_name.
This is very similar to the sphinx option ``nitpicky=True`` (see
:py:class:`sphinx.transforms.post_transforms.ReferencesResolver`), but there
is no way to restrict that option to a specific package.
"""
# this transform needs to happen before ReferencesResolver
default_priority = 5
def run(self):
for node in self.document.traverse(addnodes.pending_xref):
target = node["reftarget"]
if target.startswith("my_package_name."):
found_ref = False
with suppress(NoUri, KeyError):
# let the domain try to resolve the reference
found_ref = self.env.domains[node["refdomain"]].resolve_xref(
self.env,
node.get("refdoc", self.env.docname),
self.app.builder,
node["reftype"],
target,
node,
nodes.TextElement("", ""),
)
# warn if resolve_xref did not return or raised
if not found_ref:
logger.warning(
f"API link {target} is broken.", location=node, type="ref"
)
def setup(app):
app.add_post_transform(MyLinkWarner)

How to embed markdown documentation inside a working code with C type syntax for commenting?

Basically I want to write one piece of text which qualifies both as a working code and MarkDown (preferably GitHub flavor) for documentation. The language I'm using has C form commenting \\ for rest-of-line and /* ... */ for multi line comments. So far what I can do is:
/* --> start with multi line comments
here some markdown text
# heading
* list
end markdown section with
<!--- */ // -->
or
[//]: # (end of comment block --> */ // <-- inline comment)
_-_-indented code
_-_-_-_-more indented code
The issues are:
the first /* still showing in the documentation
I can't use the proper multiline code block ``` ... ```. I have to indent the code parts once more than what is required. Also the syntax highlighting doen't work in this format AFIK.
I would appreciate if you could help me know first how to solve above issues. and Secondly if there is any better way to do this?
I think I have a proper solution now with colapsible / foldable code section:
/*
This is the markdown **text**
used for documentation
<details>
<summary>Click to see the source code</summary>
``` scilab
*/
This is the
actual code
which will
be executed
/*
```
</details>
<!--- */ // -->
which will be rendered as:
/*
This is the markdown text
used for documentation
*/
This is the
actual code
which will
be executed
/*
The collapsible section makes sure that the documentation is clean and readable. you may see the final result here on GitHub. I used the code from here. Now there are a bunch of /*s and */s which would be nice to get ride of. Next step would be to modularize the MarkDown document into different files as I have asked here.
P.S. Implementation of the same idea using AsciiDoc here.

How to add link to source code in Sphinx

class torch.FloatStorage[source]
byte()
Casts this storage to byte type
char()
Casts this storage to char type
Im trying to get some documentation done, i have managed to to get the format like the one shown above, But im not sure how to give that link of source code which is at the end of that function!
The link takes the person to the file which contains the code,But im not sure how to do it,
This is achieved thanks to one of the builtin sphinx extension.
The one you are looking for in spinx.ext.viewcode. To enable it, add the string 'sphinx.ext.viewcode' to the list extensions in your conf.py file.
In summary, you should see something like that in conf.py
extensions = [
# other extensions that you might already use
# ...
'sphinx.ext.viewcode',
]
I'd recommend looking at the linkcode extension too. Allows you to build a full HTTP link to the code on GitHub or such like. This is sometimes a better option that including the code within the documentation itself. (E.g. may have stronger permission on it than the docs themselves.)
You write a little helper function in your conf.py file, and it does the rest.
What I really like about linkcode is that it creates links for enums, enum values, and data elements, which I could not get to be linked with viewcode.
I extended the link building code to use #:~:text= to cause the linked-to page to scroll to the text. Not perfect, as it will only scroll to the first instance, which may not always be correct, but likely 80~90% of the time it will be.
from urllib.parse import quote
def linkcode_resolve(domain, info):
# print(f"domain={domain}, info={info}")
if domain != 'py':
return None
if not info['module']:
return None
filename = quote(info['module'].replace('.', '/'))
if not filename.startswith("tests"):
filename = "src/" + filename
if "fullname" in info:
anchor = info["fullname"]
anchor = "#:~:text=" + quote(anchor.split(".")[-1])
else:
anchor = ""
# github
result = "https://<github>/<user>/<repo>/blob/master/%s.py%s" % (filename, anchor)
# print(result)
return result

Extending sphinx.ext.graphviz with additional extension

I would like to extend the built-in sphinx-doc extension sphinx.ext.graphviz with a few featues. As the features are very special for my use case i do not want to extend sphinx.ext.graphviz itself.
Essentially i just want to (graphviz sources for reference)
parse with graphviz to get the graphviz nodes (~ Graphviz.run()),
modify the graphviz dotcode of the nodes (~ node['code'] = dotcode),
output/render (html/pdf) with graphviz without modification (~ e.g. for
html: html_visit_graphviz() -> render_dot_html()).
I have read the sphinx-doc extension developer guide but do not fully
understand the build phases/procedure and how to "combine" extensions like described above.
Is it possible to modifiy the inlined graphviz code between "Build Phase
1: Reading" and "Build Phase 3: Resolving" somehow using an additional
sphinx extension which "invokes" sphinx.ext.graphviz?
The solution provided by a sphinx-doc contributor [https://github.com/sphinx-doc/sphinx/issues/2246]:
Maybe you can do it with following code:
def on_doctree_read(app, doctree):
for node in doctree.traverse(graphviz):
code = re.sub('\];', ', color = red];', node['code']) # change color of nodes and edges
node['code'] = code
def setup(app):
app.connect('doctree-read', on_doctree_read)
In this example, I used the doctree-read event. It is raised at Reading phase. In more detail, you can see what is "Sphinx core events" at http://www.sphinx-doc.org/en/stable/extdev/appapi.html#sphinx-core-events

Resources