Commits

Georg Brandl committed 98f9c2d

Introduce "domains".

Comments (0)

Files changed (4)

sphinx/application.py

 from sphinx.roles import xfileref_role, innernodetypes
 from sphinx.config import Config
 from sphinx.errors import SphinxError, SphinxWarning, ExtensionError
+from sphinx.domains import domains
 from sphinx.builders import BUILTIN_BUILDERS
 from sphinx.directives import GenericDesc, Target, additional_xref_types
 from sphinx.environment import SphinxStandaloneReader
         role = roles.GenericRole(name, nodeclass)
         roles.register_local_role(name, role)
 
+    def add_domain(self, domain):
+        if domain.name in domains:
+            raise ExtensionError('domain %s already registered' % domain.name)
+        domains[domain.name] = domain
+
     def add_description_unit(self, directivename, rolename, indextemplate='',
                              parse_node=None, ref_nodeclass=None):
         additional_xref_types[directivename] = (rolename, indextemplate,

sphinx/directives/desc.py

 from docutils.parsers.rst import directives
 
 from sphinx import addnodes
+from sphinx.domains import Domain, domains
 from sphinx.util import ws_re
 from sphinx.util.compat import Directive, directive_dwim
 
         env.note_reftarget(rolename, fullname, targetname)
         return ret
 
+
+class DefaultDomain(Directive):
+    """
+    Directive to (re-)set the default domain for this source file.
+    """
+
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def run(self):
+        env = self.state.document.settings.env
+        domain_name = arguments[0]
+        env.default_domain = domains.get(domain_name)
+
+
 # Note: the target directive is not registered here, it is used by the
 # application when registering additional xref types.
 
 del _
 
 
+directives.register_directive('default-domain', directive_dwim(DefaultDomain))
 directives.register_directive('describe', directive_dwim(DescDirective))
-
-directives.register_directive('function', directive_dwim(ModulelevelDesc))
-directives.register_directive('data', directive_dwim(ModulelevelDesc))
-directives.register_directive('class', directive_dwim(ClasslikeDesc))
-directives.register_directive('exception', directive_dwim(ClasslikeDesc))
-directives.register_directive('method', directive_dwim(ClassmemberDesc))
-directives.register_directive('classmethod', directive_dwim(ClassmemberDesc))
-directives.register_directive('staticmethod', directive_dwim(ClassmemberDesc))
-directives.register_directive('attribute', directive_dwim(ClassmemberDesc))
-
-directives.register_directive('cfunction', directive_dwim(CDesc))
-directives.register_directive('cmember', directive_dwim(CDesc))
-directives.register_directive('cmacro', directive_dwim(CDesc))
-directives.register_directive('ctype', directive_dwim(CDesc))
-directives.register_directive('cvar', directive_dwim(CDesc))
-
 directives.register_directive('cmdoption', directive_dwim(CmdoptionDesc))
 directives.register_directive('envvar', directive_dwim(GenericDesc))
+
+
+class PythonDomain(Domain):
+    name = 'py'
+    label = 'Python'
+    directives = {
+        'function': ModulelevelDesc,
+        'data': ModulelevelDesc,
+        'class': ClasslikeDesc,
+        'exception': ClasslikeDesc,
+        'method': ClassmemberDesc,
+        'classmethod': ClassmemberDesc,
+        'staticmethod': ClassmemberDesc,
+        'attribute': ClassmemberDesc,
+    }
+
+class CDomain(Domain):
+    name = 'c'
+    label = 'C'
+    directives = {
+        'function': CDesc,
+        'member': CDesc,
+        'macro': CDesc,
+        'type': CDesc,
+        'var': CDesc,
+    }
+
+
+domains['py'] = PythonDomain
+domains['c'] = CDomain

sphinx/domains.py

+# -*- coding: utf-8 -*-
+"""
+    sphinx.domains
+    ~~~~~~~~~~~~~~
+
+    Support for domains, which are groupings of description directives
+    describing e.g. constructs of one programming language.
+
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+class Domain(object):
+    name = ''
+    directives = {}
+    label = ''
+

sphinx/environment.py

 from docutils.core import Publisher
 from docutils.utils import Reporter, relative_path
 from docutils.readers import standalone
-from docutils.parsers.rst import roles
+from docutils.parsers.rst import roles, directives
 from docutils.parsers.rst.languages import en as english
 from docutils.parsers.rst.directives.html import MetaBody
 from docutils.writers import UnfilteredWriter
 from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
      docname_join, FilenameUniqDict, url_re
 from sphinx.errors import SphinxError
+from sphinx.domains import domains
 from sphinx.directives import additional_xref_types
 
+orig_directive_function = directives.directive
+
 default_settings = {
     'embed_stylesheet': False,
     'cloak_email_addresses': True,
                 else:
                     return data
 
+        # defaults to the global default, but can be re-set in a document
+        self.default_domain = domains.get(self.config.default_domain)
+
+        # monkey-patch, so that domain directives take precedence
+        def directive(directive_name, language_module, document):
+            if ':' in directive_name:
+                domain_name, directive_name = directive_name.split(':', 1)
+                if domain_name in domains:
+                    domain = domains[domain_name]
+                    if directive_name in domain.directives:
+                        return domain.directives[directive_name], []
+            elif self.default_domain is not None:
+                directive = self.default_domain.directives.get(directive_name)
+                if directive is not None:
+                    return directive, []
+            return orig_directive_function(directive_name, language_module,
+                                           document)
+        directives.directive = directive
+
         # publish manually
         pub = Publisher(reader=SphinxStandaloneReader(),
+                        parser=SphinxRstParser(),
                         writer=SphinxDummyWriter(),
                         source_class=SphinxSourceClass,
                         destination_class=NullOutput)