"""fluiddocset utility: Generate docsets compatible with Zeal and Dash
======================================================================
Docset is an easy to use offline documentation format. Different applications
such as Zeal (Linux, Windows) and Dash (Mac OS) are available to load such
docsets. Read more about generating docsets `here
<https://kapeli.com/docsets#python>`_.
.. autofunction:: check_sphinx_build
.. autofunction:: doc_to_docsets
"""
import argparse
import os
import shutil
import sys
from importlib import resources
from shlex import split
from subprocess import call
from fluiddyn.io import Path
try:
from doc2dash.__main__ import main as doc2dash
except ModuleNotFoundError:
doc2dash = False
try:
from click.testing import CliRunner
except ModuleNotFoundError:
print("Install click to use this tool.")
[docs]
def check_sphinx_build(pkg_name, verbose, theme, regenerate=True):
"""Check if Sphinx docs has been built. Return path to generated html.
Parameters
----------
pkg_name : str
Name of a FluidDyn package.
Returns
-------
str, str
"""
path_package = Path(resources.files(pkg_name))
path_root = path_package.parent
if path_root.name == "src":
path_root = path_root.parent
doc_src = path_root / "doc"
doc_build = doc_src / "_build" / "html"
if not doc_build.exists() or regenerate:
print("Generating Sphinx documentation ...")
os.chdir(doc_src)
cmd = (
"sphinx-build -b html -d _build/doctrees "
f"-D html_theme={theme} "
"-D html_theme_options.nosidebar=True "
". _build/html"
)
print(cmd)
cmd = split(cmd)
# FIXME: with stdout_redirected(not verbose):
call(cmd)
return doc_src, doc_build
[docs]
def doc_to_docsets(pkg_name, verbose, archive, theme):
"""Convert Sphinx docs to docsets and install them.
Parameters
----------
pkg_name : str
Name of the Python package.
verbose : bool
Verbose output messages.
archive : bool
To make an archive or install locally.
"""
if not doc2dash:
print(
"Cannot produce docsets: first install "
"https://github.com/hynek/doc2dash to use this tool."
)
sys.exit(1)
if archive:
doc_dest = os.getcwd()
else:
doc_dest = os.path.expanduser("~/.local/share/Zeal/Zeal/docsets")
os.makedirs(doc_dest, exist_ok=True)
doc_src, doc_build = check_sphinx_build(pkg_name, verbose, theme)
docset_name = pkg_name.title()
runner = CliRunner()
cmd = "doc2dash -n {} -d {} -f -v -u https://{}.readthedocs.io ".format(
docset_name, doc_dest, pkg_name
)
path_icon = doc_src / "icon.png"
if path_icon.exists():
cmd += f"-i {path_icon} "
cmd += str(doc_build)
print(cmd)
cmd = split(cmd)
# FIXME: with stdout_redirected(not verbose):
result = runner.invoke(doc2dash, args=cmd[1:])
if archive:
doc_archive = os.path.abspath(os.path.join(doc_dest, docset_name))
doc_format = ("gztar", ".tar.gz")
doc_dest = os.path.join(doc_dest, docset_name + ".docset")
# Make tarball and remove directory generated by doc2dash
shutil.make_archive(doc_archive, doc_format[0], doc_dest)
shutil.rmtree(doc_dest)
doc_dest = doc_archive + doc_format[1]
else:
doc_dest = os.path.join(doc_dest, docset_name + ".docset")
if verbose:
print(result.output)
print("Docset generated at", doc_dest)
def main():
"""Parse arguments and execute."""
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("package", help="Name of a FluidDyn package", type=str)
parser.add_argument(
"-a",
"--archive",
help="Do not install to home directory, only create a zip file.",
action="store_true",
)
parser.add_argument(
"-t",
"--theme",
help="a builtin or installed sphinx theme",
default="classic",
)
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()
doc_to_docsets(args.package, args.verbose, args.archive, args.theme)
if __name__ == "__main__":
main()