summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-07-13 18:27:34 +0200
committerGeorg Brandl <georg@python.org>2009-07-13 18:27:34 +0200
commitdb8395f9e18cfc1f620d7c86befa98cae91079ba (patch)
treec4e12cbdf6cc25ad26f0fdf875230772ebb619eb
parentd4f957da8c436347c4fbb740db73a73dbddf2324 (diff)
downloadsphinx-git-db8395f9e18cfc1f620d7c86befa98cae91079ba.tar.gz
Add make_refnode() utility function.
-rw-r--r--sphinx/domains.py69
-rw-r--r--sphinx/environment.py43
-rw-r--r--sphinx/util/__init__.py15
3 files changed, 58 insertions, 69 deletions
diff --git a/sphinx/domains.py b/sphinx/domains.py
index fdf5a9d7c..f3389da1a 100644
--- a/sphinx/domains.py
+++ b/sphinx/domains.py
@@ -15,6 +15,7 @@ import re
from sphinx import addnodes
from sphinx.roles import XRefRole
from sphinx.directives import DescDirective
+from sphinx.util import make_refnode
class Domain(object):
@@ -50,7 +51,7 @@ class Domain(object):
inliner, options, content)
self._role_cache[name] = role_adapter
return role_adapter
-
+
def directive(self, name):
"""
Return a directive adapter class that always gives the registered
@@ -384,8 +385,10 @@ class PythonDomain(Domain):
}
def find_desc(self, env, modname, classname, name, type, searchorder=0):
- """Find a description node matching "name", perhaps using
- the given module and/or classname."""
+ """
+ Find a Python object description for "name", perhaps using the given
+ module and/or classname.
+ """
# skip parens
if name[-2:] == '()':
name = name[:-2]
@@ -393,14 +396,6 @@ class PythonDomain(Domain):
if not name:
return None, None
- # don't add module and class names for C things
- if type[0] == 'c' and type not in ('class', 'const'):
- # skip trailing star and whitespace
- name = name.rstrip(' *')
- if name in env.descrefs and env.descrefs[name][1][0] == 'c':
- return name, env.descrefs[name]
- return None, None
-
newname = None
if searchorder == 1:
if modname and classname and \
@@ -432,28 +427,22 @@ class PythonDomain(Domain):
def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
-
- if typ == 'mod' or \
- typ == 'obj' and target in env.modules:
+ if (typ == 'mod' or
+ typ == 'obj' and target in env.modules):
docname, synopsis, platform, deprecated = \
env.modules.get(target, ('','','', ''))
if not docname:
- newnode = builder.app.emit_firstresult(
- 'missing-reference', env, node, contnode)
- if not newnode:
- newnode = contnode
+ return None
elif docname == fromdocname:
# don't link to self
- newnode = contnode
+ return contnode
else:
- newnode = nodes.reference('', '')
- newnode['refuri'] = builder.get_relative_uri(
- fromdocname, docname) + '#module-' + target
- newnode['reftitle'] = '%s%s%s' % (
- (platform and '(%s) ' % platform),
- synopsis, (deprecated and ' (deprecated)' or ''))
- newnode.append(contnode)
- elif typ in env.descroles:
+ title = '%s%s%s' % ((platform and '(%s) ' % platform),
+ synopsis,
+ (deprecated and ' (deprecated)' or ''))
+ return make_refnode(builder, fromdocname, docname,
+ 'module-' + target, contnode, title)
+ else:
# "descrefs"
modname = node['modname']
clsname = node['classname']
@@ -461,20 +450,10 @@ class PythonDomain(Domain):
name, desc = self.find_desc(env, modname, clsname,
target, typ, searchorder)
if not desc:
- newnode = builder.app.emit_firstresult(
- 'missing-reference', env, node, contnode)
- if not newnode:
- newnode = contnode
+ return None
else:
- newnode = nodes.reference('', '')
- if desc[0] == fromdocname:
- newnode['refid'] = name
- else:
- newnode['refuri'] = (
- builder.get_relative_uri(fromdocname, desc[0])
- + '#' + name)
- newnode['reftitle'] = name
- newnode.append(contnode)
+ return make_refnode(builder, fromdocname, desc[0], name,
+ contnode, name)
@@ -620,6 +599,16 @@ class CDomain(Domain):
'type': XRefRole(),
}
+ def resolve_xref(self, env, fromdocname, builder,
+ typ, target, node, contnode):
+ # strip pointer asterisk
+ target = target.rstrip(' *')
+ # XXX descrefs
+ if target not in env.descrefs:
+ return None
+ desc = env.descrefs[target]
+ return make_refnode(builder, fromdocname, desc[0], contnode, target)
+
# this contains all registered domains
all_domains = {
diff --git a/sphinx/environment.py b/sphinx/environment.py
index 80bc77535..a5bf49ebb 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -43,7 +43,7 @@ from docutils.transforms.parts import ContentsFilter
from sphinx import addnodes
from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
- docname_join, FilenameUniqDict, url_re
+ docname_join, FilenameUniqDict, url_re, make_refnode
from sphinx.errors import SphinxError
from sphinx.directives import additional_xref_types
@@ -1199,10 +1199,6 @@ class BuildEnvironment:
docname, refnode['refuri']) + refnode['anchorname']
return newnode
- descroles = frozenset(('data', 'exc', 'func', 'class', 'const',
- 'attr', 'obj', 'meth', 'cfunc', 'cmember',
- 'cdata', 'ctype', 'cmacro'))
-
def resolve_references(self, doctree, fromdocname, builder):
# XXX remove this
reftarget_roles = set(('token', 'term', 'citation'))
@@ -1218,7 +1214,7 @@ class BuildEnvironment:
try:
if node.has_key('refdomain'):
- # let the domain resolve the reference
+ # let the domain try to resolve the reference
try:
domain = builder.app.domains[node['refdomain']]
except KeyError:
@@ -1290,13 +1286,8 @@ class BuildEnvironment:
#self.warn(fromdocname, 'unknown keyword: %s' % target)
newnode = contnode
else:
- newnode = nodes.reference('', '')
- if docname == fromdocname:
- newnode['refid'] = labelid
- else:
- newnode['refuri'] = builder.get_relative_uri(
- fromdocname, docname) + '#' + labelid
- newnode.append(contnode)
+ newnode = make_refnode(builder, fromdocname, docname,
+ labelid, contnode)
elif typ == 'option':
progname = node['refprogram']
docname, labelid = self.progoptions.get((progname, target),
@@ -1304,13 +1295,8 @@ class BuildEnvironment:
if not docname:
newnode = contnode
else:
- newnode = nodes.reference('', '')
- if docname == fromdocname:
- newnode['refid'] = labelid
- else:
- newnode['refuri'] = builder.get_relative_uri(
- fromdocname, docname) + '#' + labelid
- newnode.append(contnode)
+ newnode = make_refnode(builder, fromdocname, docname,
+ labelid, contnode)
elif typ in reftarget_roles:
docname, labelid = self.reftargets.get((typ, target),
('', ''))
@@ -1325,20 +1311,19 @@ class BuildEnvironment:
node.line)
newnode = contnode
else:
- newnode = nodes.reference('', '')
- if docname == fromdocname:
- newnode['refid'] = labelid
- else:
- newnode['refuri'] = builder.get_relative_uri(
- fromdocname, docname, typ) + '#' + labelid
- newnode.append(contnode)
+ newnode = make_refnode(builder, fromdocname, docname,
+ labelid, contnode)
else:
raise RuntimeError('unknown xfileref node encountered: %s'
% node)
+
+ # no new node found? try the missing-reference event
+ if newnode is None:
+ newnode = builder.app.emit_firstresult(
+ 'missing-reference', env, node, contnode)
except NoUri:
newnode = contnode
- if newnode:
- node.replace_self(newnode)
+ node.replace_self(newnode or contnode)
for node in doctree.traverse(addnodes.only):
try:
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 3465403df..2d59edfcd 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -435,6 +435,21 @@ def split_explicit_title(text):
else:
return False, text, text
+
+def make_refnode(builder, fromdocname, todocname, targetid, child, title=None):
+ """Shortcut to create a reference node."""
+ node = nodes.reference('', '')
+ if fromdocname == todocname:
+ node['refid'] = targetid
+ else:
+ node['refuri'] = (builder.get_relative_uri(fromdocname, todocname)
+ + '#' + targetid)
+ if title:
+ node['reftitle'] = title
+ node.append(child)
+ return node
+
+
# monkey-patch Node.traverse to get more speed
# traverse() is called so many times during a build that it saves
# on average 20-25% overall build time!