Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

DOC: generate links to source code

  • Loading branch information...
commit 39029f56f3851f703eafc77dd83c3d51136c9471 1 parent 56f66bb
@pv pv authored
Showing with 143 additions and 0 deletions.
  1. +64 −0 doc/source/conf.py
  2. +79 −0 doc/sphinxext/linkcode.py
View
64 doc/source/conf.py
@@ -286,3 +286,67 @@
if not use_matplotlib_plot_directive:
import matplotlib
matplotlib.rcParams.update(plot_rcparams)
+
+# -----------------------------------------------------------------------------
+# Source code links
+# -----------------------------------------------------------------------------
+
+import inspect
+from os.path import relpath, dirname
+
+for name in ['sphinx.ext.linkcode', 'linkcode', 'numpydoc.linkcode']:
+ try:
+ __import__(name)
+ extensions.append(name)
+ break
+ except ImportError:
+ pass
+else:
+ print "NOTE: linkcode extension not found -- no links to source generated"
+
+def linkcode_resolve(domain, info):
+ """
+ Determine the URL corresponding to Python object
+ """
+ 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:
+ return None
+
+ try:
+ fn = inspect.getsourcefile(obj)
+ except:
+ fn = None
+ if not fn:
+ return None
+
+ try:
+ source, lineno = inspect.findsource(obj)
+ except:
+ lineno = None
+
+ if lineno:
+ linespec = "#L%d" % (lineno + 1)
+ else:
+ linespec = ""
+
+ fn = relpath(fn, start=dirname(numpy.__file__))
+
+ if 'dev' in numpy.__version__:
+ return "http://github.com/numpy/numpy/blob/master/numpy/%s%s" % (
+ fn, linespec)
+ else:
+ return "http://github.com/numpy/numpy/blob/v%s/numpy/%s%s" % (
+ numpy.__version__, fn, linespec)
View
79 doc/sphinxext/linkcode.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+"""
+ linkcode
+ ~~~~~~~~
+
+ Add external links to module code in Python object descriptions.
+
+ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import warnings
+warnings.warn("This extension has been submitted to Sphinx upstream. "
+ "Use the version from there if it is accepted "
+ "https://bitbucket.org/birkenfeld/sphinx/pull-request/47/sphinxextlinkcode",
+ FutureWarning, stacklevel=1)
+
+
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.locale import _
+from sphinx.errors import SphinxError
+
+class LinkcodeError(SphinxError):
+ category = "linkcode error"
+
+def doctree_read(app, doctree):
+ env = app.builder.env
+
+ resolve_target = getattr(env.config, 'linkcode_resolve', None)
+ if not callable(env.config.linkcode_resolve):
+ raise LinkcodeError(
+ "Function `linkcode_resolve` is not given in conf.py")
+
+ domain_keys = dict(
+ py=['module', 'fullname'],
+ c=['names'],
+ cpp=['names'],
+ js=['object', 'fullname'],
+ )
+
+ for objnode in doctree.traverse(addnodes.desc):
+ domain = objnode.get('domain')
+ uris = set()
+ for signode in objnode:
+ if not isinstance(signode, addnodes.desc_signature):
+ continue
+
+ # Convert signode to a specified format
+ info = {}
+ for key in domain_keys.get(domain, []):
+ value = signode.get(key)
+ if not value:
+ value = ''
+ info[key] = value
+ if not info:
+ continue
+
+ # Call user code to resolve the link
+ uri = resolve_target(domain, info)
+ if not uri:
+ # no source
+ continue
+
+ if uri in uris or not uri:
+ # only one link per name, please
+ continue
+ uris.add(uri)
+
+ onlynode = addnodes.only(expr='html')
+ onlynode += nodes.reference('', '', internal=False, refuri=uri)
+ onlynode[0] += nodes.inline('', _('[source]'),
+ classes=['viewcode-link'])
+ signode += onlynode
+
+def setup(app):
+ app.connect('doctree-read', doctree_read)
+ app.add_config_value('linkcode_resolve', None, 'env')

1 comment on commit 39029f5

@rgommers
Owner

Awesome, and already live! Would be good to mention that on the relevant thread.

Please sign in to comment.
Something went wrong with that request. Please try again.