Georg Brandl avatar Georg Brandl committed 5ebfb7e

Refactor warning-emission for unknown references.

Comments (0)

Files changed (1)

sphinx/environment.py

             typ = node['reftype']
             target = node['reftarget']
             refdoc = node.get('refdoc', fromdocname)
-            warned = False
             domain = None
 
             try:
                     # directly reference to document by source name;
                     # can be absolute or relative
                     docname = docname_join(refdoc, target)
-                    if docname not in self.all_docs:
-                        self.warn(refdoc,
-                                  'unknown document: %s' % docname, node.line)
-                        warned = True
-                    else:
+                    if docname in self.all_docs:
                         if node['refexplicit']:
                             # reference with explicit title
                             caption = node.astext()
                         newnode.append(innernode)
                 elif typ == 'citation':
                     docname, labelid = self.citations.get(target, ('', ''))
-                    if not docname:
-                        self.warn(refdoc,
-                                  'citation not found: %s' % target, node.line)
-                        warned = True
-                    else:
+                    if docname:
                         newnode = make_refnode(builder, fromdocname, docname,
                                                labelid, contnode)
                 # no new node found? try the missing-reference event
                     newnode = builder.app.emit_firstresult(
                         'missing-reference', self, node, contnode)
                     # still not found? warn if in nit-picky mode
-                    if newnode is None and not warned and \
-                       (self.config.nitpicky or node.get('refwarn')):
-                        if domain and typ in domain.dangling_warnings:
-                            msg = domain.dangling_warnings[typ]
-                        elif node.get('refdomain') != 'std':
-                            msg = '%s:%s reference target not found: ' \
-                                  '%%(target)s' % (node['refdomain'], typ)
-                        else:
-                            msg = '%s reference target not found: ' \
-                                  '%%(target)s' % typ
-                        self.warn(refdoc, msg % {'target': target}, node.line)
+                    if newnode is None:
+                        self._warn_missing_reference(
+                            fromdocname, typ, target, node, domain)
             except NoUri:
                 newnode = contnode
             node.replace_self(newnode or contnode)
 
+        # remove only-nodes that do not belong to our builder
+        self.process_only_nodes(doctree, fromdocname, builder)
+
+        # allow custom references to be resolved
+        builder.app.emit('doctree-resolved', doctree, fromdocname)
+
+    def _warn_missing_reference(self, fromdoc, typ, target, node, domain):
+        warn = node.get('refwarn')
+        if self.config.nitpicky:
+            warn = True  # XXX process exceptions here
+        if not warn:
+            return
+        refdoc = node.get('refdoc', fromdoc)
+        if domain and typ in domain.dangling_warnings:
+            msg = domain.dangling_warnings[typ]
+        elif typ == 'doc':
+            msg = 'unknown document: %(target)s'
+        elif typ == 'citation':
+            msg = 'citation not found: %(target)s'
+        elif node.get('refdomain', 'std') != 'std':
+            msg = '%s:%s reference target not found: %%(target)s' % \
+                  (node['refdomain'], typ)
+        else:
+            msg = '%s reference target not found: %%(target)s' % typ
+        self.warn(refdoc, msg % {'target': target}, node.line)
+
+    def process_only_nodes(self, doctree, fromdocname, builder):
         for node in doctree.traverse(addnodes.only):
             try:
                 ret = builder.tags.eval_condition(node['expr'])
                     # if there is a target node before the only node
                     node.replace_self(nodes.comment())
 
-        # allow custom references to be resolved
-        builder.app.emit('doctree-resolved', doctree, fromdocname)
-
     def assign_section_numbers(self):
         """Assign a section number to each heading under a numbered toctree."""
         # a list of all docnames whose section numbers changed
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.