You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.4 KiB
84 lines
2.4 KiB
# -*- 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. |
|
|
|
""" |
|
from __future__ import division, absolute_import, print_function |
|
|
|
import warnings |
|
import collections |
|
|
|
warnings.warn( |
|
"This extension has been accepted to Sphinx upstream. " |
|
"Use the version from there (Sphinx >= 1.2) " |
|
"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 isinstance(env.config.linkcode_resolve, collections.Callable): |
|
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, "")
|
|
|