Skip to content
Browse files

DOC: generate links to source code

  • Loading branch information...
1 parent 56f66bb commit 39029f56f3851f703eafc77dd83c3d51136c9471 @pv pv committed Mar 11, 2012
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
NumPy member

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.