diff --git a/CHANGES.rst b/CHANGES.rst index 0a48d55..b699b6a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -29,6 +29,8 @@ Release History - Added ``one_page`` theme option, which can be set to True for docs that include all content on a single index page. (`#59`_) - Added custom 404 page. (`#65`_) +- Added ``nengo_sphinx_theme.ext.sourcelinks`` extension which allows the autodoc + source links to point to a different site (like GitHub). (`#66`_) **Changed** @@ -47,6 +49,7 @@ Release History .. _#62: https://github.com/nengo/nengo-sphinx-theme/pull/62 .. _#63: https://github.com/nengo/nengo-sphinx-theme/pull/63 .. _#65: https://github.com/nengo/nengo-sphinx-theme/pull/65 +.. _#66: https://github.com/nengo/nengo-sphinx-theme/pull/66 1.2.2 (April 14, 2020) ====================== diff --git a/docs/conf.py b/docs/conf.py index 604c880..fbe47a7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,11 +14,11 @@ "sphinx.ext.intersphinx", "sphinx.ext.mathjax", "sphinx.ext.todo", - "sphinx.ext.viewcode", "nbsphinx", "nengo_sphinx_theme", "nengo_sphinx_theme.ext.backoff", "nengo_sphinx_theme.ext.redirects", + "nengo_sphinx_theme.ext.sourcelinks", "notfound.extension", "numpydoc", "nengo_sphinx_theme.ext.resolvedefaults", @@ -63,6 +63,10 @@ ], } +# -- nengo_sphinx_theme.ext.sourcelinks +sourcelinks_module = "nengo_sphinx_theme" +sourcelinks_url = "https://github.com/nengo/nengo-sphinx-theme" + # -- sphinx nitpicky = True exclude_patterns = [ diff --git a/nengo_sphinx_theme/ext/sourcelinks.py b/nengo_sphinx_theme/ext/sourcelinks.py new file mode 100644 index 0000000..953d083 --- /dev/null +++ b/nengo_sphinx_theme/ext/sourcelinks.py @@ -0,0 +1,80 @@ +""" +This extension replaces the default Sphinx HTML source links with links to some +other site (e.g., GitHub). + +This extension can be enabled by adding ``"nengo_sphinx_theme.ext.sourcelinks"`` +to the ``extensions`` list in ``conf.py``. + +This extension adds two new configuration options, ``sourcelinks_module`` (the +importable name of the package we're setting up) and ``sourcelinks_url`` (the base +URL for the site we want the links to refer to). +""" + +import importlib +import inspect +import os +import sys + + +def set_resolver(_, config): # noqa: C901 + def linkcode_resolve(domain, info): + """Determine the URL corresponding to Python object. + + Code borrowed from: + https://github.com/numpy/numpy/blob/master/doc/source/conf.py + """ + if domain != "py": + return None + + modname = info["module"] + fullname = info["fullname"] + + submod = sys.modules.get(modname) + if submod is None: + return None + + obj = submod + for part in fullname.split("."): + try: + obj = getattr(obj, part) + except AttributeError: + return None + + try: + fn = inspect.getsourcefile(obj) + except TypeError: + fn = None + if not fn: + return None + + try: + source, lineno = inspect.getsourcelines(obj) + linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1) + except IOError: + linespec = "" + + fn = os.path.relpath( + fn, + start=os.path.dirname( + importlib.import_module(config["sourcelinks_module"]).__file__ + ), + ) + + return "%s/blob/%s/%s/%s%s" % ( + config["sourcelinks_url"], + "master" if "dev" in config["release"] else ("v" + config["release"]), + config["sourcelinks_module"], + fn, + linespec, + ) + + config["linkcode_resolve"] = linkcode_resolve + + +def setup(app): + app.setup_extension("sphinx.ext.linkcode") + + app.add_config_value("sourcelinks_module", None, "") + app.add_config_value("sourcelinks_url", None, "") + + app.connect("config-inited", set_resolver)