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