Skip to content

Instantly share code, notes, and snippets.

@matteoferla
Last active April 3, 2024 12:26
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matteoferla/ba72ab12a9e5f690277e2e88551773aa to your computer and use it in GitHub Desktop.
Save matteoferla/ba72ab12a9e5f690277e2e88551773aa to your computer and use it in GitHub Desktop.
Python codeblock to generate a file called 'autogenerated_docs.md' which has all the docstrings converted to markdown via Sphinx ๐Ÿ๐Ÿ“๐Ÿฆ
# for details see https://stackoverflow.com/questions/36237477/python-docstrings-to-github-readme-md
# further details in https://blog.matteoferla.com/2019/11/convert-python-docstrings-to-github.html
import re
import shutil
import os
import subprocess
# ## Settings
repo_path = '/Users/๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ/๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ'
module_name = '๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ'
author_name = '๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ ๐Ÿ‘พ๐Ÿ‘พ๐Ÿ‘พ'
output_filename = 'autogenerated_docs.md'
# ## Apidoc call
os.system('pip install sphinx sphinx-markdown-builder sphinx-autodoc-typehints')
os.chdir(repo_path)
arguments = ['-o',
'Sphinx-docs',
module_name,
'sphinx-apidoc',
'--full',
'-A',
f"'${author_name}'",
'--module-first',
]
proc = subprocess.run(["sphinx-apidoc", *arguments], capture_output=True)
if proc.stderr:
raise RuntimeError(r.decode())
print(proc.stdout.decode())
# ## tweak configuration
with open('Sphinx-docs/conf.py') as fh:
conf_codeblock = fh.read()
conf_codeblock = conf_codeblock.replace('# import os', 'import os')\
.replace('# import sys', 'import sys\nsys.path.insert(0, os.path.abspath("../"))')
.replace("'sphinx.ext.autodoc',", "'sphinx.ext.autodoc','sphinx_autodoc_typehints',")
conf_codeblock += '''
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)
'''
with open('Sphinx-docs/conf.py', 'w') as fh:
fh.write(conf_codeblock)
# ## Make
os.chdir('Sphinx-docs')
os.system('make markdown')
os.chdir('..')
# ## Consolidate Markdown
folder = 'Sphinx-docs/_build/markdown'
def clean_markdown(markdown):
markdown = re.sub(r'\n+ \* ', '\n * ', markdown)
markdown = re.sub(r'\n+\* ', '\n* ', markdown)
return markdown.replace(' *', '*')\
.replace('>>> ', '')
with open(os.path.join(folder, module_name+'.md')) as fh:
markdown = clean_markdown(fh.read())
for filename in os.listdir(folder):
if filename == module_name+'.md':
continue
if module_name not in filename:
continue
with open(os.path.join(folder, filename)) as fh:
markdown += clean_markdown(fh.read())
with open(output_filename, 'w') as fh:
fh.write(markdown)
# ## Removing Sphynx folder
shutil.rmtree('Sphinx-docs')
@matteoferla
Copy link
Author

This snippet meant for a cell in a Jupyter notebook and will run run Sphinx, tweak the configuration as discussed in this blog post combine the markdown files (with a clean-up) and delete the Sphinx folder.

@hermandr
Copy link

Hi Matteo, Thanks for this work. In line 29 there is r.decode(). I don't think r is defined.

@aaBoustani
Copy link

Hi @hermandr, replacing line 28 (if proc.stderr:) with: if r := proc.stderr: should solve the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment