using :ref: in Python docstrings using Sphinx - python

I'm using Sphinx to document a python project, and I'm trying to create a reusable tip to be used in several locations.
Typically, I'll use the following syntax in a python file:
"""
.. tip::
I want this tip to be used in several locations. Why?
- Save time
- Work less
"""
Now this works whether I put it at the beginning of the file, right under class definition or right under function definition.
I found Sphinx's manual for :ref:, which suggests to use a label:
.. _my_reusable_tip:
.. tip::
...
And then call this tip with :ref:`my_reusable_tip` anywhere I want.
The manual states that 'it works across files, when section headings are changed, and for all builders that support cross-references'
The thing is, it doesn't matter in which .py file in the project I write the label and tip definition, the :ref:`my_reusable_tip` just displays 'my_reusable_tip', and not the tip itself.
What I'm using to build the documentation is
sphinx-apidoc -f -F -o
make html
I'm pretty sure my logic is flawed in some way, but I can't figure out why.
I know that Sphinx searches the project for reStructuredText and renders it if it can, but I think I'm missing something here.
I tried to add this label in a seperate .py file enclosed in """, and in a separate .txt file without enclosed """.
I tried creating an .rst file with the label definition and rebuild the html documentation.
What am I missing here?
Python 3.4.3 BTW.

In sphinx, a :ref: is simply a more robust way of linking (or referencing) another part of the document. Thus, your use of :ref: will simply provide a hyperlink to the label.
It is not a way of substituting or expanding a block.
Inline substitutions are available using using |...|, however an inline substitution cannot be used to substitute a block as you seem to require.
RestructuredText is not a template language, and thus doesn't provide macro like facilities. In the event you need it, an alternative solution is to use a template library such as mako or jinja to deal with this kind of issue.

Just using reStructuredText directive
.. include:: ./my_reusable_tip.txt
in your rst files?

Related

Is there an equivalent to Latex's \endinput in Python-Sphinx

LateX and Python-Sphinx are word-processors, transforming formatted content towards a target document. The usual workflow when working with large documents is to split them in smaller files (sections, chapters) and use a specific file as a table of contents (main.tex in most Latex projects, index.rst in Sphinx).
In Latex, it is possible to stop the processing of a specific file by using a \endinput command (then, the processor will move on to the next section or chapter).
I cannot find such a directive in Python-Sphinx's documentation. Does it exists? If not, is there a way to implement this behavior?
None that I know of. But you can do the inverse by including what you want, which would have the same effect as excluding what you don't want, by using the ifconfig Sphinx extension. You might have to indent what you want.

How to pre-process source files while a Sphinx run?

I have set up a Sphinx documentation for my project and would like to extract doc strings for the source files and embed them into the final documentation. Unfortunately, the source file's language (VHDL) is not supported by Sphinx. There seems to be no Sphinx domain for VHDL.
So my ideas is as follows:
Hook into the Sphinx run and execute some Python code before Sphinx
The Python codes extracts text blocks from each source file (the top-most multi-line comment block) and assembles one reST file per source file, consisting of this comment block and some other reST markup.
All source files are listed in an index.rst, to generate the apropriate .. toctree:: directive.
The text extraction and transformation is done recursively per source code directory.
So the main question is: How to hook into Spinx?
Or should I just import and run my own configuration in conf.py?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
from my_preprocessor import my_proc
proc = my_proc()
proc.run()
#
# Test documentation build configuration file, created by
# sphinx-quickstart on Tue May 24 11:28:20 2016.
# ....
I can't modify the build process files: Makefile and make.bat, because the real build process runs on ReadTheDocs.org. RTDs only executes conf.py.
As noted in my previous comments and mertyildiran's answer, the official way to hook into Sphinx for a language would be to create an extension to implement a new domain for VHDL.
This has already been done for many other languages - e.g. Erlang, PHP, CoffeeScript - and APIs - e.g. HTTP REST - just to name a few from sphinx-contrib. However, that is going to take a lot of time, which you don't have... You are therefore left with an option to do some quick parsing yourself and then hooking that into your Sphinx build somehow.
Since you are bypassing the official hooks, this question becomes "how do I run my own code inside a Sphinx build?" For which, I would recommend that you simply follow the guidance for a local extension - i.e. put it in a separate directory, add that to your path, then import and invoke it. As noted in the docs:
The configuration file is executed as Python code at build time (using execfile(), and with the current directory set to its containing directory), and therefore can execute arbitrarily complex code. Sphinx then reads simple names from the file’s namespace as its configuration.
As a final though, this opens up the options to use 3rd party packages like pyVhdl2Sch (with a nod again to mertyildiran's answer) to create some schematic and then maybe write your static rst files around it to explain the schematic.
You are trying to use a sledgehammer to crack a nut.
Sphinx was originally created for the new Python documentation, and it has
excellent facilities for the documentation of Python projects, but
C/C++ is already supported as well, and it is planned to add special
support for other languages as well.
http://www.sphinx-doc.org/en/stable/
VHDL is currently not a supported language by Sphinx and because VHDL is a hardware description language its priority for becoming a supported language must be low. You have two options and first one is also my suggestion to you:
1) Use a VHDL specific documentation generator tool instead of Sphinx
VHDocL -
http://www.volkerschatz.com/hardware/vhdocl.html
A VHDL documentation utility written in Perl, based on Doxygen.
pyVhdl2Sch - http://laurentcabaret.github.io/pyVhdl2Sch/
pyVhdl2Sch is a documentation generator tool. It takes VHDL files (.vhd) as entry and generates a pdf/svg/ps/png schematic for each input file. Written in pure Python, more community friendly, more up to date.
Sigasi Studio XL Doc - http://www.sigasi.com/products/
High end edition of Sigasi Studio which is a commercial product.
2) Contribute to Sphinx project and add VHDL domain
Follow Sphinx Developer's Guide and become familiar with the project structure. Eventually add vhdl.py to this project directory: https://github.com/sphinx-doc/sphinx/tree/master/sphinx/domains
This second option cannot be explained with a StackOverflow answer. It's up to you if you want to add more functionality to an open source project like Sphinx.

Documenting parameters with long descriptions in Sphinx

I'm documenting my Python classes using Sphinx, and sometimes I want to give my parameters quite long descriptions to explain something in details. Unfortunately, Sphinx generates ugly output for me which wastes a lot of space and breaks the whole page appearance:
It can be seen that Sphinx creates a table, then puts "Parameters" header to the left cell, and the actual list of parameters to the right cell. But there should be way to avoid creating this table completely. After playing with the page DOM tree I finally can show that I want to achieve:
Is there a built-in way to do this or I'd have to create a PR to Sphinx theme or Sphinx itself?
After posting an issue to Sphinx bug-tracker and having no response, I've decided to roll-out my own solution (better say, hack). To achieve the look I want, I have written a simple Sphinx extension which post-processes generated HTML code. It can be found on PyPI:
https://pypi.python.org/pypi/sphinxcontrib.divparams
https://pythonhosted.org/sphinxcontrib.divparams/
This doesn't seem to be the best way to solve the issue, but the behaviour I wanted to change is deeply hard-coded in docutils, not Sphinx.

Sphinx includes 'code' library descriptions where it's not supposed to

I'm working on a documentation of an Python wrapper around a PyObjC application with Sphinx.
Sphinx adds a confusing and unwanted library description of the library code to this class's property description that happens to be code (please see screenshot, second last line).
How to get rid of it? I looked into conf.py, but couldn't find anything.
Also, I learned, autodoc adds more docstring stuff, but I never asked for it and and can't find whether this is what's even happening and how to turn it off.
The corresponding sphinx code is simply this:
Properties
.. autosummary::
name
code
automatic

How to avoid the "too deeply nested" error when creating PDFs with Sphinx?

I have a fairly complex project with a fairly large documentation.
Converting the normal user guide to PDF with Sphinx via make latexpdf works quite well. However, if I also want to include the library reference with all function, class, and module documentations, the command fails with:
! LaTeX Error: Too deeply nested.
Manually reducing the nesting is not an option. Sphinx internally nests parameter descriptions, function descriptions, module descriptions and whatnot. So figuring out in each case how to reduce the nesting is almost impossible.
I solved the problem by adding some latex statements to the sphinx preamble.
Accordingly, I created a new latex_preamble.tex file in my sphinx source folder. It contains only the following two commands:
\usepackage{enumitem}
\setlistdepth{99}
Moreover, In the conf.py file, also within my source folder, I changed the following (you can lookout for the latex_elements variable in the conf.py file, it is usually commented out):
fh = open('latex_preamble.tex', 'r+')
PREAMBLE = fh.read()
fh.close()
latex_elements = {
# Additional stuff for the LaTeX preamble.
'preamble': PREAMBLE,
}
Hence, now sphinx uses the enumitem package that allows arbitrary nesting. I guess nowadays enumitem should be part of any latex distribution. I did not need to install the package. Moreover, this also worked out of the box on read the docs.

Categories

Resources