mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #3372 from tk0miya/move_docref_to_stddomain
Refactor: Move doc reference to under standard domain
This commit is contained in:
commit
ecdcb4c123
@ -23,7 +23,7 @@ from sphinx.roles import XRefRole
|
||||
from sphinx.locale import l_, _
|
||||
from sphinx.domains import Domain, ObjType
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.util import ws_re, logging
|
||||
from sphinx.util import ws_re, logging, docname_join
|
||||
from sphinx.util.nodes import clean_astext, make_refnode
|
||||
|
||||
if False:
|
||||
@ -465,6 +465,7 @@ class StandardDomain(Domain):
|
||||
searchprio=-1),
|
||||
'envvar': ObjType(l_('environment variable'), 'envvar'),
|
||||
'cmdoption': ObjType(l_('program option'), 'option'),
|
||||
'doc': ObjType(l_('document'), 'doc', searchprio=-1)
|
||||
} # type: Dict[unicode, ObjType]
|
||||
|
||||
directives = {
|
||||
@ -491,6 +492,8 @@ class StandardDomain(Domain):
|
||||
warn_dangling=True),
|
||||
# links to labels, without a different title
|
||||
'keyword': XRefRole(warn_dangling=True),
|
||||
# links to documents
|
||||
'doc': XRefRole(warn_dangling=True, innernodeclass=nodes.inline),
|
||||
} # type: Dict[unicode, Union[RoleFunction, XRefRole]]
|
||||
|
||||
initial_data = {
|
||||
@ -515,6 +518,7 @@ class StandardDomain(Domain):
|
||||
'the label must precede a section header)',
|
||||
'numref': 'undefined label: %(target)s',
|
||||
'keyword': 'unknown keyword: %(target)s',
|
||||
'doc': 'unknown document: %(target)s',
|
||||
'option': 'unknown option: %(target)s',
|
||||
'citation': 'citation not found: %(target)s',
|
||||
}
|
||||
@ -650,6 +654,8 @@ class StandardDomain(Domain):
|
||||
resolver = self._resolve_numref_xref
|
||||
elif typ == 'keyword':
|
||||
resolver = self._resolve_keyword_xref
|
||||
elif typ == 'doc':
|
||||
resolver = self._resolve_doc_xref
|
||||
elif typ == 'option':
|
||||
resolver = self._resolve_option_xref
|
||||
elif typ == 'citation':
|
||||
@ -747,6 +753,22 @@ class StandardDomain(Domain):
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
labelid, contnode)
|
||||
|
||||
def _resolve_doc_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA
|
||||
# directly reference to document by source name; can be absolute or relative
|
||||
refdoc = node.get('refdoc', fromdocname)
|
||||
docname = docname_join(refdoc, node['reftarget'])
|
||||
if docname not in env.all_docs:
|
||||
return None
|
||||
else:
|
||||
if node['refexplicit']:
|
||||
# reference with explicit title
|
||||
caption = node.astext()
|
||||
else:
|
||||
caption = clean_astext(env.titles[docname])
|
||||
innernode = nodes.inline(caption, caption, classes=['doc'])
|
||||
return make_refnode(builder, fromdocname, docname, None, innernode)
|
||||
|
||||
def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||
# type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA
|
||||
progname = node.get('std:program')
|
||||
|
@ -34,9 +34,8 @@ from docutils.frontend import OptionParser
|
||||
from sphinx import addnodes
|
||||
from sphinx.io import SphinxStandaloneReader, SphinxDummyWriter, SphinxFileInput
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import get_matching_docs, docname_join, FilenameUniqDict, status_iterator
|
||||
from sphinx.util.nodes import clean_astext, WarningStream, is_translatable, \
|
||||
process_only_nodes
|
||||
from sphinx.util import get_matching_docs, FilenameUniqDict, status_iterator
|
||||
from sphinx.util.nodes import WarningStream, is_translatable, process_only_nodes
|
||||
from sphinx.util.osutil import SEP, ensuredir
|
||||
from sphinx.util.i18n import find_catalog_files
|
||||
from sphinx.util.console import bold # type: ignore
|
||||
@ -923,8 +922,6 @@ class BuildEnvironment(object):
|
||||
# really hardwired reference types
|
||||
elif typ == 'any':
|
||||
newnode = self._resolve_any_reference(builder, refdoc, node, contnode)
|
||||
elif typ == 'doc':
|
||||
newnode = self._resolve_doc_reference(builder, refdoc, node, contnode)
|
||||
# no new node found? try the missing-reference event
|
||||
if newnode is None:
|
||||
newnode = builder.app.emit_firstresult(
|
||||
@ -960,8 +957,6 @@ class BuildEnvironment(object):
|
||||
return
|
||||
if domain and typ in domain.dangling_warnings:
|
||||
msg = domain.dangling_warnings[typ]
|
||||
elif typ == 'doc':
|
||||
msg = 'unknown document: %(target)s'
|
||||
elif node.get('refdomain', 'std') not in ('', 'std'):
|
||||
msg = '%s:%s reference target not found: %%(target)s' % \
|
||||
(node['refdomain'], typ)
|
||||
@ -970,31 +965,14 @@ class BuildEnvironment(object):
|
||||
logger.warning(msg % {'target': target},
|
||||
location=node, type='ref', subtype=typ)
|
||||
|
||||
def _resolve_doc_reference(self, builder, refdoc, node, contnode):
|
||||
# type: (Builder, unicode, nodes.Node, nodes.Node) -> nodes.Node
|
||||
# directly reference to document by source name;
|
||||
# can be absolute or relative
|
||||
docname = docname_join(refdoc, node['reftarget'])
|
||||
if docname in self.all_docs:
|
||||
if node['refexplicit']:
|
||||
# reference with explicit title
|
||||
caption = node.astext()
|
||||
else:
|
||||
caption = clean_astext(self.titles[docname])
|
||||
innernode = nodes.inline(caption, caption)
|
||||
innernode['classes'].append('doc')
|
||||
newnode = nodes.reference('', '', internal=True)
|
||||
newnode['refuri'] = builder.get_relative_uri(refdoc, docname)
|
||||
newnode.append(innernode)
|
||||
return newnode
|
||||
|
||||
def _resolve_any_reference(self, builder, refdoc, node, contnode):
|
||||
# type: (Builder, unicode, nodes.Node, nodes.Node) -> nodes.Node
|
||||
"""Resolve reference generated by the "any" role."""
|
||||
target = node['reftarget']
|
||||
results = [] # type: List[Tuple[unicode, nodes.Node]]
|
||||
# first, try resolving as :doc:
|
||||
doc_ref = self._resolve_doc_reference(builder, refdoc, node, contnode)
|
||||
doc_ref = self.domains['std'].resolve_xref(self, refdoc, builder, 'doc',
|
||||
target, node, contnode)
|
||||
if doc_ref:
|
||||
results.append(('doc', doc_ref))
|
||||
# next, do the standard domain (makes this a priority)
|
||||
|
@ -338,9 +338,6 @@ def missing_reference(app, env, node, contnode):
|
||||
for domain in env.domains.values()
|
||||
for objtype in domain.object_types]
|
||||
domain = None
|
||||
elif node['reftype'] == 'doc':
|
||||
domain = 'std' # special case
|
||||
objtypes = ['std:doc']
|
||||
else:
|
||||
domain = node.get('refdomain')
|
||||
if not domain:
|
||||
|
@ -323,8 +323,6 @@ def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
specific_docroles = {
|
||||
# links to download references
|
||||
'download': XRefRole(nodeclass=addnodes.download_reference),
|
||||
# links to documents
|
||||
'doc': XRefRole(warn_dangling=True, innernodeclass=nodes.inline),
|
||||
# links to anything
|
||||
'any': AnyXRefRole(warn_dangling=True),
|
||||
|
||||
|
@ -325,11 +325,14 @@ def make_refnode(builder, fromdocname, todocname, targetid, child, title=None):
|
||||
# type: (Builder, unicode, unicode, unicode, nodes.Node, unicode) -> nodes.reference
|
||||
"""Shortcut to create a reference node."""
|
||||
node = nodes.reference('', '', internal=True)
|
||||
if fromdocname == todocname:
|
||||
if fromdocname == todocname and targetid:
|
||||
node['refid'] = targetid
|
||||
else:
|
||||
node['refuri'] = (builder.get_relative_uri(fromdocname, todocname) +
|
||||
'#' + targetid)
|
||||
if targetid:
|
||||
node['refuri'] = (builder.get_relative_uri(fromdocname, todocname) +
|
||||
'#' + targetid)
|
||||
else:
|
||||
node['refuri'] = builder.get_relative_uri(fromdocname, todocname)
|
||||
if title:
|
||||
node['reftitle'] = title
|
||||
node.append(child)
|
||||
|
@ -43,6 +43,7 @@ module2 py:module 0 foo.html#module-$ -
|
||||
module1.func py:function 1 sub/foo.html#$ -
|
||||
CFunc c:function 2 cfunc.html#CFunc -
|
||||
a term std:term -1 glossary.html#term-a-term -
|
||||
docname std:doc -1 docname.html -
|
||||
a term including:colon std:term -1 glossary.html#term-a-term-including-colon -
|
||||
'''.encode('utf-8'))
|
||||
|
||||
@ -212,6 +213,10 @@ def test_missing_reference(tempdir, app, status, warning):
|
||||
rn = reference_check('py', 'mod', 'py3krelparent:module1', 'foo', refdoc='sub/dir/test')
|
||||
assert rn['refuri'] == '../../../../py3k/foo.html#module-module1'
|
||||
|
||||
# check refs of standard domain
|
||||
rn = reference_check('std', 'doc', 'docname', 'docname')
|
||||
assert rn['refuri'] == 'https://docs.python.org/docname.html'
|
||||
|
||||
|
||||
def test_load_mappings_warnings(tempdir, app, status, warning):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user