buildframework/helium/external/python/lib/common/Sphinx-0.5.1-py2.5.egg/sphinx/application.py
author wbernard
Wed, 23 Dec 2009 19:29:07 +0200
changeset 179 d8ac696cc51f
permissions -rw-r--r--
helium_7.0-r14027
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
179
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     2
"""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     3
    sphinx.application
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     4
    ~~~~~~~~~~~~~~~~~~
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     5
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     6
    Sphinx application object.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     7
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     8
    Gracefully adapted from the TextPress system by Armin.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
     9
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    10
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    11
    :copyright: 2008 by Georg Brandl, Armin Ronacher.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    12
    :license: BSD.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    13
"""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    14
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    15
import sys
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    16
import posixpath
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    17
from cStringIO import StringIO
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    18
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    19
from docutils import nodes
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    20
from docutils.parsers.rst import directives, roles
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    21
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    22
import sphinx
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    23
from sphinx.roles import xfileref_role, innernodetypes
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    24
from sphinx.config import Config
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    25
from sphinx.builder import builtin_builders, StandaloneHTMLBuilder
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    26
from sphinx.directives import desc_directive, target_directive, additional_xref_types
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    27
from sphinx.environment import SphinxStandaloneReader
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    28
from sphinx.util.console import bold
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    29
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    30
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    31
class SphinxError(Exception):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    32
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    33
    Base class for Sphinx errors that are shown to the user in a nicer
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    34
    way than normal exceptions.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    35
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    36
    category = 'Sphinx error'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    37
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    38
class ExtensionError(SphinxError):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    39
    """Raised if something's wrong with the configuration."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    40
    category = 'Extension error'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    41
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    42
    def __init__(self, message, orig_exc=None):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    43
        super(ExtensionError, self).__init__(message)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    44
        self.orig_exc = orig_exc
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    45
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    46
    def __repr__(self):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    47
        if self.orig_exc:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    48
            return '%s(%r, %r)' % (self.__class__.__name__,
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    49
                                   self.message, self.orig_exc)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    50
        return '%s(%r)' % (self.__class__.__name__, self.message)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    51
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    52
    def __str__(self):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    53
        parent_str = super(ExtensionError, self).__str__()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    54
        if self.orig_exc:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    55
            return '%s (exception: %s)' % (parent_str, self.orig_exc)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    56
        return parent_str
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    57
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    58
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    59
# List of all known core events. Maps name to arguments description.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    60
events = {
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    61
    'builder-inited': '',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    62
    'env-purge-doc': 'env, docname',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    63
    'source-read': 'docname, source text',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    64
    'doctree-read': 'the doctree before being pickled',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    65
    'missing-reference': 'env, node, contnode',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    66
    'doctree-resolved': 'doctree, docname',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    67
    'env-updated': 'env',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    68
    'html-page-context': 'pagename, context, doctree or None',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    69
    'build-finished': 'exception',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    70
}
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    71
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    72
CONFIG_FILENAME = 'conf.py'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    73
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    74
class Sphinx(object):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    75
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    76
    def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    77
                 confoverrides, status, warning=sys.stderr, freshenv=False):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    78
        self.next_listener_id = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    79
        self._listeners = {}
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    80
        self.builderclasses = builtin_builders.copy()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    81
        self.builder = None
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    82
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    83
        self.srcdir = srcdir
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    84
        self.confdir = confdir
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    85
        self.outdir = outdir
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    86
        self.doctreedir = doctreedir
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    87
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    88
        if status is None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    89
            self._status = StringIO()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    90
            self.quiet = True
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    91
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    92
            self._status = status
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    93
            self.quiet = False
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    94
        if warning is None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    95
            self._warning = StringIO()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    96
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    97
            self._warning = warning
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    98
        self._warncount = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
    99
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   100
        self._events = events.copy()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   101
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   102
        # status code for command-line application
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   103
        self.statuscode = 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   104
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   105
        # read config
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   106
        self.config = Config(confdir, CONFIG_FILENAME, confoverrides)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   107
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   108
        # load all extension modules
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   109
        for extension in self.config.extensions:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   110
            self.setup_extension(extension)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   111
        # the config file itself can be an extension
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   112
        if self.config.setup:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   113
            self.config.setup(self)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   114
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   115
        # now that we know all config values, collect them from conf.py
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   116
        self.config.init_values()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   117
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   118
        if buildername is None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   119
            print >>status, 'No builder selected, using default: html'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   120
            buildername = 'html'
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   121
        if buildername not in self.builderclasses:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   122
            raise SphinxError('Builder name %s not registered' % buildername)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   123
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   124
        self.info(bold('Sphinx v%s, building %s' % (sphinx.__released__,
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   125
                                                    buildername)))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   126
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   127
        builderclass = self.builderclasses[buildername]
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   128
        self.builder = builderclass(self, freshenv=freshenv)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   129
        self.emit('builder-inited')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   130
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   131
    def build(self, all_files, filenames):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   132
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   133
            if all_files:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   134
                self.builder.build_all()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   135
            elif filenames:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   136
                self.builder.build_specific(filenames)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   137
            else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   138
                self.builder.build_update()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   139
        except Exception, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   140
            self.emit('build-finished', err)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   141
            raise
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   142
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   143
            self.emit('build-finished', None)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   144
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   145
    def warn(self, message):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   146
        self._warncount += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   147
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   148
            self._warning.write('WARNING: %s\n' % message)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   149
        except UnicodeEncodeError:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   150
            encoding = getattr(self._warning, 'encoding', 'ascii')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   151
            self._warning.write(('WARNING: %s\n' % message).encode(encoding, 'replace'))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   152
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   153
    def info(self, message='', nonl=False):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   154
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   155
            self._status.write(message)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   156
        except UnicodeEncodeError:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   157
            encoding = getattr(self._status, 'encoding', 'ascii')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   158
            self._status.write(message.encode(encoding, 'replace'))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   159
        if not nonl:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   160
            self._status.write('\n')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   161
        self._status.flush()
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   162
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   163
    # general extensibility interface
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   164
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   165
    def setup_extension(self, extension):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   166
        """Import and setup a Sphinx extension module."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   167
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   168
            mod = __import__(extension, None, None, ['setup'])
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   169
        except ImportError, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   170
            raise ExtensionError('Could not import extension %s' % extension, err)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   171
        if hasattr(mod, 'setup'):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   172
            mod.setup(self)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   173
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   174
    def import_object(self, objname, source=None):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   175
        """Import an object from a 'module.name' string."""
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   176
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   177
            module, name = objname.rsplit('.', 1)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   178
        except ValueError, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   179
            raise ExtensionError('Invalid full object name %s' % objname +
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   180
                                 (source and ' (needed for %s)' % source or ''), err)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   181
        try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   182
            return getattr(__import__(module, None, None, [name]), name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   183
        except ImportError, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   184
            raise ExtensionError('Could not import %s' % module +
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   185
                                 (source and ' (needed for %s)' % source or ''), err)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   186
        except AttributeError, err:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   187
            raise ExtensionError('Could not find %s' % objname +
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   188
                                 (source and ' (needed for %s)' % source or ''), err)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   189
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   190
    # event interface
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   191
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   192
    def _validate_event(self, event):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   193
        event = intern(event)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   194
        if event not in self._events:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   195
            raise ExtensionError('Unknown event name: %s' % event)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   196
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   197
    def connect(self, event, callback):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   198
        self._validate_event(event)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   199
        listener_id = self.next_listener_id
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   200
        if event not in self._listeners:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   201
            self._listeners[event] = {listener_id: callback}
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   202
        else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   203
            self._listeners[event][listener_id] = callback
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   204
        self.next_listener_id += 1
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   205
        return listener_id
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   206
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   207
    def disconnect(self, listener_id):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   208
        for event in self._listeners.itervalues():
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   209
            event.pop(listener_id, None)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   210
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   211
    def emit(self, event, *args):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   212
        result = []
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   213
        if event in self._listeners:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   214
            for _, callback in self._listeners[event].iteritems():
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   215
                result.append(callback(self, *args))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   216
        return result
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   217
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   218
    def emit_firstresult(self, event, *args):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   219
        for result in self.emit(event, *args):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   220
            if result is not None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   221
                return result
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   222
        return None
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   223
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   224
    # registering addon parts
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   225
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   226
    def add_builder(self, builder):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   227
        if not hasattr(builder, 'name'):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   228
            raise ExtensionError('Builder class %s has no "name" attribute' % builder)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   229
        if builder.name in self.builderclasses:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   230
            raise ExtensionError('Builder %r already exists (in module %s)' % (
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   231
                builder.name, self.builderclasses[builder.name].__module__))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   232
        self.builderclasses[builder.name] = builder
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   233
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   234
    def add_config_value(self, name, default, rebuild_env):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   235
        if name in self.config.values:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   236
            raise ExtensionError('Config value %r already present' % name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   237
        self.config.values[name] = (default, rebuild_env)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   238
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   239
    def add_event(self, name):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   240
        if name in self._events:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   241
            raise ExtensionError('Event %r already present' % name)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   242
        self._events[name] = ''
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   243
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   244
    def add_node(self, node, **kwds):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   245
        nodes._add_node_class_names([node.__name__])
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   246
        for key, val in kwds.iteritems():
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   247
            try:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   248
                visit, depart = val
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   249
            except ValueError:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   250
                raise ExtensionError('Value for key %r must be a (visit, depart) '
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   251
                                     'function tuple' % key)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   252
            if key == 'html':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   253
                from sphinx.htmlwriter import HTMLTranslator as translator
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   254
            elif key == 'latex':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   255
                from sphinx.latexwriter import LaTeXTranslator as translator
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   256
            elif key == 'text':
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   257
                from sphinx.textwriter import TextTranslator as translator
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   258
            else:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   259
                # ignore invalid keys for compatibility
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   260
                continue
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   261
            setattr(translator, 'visit_'+node.__name__, visit)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   262
            if depart:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   263
                setattr(translator, 'depart_'+node.__name__, depart)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   264
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   265
    def add_directive(self, name, func, content, arguments, **options):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   266
        func.content = content
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   267
        func.arguments = arguments
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   268
        func.options = options
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   269
        directives.register_directive(name, func)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   270
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   271
    def add_role(self, name, role):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   272
        roles.register_canonical_role(name, role)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   273
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   274
    def add_description_unit(self, directivename, rolename, indextemplate='',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   275
                             parse_node=None, ref_nodeclass=None):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   276
        additional_xref_types[directivename] = (rolename, indextemplate, parse_node)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   277
        directives.register_directive(directivename, desc_directive)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   278
        roles.register_canonical_role(rolename, xfileref_role)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   279
        if ref_nodeclass is not None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   280
            innernodetypes[rolename] = ref_nodeclass
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   281
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   282
    def add_crossref_type(self, directivename, rolename, indextemplate='',
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   283
                          ref_nodeclass=None):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   284
        additional_xref_types[directivename] = (rolename, indextemplate, None)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   285
        directives.register_directive(directivename, target_directive)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   286
        roles.register_canonical_role(rolename, xfileref_role)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   287
        if ref_nodeclass is not None:
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   288
            innernodetypes[rolename] = ref_nodeclass
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   289
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   290
    def add_transform(self, transform):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   291
        SphinxStandaloneReader.transforms.append(transform)
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   292
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   293
    def add_javascript(self, filename):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   294
        StandaloneHTMLBuilder.script_files.append(
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   295
            posixpath.join('_static', filename))
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   296
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   297
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   298
class TemplateBridge(object):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   299
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   300
    This class defines the interface for a "template bridge", that is, a class
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   301
    that renders templates given a template name and a context.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   302
    """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   303
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   304
    def init(self, builder):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   305
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   306
        Called by the builder to initialize the template system.  *builder*
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   307
        is the builder object; you'll probably want to look at the value of
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   308
        ``builder.config.templates_path``.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   309
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   310
        raise NotImplementedError('must be implemented in subclasses')
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   311
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   312
    def newest_template_mtime(self):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   313
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   314
        Called by the builder to determine if output files are outdated
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   315
        because of template changes.  Return the mtime of the newest template
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   316
        file that was changed.  The default implementation returns ``0``.
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   317
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   318
        return 0
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   319
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   320
    def render(self, template, context):
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   321
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   322
        Called by the builder to render a *template* with a specified
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   323
        context (a Python dictionary).
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   324
        """
d8ac696cc51f helium_7.0-r14027
wbernard
parents:
diff changeset
   325
        raise NotImplementedError('must be implemented in subclasses')