How do I transcode Python documentation strings to a GitHub readme.md
file?
Even though it seems like something everyone does, I cannot seem to get a decent solution and I am assuming it should be easy, so it seems unlikely folks are going throw two converters…
pydoc Actually simple. The output of pydoc is manpages (groff format for Unix systems). Which is a dead end as man to md is not a thing. Via HTML, pydoc3 -w
+ pandoc, utterly munges the docstrings to bits.
Custom code There seems to be lots of short custom code, but for the few I tried the output does not seem to be as good as that pydoc, which has a summary, adds inherited methods and lists some attributes.
mkdocs. It was suggested somewhere. It just pollutes my folder as it is a misleading name as is a not docstrings > md converter, but a md > html.
Sphinx + Pandoc. After fixing an UTF-8 issue, I gave up on Sphinx as I have a single .py script to convert and the autodoc setting of the quickstart did not parse my script. I tried in Python to import sphinx.ext.autodoc
, but TBH the documentation was too long and I gave up.
There is a year-old unanswered Stack Overflow question on the topic, but I hope that by giving a lot more detail I will get an answer.
The other answers are great. But I thought I (the OP) ought to share what I do these days (a year or two after the question).
I use Sphinx and its Markdown extension. Do the following:
You need sphinx-markdown-builder python module.
pip install sphinx sphinx-markdown-builder;
Not the autodoc
, the apidoc
!
sphinx-apidoc -o Sphinx-docs . sphinx-apidoc --full -A 'Matteo Ferla'; cd Sphinx-docs;
Fix the conf.py
file, by following the following or just lazily copy paste the echo command below.
First uncomment the lines. These are otherwise commented out.
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
Note the change to ../
One weirdness is that the magic methods get ignored. To override this, add this anywhere:
def skip(app, what, name, obj, would_skip, options):
if name in ( '__init__',):
return False
return would_skip
def setup(app):
app.connect('autodoc-skip-member', skip)
A thing to note: The docstrings ought to be written in restructuredtext (RST). If they are in Markdown, you need to add a mod - see this. The two are similar, but different. For example, a single backquote is required for <code> in Markdown, while two are for RST. If in doubt, several blog posts discuss the merits of RST documentation over Markdown.
RST typehints (:type variable: List
) are obsolete as proper typehinting def foo(variable: Optional[List[int]]=None) -> Dict[str,int]:
has been introduced since 3.6. To make these work:
pip install sphinx-autodoc-typehints
And add 'sphinx_autodoc_typehints'
at the end of the extensions
list. Note the package has hyphens while the module has underscores.
Copy paste this:
echo " import os
import sys
sys.path.insert(0,os.path.abspath('../'))
def skip(app, what, name, obj,would_skip, options):
if name in ( '__init__',):
return False
return would_skip
def setup(app):
app.connect('autodoc-skip-member', skip)
extensions.append('sphinx_autodoc_typehints')
" >> conf.py;
Then it is showtime.
make markdown;
Copy the files and clean however you fancy.
mv _build/markdown/* ../; rm -r Sphinx-docs;
It should be noted that when new files are added, the apidoc
command needs to be repeated. Nevertheless, I highly recommend generating documentation midway as I realise I am doing something wrong.