예제 #1
0
 def __init__(self, *args, **kargs):
     CPPDomain.__init__(self, *args, **kargs)
     self.directives['function'].doc_field_types = [
         TypedField('parameter', label=l_('Parameters'),
                    names=('param', 'parameter', 'arg', 'argument'),
                    typerolename='type', typenames=('type',)),
         Field('returnvalue', label=l_('Returns'), has_arg=False,
               names=('returns', 'return')),
         Field('returntype', label=l_('Return type'), has_arg=False,
               names=('rtype',)),
         ]
예제 #2
0
    def add_target_and_index(self, name, sig, signode):
        targetparts =  get_id_from_cfg(name)
        targetname = 'cfg_%s' % '_'.join(targetparts)
        signode['ids'].append(targetname)
        self.state.document.note_explicit_target(signode)
        indextype = 'single'

        # Generic index entries
        indexentry = self.indextemplate % (name,)
        self.indexnode['entries'].append((indextype, indexentry,
                                          targetname, targetname))
        self.indexnode['entries'].append((indextype, name,
                                          targetname, targetname))

        # Server section
        if targetparts[0] == 'Servers' and len(targetparts) > 1:
            indexname = ', '.join(targetparts[1:])
            self.indexnode['entries'].append((indextype, l_('server configuration; %s') % indexname,
                                              targetname, targetname))
            self.indexnode['entries'].append((indextype, indexname,
                                              targetname, targetname))
        else:
            indexname = ', '.join(targetparts)
            self.indexnode['entries'].append((indextype, indexname,
                                              targetname, targetname))

        self.env.domaindata['config']['objects'][self.objtype, name] = \
            self.env.docname, targetname
예제 #3
0
파일: sphinxext.py 프로젝트: javacruft/wsme
        def add_samples():
            protocols = get_protocols(
                self.options.protocols or self.env.app.config.wsme_protocols
            )
            content = []
            if protocols:
                sample_obj = make_sample_object(self.object)
                content.extend([
                    l_(u'Data samples:'),
                    u'',
                    u'.. cssclass:: toggle',
                    u''
                ])
                for name, protocol in protocols:
                    language, sample = protocol.encode_sample_value(
                        self.object, sample_obj, format=True)
                    content.extend([
                        name,
                        u'    .. code-block:: ' + language,
                        u'',
                    ])
                    content.extend((
                        u' ' * 8 + line for line in sample.split('\n')))
            for line in content:
                self.add_line(line, u'<wsmeext.sphinxext')

            self.add_line(u'', '<wsmeext.sphinxext>')
예제 #4
0
 def get_index_text(self, modname, name_cls):
     if self.objtype == 'dirtymodel':
         label = l_(self.env.app.config.dirty_model_class_label or 'model')
         if not modname:
             return '%s (%s)' % (name_cls[0], label)
         return '%s (%s %s)' % (name_cls[0], modname, label)
     else:
         return ''
def setup(app):
    app.add_autodocumenter(ColumnAttributeDocumenter)
    app.add_autodocumenter(MapperDocumenter)
    domain = sphinx.domains.python.PythonDomain
    domain.object_types['mapper'] = sphinx.domains.python.ObjType(
        l_('mapper'), 'mapper', 'obj')
    domain.directives['mapper'] = MapperDirective
    domain.roles['mapper'] = sphinx.domains.python.PyXRefRole()
예제 #6
0
 def get_doc_field_types(self):
     return [
         TypedField(self.field_name,
                    label=l_(self.field_label),
                    names=(self.field_name,),
                    typerolename='msg',
                    typenames=('{0}-{1}'.format(self.field_name,
                                                TYPE_SUFFIX),)),
         TypedField(self.constant_name,
                    label=l_(self.constant_label),
                    names=(self.constant_name,),
                    typerolename='msg',
                    typenames=('{0}-{1}'.format(self.constant_name,
                                                TYPE_SUFFIX),)),
         GroupedField('{0}-{1}'.format(self.constant_name,
                                       VALUE_SUFFIX),
                      label=l_('{0} (Value)'.format(self.constant_label)),
                      names=('{0}-{1}'.format(self.constant_name,
                                              VALUE_SUFFIX),)),
         ]
예제 #7
0
def setup(app):
    app.add_autodoc_attrgetter(zope.interface.interface.InterfaceClass,
                               interface_getattr)
    app.add_autodocumenter(InterfaceDocumenter)
    app.add_autodocumenter(InterfaceAttributeDocumenter)
    app.add_autodocumenter(InterfaceMethodDocumenter)

    domain = sphinx.domains.python.PythonDomain
    domain.object_types['interface'] = sphinx.domains.python.ObjType(
        l_('interface'), 'interface', 'obj')
    domain.directives['interface'] = InterfaceDirective
    domain.roles['interface'] = sphinx.domains.python.PyXRefRole()
예제 #8
0
    def get_index_text(self, modname, name_cls):
        name, cls = name_cls
        add_modules = self.env.config.add_module_names

        if self.objtype == 'dirtymodelattribute':
            label = l_(self.env.app.config.dirty_model_property_label or 'attribute')
            clsname, attrname = name.rsplit('.', 1)
            if modname and add_modules:
                return '%s (%s.%s %s)' % (attrname, modname, clsname, label)
            else:
                return '%s (%s %s)' % (attrname, clsname, label)
        else:
            return ''
예제 #9
0
def setup(app):
    app.add_autodocumenter(DirtyModelDocumenter)
    app.add_autodocumenter(DirtyModelAttributeDocumenter)

    app.add_config_value('dirty_model_add_classes_to_toc', True, True)
    app.add_config_value('dirty_model_add_attributes_to_toc', True, True)
    app.add_config_value('dirty_model_class_label', 'Model', True)
    app.add_config_value('dirty_model_property_label', 'property', True)
    app.add_config_value('dirty_model_field_type_as_annotation', True, True)

    app.connect('doctree-read', process_dirty_model_toc)

    domain = sphinx.domains.python.PythonDomain
    domain.object_types['dirtymodel'] = sphinx.domains.python.ObjType(
        l_('Model'), 'dirtymodel', 'obj')
    domain.directives['dirtymodel'] = DirtyModelDirective
    domain.roles['dirtymodel'] = sphinx.domains.python.PyXRefRole()

    domain.object_types['dirtymodelattribute'] = sphinx.domains.python.ObjType(
        l_('Attribute'), 'dirtymodelattribute', 'obj')
    domain.directives['dirtymodelattribute'] = DirtyModelAttributeDirective
    domain.roles['dirtymodelattribute'] = sphinx.domains.python.PyXRefRole()
예제 #10
0
파일: html.py 프로젝트: Veterun/sphinx-1
def setup(app):
    # builders
    app.add_builder(StandaloneHTMLBuilder)
    app.add_builder(DirectoryHTMLBuilder)
    app.add_builder(SingleFileHTMLBuilder)
    app.add_builder(PickleHTMLBuilder)
    app.add_builder(JSONHTMLBuilder)

    # config values
    app.add_config_value('html_theme', 'alabaster', 'html')
    app.add_config_value('html_theme_path', [], 'html')
    app.add_config_value('html_theme_options', {}, 'html')
    app.add_config_value('html_title',
                         lambda self: l_('%s %s documentation') % (self.project, self.release),
                         'html', string_classes)
    app.add_config_value('html_short_title', lambda self: self.html_title, 'html')
    app.add_config_value('html_style', None, 'html', string_classes)
    app.add_config_value('html_logo', None, 'html', string_classes)
    app.add_config_value('html_favicon', None, 'html', string_classes)
    app.add_config_value('html_static_path', [], 'html')
    app.add_config_value('html_extra_path', [], 'html')
    app.add_config_value('html_last_updated_fmt', None, 'html', string_classes)
    app.add_config_value('html_use_smartypants', True, 'html')
    app.add_config_value('html_translator_class', None, 'html', string_classes)
    app.add_config_value('html_sidebars', {}, 'html')
    app.add_config_value('html_additional_pages', {}, 'html')
    app.add_config_value('html_use_modindex', True, 'html')  # deprecated
    app.add_config_value('html_domain_indices', True, 'html', [list])
    app.add_config_value('html_add_permalinks', u'\u00B6', 'html')
    app.add_config_value('html_use_index', True, 'html')
    app.add_config_value('html_split_index', False, 'html')
    app.add_config_value('html_copy_source', True, 'html')
    app.add_config_value('html_show_sourcelink', True, 'html')
    app.add_config_value('html_sourcelink_suffix', '.txt', 'html')
    app.add_config_value('html_use_opensearch', '', 'html')
    app.add_config_value('html_file_suffix', None, 'html', string_classes)
    app.add_config_value('html_link_suffix', None, 'html', string_classes)
    app.add_config_value('html_show_copyright', True, 'html')
    app.add_config_value('html_show_sphinx', True, 'html')
    app.add_config_value('html_context', {}, 'html')
    app.add_config_value('html_output_encoding', 'utf-8', 'html')
    app.add_config_value('html_compact_lists', True, 'html')
    app.add_config_value('html_secnumber_suffix', '. ', 'html')
    app.add_config_value('html_search_language', None, 'html', string_classes)
    app.add_config_value('html_search_options', {}, 'html')
    app.add_config_value('html_search_scorer', '', None)
    app.add_config_value('html_scaled_image_link', True, 'html')
예제 #11
0
def render_domain_data(mongodb_directives):
    directives = { }
    roles = { }
    object_types = { }

    for directive in mongodb_directives:
        reftype = directive['name']

        roles[reftype] = MongoDBXRefRole()
        object_types[reftype] = ObjType(l_(reftype), reftype)

        if directive['callable']:
            directives[reftype] = MongoDBMethod
        else:
            directives[reftype] = MongoDBObject

    return directives, roles, object_types
예제 #12
0
    def handle_signature(self, sig, signode):
        result = super(DirtyModelAttributeDirective, self).handle_signature(sig, signode)

        if self.options.get('annotation'):
            anno = addnodes.desc_annotation()
            old_node = signode[2]
            if not isinstance(old_node, addnodes.desc_annotation):
                old_node = signode[3]
                del signode[1]
            old_node.replace_self(anno)
            self.state.nested_parse(ViewList([':  ', self.options.get('annotation')]), 0, anno)

        readonly = 'readonly' in self.options
        if readonly:
            signode['classes'].append('readonly')
            t = ' [{}]'.format(l_('READ ONLY'))
            signode += nodes.emphasis(t, t, classes=['readonly-label'])

        return result
예제 #13
0
class PythonDomain(Domain):
    """Python language domain."""
    name = 'py'
    label = 'Python'
    object_types = {
        'function': ObjType(l_('function'), 'func', 'obj'),
        'data': ObjType(l_('data'), 'data', 'obj'),
        'class': ObjType(l_('class'), 'class', 'exc', 'obj'),
        'exception': ObjType(l_('exception'), 'exc', 'class', 'obj'),
        'method': ObjType(l_('method'), 'meth', 'obj'),
        'classmethod': ObjType(l_('class method'), 'meth', 'obj'),
        'staticmethod': ObjType(l_('static method'), 'meth', 'obj'),
        'attribute': ObjType(l_('attribute'), 'attr', 'obj'),
        'module': ObjType(l_('module'), 'mod', 'obj'),
    }  # type: Dict[unicode, ObjType]

    directives = {
        'function': PyModulelevel,
        'data': PyModulelevel,
        'class': PyClasslike,
        'exception': PyClasslike,
        'method': PyClassmember,
        'classmethod': PyClassmember,
        'staticmethod': PyClassmember,
        'attribute': PyClassmember,
        'module': PyModule,
        'currentmodule': PyCurrentModule,
        'decorator': PyDecoratorFunction,
        'decoratormethod': PyDecoratorMethod,
    }
    roles = {
        'data': PyXRefRole(),
        'exc': PyXRefRole(),
        'func': PyXRefRole(fix_parens=True),
        'class': PyXRefRole(),
        'const': PyXRefRole(),
        'attr': PyXRefRole(),
        'meth': PyXRefRole(fix_parens=True),
        'mod': PyXRefRole(),
        'obj': PyXRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
        'modules': {},  # modname -> docname, synopsis, platform, deprecated
    }  # type: Dict[unicode, Dict[unicode, Tuple[Any]]]
    indices = [
        PythonModuleIndex,
    ]

    def clear_doc(self, docname):
        # type: (unicode) -> None
        for fullname, (fn, _l) in list(self.data['objects'].items()):
            if fn == docname:
                del self.data['objects'][fullname]
        for modname, (fn, _x, _x, _x) in list(self.data['modules'].items()):
            if fn == docname:
                del self.data['modules'][modname]

    def merge_domaindata(self, docnames, otherdata):
        # type: (List[unicode], Dict) -> None
        # XXX check duplicates?
        for fullname, (fn, objtype) in otherdata['objects'].items():
            if fn in docnames:
                self.data['objects'][fullname] = (fn, objtype)
        for modname, data in otherdata['modules'].items():
            if data[0] in docnames:
                self.data['modules'][modname] = data

    def find_obj(self, env, modname, classname, name, type, searchmode=0):
        # type: (BuildEnvironment, unicode, unicode, unicode, unicode, int) -> List[Tuple[unicode, Any]]  # NOQA
        """Find a Python object for "name", perhaps using the given module
        and/or classname.  Returns a list of (name, object entry) tuples.
        """
        # skip parens
        if name[-2:] == '()':
            name = name[:-2]

        if not name:
            return []

        objects = self.data['objects']
        matches = []  # type: List[Tuple[unicode, Any]]

        newname = None
        if searchmode == 1:
            if type is None:
                objtypes = list(self.object_types)
            else:
                objtypes = self.objtypes_for_role(type)
            if objtypes is not None:
                if modname and classname:
                    fullname = modname + '.' + classname + '.' + name
                    if fullname in objects and objects[fullname][1] in objtypes:
                        newname = fullname
                if not newname:
                    if modname and modname + '.' + name in objects and \
                       objects[modname + '.' + name][1] in objtypes:
                        newname = modname + '.' + name
                    elif name in objects and objects[name][1] in objtypes:
                        newname = name
                    else:
                        # "fuzzy" searching mode
                        searchname = '.' + name
                        matches = [(oname, objects[oname]) for oname in objects
                                   if oname.endswith(searchname)
                                   and objects[oname][1] in objtypes]
        else:
            # NOTE: searching for exact match, object type is not considered
            if name in objects:
                newname = name
            elif type == 'mod':
                # only exact matches allowed for modules
                return []
            elif classname and classname + '.' + name in objects:
                newname = classname + '.' + name
            elif modname and modname + '.' + name in objects:
                newname = modname + '.' + name
            elif modname and classname and \
                    modname + '.' + classname + '.' + name in objects:
                newname = modname + '.' + classname + '.' + name
            # special case: builtin exceptions have module "exceptions" set
            elif type == 'exc' and '.' not in name and \
                    'exceptions.' + name in objects:
                newname = 'exceptions.' + name
            # special case: object methods
            elif type in ('func', 'meth') and '.' not in name and \
                    'object.' + name in objects:
                newname = 'object.' + name
        if newname is not None:
            matches.append((newname, objects[newname]))
        return matches

    def resolve_xref(self, env, fromdocname, builder, type, target, node,
                     contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        modname = node.get('py:module')
        clsname = node.get('py:class')
        searchmode = node.hasattr('refspecific') and 1 or 0
        matches = self.find_obj(env, modname, clsname, target, type,
                                searchmode)
        if not matches:
            return None
        elif len(matches) > 1:
            logger.warning(
                'more than one target found for cross-reference %r: %s',
                target,
                ', '.join(match[0] for match in matches),
                type='ref',
                subtype='python',
                location=node)
        name, obj = matches[0]

        if obj[1] == 'module':
            return self._make_module_refnode(builder, fromdocname, name,
                                             contnode)
        else:
            return make_refnode(builder, fromdocname, obj[0], name, contnode,
                                name)

    def resolve_any_xref(self, env, fromdocname, builder, target, node,
                         contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]]  # NOQA
        modname = node.get('py:module')
        clsname = node.get('py:class')
        results = []  # type: List[Tuple[unicode, nodes.Node]]

        # always search in "refspecific" mode with the :any: role
        matches = self.find_obj(env, modname, clsname, target, None, 1)
        for name, obj in matches:
            if obj[1] == 'module':
                results.append(
                    ('py:mod',
                     self._make_module_refnode(builder, fromdocname, name,
                                               contnode)))
            else:
                results.append(('py:' + self.role_for_objtype(obj[1]),
                                make_refnode(builder, fromdocname, obj[0],
                                             name, contnode, name)))
        return results

    def _make_module_refnode(self, builder, fromdocname, name, contnode):
        # type: (Builder, unicode, unicode, nodes.Node) -> nodes.Node
        # get additional info for modules
        docname, synopsis, platform, deprecated = self.data['modules'][name]
        title = name
        if synopsis:
            title += ': ' + synopsis
        if deprecated:
            title += _(' (deprecated)')
        if platform:
            title += ' (' + platform + ')'
        return make_refnode(builder, fromdocname, docname, 'module-' + name,
                            contnode, title)

    def get_objects(self):
        # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]]
        for modname, info in iteritems(self.data['modules']):
            yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
        for refname, (docname, type) in iteritems(self.data['objects']):
            if type != 'module':  # modules are already handled
                yield (refname, refname, type, docname, refname, 1)

    def get_full_qualified_name(self, node):
        # type: (nodes.Node) -> unicode
        modname = node.get('py:module')
        clsname = node.get('py:class')
        target = node.get('reftarget')
        if target is None:
            return None
        else:
            return '.'.join(filter(None, [modname, clsname, target]))
예제 #14
0
class Config(object):
    """
    Configuration file abstraction.
    """

    # the values are: (default, what needs to be rebuilt if changed)

    # If you add a value here, don't forget to include it in the
    # quickstart.py file template as well as in the docs!

    config_values = dict(
        # general options
        project=('Python', 'env'),
        copyright=('', 'html'),
        version=('', 'env'),
        release=('', 'env'),
        today=('', 'env'),
        # the real default is locale-dependent
        today_fmt=(None, 'env', string_classes),
        language=(None, 'env', string_classes),
        locale_dirs=(['locales'], 'env'),
        figure_language_filename=(u'{root}.{language}{ext}', 'env', [str]),
        master_doc=('contents', 'env'),
        source_suffix=(['.rst'], 'env'),
        source_encoding=('utf-8-sig', 'env'),
        source_parsers=({}, 'env'),
        exclude_patterns=([], 'env'),
        default_role=(None, 'env', string_classes),
        add_function_parentheses=(True, 'env'),
        add_module_names=(True, 'env'),
        trim_footnote_reference_space=(False, 'env'),
        show_authors=(False, 'env'),
        pygments_style=(None, 'html', string_classes),
        highlight_language=('default', 'env'),
        highlight_options=({}, 'env'),
        templates_path=([], 'html'),
        template_bridge=(None, 'html', string_classes),
        keep_warnings=(False, 'env'),
        suppress_warnings=([], 'env'),
        modindex_common_prefix=([], 'html'),
        rst_epilog=(None, 'env', string_classes),
        rst_prolog=(None, 'env', string_classes),
        trim_doctest_flags=(True, 'env'),
        primary_domain=('py', 'env', [NoneType]),
        needs_sphinx=(None, None, string_classes),
        needs_extensions=({}, None),
        nitpicky=(False, None),
        nitpick_ignore=([], None),
        numfig=(False, 'env'),
        numfig_secnum_depth=(1, 'env'),
        numfig_format=({
            'section': l_('Section %s'),
            'figure': l_('Fig. %s'),
            'table': l_('Table %s'),
            'code-block': l_('Listing %s')
        }, 'env'),
        tls_verify=(True, 'env'),
        tls_cacerts=(None, 'env'),

        # pre-initialized confval for HTML builder
        html_translator_class=(None, 'html', string_classes),
    )

    def __init__(self, dirname, filename, overrides, tags):
        self.overrides = overrides
        self.values = Config.config_values.copy()
        config = {}
        if dirname is not None:
            config_file = path.join(dirname, filename)
            config['__file__'] = config_file
            config['tags'] = tags
            with cd(dirname):
                # we promise to have the config dir as current dir while the
                # config file is executed
                try:
                    execfile_(filename, config)
                except SyntaxError as err:
                    raise ConfigError(CONFIG_SYNTAX_ERROR % err)
                except SystemExit:
                    raise ConfigError(CONFIG_EXIT_ERROR)

        self._raw_config = config
        # these two must be preinitialized because extensions can add their
        # own config values
        self.setup = config.get('setup', None)

        if 'extensions' in overrides:
            if isinstance(overrides['extensions'], string_types):
                config['extensions'] = overrides.pop('extensions').split(',')
            else:
                config['extensions'] = overrides.pop('extensions')
        self.extensions = config.get('extensions', [])

        # correct values of copyright year that are not coherent with
        # the SOURCE_DATE_EPOCH environment variable (if set)
        # See https://reproducible-builds.org/specs/source-date-epoch/
        if getenv('SOURCE_DATE_EPOCH') is not None:
            for k in ('copyright', 'epub_copyright'):
                if k in config:
                    config[k] = copyright_year_re.sub(
                        '\g<1>%s' % format_date('%Y'), config[k])

    def check_types(self, warn):
        # check all values for deviation from the default value's type, since
        # that can result in TypeErrors all over the place
        # NB. since config values might use l_() we have to wait with calling
        # this method until i18n is initialized
        for name in self._raw_config:
            if name not in self.values:
                continue  # we don't know a default value
            settings = self.values[name]
            default, dummy_rebuild = settings[:2]
            permitted = settings[2] if len(settings) == 3 else ()

            if hasattr(default, '__call__'):
                default = default(self)  # could invoke l_()
            if default is None and not permitted:
                continue  # neither inferrable nor expliclitly permitted types
            current = self[name]
            if isinstance(permitted, ENUM):
                if not permitted.match(current):
                    warn(
                        CONFIG_ENUM_WARNING.format(
                            name=name,
                            current=current,
                            candidates=permitted.candidates))
            else:
                if type(current) is type(default):
                    continue
                if type(current) in permitted:
                    continue

                common_bases = (
                    set(type(current).__bases__ +
                        (type(current), )) & set(type(default).__bases__))
                common_bases.discard(object)
                if common_bases:
                    continue  # at least we share a non-trivial base class

                if permitted:
                    warn(
                        CONFIG_PERMITTED_TYPE_WARNING.format(
                            name=name,
                            current=type(current),
                            permitted=str([cls.__name__
                                           for cls in permitted])))
                else:
                    warn(
                        CONFIG_TYPE_WARNING.format(name=name,
                                                   current=type(current),
                                                   default=type(default)))

    def check_unicode(self, warn):
        # check all string values for non-ASCII characters in bytestrings,
        # since that can result in UnicodeErrors all over the place
        for name, value in iteritems(self._raw_config):
            if isinstance(value, binary_type) and nonascii_re.search(value):
                warn('the config value %r is set to a string with non-ASCII '
                     'characters; this can lead to Unicode errors occurring. '
                     'Please use Unicode strings, e.g. %r.' %
                     (name, u'Content'))

    def convert_overrides(self, name, value):
        if not isinstance(value, string_types):
            return value
        else:
            defvalue = self.values[name][0]
            if isinstance(defvalue, dict):
                raise ValueError(
                    'cannot override dictionary config setting %r, '
                    'ignoring (use %r to set individual elements)' %
                    (name, name + '.key=value'))
            elif isinstance(defvalue, list):
                return value.split(',')
            elif isinstance(defvalue, integer_types):
                try:
                    return int(value)
                except ValueError:
                    raise ValueError(
                        'invalid number %r for config value %r, ignoring' %
                        (value, name))
            elif hasattr(defvalue, '__call__'):
                return value
            elif defvalue is not None and not isinstance(
                    defvalue, string_types):
                raise ValueError(
                    'cannot override config setting %r with unsupported '
                    'type, ignoring' % name)
            else:
                return value

    def pre_init_values(self, warn):
        """Initialize some limited config variables before loading extensions"""
        variables = [
            'needs_sphinx', 'suppress_warnings', 'html_translator_class'
        ]
        for name in variables:
            try:
                if name in self.overrides:
                    self.__dict__[name] = self.convert_overrides(
                        name, self.overrides[name])
                elif name in self._raw_config:
                    self.__dict__[name] = self._raw_config[name]
            except ValueError as exc:
                warn(exc)

    def init_values(self, warn):
        config = self._raw_config
        for valname, value in iteritems(self.overrides):
            try:
                if '.' in valname:
                    realvalname, key = valname.split('.', 1)
                    config.setdefault(realvalname, {})[key] = value
                    continue
                elif valname not in self.values:
                    warn('unknown config value %r in override, ignoring' %
                         valname)
                    continue
                if isinstance(value, string_types):
                    config[valname] = self.convert_overrides(valname, value)
                else:
                    config[valname] = value
            except ValueError as exc:
                warn(exc)
        for name in config:
            if name in self.values:
                self.__dict__[name] = config[name]
        if isinstance(self.source_suffix, string_types):
            self.source_suffix = [self.source_suffix]

    def __getattr__(self, name):
        if name.startswith('_'):
            raise AttributeError(name)
        if name not in self.values:
            raise AttributeError('No such config value: %s' % name)
        default = self.values[name][0]
        if hasattr(default, '__call__'):
            return default(self)
        return default

    def __getitem__(self, name):
        return getattr(self, name)

    def __setitem__(self, name, value):
        setattr(self, name, value)

    def __delitem__(self, name):
        delattr(self, name)

    def __contains__(self, name):
        return name in self.values
예제 #15
0
class StandardDomain(Domain):
    """
    Domain for all objects that don't fit into another domain or are added
    via the application interface.
    """

    name = 'std'
    label = 'Default'

    object_types = {
        'term': ObjType(l_('glossary term'), 'term', searchprio=-1),
        'token': ObjType(l_('grammar token'), 'token', searchprio=-1),
        'label': ObjType(l_('reference label'),
                         'ref',
                         'keyword',
                         searchprio=-1),
        'envvar': ObjType(l_('environment variable'), 'envvar'),
        'cmdoption': ObjType(l_('program option'), 'option'),
    }

    directives = {
        'program': Program,
        'cmdoption': Cmdoption,  # old name for backwards compatibility
        'option': Cmdoption,
        'envvar': EnvVar,
        'glossary': Glossary,
        'productionlist': ProductionList,
    }
    roles = {
        'option':
        OptionXRefRole(warn_dangling=True),
        'envvar':
        EnvVarXRefRole(),
        # links to tokens in grammar productions
        'token':
        XRefRole(),
        # links to terms in glossary
        'term':
        XRefRole(lowercase=True,
                 innernodeclass=nodes.inline,
                 warn_dangling=True),
        # links to headings or arbitrary labels
        'ref':
        XRefRole(lowercase=True,
                 innernodeclass=nodes.inline,
                 warn_dangling=True),
        # links to labels of numbered figures, tables and code-blocks
        'numref':
        XRefRole(lowercase=True, warn_dangling=True),
        # links to labels, without a different title
        'keyword':
        XRefRole(warn_dangling=True),
    }

    initial_data = {
        'progoptions': {},  # (program, name) -> docname, labelid
        'objects': {},      # (type, name) -> docname, labelid
        'labels': {         # labelname -> docname, labelid, sectionname
            'genindex': ('genindex', '', l_('Index')),
            'modindex': ('py-modindex', '', l_('Module Index')),
            'search':   ('search', '', l_('Search Page')),
        },
        'anonlabels': {     # labelname -> docname, labelid
            'genindex': ('genindex', ''),
            'modindex': ('py-modindex', ''),
            'search':   ('search', ''),
        },
    }

    dangling_warnings = {
        'term': 'term not in glossary: %(target)s',
        'ref': 'undefined label: %(target)s (if the link has no caption '
        'the label must precede a section header)',
        'numref': 'undefined label: %(target)s',
        'keyword': 'unknown keyword: %(target)s',
        'option': 'unknown option: %(target)s',
    }

    enumerable_nodes = {  # node_class -> (figtype, title_getter)
        nodes.figure: ('figure', None),
        nodes.table: ('table', None),
        nodes.container: ('code-block', None),
    }

    def clear_doc(self, docname):
        for key, (fn, _l) in list(self.data['progoptions'].items()):
            if fn == docname:
                del self.data['progoptions'][key]
        for key, (fn, _l) in list(self.data['objects'].items()):
            if fn == docname:
                del self.data['objects'][key]
        for key, (fn, _l, _l) in list(self.data['labels'].items()):
            if fn == docname:
                del self.data['labels'][key]
        for key, (fn, _l) in list(self.data['anonlabels'].items()):
            if fn == docname:
                del self.data['anonlabels'][key]

    def merge_domaindata(self, docnames, otherdata):
        # XXX duplicates?
        for key, data in otherdata['progoptions'].items():
            if data[0] in docnames:
                self.data['progoptions'][key] = data
        for key, data in otherdata['objects'].items():
            if data[0] in docnames:
                self.data['objects'][key] = data
        for key, data in otherdata['labels'].items():
            if data[0] in docnames:
                self.data['labels'][key] = data
        for key, data in otherdata['anonlabels'].items():
            if data[0] in docnames:
                self.data['anonlabels'][key] = data

    def process_doc(self, env, docname, document):
        labels, anonlabels = self.data['labels'], self.data['anonlabels']
        for name, explicit in iteritems(document.nametypes):
            if not explicit:
                continue
            labelid = document.nameids[name]
            if labelid is None:
                continue
            node = document.ids[labelid]
            if name.isdigit() or 'refuri' in node or \
               node.tagname.startswith('desc_'):
                # ignore footnote labels, labels automatically generated from a
                # link and object descriptions
                continue
            if name in labels:
                env.warn_node(
                    'duplicate label %s, ' % name + 'other instance '
                    'in ' + env.doc2path(labels[name][0]), node)
            anonlabels[name] = docname, labelid
            if node.tagname == 'section':
                sectname = clean_astext(node[0])  # node[0] == title node
            elif self.is_enumerable_node(node):
                sectname = self.get_numfig_title(node)
                if sectname is None:
                    continue
            elif node.traverse(addnodes.toctree):
                n = node.traverse(addnodes.toctree)[0]
                if n.get('caption'):
                    sectname = n['caption']
                else:
                    continue
            else:
                # anonymous-only labels
                continue
            labels[name] = docname, labelid, sectname

    def build_reference_node(self, fromdocname, builder, docname, labelid,
                             sectname, rolename, **options):
        nodeclass = options.pop('nodeclass', nodes.reference)
        newnode = nodeclass('', '', internal=True, **options)
        innernode = nodes.inline(sectname, sectname)
        if innernode.get('classes') is not None:
            innernode['classes'].append('std')
            innernode['classes'].append('std-' + rolename)
        if docname == fromdocname:
            newnode['refid'] = labelid
        else:
            # set more info in contnode; in case the
            # get_relative_uri call raises NoUri,
            # the builder will then have to resolve these
            contnode = addnodes.pending_xref('')
            contnode['refdocname'] = docname
            contnode['refsectname'] = sectname
            newnode['refuri'] = builder.get_relative_uri(fromdocname, docname)
            if labelid:
                newnode['refuri'] += '#' + labelid
        newnode.append(innernode)
        return newnode

    def resolve_xref(self, env, fromdocname, builder, typ, target, node,
                     contnode):
        if typ == 'ref':
            if node['refexplicit']:
                # reference to anonymous label; the reference uses
                # the supplied link caption
                docname, labelid = self.data['anonlabels'].get(
                    target, ('', ''))
                sectname = node.astext()
            else:
                # reference to named label; the final node will
                # contain the section name after the label
                docname, labelid, sectname = self.data['labels'].get(
                    target, ('', '', ''))
            if not docname:
                return None

            return self.build_reference_node(fromdocname, builder, docname,
                                             labelid, sectname, 'ref')
        elif typ == 'numref':
            docname, labelid = self.data['anonlabels'].get(target, ('', ''))
            if not docname:
                return None

            if env.config.numfig is False:
                env.warn(fromdocname,
                         'numfig is disabled. :numref: is ignored.',
                         lineno=node.line)
                return contnode

            target_node = env.get_doctree(docname).ids.get(labelid)
            figtype = self.get_figtype(target_node)
            if figtype is None:
                return None

            try:
                figure_id = target_node['ids'][0]
                fignumber = env.toc_fignumbers[docname][figtype][figure_id]
            except (KeyError, IndexError):
                # target_node is found, but fignumber is not assigned.
                # Maybe it is defined in orphaned document.
                env.warn(fromdocname,
                         "no number is assigned for %s: %s" %
                         (figtype, labelid),
                         lineno=node.line)
                return contnode

            title = contnode.astext()
            if target == fully_normalize_name(title):
                title = env.config.numfig_format.get(figtype, '')

            try:
                newtitle = title % '.'.join(map(str, fignumber))
            except TypeError:
                env.warn(fromdocname,
                         'invalid numfig_format: %s' % title,
                         lineno=node.line)
                return None

            return self.build_reference_node(
                fromdocname,
                builder,
                docname,
                labelid,
                newtitle,
                'numref',
                nodeclass=addnodes.number_reference,
                title=title)
        elif typ == 'keyword':
            # keywords are oddballs: they are referenced by named labels
            docname, labelid, _ = self.data['labels'].get(target, ('', '', ''))
            if not docname:
                return None
            return make_refnode(builder, fromdocname, docname, labelid,
                                contnode)
        elif typ == 'option':
            progname = node.get('std:program')
            target = target.strip()
            docname, labelid = self.data['progoptions'].get((progname, target),
                                                            ('', ''))
            if not docname:
                commands = []
                while ws_re.search(target):
                    subcommand, target = ws_re.split(target, 1)
                    commands.append(subcommand)
                    progname = "-".join(commands)

                    docname, labelid = self.data['progoptions'].get(
                        (progname, target), ('', ''))
                    if docname:
                        break
                else:
                    return None

            return make_refnode(builder, fromdocname, docname, labelid,
                                contnode)
        else:
            objtypes = self.objtypes_for_role(typ) or []
            for objtype in objtypes:
                if (objtype, target) in self.data['objects']:
                    docname, labelid = self.data['objects'][objtype, target]
                    break
            else:
                docname, labelid = '', ''
            if not docname:
                return None
            return make_refnode(builder, fromdocname, docname, labelid,
                                contnode)

    def resolve_any_xref(self, env, fromdocname, builder, target, node,
                         contnode):
        results = []
        ltarget = target.lower()  # :ref: lowercases its target automatically
        for role in ('ref', 'option'):  # do not try "keyword"
            res = self.resolve_xref(env, fromdocname, builder, role,
                                    ltarget if role == 'ref' else target, node,
                                    contnode)
            if res:
                results.append(('std:' + role, res))
        # all others
        for objtype in self.object_types:
            key = (objtype, target)
            if objtype == 'term':
                key = (objtype, ltarget)
            if key in self.data['objects']:
                docname, labelid = self.data['objects'][key]
                results.append(('std:' + self.role_for_objtype(objtype),
                                make_refnode(builder, fromdocname, docname,
                                             labelid, contnode)))
        return results

    def get_objects(self):
        # handle the special 'doc' reference here
        for doc in self.env.all_docs:
            yield (doc, clean_astext(self.env.titles[doc]), 'doc', doc, '', -1)
        for (prog, option), info in iteritems(self.data['progoptions']):
            yield (option, option, 'option', info[0], info[1], 1)
        for (type, name), info in iteritems(self.data['objects']):
            yield (name, name, type, info[0], info[1],
                   self.object_types[type].attrs['searchprio'])
        for name, info in iteritems(self.data['labels']):
            yield (name, info[2], 'label', info[0], info[1], -1)
        # add anonymous-only labels as well
        non_anon_labels = set(self.data['labels'])
        for name, info in iteritems(self.data['anonlabels']):
            if name not in non_anon_labels:
                yield (name, name, 'label', info[0], info[1], -1)

    def get_type_name(self, type, primary=False):
        # never prepend "Default"
        return type.lname

    def is_enumerable_node(self, node):
        return node.__class__ in self.enumerable_nodes

    def get_numfig_title(self, node):
        """Get the title of enumerable nodes to refer them using its title"""
        if self.is_enumerable_node(node):
            _, title_getter = self.enumerable_nodes.get(
                node.__class__, (None, None))
            if title_getter:
                return title_getter(node)
            else:
                for subnode in node:
                    if subnode.tagname in ('caption', 'title'):
                        return clean_astext(subnode)

        return None

    def get_figtype(self, node):
        """Get figure type of nodes."""
        def has_child(node, cls):
            return any(isinstance(child, cls) for child in node)

        if isinstance(node, nodes.container):
            if node.get('literal_block') and has_child(node,
                                                       nodes.literal_block):
                return 'code-block'
            else:
                return None
        else:
            figtype, _ = self.enumerable_nodes.get(node.__class__,
                                                   (None, None))
            return figtype
예제 #16
0
파일: rst.py 프로젝트: rds0751/odfo
class ReSTDomain(Domain):
    """ReStructuredText domain."""
    name = 'rst'
    label = 'reStructuredText'

    object_types = {
        'directive': ObjType(l_('directive'), 'dir'),
        'role': ObjType(l_('role'), 'role'),
    }
    directives = {
        'directive': ReSTDirective,
        'role': ReSTRole,
    }
    roles = {
        'dir': XRefRole(),
        'role': XRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
    }  # type: Dict[unicode, Dict[unicode, Tuple[unicode, ObjType]]]

    def clear_doc(self, docname):
        # type: (unicode) -> None
        for (typ, name), doc in list(self.data['objects'].items()):
            if doc == docname:
                del self.data['objects'][typ, name]

    def merge_domaindata(self, docnames, otherdata):
        # type: (List[unicode], Dict) -> None
        # XXX check duplicates
        for (typ, name), doc in otherdata['objects'].items():
            if doc in docnames:
                self.data['objects'][typ, name] = doc

    def resolve_xref(self, env, fromdocname, builder, typ, target, node,
                     contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        objects = self.data['objects']
        objtypes = self.objtypes_for_role(typ)
        for objtype in objtypes:
            if (objtype, target) in objects:
                return make_refnode(builder, fromdocname, objects[objtype,
                                                                  target],
                                    objtype + '-' + target, contnode,
                                    target + ' ' + objtype)

    def resolve_any_xref(self, env, fromdocname, builder, target, node,
                         contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[nodes.Node]  # NOQA
        objects = self.data['objects']
        results = []
        for objtype in self.object_types:
            if (objtype, target) in self.data['objects']:
                results.append(
                    ('rst:' + self.role_for_objtype(objtype),
                     make_refnode(builder, fromdocname, objects[objtype,
                                                                target],
                                  objtype + '-' + target, contnode,
                                  target + ' ' + objtype)))
        return results

    def get_objects(self):
        # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]]
        for (typ, name), docname in iteritems(self.data['objects']):
            yield name, name, typ, docname, typ + '-' + name, 1
예제 #17
0
class PythonModuleIndex(Index):
    """
    Index subclass to provide the Python module index.
    """

    name = 'modindex'
    localname = l_('Python Module Index')
    shortname = l_('modules')

    def generate(self, docnames=None):
        content = {}
        # list of prefixes to ignore
        ignores = self.domain.env.config['modindex_common_prefix']
        ignores = sorted(ignores, key=len, reverse=True)
        # list of all modules, sorted by module name
        modules = sorted(iteritems(self.domain.data['modules']),
                         key=lambda x: x[0].lower())
        # sort out collapsable modules
        prev_modname = ''
        num_toplevels = 0
        for modname, (docname, synopsis, platforms, deprecated) in modules:
            if docnames and docname not in docnames:
                continue

            for ignore in ignores:
                if modname.startswith(ignore):
                    modname = modname[len(ignore):]
                    stripped = ignore
                    break
            else:
                stripped = ''

            # we stripped the whole module name?
            if not modname:
                modname, stripped = stripped, ''

            entries = content.setdefault(modname[0].lower(), [])

            package = modname.split('.')[0]
            if package != modname:
                # it's a submodule
                if prev_modname == package:
                    # first submodule - make parent a group head
                    if entries:
                        entries[-1][1] = 1
                elif not prev_modname.startswith(package):
                    # submodule without parent in list, add dummy entry
                    entries.append([stripped + package, 1, '', '', '', '', ''])
                subtype = 2
            else:
                num_toplevels += 1
                subtype = 0

            qualifier = deprecated and _('Deprecated') or ''
            entries.append([stripped + modname, subtype, docname,
                            'module-' + stripped + modname, platforms,
                            qualifier, synopsis])
            prev_modname = modname

        # apply heuristics when to collapse modindex at page load:
        # only collapse if number of toplevel modules is larger than
        # number of submodules
        collapse = len(modules) - num_toplevels < num_toplevels

        # sort by first letter
        content = sorted(iteritems(content))

        return content, collapse
예제 #18
0
class EverettComponent(ObjectDescription):
    """
    Description of an Everett component""
    """

    doc_field_types = [
        TypedField('options',
                   label=l_('Options'),
                   names=('option', 'opt'),
                   typerolename='obj',
                   typenames=('parser', ),
                   can_collapse=True),
    ]

    allow_nesting = False

    def handle_signature(self, sig, signode):
        if sig != 'Configuration':
            # Add "component" to the beginning if it's a specific component
            signode.clear()

            # Add "component" which is the type of this thing
            signode += addnodes.desc_annotation('component ', 'component ')

            if '.' in sig:
                modname, clsname = sig.rsplit('.', 1)
            else:
                modname, clsname = '', sig

            # If there's a module name, then we add the module
            if modname:
                signode += addnodes.desc_addname(modname + '.', modname + '.')

            # Add the class name
            signode += addnodes.desc_name(clsname, clsname)
        else:
            # Add just "Configuration"
            signode += addnodes.desc_name(sig, sig)

        return sig

    def add_target_and_index(self, name, sig, signode):
        targetname = '%s-%s' % (self.objtype, name)

        if targetname not in self.state.document.ids:
            signode['names'].append(targetname)
            signode['ids'].append(targetname)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)

            objects = self.env.domaindata['everett']['objects']
            key = (self.objtype, name)
            if key in objects:
                self.state_machine.reporter.warning(
                    'duplicate description of %s %s, ' % (self.objtype, name) +
                    'other instance in ' + self.env.doc2path(objects[key]),
                    line=self.lineno)
            objects[key] = self.env.docname

        indextext = _('%s (component)') % name
        self.indexnode['entries'].append(
            ('single', indextext, targetname, '', None))
예제 #19
0
class BroDomain(Domain):
    """Bro domain."""
    name = 'bro'
    label = 'Bro'

    object_types = {
        'type': ObjType(l_('type'), 'type'),
        'namespace': ObjType(l_('namespace'), 'namespace'),
        'id': ObjType(l_('id'), 'id'),
        'enum': ObjType(l_('enum'), 'enum'),
        'attr': ObjType(l_('attr'), 'attr'),
    }

    directives = {
        'type': BroGeneric,
        'namespace': BroNamespace,
        'id': BroIdentifier,
        'enum': BroEnum,
        'attr': BroAttribute,
    }

    roles = {
        'type': XRefRole(),
        'namespace': XRefRole(),
        'id': XRefRole(),
        'enum': XRefRole(),
        'attr': XRefRole(),
        'see': XRefRole(),
    }

    indices = [
        BroNotices,
    ]

    initial_data = {
        'objects': {},  # fullname -> docname, objtype
    }

    def clear_doc(self, docname):
        for (typ, name), doc in self.data['objects'].items():
            if doc == docname:
                del self.data['objects'][typ, name]

    def resolve_xref(self, env, fromdocname, builder, typ, target, node,
                     contnode):
        objects = self.data['objects']
        if typ == "see":
            if target not in self.data['idtypes']:
                self.env.warn(fromdocname,
                              'unknown target for ":bro:see:`%s`"' % (target))
                return []
            objtype = self.data['idtypes'][target]
            return make_refnode(builder, fromdocname, objects[objtype, target],
                                objtype + '-' + target, contnode,
                                target + ' ' + objtype)
        else:
            objtypes = self.objtypes_for_role(typ)
            for objtype in objtypes:
                if (objtype, target) in objects:
                    return make_refnode(builder, fromdocname, objects[objtype,
                                                                      target],
                                        objtype + '-' + target, contnode,
                                        target + ' ' + objtype)
                else:
                    self.env.warn(
                        fromdocname,
                        'unknown target for ":bro:%s:`%s`"' % (typ, target))

    def get_objects(self):
        for (typ, name), docname in self.data['objects'].iteritems():
            yield name, name, typ, docname, typ + '-' + name, 1
예제 #20
0
class NimObject(ObjectDescription):
    """
    Description of a Nim language object.
    """

    doc_field_types = [
        TypedField('parameter',
                   label=l_('Parameters'),
                   names=('param', 'parameter', 'arg', 'argument'),
                   typerolename='type',
                   typenames=('type', )),
        Field('returnvalue',
              label=l_('Returns'),
              has_arg=False,
              names=('returns', 'return')),
        Field('returntype',
              label=l_('Return type'),
              has_arg=False,
              names=('rtype', )),
    ]

    # These Nim types aren't described anywhere, so don't try to create
    # a cross-reference to them
    stopwords = set(
        ('int', 'uint', 'float', 'bool', 'int8', 'int16', 'int32', 'int64',
         'uint8', 'uint16', 'uint32', 'uint64', 'float32', 'float64', 'char',
         'string', 'cstring', 'pointer', 'void', 'expr', 'typedesc',
         'tsignedint', 'tunsignedint', 'tinteger', 'tordinal', 'treal',
         'tnumber', 'byte', 'natural', 'positive', 'exception'))

    def _parse_type(self, node, ctype):
        # add cross-ref nodes for all words
        for part in filter(None, wsplit_re.split(ctype)):
            tnode = nodes.Text(part, part)
            if part[0] in string.ascii_letters + '_' and \
                   part.lower() not in self.stopwords:
                pnode = addnodes.pending_xref('',
                                              refdomain='nim',
                                              reftype='type',
                                              reftarget=part,
                                              modname=None,
                                              classname=None)
                pnode += tnode
                node += pnode
            else:
                node += tnode

    def _handle_proc_signature(self, sig, signode, m):
        "Transform a Nim proc node into RST nodes."

        name, arglist, rettype, pragmas = m.groups()

        signode += addnodes.desc_type('proc', 'proc')
        signode += addnodes.desc_name(name, name)

        if arglist is None:
            signode += addnodes.desc_parameterlist()
        else:
            arguments = nim_arg_sig_re.match(arglist).groups()[0]
            signode += addnodes.desc_parameterlist(arguments, arguments)

        if rettype is not None:
            retnode = addnodes.desc_returns()
            self._parse_type(retnode,
                             nim_rettype_sig_re.match(rettype).groups()[0])
            signode += retnode

        if pragmas:
            signode += addnodes.desc_addname(pragmas, pragmas)
        return name

    def _handle_enum_signature(self, sig, signode, m):
        "Transform a Nim enum into RST nodes."
        name, values = m.groups()

        signode += addnodes.desc_type('enum', 'enum')
        signode += addnodes.desc_name(name, name)
        signode += addnodes.desc_addname(values, '= ' + values)
        return name

    def _handle_object_signature(self, sig, signode, m):
        "Transform a Nim object into RST nodes."
        name = m.groups()[0]

        signode += addnodes.desc_type('object', 'object')
        signode += addnodes.desc_name(name, name)
        return name

    def handle_signature(self, sig, signode):
        "Transform a Nim signature into RST nodes."
        print "handle_signature:", sig
        m = nim_proc_sig_re.match(sig)
        if m is not None:
            return self._handle_proc_signature(sig, signode, m)

        m = nim_enum_sig_re.match(sig)
        if m is not None:
            return self._handle_enum_signature(sig, signode, m)

        m = nim_object_sig_re.match(sig)
        if m is not None:
            return self._handle_object_signature(sig, signode, m)

        raise ValueError('no match')

    def get_index_text(self, name):
        if self.objtype == 'proc':
            return _('%s (Nim procedure)') % name
        elif self.objtype == 'template':
            return _('%s (Nim template)') % name
        elif self.objtype == 'enum':
            return _('%s (Nim enumeration)') % name
        elif self.objtype == 'type':
            return _('%s (Nim type)') % name
        elif self.objtype == 'const':
            return _('%s (Nim constant)') % name
        else:
            return ''

    def add_target_and_index(self, name, sig, signode):
        # for Nim API items we add a prefix since names are usually not qualified
        # by a module name and so easily clash with e.g. section titles
        targetname = 'nim.' + name
        if targetname not in self.state.document.ids:
            signode['names'].append(targetname)
            signode['ids'].append(targetname)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)
            inv = self.env.domaindata['nim']['objects']
            if name in inv:
                self.state_machine.reporter.warning(
                    'duplicate Nim object description of %s, ' % name +
                    'other instance in ' + self.env.doc2path(inv[name][0]),
                    line=self.lineno)
            inv[name] = (self.env.docname, self.objtype)

        indextext = self.get_index_text(name)
        if indextext:
            self.indexnode['entries'].append(
                ('single', indextext, targetname, ''))

    def before_content(self):
        self.typename_set = False
        if self.name == 'nim:type':
            if self.names:
                self.env.temp_data['nim:type'] = self.names[0]
                self.typename_set = True

    def after_content(self):
        if self.typename_set:
            self.env.temp_data['nim:type'] = None
예제 #21
0
파일: c.py 프로젝트: tu44okawa3/sphinx
class CDomain(Domain):
    """C language domain."""
    name = 'c'
    label = 'C'
    object_types = {
        'function': ObjType(l_('function'), 'func'),
        'member': ObjType(l_('member'), 'member'),
        'macro': ObjType(l_('macro'), 'macro'),
        'type': ObjType(l_('type'), 'type'),
        'var': ObjType(l_('variable'), 'data'),
    }

    directives = {
        'function': CObject,
        'member': CObject,
        'macro': CObject,
        'type': CObject,
        'var': CObject,
    }
    roles = {
        'func': CXRefRole(fix_parens=True),
        'member': CXRefRole(),
        'macro': CXRefRole(),
        'data': CXRefRole(),
        'type': CXRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
    }

    def clear_doc(self, docname):
        for fullname, (fn, _) in list(self.data['objects'].items()):
            if fn == docname:
                del self.data['objects'][fullname]

    def merge_domaindata(self, docnames, otherdata):
        # XXX check duplicates
        for fullname, (fn, objtype) in otherdata['objects'].items():
            if fn in docnames:
                self.data['objects'][fullname] = (fn, objtype)

    def resolve_xref(self, env, fromdocname, builder, typ, target, node,
                     contnode):
        # strip pointer asterisk
        target = target.rstrip(' *')
        if target not in self.data['objects']:
            return None
        obj = self.data['objects'][target]
        return make_refnode(builder, fromdocname, obj[0], 'c.' + target,
                            contnode, target)

    def resolve_any_xref(self, env, fromdocname, builder, target, node,
                         contnode):
        # strip pointer asterisk
        target = target.rstrip(' *')
        if target not in self.data['objects']:
            return []
        obj = self.data['objects'][target]
        return [('c:' + self.role_for_objtype(obj[1]),
                 make_refnode(builder, fromdocname, obj[0], 'c.' + target,
                              contnode, target))]

    def get_objects(self):
        for refname, (docname, type) in list(self.data['objects'].items()):
            yield (refname, refname, type, docname, 'c.' + refname, 1)
예제 #22
0
class OCamlDomain(PolyglotDomain):
    name, label = 'ml', l_('OCaml')
    directives = {
      'module':  make_namespace_directive('module'),
      'package': make_directive('package'),
    }
예제 #23
0
class LuaDomain(PolyglotDomain):
    name, label = 'lua', l_('Lua')
    directives = {
      'module': make_namespace_directive('module'),
    }
예제 #24
0
class JavaDomain(JVMDomain):
    name, label = 'java', l_('Java')
예제 #25
0
# -*- coding: utf-8 -*-

"""
Adds a new "exercise" admonition type
"""

def setup(app):
    app.add_directive('exercise', Exercise)
    app.add_node(exercise, html=(
        lambda self, node: self.visit_admonition(node, 'exercise'),
        lambda self, node: self.depart_admonition(node)
    ), latex=(
        lambda self, node: self.visit_admonition(node),
        lambda self, node: self.depart_admonition(node)
    ))

from docutils import nodes
from docutils.parsers.rst.directives import admonitions
class exercise(nodes.Admonition, nodes.Element): pass
class Exercise(admonitions.BaseAdmonition):
    node_class = exercise

from sphinx.locale import admonitionlabels, l_
admonitionlabels['exercise'] = l_('Exercise')
예제 #26
0
class CObject(ObjectDescription):
    """
    Description of a C language object.
    """

    doc_field_types = [
        TypedField('parameter',
                   label=l_('Parameters'),
                   names=('param', 'parameter', 'arg', 'argument'),
                   typerolename='type',
                   typenames=('type', )),
        Field('returnvalue',
              label=l_('Returns'),
              has_arg=False,
              names=('returns', 'return')),
        Field('returntype',
              label=l_('Return type'),
              has_arg=False,
              names=('rtype', )),
    ]

    # These C types aren't described anywhere, so don't try to create
    # a cross-reference to them
    stopwords = set(('const', 'void', 'char', 'int', 'long', 'FILE', 'struct'))

    def _parse_type(self, node, ctype):
        # add cross-ref nodes for all words
        for part in filter(None, wsplit_re.split(ctype)):
            tnode = nodes.Text(part, part)
            if part[0] in string.ascii_letters+'_' and \
                   part not in self.stopwords:
                pnode = addnodes.pending_xref('',
                                              refdomain='c',
                                              reftype='type',
                                              reftarget=part,
                                              modname=None,
                                              classname=None)
                pnode += tnode
                node += pnode
            else:
                node += tnode

    def handle_signature(self, sig, signode):
        """Transform a C signature into RST nodes."""
        # first try the function pointer signature regex, it's more specific
        m = c_funcptr_sig_re.match(sig)
        if m is None:
            m = c_sig_re.match(sig)
        if m is None:
            raise ValueError('no match')
        rettype, name, arglist, const = m.groups()

        signode += addnodes.desc_type('', '')
        self._parse_type(signode[-1], rettype)
        try:
            classname, funcname = name.split('::', 1)
            classname += '::'
            signode += addnodes.desc_addname(classname, classname)
            signode += addnodes.desc_name(funcname, funcname)
            # name (the full name) is still both parts
        except ValueError:
            signode += addnodes.desc_name(name, name)
        # clean up parentheses from canonical name
        m = c_funcptr_name_re.match(name)
        if m:
            name = m.group(1)

        typename = self.env.temp_data.get('c:type')
        if self.name == 'c:member' and typename:
            fullname = typename + '.' + name
        else:
            fullname = name

        if not arglist:
            if self.objtype == 'function':
                # for functions, add an empty parameter list
                signode += addnodes.desc_parameterlist()
            if const:
                signode += addnodes.desc_addname(const, const)
            return fullname

        paramlist = addnodes.desc_parameterlist()
        arglist = arglist.replace('`', '').replace('\\ ', '')  # remove markup
        # this messes up function pointer types, but not too badly ;)
        args = arglist.split(',')
        for arg in args:
            arg = arg.strip()
            param = addnodes.desc_parameter('', '', noemph=True)
            try:
                ctype, argname = arg.rsplit(' ', 1)
            except ValueError:
                # no argument name given, only the type
                self._parse_type(param, arg)
            else:
                self._parse_type(param, ctype)
                # separate by non-breaking space in the output
                param += nodes.emphasis(' ' + argname, u'\xa0' + argname)
            paramlist += param
        signode += paramlist
        if const:
            signode += addnodes.desc_addname(const, const)
        return fullname

    def get_index_text(self, name):
        if self.objtype == 'function':
            return _('%s (C function)') % name
        elif self.objtype == 'member':
            return _('%s (C member)') % name
        elif self.objtype == 'macro':
            return _('%s (C macro)') % name
        elif self.objtype == 'type':
            return _('%s (C type)') % name
        elif self.objtype == 'var':
            return _('%s (C variable)') % name
        else:
            return ''

    def add_target_and_index(self, name, sig, signode):
        # note target
        if name not in self.state.document.ids:
            signode['names'].append(name)
            signode['ids'].append(name)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)
            inv = self.env.domaindata['c']['objects']
            if name in inv:
                self.env.warn(
                    self.env.docname,
                    'duplicate C object description of %s, ' % name +
                    'other instance in ' + self.env.doc2path(inv[name][0]),
                    self.lineno)
            inv[name] = (self.env.docname, self.objtype)

        indextext = self.get_index_text(name)
        if indextext:
            self.indexnode['entries'].append(('single', indextext, name, ''))

    def before_content(self):
        self.typename_set = False
        if self.name == 'c:type':
            if self.names:
                self.env.temp_data['c:type'] = self.names[0]
                self.typename_set = True

    def after_content(self):
        if self.typename_set:
            self.env.temp_data['c:type'] = None
예제 #27
0
class ErlangDomain(PolyglotDomain):
    name, label = 'erl', l_('Erlang')
    directives = {
      'module':  make_namespace_directive('module'),
      'package': make_directive('package'),
    }
예제 #28
0
class MATLABDomain(Domain):
    """MATLAB language domain."""
    name = 'mat'
    label = 'MATLAB'
    object_types = {
        'function':     ObjType(l_('function'),      'func', 'obj'),
        'data':         ObjType(l_('data'),          'data', 'obj'),
        'class':        ObjType(l_('class'),         'class', 'obj'),
        'exception':    ObjType(l_('exception'),     'exc', 'obj'),
        'method':       ObjType(l_('method'),        'meth', 'obj'),
        'classmethod':  ObjType(l_('class method'),  'meth', 'obj'),
        'staticmethod': ObjType(l_('static method'), 'meth', 'obj'),
        'attribute':    ObjType(l_('attribute'),     'attr', 'obj'),
        'module':       ObjType(l_('module'),        'mod', 'obj'),
    }

    directives = {
        'function':        MatModulelevel,
        'data':            MatModulelevel,
        'class':           MatClasslike,
        'exception':       MatClasslike,
        'method':          MatClassmember,
        'classmethod':     MatClassmember,
        'staticmethod':    MatClassmember,
        'attribute':       MatClassmember,
        'module':          MatModule,
        'currentmodule':   MatCurrentModule,
        'decorator':       MatDecoratorFunction,
        'decoratormethod': MatDecoratorMethod,
    }
    roles = {
        'data':  MatXRefRole(),
        'exc':   MatXRefRole(),
        'func':  MatXRefRole(fix_parens=True),
        'class': MatXRefRole(),
        'const': MatXRefRole(),
        'attr':  MatXRefRole(),
        'meth':  MatXRefRole(fix_parens=True),
        'mod':   MatXRefRole(),
        'obj':   MatXRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
        'modules': {},  # modname -> docname, synopsis, platform, deprecated
    }
    indices = [
        MATLABModuleIndex,
    ]

    def clear_doc(self, docname):
        for fullname, (fn, _) in self.data['objects'].items():
            if fn == docname:
                del self.data['objects'][fullname]
        for modname, (fn, _, _, _) in self.data['modules'].items():
            if fn == docname:
                del self.data['modules'][modname]

    def find_obj(self, env, modname, classname, name, type, searchmode=0):
        """Find a MATLAB object for "name", perhaps using the given module
        and/or classname.  Returns a list of (name, object entry) tuples.
        """
        # skip parens
        if name[-2:] == '()':
            name = name[:-2]

        if not name:
            return []

        objects = self.data['objects']
        matches = []

        newname = None
        if searchmode == 1:
            objtypes = self.objtypes_for_role(type)
            if objtypes is not None:
                if modname and classname:
                    fullname = modname + '.' + classname + '.' + name
                    if fullname in objects and objects[fullname][1] in objtypes:
                        newname = fullname
                if not newname:
                    if modname and modname + '.' + name in objects and \
                       objects[modname + '.' + name][1] in objtypes:
                        newname = modname + '.' + name
                    elif name in objects and objects[name][1] in objtypes:
                        newname = name
                    else:
                        # "fuzzy" searching mode
                        searchname = '.' + name
                        matches = [(oname, objects[oname]) for oname in objects
                                   if oname.endswith(searchname)
                                   and objects[oname][1] in objtypes]
        else:
            # NOTE: searching for exact match, object type is not considered
            if name in objects:
                newname = name
            elif type == 'mod':
                # only exact matches allowed for modules
                return []
            elif classname and classname + '.' + name in objects:
                newname = classname + '.' + name
            elif modname and modname + '.' + name in objects:
                newname = modname + '.' + name
            elif modname and classname and \
                     modname + '.' + classname + '.' + name in objects:
                newname = modname + '.' + classname + '.' + name
            # special case: builtin exceptions have module "exceptions" set
            elif type == 'exc' and '.' not in name and \
                 'exceptions.' + name in objects:
                newname = 'exceptions.' + name
            # special case: object methods
            elif type in ('func', 'meth') and '.' not in name and \
                 'object.' + name in objects:
                newname = 'object.' + name
        if newname is not None:
            matches.append((newname, objects[newname]))
        return matches

    def resolve_xref(self, env, fromdocname, builder,
                     type, target, node, contnode):
        modname = node.get('mat:module')
        clsname = node.get('mat:class')
        searchmode = node.hasattr('refspecific') and 1 or 0
        matches = self.find_obj(env, modname, clsname, target,
                                type, searchmode)
        if not matches:
            return None
        elif len(matches) > 1:
            env.warn_node(
                'more than one target found for cross-reference '
                '%r: %s' % (target, ', '.join(match[0] for match in matches)),
                node)
        name, obj = matches[0]

        if obj[1] == 'module':
            # get additional info for modules
            docname, synopsis, platform, deprecated = self.data['modules'][name]
            assert docname == obj[0]
            title = name
            if synopsis:
                title += ': ' + synopsis
            if deprecated:
                title += _(' (deprecated)')
            if platform:
                title += ' (' + platform + ')'
            return make_refnode(builder, fromdocname, docname,
                                'module-' + name, contnode, title)
        else:
            return make_refnode(builder, fromdocname, obj[0], name,
                                contnode, name)

    def get_objects(self):
        for modname, info in self.data['modules'].iteritems():
            yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
        for refname, (docname, type) in self.data['objects'].iteritems():
            yield (refname, refname, type, docname, refname, 1)
예제 #29
0
def document_function(funcdef, docstrings=None, protocols=['restjson']):
    """A helper function to complete a function documentation with return and
    parameter types"""
    # If the function doesn't have a docstring, add an empty list
    # so the default behaviors below work correctly.
    if not docstrings:
        docstrings = [[]]
    found_params = set()

    for si, docstring in enumerate(docstrings):
        for i, line in enumerate(docstring):
            m = field_re.match(line)
            if m and m.group('field') == 'param':
                found_params.add(m.group('name'))

    next_param_pos = (0, 0)

    for arg in funcdef.arguments:
        content = [
            u':type  %s: :wsme:type:`%s`' %
            (arg.name, datatypename(arg.datatype))
        ]
        if arg.name not in found_params:
            content.insert(0, u':param %s: ' % (arg.name))
            pos = next_param_pos
        else:
            for si, docstring in enumerate(docstrings):
                for i, line in enumerate(docstring):
                    m = field_re.match(line)
                    if m and m.group('field') == 'param' \
                            and m.group('name') == arg.name:
                        pos = (si, i + 1)
                        break
        docstring = docstrings[pos[0]]
        docstring[pos[1]:pos[1]] = content
        next_param_pos = (pos[0], pos[1] + len(content))

    if funcdef.return_type:
        content = [u':rtype: %s' % datatypename(funcdef.return_type)]
        pos = None
        for si, docstring in enumerate(docstrings):
            for i, line in enumerate(docstring):
                m = field_re.match(line)
                if m and m.group('field') == 'return':
                    pos = (si, i + 1)
                    break
        else:
            pos = next_param_pos
        docstring = docstrings[pos[0]]
        docstring[pos[1]:pos[1]] = content

    codesamples = []

    if protocols:
        params = []
        for arg in funcdef.arguments:
            params.append(
                (arg.name, arg.datatype, make_sample_object(arg.datatype)))
        codesamples.extend([
            u':%s:' % l_(u'Parameters samples'), u'    .. cssclass:: toggle',
            u''
        ])
        for name, protocol in protocols:
            language, sample = protocol.encode_sample_params(params,
                                                             format=True)
            codesamples.extend([
                u' ' * 4 + name,
                u'        .. code-block:: ' + language,
                u'',
            ])
            codesamples.extend((u' ' * 12 + line
                                for line in six.text_type(sample).split('\n')))

        if funcdef.return_type:
            codesamples.extend([
                u':%s:' % l_(u'Return samples'), u'    .. cssclass:: toggle',
                u''
            ])
            sample_obj = make_sample_object(funcdef.return_type)
            for name, protocol in protocols:
                language, sample = protocol.encode_sample_result(
                    funcdef.return_type, sample_obj, format=True)
                codesamples.extend([
                    u' ' * 4 + name,
                    u'        .. code-block:: ' + language,
                    u'',
                ])
                codesamples.extend(
                    (u' ' * 12 + line
                     for line in six.text_type(sample).split('\n')))

    docstrings[0:0] = [codesamples]
    return docstrings
예제 #30
0
class Config(object):
    """
    Configuration file abstraction.
    """

    # the values are: (default, what needs to be rebuilt if changed)

    # If you add a value here, don't forget to include it in the
    # quickstart.py file template as well as in the docs!

    config_values = dict(
        # general options
        project=('Python', 'env'),
        copyright=('', 'html'),
        version=('', 'env'),
        release=('', 'env'),
        today=('', 'env'),
        # the real default is locale-dependent
        today_fmt=(None, 'env', string_classes),
        language=(None, 'env', string_classes),
        locale_dirs=(['locales'], 'env'),
        figure_language_filename=(u'{root}.{language}{ext}', 'env', [str]),
        master_doc=('contents', 'env'),
        source_suffix=(['.rst'], 'env'),
        source_encoding=('utf-8-sig', 'env'),
        source_parsers=({}, 'env'),
        exclude_patterns=([], 'env'),
        default_role=(None, 'env', string_classes),
        add_function_parentheses=(True, 'env'),
        add_module_names=(True, 'env'),
        trim_footnote_reference_space=(False, 'env'),
        show_authors=(False, 'env'),
        pygments_style=(None, 'html', string_classes),
        highlight_language=('default', 'env'),
        highlight_options=({}, 'env'),
        templates_path=([], 'html'),
        template_bridge=(None, 'html', string_classes),
        keep_warnings=(False, 'env'),
        suppress_warnings=([], 'env'),
        modindex_common_prefix=([], 'html'),
        rst_epilog=(None, 'env', string_classes),
        rst_prolog=(None, 'env', string_classes),
        trim_doctest_flags=(True, 'env'),
        primary_domain=('py', 'env', [NoneType]),
        needs_sphinx=(None, None, string_classes),
        needs_extensions=({}, None),
        nitpicky=(False, None),
        nitpick_ignore=([], None),
        numfig=(False, 'env'),
        numfig_secnum_depth=(1, 'env'),
        numfig_format=({
            'figure': l_('Fig. %s'),
            'table': l_('Table %s'),
            'code-block': l_('Listing %s')
        }, 'env'),

        # HTML options
        html_theme=('alabaster', 'html'),
        html_theme_path=([], 'html'),
        html_theme_options=({}, 'html'),
        html_title=(lambda self: l_('%s %s documentation') %
                    (self.project, self.release), 'html', string_classes),
        html_short_title=(lambda self: self.html_title, 'html'),
        html_style=(None, 'html', string_classes),
        html_logo=(None, 'html', string_classes),
        html_favicon=(None, 'html', string_classes),
        html_static_path=([], 'html'),
        html_extra_path=([], 'html'),
        # the real default is locale-dependent
        html_last_updated_fmt=(None, 'html', string_classes),
        html_use_smartypants=(True, 'html'),
        html_translator_class=(None, 'html', string_classes),
        html_sidebars=({}, 'html'),
        html_additional_pages=({}, 'html'),
        html_use_modindex=(True, 'html'),  # deprecated
        html_domain_indices=(True, 'html', [list]),
        html_add_permalinks=(u'\u00B6', 'html'),
        html_use_index=(True, 'html'),
        html_split_index=(False, 'html'),
        html_copy_source=(True, 'html'),
        html_show_sourcelink=(True, 'html'),
        html_use_opensearch=('', 'html'),
        html_file_suffix=(None, 'html', string_classes),
        html_link_suffix=(None, 'html', string_classes),
        html_show_copyright=(True, 'html'),
        html_show_sphinx=(True, 'html'),
        html_context=({}, 'html'),
        html_output_encoding=('utf-8', 'html'),
        html_compact_lists=(True, 'html'),
        html_secnumber_suffix=('. ', 'html'),
        html_search_language=(None, 'html', string_classes),
        html_search_options=({}, 'html'),
        html_search_scorer=('', None),
        html_scaled_image_link=(True, 'html'),

        # HTML help only options
        htmlhelp_basename=(lambda self: make_filename(self.project), None),

        # Qt help only options
        qthelp_basename=(lambda self: make_filename(self.project), None),

        # Devhelp only options
        devhelp_basename=(lambda self: make_filename(self.project), None),

        # Apple help options
        applehelp_bundle_name=(lambda self: make_filename(self.project),
                               'applehelp'),
        applehelp_bundle_id=(None, 'applehelp', string_classes),
        applehelp_dev_region=('en-us', 'applehelp'),
        applehelp_bundle_version=('1', 'applehelp'),
        applehelp_icon=(None, 'applehelp', string_classes),
        applehelp_kb_product=(lambda self: '%s-%s' %
                              (make_filename(self.project), self.release),
                              'applehelp'),
        applehelp_kb_url=(None, 'applehelp', string_classes),
        applehelp_remote_url=(None, 'applehelp', string_classes),
        applehelp_index_anchors=(False, 'applehelp', string_classes),
        applehelp_min_term_length=(None, 'applehelp', string_classes),
        applehelp_stopwords=(lambda self: self.language or 'en', 'applehelp'),
        applehelp_locale=(lambda self: self.language or 'en', 'applehelp'),
        applehelp_title=(lambda self: self.project + ' Help', 'applehelp'),
        applehelp_codesign_identity=(
            lambda self: environ.get('CODE_SIGN_IDENTITY', None), 'applehelp'),
        applehelp_codesign_flags=(
            lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')),
            'applehelp'),
        applehelp_indexer_path=('/usr/bin/hiutil', 'applehelp'),
        applehelp_codesign_path=('/usr/bin/codesign', 'applehelp'),
        applehelp_disable_external_tools=(False, None),

        # Epub options
        epub_basename=(lambda self: make_filename(self.project), None),
        epub_theme=('epub', 'html'),
        epub_theme_options=({}, 'html'),
        epub_title=(lambda self: self.html_title, 'html'),
        epub3_description=('', 'epub3', string_classes),
        epub_author=('unknown', 'html'),
        epub3_contributor=('unknown', 'epub3', string_classes),
        epub_language=(lambda self: self.language or 'en', 'html'),
        epub_publisher=('unknown', 'html'),
        epub_copyright=(lambda self: self.copyright, 'html'),
        epub_identifier=('unknown', 'html'),
        epub_scheme=('unknown', 'html'),
        epub_uid=('unknown', 'env'),
        epub_cover=((), 'env'),
        epub_guide=((), 'env'),
        epub_pre_files=([], 'env'),
        epub_post_files=([], 'env'),
        epub_exclude_files=([], 'env'),
        epub_tocdepth=(3, 'env'),
        epub_tocdup=(True, 'env'),
        epub_tocscope=('default', 'env'),
        epub_fix_images=(False, 'env'),
        epub_max_image_width=(0, 'env'),
        epub_show_urls=('inline', 'html'),
        epub_use_index=(lambda self: self.html_use_index, 'html'),
        epub3_page_progression_direction=('ltr', 'epub3', string_classes),

        # LaTeX options
        latex_documents=(
            lambda self: [(self.master_doc, make_filename(self.project) +
                           '.tex', self.project, '', 'manual')], None),
        latex_logo=(None, None, string_classes),
        latex_appendices=([], None),
        # now deprecated - use latex_toplevel_sectioning
        latex_use_parts=(False, None),
        latex_toplevel_sectioning=(None, None, [str]),
        latex_use_modindex=(True, None),  # deprecated
        latex_domain_indices=(True, None, [list]),
        latex_show_urls=('no', None),
        latex_show_pagerefs=(False, None),
        # paper_size and font_size are still separate values
        # so that you can give them easily on the command line
        latex_paper_size=('letter', None),
        latex_font_size=('10pt', None),
        latex_elements=({}, None),
        latex_additional_files=([], None),
        latex_docclass=({}, None),
        # now deprecated - use latex_elements
        latex_preamble=('', None),

        # text options
        text_sectionchars=('*=-~"+`', 'env'),
        text_newlines=('unix', 'env'),

        # manpage options
        man_pages=(lambda self: [(self.master_doc, make_filename(
            self.project).lower(), '%s %s' %
                                  (self.project, self.release), [], 1)], None),
        man_show_urls=(False, None),

        # Texinfo options
        texinfo_documents=(lambda self: [(
            self.master_doc, make_filename(self.project).lower(), self.project,
            '', make_filename(self.project), 'The %s reference manual.' %
            make_filename(self.project), 'Python')], None),
        texinfo_appendices=([], None),
        texinfo_elements=({}, None),
        texinfo_domain_indices=(True, None, [list]),
        texinfo_show_urls=('footnote', None),
        texinfo_no_detailmenu=(False, None),

        # linkcheck options
        linkcheck_ignore=([], None),
        linkcheck_retries=(1, None),
        linkcheck_timeout=(None, None, [int]),
        linkcheck_workers=(5, None),
        linkcheck_anchors=(True, None),

        # gettext options
        gettext_compact=(True, 'gettext'),
        gettext_location=(True, 'gettext'),
        gettext_uuid=(False, 'gettext'),
        gettext_auto_build=(True, 'env'),
        gettext_additional_targets=([], 'env'),

        # XML options
        xml_pretty=(True, 'env'),
    )

    def __init__(self, dirname, filename, overrides, tags):
        self.overrides = overrides
        self.values = Config.config_values.copy()
        config = {}
        if 'extensions' in overrides:  # XXX do we need this?
            if isinstance(overrides['extensions'], string_types):
                config['extensions'] = overrides.pop('extensions').split(',')
            else:
                config['extensions'] = overrides.pop('extensions')
        if dirname is not None:
            config_file = path.join(dirname, filename)
            config['__file__'] = config_file
            config['tags'] = tags
            with cd(dirname):
                # we promise to have the config dir as current dir while the
                # config file is executed
                try:
                    execfile_(filename, config)
                except SyntaxError as err:
                    raise ConfigError(CONFIG_SYNTAX_ERROR % err)
                except SystemExit:
                    raise ConfigError(CONFIG_EXIT_ERROR)

        self._raw_config = config
        # these two must be preinitialized because extensions can add their
        # own config values
        self.setup = config.get('setup', None)
        self.extensions = config.get('extensions', [])

        # correct values of copyright year that are not coherent with
        # the SOURCE_DATE_EPOCH environment variable (if set)
        # See https://reproducible-builds.org/specs/source-date-epoch/
        if getenv('SOURCE_DATE_EPOCH') is not None:
            for k in ('copyright', 'epub_copyright'):
                if k in config:
                    config[k] = copyright_year_re.sub(
                        '\g<1>%s' % format_date('%Y'), config[k])

    def check_types(self, warn):
        # check all values for deviation from the default value's type, since
        # that can result in TypeErrors all over the place
        # NB. since config values might use l_() we have to wait with calling
        # this method until i18n is initialized
        for name in self._raw_config:
            if name not in self.values:
                continue  # we don't know a default value
            settings = self.values[name]
            default, dummy_rebuild = settings[:2]
            permitted = settings[2] if len(settings) == 3 else ()

            if hasattr(default, '__call__'):
                default = default(self)  # could invoke l_()
            if default is None and not permitted:
                continue  # neither inferrable nor expliclitly permitted types
            current = self[name]
            if type(current) is type(default):
                continue
            if type(current) in permitted:
                continue

            common_bases = (set(type(current).__bases__ + (type(current), ))
                            & set(type(default).__bases__))
            common_bases.discard(object)
            if common_bases:
                continue  # at least we share a non-trivial base class

            warn(
                CONFIG_TYPE_WARNING.format(name=name,
                                           current=type(current),
                                           default=type(default)))

    def check_unicode(self, warn):
        # check all string values for non-ASCII characters in bytestrings,
        # since that can result in UnicodeErrors all over the place
        for name, value in iteritems(self._raw_config):
            if isinstance(value, binary_type) and nonascii_re.search(value):
                warn('the config value %r is set to a string with non-ASCII '
                     'characters; this can lead to Unicode errors occurring. '
                     'Please use Unicode strings, e.g. %r.' %
                     (name, u'Content'))

    def convert_overrides(self, name, value):
        if not isinstance(value, string_types):
            return value
        else:
            defvalue = self.values[name][0]
            if isinstance(defvalue, dict):
                raise ValueError(
                    'cannot override dictionary config setting %r, '
                    'ignoring (use %r to set individual elements)' %
                    (name, name + '.key=value'))
            elif isinstance(defvalue, list):
                return value.split(',')
            elif isinstance(defvalue, integer_types):
                try:
                    return int(value)
                except ValueError:
                    raise ValueError(
                        'invalid number %r for config value %r, ignoring' %
                        (value, name))
            elif hasattr(defvalue, '__call__'):
                return value
            elif defvalue is not None and not isinstance(
                    defvalue, string_types):
                raise ValueError(
                    'cannot override config setting %r with unsupported '
                    'type, ignoring' % name)
            else:
                return value

    def pre_init_values(self, warn):
        """Initialize some limited config variables before loading extensions"""
        variables = ['needs_sphinx', 'suppress_warnings']
        for name in variables:
            try:
                if name in self.overrides:
                    self.__dict__[name] = self.convert_overrides(
                        name, self.overrides[name])
                elif name in self._raw_config:
                    self.__dict__[name] = self._raw_config[name]
            except ValueError as exc:
                warn(exc)

    def init_values(self, warn):
        config = self._raw_config
        for valname, value in iteritems(self.overrides):
            try:
                if '.' in valname:
                    realvalname, key = valname.split('.', 1)
                    config.setdefault(realvalname, {})[key] = value
                    continue
                elif valname not in self.values:
                    warn('unknown config value %r in override, ignoring' %
                         valname)
                    continue
                if isinstance(value, string_types):
                    config[valname] = self.convert_overrides(valname, value)
                else:
                    config[valname] = value
            except ValueError as exc:
                warn(exc)
        for name in config:
            if name in self.values:
                self.__dict__[name] = config[name]
        if isinstance(self.source_suffix, string_types):
            self.source_suffix = [self.source_suffix]

    def __getattr__(self, name):
        if name.startswith('_'):
            raise AttributeError(name)
        if name not in self.values:
            raise AttributeError('No such config value: %s' % name)
        default = self.values[name][0]
        if hasattr(default, '__call__'):
            return default(self)
        return default

    def __getitem__(self, name):
        return getattr(self, name)

    def __setitem__(self, name, value):
        setattr(self, name, value)

    def __delitem__(self, name):
        delattr(self, name)

    def __contains__(self, name):
        return name in self.values
예제 #31
0
class PyObject(ObjectDescription):
    """
    Description of a general Python object.
    """
    option_spec = {
        'noindex': directives.flag,
        'module': directives.unchanged,
        'annotation': directives.unchanged,
    }

    doc_field_types = [
        PyTypedField('parameter', label=l_('Parameters'),
                     names=('param', 'parameter', 'arg', 'argument',
                            'keyword', 'kwarg', 'kwparam'),
                     typerolename='obj', typenames=('paramtype', 'type'),
                     can_collapse=True),
        PyTypedField('variable', label=l_('Variables'), rolename='obj',
                     names=('var', 'ivar', 'cvar'),
                     typerolename='obj', typenames=('vartype',),
                     can_collapse=True),
        Field('returnvalue', label=l_('Returns'), has_arg=False,
              names=('returns', 'return')),
        PyField('returntype', label=l_('Return type'), has_arg=False,
                names=('rtype',), bodyrolename='obj'),
    ]

    def get_signature_prefix(self, sig):
        """May return a prefix to put before the object name in the
        signature.
        """
        return ''

    def needs_arglist(self):
        """May return true if an empty argument list is to be generated even if
        the document contains none.
        """
        return False

    def handle_signature(self, sig, signode):
        """Transform a Python signature into RST nodes.

        Return (fully qualified name of the thing, classname if any).

        If inside a class, the current class name is handled intelligently:
        * it is stripped from the displayed name if present
        * it is added to the full name (return value) if not present
        """
        m = py_sig_re.match(sig)
        if m is None:
            raise ValueError
        name_prefix, name, arglist, retann = m.groups()

        # determine module and class name (if applicable), as well as full name
        modname = self.options.get(
            'module', self.env.ref_context.get('gobject:module'))
        classname = self.env.ref_context.get('gobject:class')
        if not classname:
            classname = self.env.ref_context.get('gobject:interface')
        if not classname:
            classname = self.env.ref_context.get('gobject:enum')
        if classname:
            add_module = False
            if name_prefix and name_prefix.startswith(classname):
                fullname = name_prefix + name
                # class name is given again in the signature
                name_prefix = name_prefix[len(classname):].lstrip('.')
            elif name_prefix:
                # class name is given in the signature, but different
                # (shouldn't happen)
                fullname = classname + '.' + name_prefix + name
            else:
                # class name is not given in the signature
                fullname = classname + '.' + name
        else:
            add_module = True
            if name_prefix:
                classname = name_prefix.rstrip('.')
                fullname = name_prefix + name
            else:
                classname = ''
                fullname = name

        signode['module'] = modname
        signode['class'] = classname
        signode['fullname'] = fullname

        sig_prefix = self.get_signature_prefix(sig)
        if sig_prefix:
            signode += addnodes.desc_annotation(sig_prefix, sig_prefix)

        if name_prefix:
            signode += addnodes.desc_addname(name_prefix, name_prefix)
        elif add_module and self.env.config.add_module_names:
            modname = self.options.get(
                'module', self.env.ref_context.get('gobject:module'))
            if modname:
                nodetext = modname + '.'
                signode += addnodes.desc_addname(nodetext, nodetext)

        anno = self.options.get('annotation')

        signode += addnodes.desc_name(name, name)
        if not arglist:
            if self.needs_arglist():
                # for callables, add an empty parameter list
                signode += addnodes.desc_parameterlist()
            if retann:
                signode += addnodes.desc_returns(retann, retann)
            if anno:
                signode += addnodes.desc_annotation(' ' + anno, ' ' + anno)
            return fullname, name_prefix

        _pseudo_parse_arglist(signode, arglist)
        if retann:
            signode += addnodes.desc_returns(retann, retann)
        if anno:
            signode += addnodes.desc_annotation(' ' + anno, ' ' + anno)
        return fullname, name_prefix

    def get_index_text(self, modname, name):
        """Return the text for the index entry of the object."""
        raise NotImplementedError('must be implemented in subclasses')

    def add_target_and_index(self, name_cls, sig, signode):
        modname = self.options.get(
            'module', self.env.ref_context.get('gobject:module'))
        fullname = (modname and modname + '.' or '') + name_cls[0]
        # note target
        if fullname not in self.state.document.ids:
            signode['names'].append(fullname)
            signode['ids'].append(fullname)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)
            objects = self.env.domaindata['py']['objects']
            if fullname in objects:
                self.state_machine.reporter.warning(
                    'duplicate object description of %s, ' % fullname +
                    'other instance in ' +
                    self.env.doc2path(objects[fullname][0]) +
                    ', use :noindex: for one of them',
                    line=self.lineno)
            objects[fullname] = (self.env.docname, self.objtype)

        indextext = self.get_index_text(modname, name_cls)
        if indextext:
            self.indexnode['entries'].append(('single', indextext,
                                              fullname, '', None))

    def before_content(self):
        # needed for automatic qualification of members (reset in subclasses)
        self.clsname_set = False

    def after_content(self):
        if self.clsname_set:
            self.env.ref_context.pop('gobject:class', None)
            self.env.ref_context.pop('gobject:interface', None)
            self.env.ref_context.pop('gobject:enum', None)
예제 #32
0
class PolyglotDomain(Domain):
    """Base class for polyglot domains."""

    # See: http://www.sphinx-doc.org/en/stable/extdev/domainapi.html
    #name, label = 'polyglot', l_('Polyglot')
    object_types = {
      'assembly':  ObjType(l_('assembly'),  'assembly'),
      'channel':   ObjType(l_('channel'),   'channel'),
      'class':     ObjType(l_('class'),     'class'),
      'const':     ObjType(l_('constant'),  'constant'),
      'func':      ObjType(l_('function'),  'function'),
      'function':  ObjType(l_('function'),  'function'),
      'header':    ObjType(l_('header'),    'header'),
      'library':   ObjType(l_('library'),   'library'),
      'method':    ObjType(l_('method'),    'method'),
      'module':    ObjType(l_('module'),    'module'),
      'namespace': ObjType(l_('namespace'), 'namespace'),
      'package':   ObjType(l_('package'),   'package'),
      'property':  ObjType(l_('property'),  'property'),
      'schema':    ObjType(l_('schema'),    'schema'),
      'system':    ObjType(l_('system'),    'system'),
      'table':     ObjType(l_('table'),     'table'),
      'trigger':   ObjType(l_('trigger'),   'trigger'),
      'type':      ObjType(l_('type'),      'type'),
      'view':      ObjType(l_('view'),      'view'),
    }
    directives = {}
    initial_data = {
      'objects': {},  # (objtype, name) -> docname
    }
    data_version = 0 # bump this when the format of self.data changes
예제 #33
0
class PythonDomain(Domain):
    """Python language domain."""
    name = 'gobject'
    label = 'GObject'
    object_types = {
        'function':     ObjType(l_('function'),      'func', 'obj'),
        'class':        ObjType(l_('class'),         'class', 'exc', 'obj'),
        'interface':    ObjType(l_('interface'),     'interface', 'exc', 'obj'),
        'enum':         ObjType(l_('enum'),   'enum', 'exc', 'obj'),
        'method':       ObjType(l_('method'),        'meth', 'obj'),
        'classmethod':  ObjType(l_('class method'),  'meth', 'obj'),
        'staticmethod': ObjType(l_('static method'), 'meth', 'obj'),
        'property':     ObjType(l_('property'),      'prop', 'obj'),
        'member':       ObjType(l_('property'),      'member', 'obj'),
        'signal':       ObjType(l_('signal'),        'signal', 'obj'),
        'module':       ObjType(l_('module'),        'mod', 'obj'),
    }

    directives = {
        'function':        PyModulelevel,
        'class':           PyClasslike,
        'interface':       PyClasslike,
        'enum':            PyClasslike,
        'member':          PyClassmember,
        'method':          PyClassmember,
        'classmethod':     PyClassmember,
        'staticmethod':    PyClassmember,
        'property':        PyClassmember,
        'signal':          PyClassmember,
        'module':          PyModule,
        'currentmodule':   PyCurrentModule,
    }
    roles = {
        'exc':   PyXRefRole(),
        'func':  PyXRefRole(fix_parens=True),
        'class': PyXRefRole(),
        'interface': PyXRefRole(),
        'const': PyXRefRole(),
        'prop':  PyXRefRole(),
        'signal': PyXRefRole(fix_parens=True),
        'meth':  PyXRefRole(fix_parens=True),
        'mod':   PyXRefRole(),
        'obj':   PyXRefRole(),
        'enum':  PyXRefRole(),
        'member': PyXRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
        'modules': {},  # modname -> docname, synopsis, platform, deprecated
    }
    indices = [
        PythonModuleIndex,
    ]

    def clear_doc(self, docname):
        for fullname, (fn, _l) in list(self.data['objects'].items()):
            if fn == docname:
                del self.data['objects'][fullname]
        for modname, (fn, _x, _x, _x) in list(self.data['modules'].items()):
            if fn == docname:
                del self.data['modules'][modname]

    def merge_domaindata(self, docnames, otherdata):
        # XXX check duplicates?
        for fullname, (fn, objtype) in otherdata['objects'].items():
            if fn in docnames:
                self.data['objects'][fullname] = (fn, objtype)
        for modname, data in otherdata['modules'].items():
            if data[0] in docnames:
                self.data['modules'][modname] = data

    def find_obj(self, env, modname, classname, name, type, searchmode=0):
        """Find a Python object for "name", perhaps using the given module
        and/or classname.  Returns a list of (name, object entry) tuples.
        """
        # skip parens
        if name[-2:] == '()':
            name = name[:-2]

        if not name:
            return []

        objects = self.data['objects']
        matches = []

        newname = None
        if searchmode == 1:
            if type is None:
                objtypes = list(self.object_types)
            else:
                objtypes = self.objtypes_for_role(type)
            if objtypes is not None:
                if modname and classname:
                    fullname = modname + '.' + classname + '.' + name
                    if fullname in objects and objects[fullname][1] in objtypes:
                        newname = fullname
                if not newname:
                    if modname and modname + '.' + name in objects and \
                       objects[modname + '.' + name][1] in objtypes:
                        newname = modname + '.' + name
                    elif name in objects and objects[name][1] in objtypes:
                        newname = name
                    else:
                        # "fuzzy" searching mode
                        searchname = '.' + name
                        matches = [(oname, objects[oname]) for oname in objects
                                   if oname.endswith(searchname) and
                                   objects[oname][1] in objtypes]
        else:
            # NOTE: searching for exact match, object type is not considered
            if name in objects:
                newname = name
            elif type == 'mod':
                # only exact matches allowed for modules
                return []
            elif classname and classname + '.' + name in objects:
                newname = classname + '.' + name
            elif modname and modname + '.' + name in objects:
                newname = modname + '.' + name
            elif modname and classname and \
                    modname + '.' + classname + '.' + name in objects:
                newname = modname + '.' + classname + '.' + name
            # special case: object methods
            elif type in ('func', 'meth', 'signal', ) and '.' not in name and \
                    'object.' + name in objects:
                newname = 'object.' + name
        if newname is not None:
            matches.append((newname, objects[newname]))
        return matches

    def resolve_xref(self, env, fromdocname, builder,
                     type, target, node, contnode):
        modname = node.get('gobject:module')
        clsname = node.get('gobject:class')
        # FIXME
        searchmode = 0  # node.hasprop('refspecific') and 1 or 0
        matches = self.find_obj(env, modname, clsname, target,
                                type, searchmode)
        if not matches:
            return None
        elif len(matches) > 1:
            env.warn_node(
                'more than one target found for cross-reference '
                '%r: %s' % (target, ', '.join(match[0] for match in matches)),
                node)
        name, obj = matches[0]

        if obj[1] == 'module':
            return self._make_module_refnode(builder, fromdocname, name,
                                             contnode)
        else:
            return make_refnode(builder, fromdocname, obj[0], name,
                                contnode, name)

    def resolve_any_xref(self, env, fromdocname, builder, target,
                         node, contnode):
        modname = node.get('gobject:module')
        clsname = node.get('gobject:class')
        results = []

        # always search in "refspecific" mode with the :any: role
        matches = self.find_obj(env, modname, clsname, target, None, 1)
        for name, obj in matches:
            if obj[1] == 'module':
                results.append(('gobject:mod',
                                self._make_module_refnode(builder, fromdocname,
                                                          name, contnode)))
            else:
                results.append(('gobject:' + self.role_for_objtype(obj[1]),
                                make_refnode(builder, fromdocname, obj[0], name,
                                             contnode, name)))
        return results

    def _make_module_refnode(self, builder, fromdocname, name, contnode):
        # get additional info for modules
        docname, synopsis, platform, deprecated = self.data['modules'][name]
        title = name
        if synopsis:
            title += ': ' + synopsis
        if deprecated:
            title += _(' (deprecated)')
        if platform:
            title += ' (' + platform + ')'
        return make_refnode(builder, fromdocname, docname,
                            'module-' + name, contnode, title)

    def get_objects(self):
        for modname, info in iteritems(self.data['modules']):
            yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
        for refname, (docname, type) in iteritems(self.data['objects']):
            if type != 'module':  # modules are already handled
                yield (refname, refname, type, docname, refname, 1)
예제 #34
0
class TrafficServerDomain(Domain):
    """
    Apache Traffic Server Documentation.
    """

    name = 'ts'
    label = 'Traffic Server'
    data_version = 2

    object_types = {
        'cv': ObjType(l_('configuration variable'), 'cv'),
        'stat': ObjType(l_('statistic'), 'stat')
    }

    directives = {'cv': TSConfVar, 'stat': TSStat}

    roles = {'cv': TSConfVarRef(), 'stat': TSStatRef()}

    initial_data = {
        'cv': {},  # full name -> docname
        'stat': {}
    }

    dangling_warnings = {
        'cv': "No definition found for configuration variable '%(target)s'",
        'stat': "No definition found for statistic '%(target)s'"
    }

    def clear_doc(self, docname):
        cv_list = self.data['cv']
        for var, doc in cv_list.items():
            if doc == docname:
                del cv_list[var]
        stat_list = self.data['stat']
        for var, doc in stat_list.items():
            if doc == docname:
                del stat_list[var]

    def find_doc(self, key, obj_type):
        zret = None

        if obj_type == 'cv':
            obj_list = self.data['cv']
        elif obj_type == 'stat':
            obj_list = self.data['stat']
        else:
            obj_list = None

        if obj_list and key in obj_list:
            zret = obj_list[key]

        return zret

    def resolve_xref(self, env, src_doc, builder, obj_type, target, node,
                     cont_node):
        dst_doc = self.find_doc(target, obj_type)
        if (dst_doc):
            return sphinx.util.nodes.make_refnode(builder, src_doc, dst_doc,
                                                  nodes.make_id(target),
                                                  cont_node, 'records.config')

    def get_objects(self):
        for var, doc in self.data['cv'].iteritems():
            yield var, var, 'cv', doc, var, 1
        for var, doc in self.data['stat'].iteritems():
            yield var, var, 'stat', doc, var, 1
예제 #35
0
class AvroFixedField(AvroObject):
    prefix = 'fixed'
    doc_field_types = [Field('size', label=l_('Size'), names=('size', ))]
예제 #36
0
class StandardDomain(Domain):
    """
    Domain for all objects that don't fit into another domain or are added
    via the application interface.
    """

    name = 'std'
    label = 'Default'

    object_types = {
        'term': ObjType(l_('glossary term'), 'term', searchprio=-1),
        'token': ObjType(l_('grammar token'), 'token', searchprio=-1),
        'label': ObjType(l_('reference label'), 'ref', 'keyword',
                         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 = {
        'program': Program,
        'cmdoption': Cmdoption,  # old name for backwards compatibility
        'option': Cmdoption,
        'envvar': EnvVar,
        'glossary': Glossary,
        'productionlist': ProductionList,
    }  # type: Dict[unicode, Type[Directive]]
    roles = {
        'option':  OptionXRefRole(warn_dangling=True),
        'envvar':  EnvVarXRefRole(),
        # links to tokens in grammar productions
        'token':   XRefRole(),
        # links to terms in glossary
        'term':    XRefRole(lowercase=True, innernodeclass=nodes.inline,
                            warn_dangling=True),
        # links to headings or arbitrary labels
        'ref':     XRefRole(lowercase=True, innernodeclass=nodes.inline,
                            warn_dangling=True),
        # links to labels of numbered figures, tables and code-blocks
        'numref':  XRefRole(lowercase=True,
                            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 = {
        'progoptions': {},  # (program, name) -> docname, labelid
        'objects': {},      # (type, name) -> docname, labelid
        'citations': {},    # name -> docname, labelid
        'labels': {         # labelname -> docname, labelid, sectionname
            'genindex': ('genindex', '', l_('Index')),
            'modindex': ('py-modindex', '', l_('Module Index')),
            'search':   ('search', '', l_('Search Page')),
        },
        'anonlabels': {     # labelname -> docname, labelid
            'genindex': ('genindex', ''),
            'modindex': ('py-modindex', ''),
            'search':   ('search', ''),
        },
    }

    dangling_warnings = {
        'term': 'term not in glossary: %(target)s',
        'ref':  'undefined label: %(target)s (if the link has no caption '
                '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',
    }

    enumerable_nodes = {  # node_class -> (figtype, title_getter)
        nodes.figure: ('figure', None),
        nodes.table: ('table', None),
        nodes.container: ('code-block', None),
    }  # type: Dict[nodes.Node, Tuple[unicode, Callable]]

    def clear_doc(self, docname):
        # type: (unicode) -> None
        for key, (fn, _l) in list(self.data['progoptions'].items()):
            if fn == docname:
                del self.data['progoptions'][key]
        for key, (fn, _l) in list(self.data['objects'].items()):
            if fn == docname:
                del self.data['objects'][key]
        for key, (fn, _l) in list(self.data['citations'].items()):
            if fn == docname:
                del self.data['citations'][key]
        for key, (fn, _l, _l) in list(self.data['labels'].items()):
            if fn == docname:
                del self.data['labels'][key]
        for key, (fn, _l) in list(self.data['anonlabels'].items()):
            if fn == docname:
                del self.data['anonlabels'][key]

    def merge_domaindata(self, docnames, otherdata):
        # type: (List[unicode], Dict) -> None
        # XXX duplicates?
        for key, data in otherdata['progoptions'].items():
            if data[0] in docnames:
                self.data['progoptions'][key] = data
        for key, data in otherdata['objects'].items():
            if data[0] in docnames:
                self.data['objects'][key] = data
        for key, data in otherdata['citations'].items():
            if data[0] in docnames:
                self.data['citations'][key] = data
        for key, data in otherdata['labels'].items():
            if data[0] in docnames:
                self.data['labels'][key] = data
        for key, data in otherdata['anonlabels'].items():
            if data[0] in docnames:
                self.data['anonlabels'][key] = data

    def process_doc(self, env, docname, document):
        # type: (BuildEnvironment, unicode, nodes.Node) -> None
        self.note_citations(env, docname, document)
        self.note_labels(env, docname, document)

    def note_citations(self, env, docname, document):
        # type: (BuildEnvironment, unicode, nodes.Node) -> None
        for node in document.traverse(nodes.citation):
            label = node[0].astext()
            if label in self.data['citations']:
                path = env.doc2path(self.data['citations'][label][0])
                logger.warning('duplicate citation %s, other instance in %s', label, path,
                               location=node)
            self.data['citations'][label] = (docname, node['ids'][0])

    def note_labels(self, env, docname, document):
        # type: (BuildEnvironment, unicode, nodes.Node) -> None
        labels, anonlabels = self.data['labels'], self.data['anonlabels']
        for name, explicit in iteritems(document.nametypes):
            if not explicit:
                continue
            labelid = document.nameids[name]
            if labelid is None:
                continue
            node = document.ids[labelid]
            if node.tagname == 'target' and 'refid' in node:  # indirect hyperlink targets
                node = document.ids.get(node['refid'])
                labelid = node['names'][0]
            if name.isdigit() or 'refuri' in node or \
               node.tagname.startswith('desc_'):
                # ignore footnote labels, labels automatically generated from a
                # link and object descriptions
                continue
            if name in labels:
                logger.warning('duplicate label %s, ' % name + 'other instance '
                               'in ' + env.doc2path(labels[name][0]),
                               location=node)
            anonlabels[name] = docname, labelid
            if node.tagname in ('section', 'rubric'):
                sectname = clean_astext(node[0])  # node[0] == title node
            elif self.is_enumerable_node(node):
                sectname = self.get_numfig_title(node)
                if not sectname:
                    continue
            elif node.traverse(addnodes.toctree):
                n = node.traverse(addnodes.toctree)[0]
                if n.get('caption'):
                    sectname = n['caption']
                else:
                    continue
            else:
                # anonymous-only labels
                continue
            labels[name] = docname, labelid, sectname

    def build_reference_node(self, fromdocname, builder, docname, labelid,
                             sectname, rolename, **options):
        # type: (unicode, Builder, unicode, unicode, unicode, unicode, Any) -> nodes.Node
        nodeclass = options.pop('nodeclass', nodes.reference)
        newnode = nodeclass('', '', internal=True, **options)
        innernode = nodes.inline(sectname, sectname)
        if innernode.get('classes') is not None:
            innernode['classes'].append('std')
            innernode['classes'].append('std-' + rolename)
        if docname == fromdocname:
            newnode['refid'] = labelid
        else:
            # set more info in contnode; in case the
            # get_relative_uri call raises NoUri,
            # the builder will then have to resolve these
            contnode = addnodes.pending_xref('')
            contnode['refdocname'] = docname
            contnode['refsectname'] = sectname
            newnode['refuri'] = builder.get_relative_uri(
                fromdocname, docname)
            if labelid:
                newnode['refuri'] += '#' + labelid
        newnode.append(innernode)
        return newnode

    def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        if typ == 'ref':
            resolver = self._resolve_ref_xref
        elif typ == 'numref':
            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':
            resolver = self._resolve_citation_xref
        else:
            resolver = self._resolve_obj_xref

        return resolver(env, fromdocname, builder, typ, target, node, contnode)

    def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        if node['refexplicit']:
            # reference to anonymous label; the reference uses
            # the supplied link caption
            docname, labelid = self.data['anonlabels'].get(target, ('', ''))
            sectname = node.astext()
        else:
            # reference to named label; the final node will
            # contain the section name after the label
            docname, labelid, sectname = self.data['labels'].get(target,
                                                                 ('', '', ''))
        if not docname:
            return None

        return self.build_reference_node(fromdocname, builder,
                                         docname, labelid, sectname, 'ref')

    def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        if target in self.data['labels']:
            docname, labelid, figname = self.data['labels'].get(target, ('', '', ''))
        else:
            docname, labelid = self.data['anonlabels'].get(target, ('', ''))
            figname = None

        if not docname:
            return None

        if env.config.numfig is False:
            logger.warning('numfig is disabled. :numref: is ignored.', location=node)
            return contnode

        target_node = env.get_doctree(docname).ids.get(labelid)
        figtype = self.get_figtype(target_node)
        if figtype is None:
            return None

        try:
            fignumber = self.get_fignumber(env, builder, figtype, docname, target_node)
            if fignumber is None:
                return contnode
        except ValueError:
            logger.warning("no number is assigned for %s: %s", figtype, labelid,
                           location=node)
            return contnode

        try:
            if node['refexplicit']:
                title = contnode.astext()
            else:
                title = env.config.numfig_format.get(figtype, '')

            if figname is None and '{name}' in title:
                logger.warning('the link has no caption: %s', title, location=node)
                return contnode
            else:
                fignum = '.'.join(map(str, fignumber))
                if '{name}' in title or 'number' in title:
                    # new style format (cf. "Fig.{number}")
                    if figname:
                        newtitle = title.format(name=figname, number=fignum)
                    else:
                        newtitle = title.format(number=fignum)
                else:
                    # old style format (cf. "Fig.%s")
                    newtitle = title % fignum
        except KeyError as exc:
            logger.warning('invalid numfig_format: %s (%r)', title, exc, location=node)
            return contnode
        except TypeError:
            logger.warning('invalid numfig_format: %s', title, location=node)
            return contnode

        return self.build_reference_node(fromdocname, builder,
                                         docname, labelid, newtitle, 'numref',
                                         nodeclass=addnodes.number_reference,
                                         title=title)

    def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        # keywords are oddballs: they are referenced by named labels
        docname, labelid, _ = self.data['labels'].get(target, ('', '', ''))
        if not docname:
            return None
        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')
        target = target.strip()
        docname, labelid = self.data['progoptions'].get((progname, target), ('', ''))
        if not docname:
            commands = []
            while ws_re.search(target):
                subcommand, target = ws_re.split(target, 1)
                commands.append(subcommand)
                progname = "-".join(commands)

                docname, labelid = self.data['progoptions'].get((progname, target),
                                                                ('', ''))
                if docname:
                    break
            else:
                return None

        return make_refnode(builder, fromdocname, docname,
                            labelid, contnode)

    def _resolve_citation_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        from sphinx.environment import NoUri

        docname, labelid = self.data['citations'].get(target, ('', ''))
        if not docname:
            if 'ids' in node:
                # remove ids attribute that annotated at
                # transforms.CitationReference.apply.
                del node['ids'][:]
            return None

        try:
            return make_refnode(builder, fromdocname, docname,
                                labelid, contnode)
        except NoUri:
            # remove the ids we added in the CitationReferences
            # transform since they can't be transfered to
            # the contnode (if it's a Text node)
            if not isinstance(contnode, nodes.Element):
                del node['ids'][:]
            raise

    def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node  # NOQA
        objtypes = self.objtypes_for_role(typ) or []
        for objtype in objtypes:
            if (objtype, target) in self.data['objects']:
                docname, labelid = self.data['objects'][objtype, target]
                break
        else:
            docname, labelid = '', ''
        if not docname:
            return None
        return make_refnode(builder, fromdocname, docname,
                            labelid, contnode)

    def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
        # type: (BuildEnvironment, unicode, Builder, unicode, nodes.Node, nodes.Node) -> List[Tuple[unicode, nodes.Node]]  # NOQA
        results = []  # type: List[Tuple[unicode, nodes.Node]]
        ltarget = target.lower()  # :ref: lowercases its target automatically
        for role in ('ref', 'option'):  # do not try "keyword"
            res = self.resolve_xref(env, fromdocname, builder, role,
                                    ltarget if role == 'ref' else target,
                                    node, contnode)
            if res:
                results.append(('std:' + role, res))
        # all others
        for objtype in self.object_types:
            key = (objtype, target)
            if objtype == 'term':
                key = (objtype, ltarget)
            if key in self.data['objects']:
                docname, labelid = self.data['objects'][key]
                results.append(('std:' + self.role_for_objtype(objtype),
                                make_refnode(builder, fromdocname, docname,
                                             labelid, contnode)))
        return results

    def get_objects(self):
        # type: () -> Iterator[Tuple[unicode, unicode, unicode, unicode, unicode, int]]
        # handle the special 'doc' reference here
        for doc in self.env.all_docs:
            yield (doc, clean_astext(self.env.titles[doc]), 'doc', doc, '', -1)
        for (prog, option), info in iteritems(self.data['progoptions']):
            yield (option, option, 'option', info[0], info[1], 1)
        for (type, name), info in iteritems(self.data['objects']):
            yield (name, name, type, info[0], info[1],
                   self.object_types[type].attrs['searchprio'])
        for name, info in iteritems(self.data['labels']):
            yield (name, info[2], 'label', info[0], info[1], -1)
        # add anonymous-only labels as well
        non_anon_labels = set(self.data['labels'])
        for name, info in iteritems(self.data['anonlabels']):
            if name not in non_anon_labels:
                yield (name, name, 'label', info[0], info[1], -1)

    def get_type_name(self, type, primary=False):
        # type: (ObjType, bool) -> unicode
        # never prepend "Default"
        return type.lname

    def is_enumerable_node(self, node):
        # type: (nodes.Node) -> bool
        return node.__class__ in self.enumerable_nodes

    def get_numfig_title(self, node):
        # type: (nodes.Node) -> unicode
        """Get the title of enumerable nodes to refer them using its title"""
        if self.is_enumerable_node(node):
            _, title_getter = self.enumerable_nodes.get(node.__class__, (None, None))
            if title_getter:
                return title_getter(node)
            else:
                for subnode in node:
                    if subnode.tagname in ('caption', 'title'):
                        return clean_astext(subnode)

        return None

    def get_figtype(self, node):
        # type: (nodes.Node) -> unicode
        """Get figure type of nodes."""
        def has_child(node, cls):
            # type: (nodes.Node, Type) -> bool
            return any(isinstance(child, cls) for child in node)

        if isinstance(node, nodes.section):
            return 'section'
        elif isinstance(node, nodes.container):
            if node.get('literal_block') and has_child(node, nodes.literal_block):
                return 'code-block'
            else:
                return None
        else:
            figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
            return figtype

    def get_fignumber(self, env, builder, figtype, docname, target_node):
        # type: (BuildEnvironment, Builder, unicode, unicode, nodes.Node) -> Tuple[int, ...]
        if figtype == 'section':
            if builder.name == 'latex':
                return tuple()
            elif docname not in env.toc_secnumbers:
                raise ValueError  # no number assigned
            else:
                anchorname = '#' + target_node['ids'][0]
                if anchorname not in env.toc_secnumbers[docname]:
                    # try first heading which has no anchor
                    return env.toc_secnumbers[docname].get('')
                else:
                    return env.toc_secnumbers[docname].get(anchorname)
        else:
            try:
                figure_id = target_node['ids'][0]
                return env.toc_fignumbers[docname][figtype][figure_id]
            except (KeyError, IndexError):
                # target_node is found, but fignumber is not assigned.
                # Maybe it is defined in orphaned document.
                raise ValueError
예제 #37
0
class AvroEnum(AvroObject):
    prefix = 'enum'
    doc_field_types = [
        Field('symbols', label=l_('Symbols'), names=('symbols', ))
    ]
예제 #38
0
class StandardDomain(Domain):
    """
    Domain for all objects that don't fit into another domain or are added
    via the application interface.
    """

    name = 'std'
    label = 'Default'

    object_types = {
        'term': ObjType(l_('glossary term'), 'term', searchprio=-1),
        'token': ObjType(l_('grammar token'), 'token', searchprio=-1),
        'label': ObjType(l_('reference label'), 'ref', searchprio=-1),
        'envvar': ObjType(l_('environment variable'), 'envvar'),
        'cmdoption': ObjType(l_('program option'), 'option'),
    }

    directives = {
        'program': Program,
        'cmdoption': Cmdoption,  # old name for backwards compatibility
        'option': Cmdoption,
        'envvar': EnvVar,
        'glossary': Glossary,
        'productionlist': ProductionList,
    }
    roles = {
        'option':  OptionXRefRole(innernodeclass=addnodes.literal_emphasis),
        'envvar':  EnvVarXRefRole(),
        # links to tokens in grammar productions
        'token':   XRefRole(),
        # links to terms in glossary
        'term':    XRefRole(lowercase=True, innernodeclass=nodes.emphasis,
                            warn_dangling=True),
        # links to headings or arbitrary labels
        'ref':     XRefRole(lowercase=True, innernodeclass=nodes.emphasis,
                            warn_dangling=True),
        # links to labels, without a different title
        'keyword': XRefRole(warn_dangling=True),
    }

    initial_data = {
        'progoptions': {},  # (program, name) -> docname, labelid
        'objects': {},      # (type, name) -> docname, labelid
        'labels': {         # labelname -> docname, labelid, sectionname
            'genindex': ('genindex', '', l_('Index')),
            'modindex': ('py-modindex', '', l_('Module Index')),
            'search':   ('search', '', l_('Search Page')),
        },
        'anonlabels': {     # labelname -> docname, labelid
            'genindex': ('genindex', ''),
            'modindex': ('py-modindex', ''),
            'search':   ('search', ''),
        },
    }

    dangling_warnings = {
        'term': 'term not in glossary: %(target)s',
        'ref':  'undefined label: %(target)s (if the link has no caption '
                'the label must precede a section header)',
        'keyword': 'unknown keyword: %(target)s',
    }

    def clear_doc(self, docname):
        for key, (fn, _) in self.data['progoptions'].items():
            if fn == docname:
                del self.data['progoptions'][key]
        for key, (fn, _) in self.data['objects'].items():
            if fn == docname:
                del self.data['objects'][key]
        for key, (fn, _, _) in self.data['labels'].items():
            if fn == docname:
                del self.data['labels'][key]
        for key, (fn, _) in self.data['anonlabels'].items():
            if fn == docname:
                del self.data['anonlabels'][key]

    def process_doc(self, env, docname, document):
        labels, anonlabels = self.data['labels'], self.data['anonlabels']
        for name, explicit in document.nametypes.iteritems():
            if not explicit:
                continue
            labelid = document.nameids[name]
            if labelid is None:
                continue
            node = document.ids[labelid]
            if name.isdigit() or node.has_key('refuri') or \
                   node.tagname.startswith('desc_'):
                # ignore footnote labels, labels automatically generated from a
                # link and object descriptions
                continue
            if name in labels:
                env.warn(docname, 'duplicate label %s, ' % name +
                         'other instance in ' + env.doc2path(labels[name][0]),
                         node.line)
            anonlabels[name] = docname, labelid
            if node.tagname == 'section':
                sectname = clean_astext(node[0]) # node[0] == title node
            elif node.tagname == 'figure':
                for n in node:
                    if n.tagname == 'caption':
                        sectname = clean_astext(n)
                        break
                else:
                    continue
            elif node.tagname == 'table':
                for n in node:
                    if n.tagname == 'title':
                        sectname = clean_astext(n)
                        break
                else:
                    continue
            else:
                # anonymous-only labels
                continue
            labels[name] = docname, labelid, sectname

    def resolve_xref(self, env, fromdocname, builder,
                     typ, target, node, contnode):
        if typ == 'ref':
            if node['refexplicit']:
                # reference to anonymous label; the reference uses
                # the supplied link caption
                docname, labelid = self.data['anonlabels'].get(target, ('',''))
                sectname = node.astext()
            else:
                # reference to named label; the final node will
                # contain the section name after the label
                docname, labelid, sectname = self.data['labels'].get(target,
                                                                     ('','',''))
            if not docname:
                return None
            newnode = nodes.reference('', '', internal=True)
            innernode = nodes.emphasis(sectname, sectname)
            if docname == fromdocname:
                newnode['refid'] = labelid
            else:
                # set more info in contnode; in case the
                # get_relative_uri call raises NoUri,
                # the builder will then have to resolve these
                contnode = addnodes.pending_xref('')
                contnode['refdocname'] = docname
                contnode['refsectname'] = sectname
                newnode['refuri'] = builder.get_relative_uri(
                    fromdocname, docname)
                if labelid:
                    newnode['refuri'] += '#' + labelid
            newnode.append(innernode)
            return newnode
        elif typ == 'keyword':
            # keywords are oddballs: they are referenced by named labels
            docname, labelid, _ = self.data['labels'].get(target, ('','',''))
            if not docname:
                return None
            return make_refnode(builder, fromdocname, docname,
                                labelid, contnode)
        elif typ == 'option':
            progname = node['refprogram']
            docname, labelid = self.data['progoptions'].get((progname, target),
                                                            ('', ''))
            if not docname:
                return None
            return make_refnode(builder, fromdocname, docname,
                                labelid, contnode)
        else:
            objtypes = self.objtypes_for_role(typ) or []
            for objtype in objtypes:
                if (objtype, target) in self.data['objects']:
                    docname, labelid = self.data['objects'][objtype, target]
                    break
            else:
                docname, labelid = '', ''
            if not docname:
                return None
            return make_refnode(builder, fromdocname, docname,
                                labelid, contnode)

    def get_objects(self):
        for (prog, option), info in self.data['progoptions'].iteritems():
            yield (option, option, 'option', info[0], info[1], 1)
        for (type, name), info in self.data['objects'].iteritems():
            yield (name, name, type, info[0], info[1],
                   self.object_types[type].attrs['searchprio'])
        for name, info in self.data['labels'].iteritems():
            yield (name, info[2], 'label', info[0], info[1], -1)

    def get_type_name(self, type, primary=False):
        # never prepend "Default"
        return type.lname
예제 #39
0
 def get_signature_prefix(self, sig):
     if self.env.app.config.dirty_model_class_label is None:
         return super(DirtyModelDirective, self).get_signature_prefix()
     return '{} '.format(l_(self.env.app.config.dirty_model_class_label))
예제 #40
0
class EnvVar(GenericObject):
    indextemplate = l_('environment variable; %s')
 def get_type(cls):
     return ObjType(l_(cls.long_name), cls.short_name, cls.long_name, 'obj')
예제 #42
0
    github.setup(app)

    app.add_directive('exercise', Exercise)
    app.add_node(
        exercise,
        html=(lambda self, node: self.visit_admonition(node, 'exercise'),
              lambda self, node: self.depart_admonition(node)),
        latex=(lambda self, node: self.visit_admonition(node),
               lambda self, node: self.depart_admonition(node)))


from docutils import nodes
from docutils.parsers.rst.directives import admonitions


class exercise(nodes.Admonition, nodes.Element):
    pass


class Exercise(admonitions.BaseAdmonition):
    node_class = exercise


from sphinx.locale import admonitionlabels, l_
admonitionlabels['exercise'] = l_('Exercise')

# monkeypatch PHP lexer to not require <?php
from sphinx.highlighting import lexers
from pygments.lexers.web import PhpLexer
lexers['php'] = PhpLexer(startinline=True)
예제 #43
0
class FortranDomain(Domain):
    """Fortran language domain."""
    name = 'f'
    label = 'Fortran'
    object_types = {
        'program': ObjType(l_('program'), 'prog'),
        'type': ObjType(l_('type'), 'type'),
        'variable': ObjType(l_('variable'), 'var'),
        'function': ObjType(l_('function'), 'func'),
        'subroutine': ObjType(l_('subroutine'), 'func', 'subr'),
        'module': ObjType(l_('module'), 'mod'),
    }

    directives = {
        'program': FortranProgram,
        'type': FortranType,
        'variable': FortranObject,
        'function': FortranWithSig,
        'subroutine': FortranWithSig,
        'module': FortranModule,
        'currentmodule': FortranCurrentModule,
    }

    roles = {
        'prog': FortranXRefRole(),
        'type': FortranXRefRole(),
        'var': FortranXRefRole(),
        'func': FortranXRefRole(fix_parens=True),
        'subr': FortranXRefRole(fix_parens=True),
        'mod': FortranXRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname -> docname, objtype
        'modules': {},  # modname -> docname, synopsis, platform, deprecated
    }
    indices = [
        FortranModuleIndex,
    ]

    def clear_doc(self, docname):
        for fullname, (fn, _) in self.data['objects'].items():
            if fn == docname:
                del self.data['objects'][fullname]
        for modname, (fn, _, _, _) in self.data['modules'].items():
            if fn == docname:
                del self.data['modules'][modname]

    def find_obj(self, env, modname, name, role, searchorder=0):
        """
        Find a Fortran object for "name", perhaps using the given module and/or
        typename.

        :Params:

            - **searchorder**, optional: Start using relative search
        """
        # skip parens
        if name.endswith('()'):
            name = name[:-2]

        if not name:
            return None, None
        if f_sep in name:
            modname, name = name.split(f_sep)
        #modname = modname or '_'
        if '%' in name:
            name, tmp = name.split('%')

        objects = self.data['objects']
        newname = None
        matches = []
        objtypes = self.objtypes_for_role(role)
        if searchorder == 1:  # :role:`/toto`
            if role in ['mod', 'prog']:
                if 'f' + f_sep + name not in objects:  # exact match
                    return []
                newname = 'f' + f_sep + name
            elif modname and 'f'+f_sep + modname + f_sep + name in objects and \
               objects['f'+f_sep + modname + f_sep + name][1] in objtypes:
                newname = 'f' + f_sep + modname + f_sep + name
            elif 'f'+f_sep + '_' + f_sep + name in objects and \
               objects['f'+f_sep + '_' + f_sep + name][1] in objtypes:
                newname = 'f' + f_sep + '_' + f_sep + name
            elif 'f'+f_sep + name in objects and \
               objects['f'+f_sep  + name][1] in objtypes:
                newname = 'f' + f_sep + name
            elif  name in objects and \
               objects[name][1] in objtypes:
                newname = name

        else:  # :role:`toto`
            # NOTE: searching for exact match, object type is not considered
            if 'f' + f_sep + name in objects:
                newname = 'f' + f_sep + name
            elif role in ['mod', 'prog']:
                # only exact matches allowed for modules
                return []
            elif 'f' + f_sep + '_' + f_sep + name in objects:
                newname = 'f' + f_sep + '_' + f_sep + name
            elif modname and 'f' + f_sep + modname + f_sep + name in objects:
                newname = 'f' + f_sep + modname + f_sep + name

        # Last chance: fuzzy search
        if newname is None:
            matches = [
                (oname, objects[oname]) for oname in objects
                if oname.endswith(f_sep +
                                  name) and objects[oname][1] in objtypes
            ]
        else:
            matches.append((newname, objects[newname]))
        return matches

    def resolve_xref(self, env, fromdocname, builder, type, target, node,
                     contnode):
        modname = node.get('f:module', node.get('modname'))
        typename = node.get('f:type', node.get('typename'))
        searchorder = node.hasattr('refspecific') and 1 or 0
        matches = self.find_obj(env, modname, target, type, searchorder)
        if not matches:
            return None
        elif len(matches) > 1:
            env.warn(
                fromdocname, 'more than one target found for cross-reference '
                '%r: %s' % (target, ', '.join(match[0] for match in matches)),
                node.line)
        name, obj = matches[0]

        if obj[1] == 'module':
            # get additional info for modules
            docname, synopsis, platform, deprecated = self.data['modules'][
                name[1 + len(f_sep):]]
            assert docname == obj[0]
            title = name
            if synopsis:
                title += ': ' + synopsis
            if deprecated:
                title += _(' (deprecated)')
            #return make_refnode(builder, fromdocname, docname,
            #'module-' + name, contnode, title)
            return make_refnode(builder, fromdocname, docname, name, contnode,
                                title)
        else:
            return make_refnode(builder, fromdocname, obj[0], name, contnode,
                                name)

    def get_objects(self):
        for modname, info in self.data['modules'].iteritems():
            yield (modname, modname, 'module', info[0], 'module-' + modname, 0)
        for refname, (docname, type) in self.data['objects'].iteritems():
            yield (refname, refname, type, docname, refname, 1)
예제 #44
0
class ElixirDomain(PolyglotDomain):
    name, label = 'ex', l_('Elixir')
    directives = {
      'module':  make_namespace_directive('module'),
      'package': make_directive('package'),
    }
예제 #45
0
파일: sphinxext.py 프로젝트: javacruft/wsme
def document_function(funcdef, docstrings=None, protocols=['restjson']):
    """A helper function to complete a function documentation with return and
    parameter types"""
    # If the function doesn't have a docstring, add an empty list
    # so the default behaviors below work correctly.
    if not docstrings:
        docstrings = [[]]
    found_params = set()

    for si, docstring in enumerate(docstrings):
        for i, line in enumerate(docstring):
            m = field_re.match(line)
            if m and m.group('field') == 'param':
                found_params.add(m.group('name'))

    next_param_pos = (0, 0)

    for arg in funcdef.arguments:
        content = [
            u':type  %s: :wsme:type:`%s`' % (
                arg.name, datatypename(arg.datatype))
        ]
        if arg.name not in found_params:
            content.insert(0, u':param %s: ' % (arg.name))
            pos = next_param_pos
        else:
            for si, docstring in enumerate(docstrings):
                for i, line in enumerate(docstring):
                    m = field_re.match(line)
                    if m and m.group('field') == 'param' \
                            and m.group('name') == arg.name:
                        pos = (si, i + 1)
                        break
        docstring = docstrings[pos[0]]
        docstring[pos[1]:pos[1]] = content
        next_param_pos = (pos[0], pos[1] + len(content))

    if funcdef.return_type:
        content = [
            u':rtype: %s' % datatypename(funcdef.return_type)
        ]
        pos = None
        for si, docstring in enumerate(docstrings):
            for i, line in enumerate(docstring):
                m = field_re.match(line)
                if m and m.group('field') == 'return':
                    pos = (si, i + 1)
                    break
        else:
            pos = next_param_pos
        docstring = docstrings[pos[0]]
        docstring[pos[1]:pos[1]] = content

    codesamples = []

    if protocols:
        params = []
        for arg in funcdef.arguments:
            params.append((
                arg.name,
                arg.datatype,
                make_sample_object(arg.datatype)
            ))
        codesamples.extend([
            u':%s:' % l_(u'Parameters samples'),
            u'    .. cssclass:: toggle',
            u''
        ])
        for name, protocol in protocols:
            language, sample = protocol.encode_sample_params(
                params, format=True)
            codesamples.extend([
                u' ' * 4 + name,
                u'        .. code-block:: ' + language,
                u'',
            ])
            codesamples.extend((
                u' ' * 12 + line for line in sample.split('\n')))

        if funcdef.return_type:
            codesamples.extend([
                u':%s:' % l_(u'Return samples'),
                u'    .. cssclass:: toggle',
                u''
            ])
            sample_obj = make_sample_object(funcdef.return_type)
            for name, protocol in protocols:
                language, sample = protocol.encode_sample_result(
                    funcdef.return_type, sample_obj, format=True)
                codesamples.extend([
                    u' ' * 4 + name,
                    u'        .. code-block:: ' + language,
                    u'',
                ])
                codesamples.extend((
                    u' ' * 12 + line for line in sample.split('\n')))

    docstrings[0:0] = [codesamples]
    return docstrings
예제 #46
0
class FortranObject(ObjectDescription):
    """
    Description of a general Fortran object.
    """
    option_spec = {
        'noindex': directives.flag,
        'module': directives.unchanged,
        'type': directives.unchanged,
        'shape': parse_shape,
        'attrs': directives.unchanged,
    }

    doc_field_types = [
        FortranCompleteField(
            'parameter',
            label=l_('Parameters'),
            names=('p', 'param', 'parameter', 'a', 'arg', 'argument'),
            #rolename='var',
            typerolename='type',
            typenames=('paramtype', 'type', 'ptype'),
            shapenames=('shape', 'pshape'),
            attrnames=('attrs', 'pattrs', 'attr'),
            can_collapse=True),
        FortranCompleteField(
            'optional',
            label=l_('Options'),
            names=('o', 'optional', 'opt', 'keyword', 'option'),
            #rolename='var',
            typerolename='type',
            typenames=('optparamtype', 'otype'),
            shapenames=('oshape', ),
            attrnames=('oattrs', 'oattr'),
            can_collapse=True),
        FortranCompleteField(
            'typefield',
            label=l_('Type fields'),
            names=('f', 'field', 'typef', 'typefield'),
            #rolename='typef',
            typerolename='type',
            typenames=('fieldtype', 'ftype'),
            shapenames=('fshape', ),
            attrnames=('fattrs', 'fattr'),
            prefix='% ',
            strong=False,
            can_collapse=False),
        FortranCompleteField('return',
                             label=l_('Return'),
                             names=('r', 'return', 'returns'),
                             typerolename='type',
                             typenames=('returntype', 'rtype'),
                             shapenames=('rshape', ),
                             attrnames=('rattrs', 'rattr'),
                             can_collapse=True),
        FortranCallField('calledfrom',
                         label=l_('Called from'),
                         names=('calledfrom', 'from')),
        FortranCallField('callto', label=l_('Call to'),
                         names=('callto', 'to')),
    ]

    # These Fortran types aren't described anywhere, so don't try to create
    # a cross-reference to them
    stopwords = set(('float', 'integer', 'character', 'double', 'long'))

    _parens = ''

    #    def _parse_type(self, node, ftype):
    #        m = f_type_re.match(ftype)
    #        tnode = nodes.Text(ftype, ftype)
    #        modname = self.options.get(
    #            'module', self.env.temp_data.get('f:module'))
    #        if m :
    #            ftype = m.groups(0)
    #            if ftype not in self.stopwords:
    #                pnode = addnodes.pending_xref(
    #                    '', refdomain='f', reftype='type', reftarget=ftype,
    #                    modname=modname)
    #                pnode += tnode
    #                node += pnode
    #            else:
    #                node += tnode
    #        else:
    #            node += tnode

    def get_signature_prefix(self, sig):
        """
        May return a prefix to put before the object name in the signature.
        """
        return ''

    def needs_arglist(self):
        """
        May return true if an empty argument list is to be generated even if
        the document contains none.
        """
        return False

    def handle_signature(self, sig, signode):
        """
        Transform a Fortran signature into RST nodes.
        Returns (fully qualified name of the thing, classname if any).

        If inside a class, the current class name is handled intelligently:
        * it is stripped from the displayed name if present
        * it is added to the full name (return value) if not present
        """
        m = f_sig_re.match(sig)
        if m is None:
            raise ValueError
        ftype, objtype, modname, typename, name, arglist = m.groups()
        if not typename: typename = ""

        # determine module, type, shape and attributes
        modname = (modname and modname[:-1]) or self.options.get(
            'module', self.env.temp_data.get('f:module'))
        if typename:
            name = typename[:-1]
        attrs = self.options.get('attrs')
        shape = parse_shape(self.options.get('shape'))
        ftype = ftype or self.options.get('type')
        if self.objtype == 'typefield' and not typename:
            raise ValueError

        #if typename: name = typename+'%'+name

        #fullname = name
        #if modname:
        if self.objtype == 'program':
            fullname = name
        else:
            fullname = (modname or '_') + f_sep + name

        signode['module'] = modname
        signode['type'] = typename
        signode['fullname'] = fullname

        # Add "function" or "subroutine" tag
        sig_prefix = self.get_signature_prefix(sig)
        if objtype or sig_prefix:
            objtype = objtype or sig_prefix
            signode += addnodes.desc_annotation(objtype + ' ', objtype + ' ')

        # Add module
        if self.env.config.add_module_names and modname and self.objtype != 'typefield':
            nodetext = modname + f_sep
            signode += addnodes.desc_addname(nodetext, nodetext)

        # Add name
        signode += addnodes.desc_name(name, name)

        # In the parenthesis
        if self.needs_arglist():  # call for functions and subroutines
            if arglist:  # Calling arguments
                _pseudo_parse_arglist(signode, arglist)
            elif self.needs_arglist(
            ):  # for callables, add an empty parameter list
                signode += addnodes.desc_parameterlist()
        elif arglist and not shape:  # Declare shape instead of arguments (variables)
            shape = arglist

        # Add remaining
        self.add_shape_and_attrs(signode, modname, ftype, shape, attrs)

        return fullname, ftype

    def add_shape_and_attrs(self, signode, modname, ftype, shape, attrs):
        # add shape
        if shape:
            add_shape(signode, shape, modname=modname)
            #signode += nodes.Text(' '+shape)
        # add type ('float', 'interger', etc)
        if ftype or attrs:
            signode += nodes.emphasis(' [', ' [')
        if ftype:
            refnode = addnodes.pending_xref(
                '',
                refdomain='f',
                reftype='type',
                reftarget=ftype,
                modname=modname,
            )
            refnode += nodes.emphasis(ftype, ftype)
            signode += refnode
            #tnode = addnodes.desc_type(ftype, ftype)
            #tnode +=
            #signode += addnodes.desc_type(ftype, ftype)
            #signode +=

    #        signode += addnodes.desc_type('', '')
    #        self._parse_type(signode[-1], ftype)
        if attrs:
            if ftype: signode += nodes.emphasis(',', ',')
            for iatt, att in enumerate(re.split('\s*,\s*', attrs)):
                if iatt:
                    signode += nodes.emphasis(',', ',')
                if att.startswith('parameter'):
                    value = att.split('=')[1]
                    signode += nodes.emphasis('parameter=', 'parameter=')
                    convert_arithm(signode, value, modname=modname)
                else:
                    signode += nodes.emphasis(att, att)
            #signode += nodes.emphasis(attrs, attrs)

        if ftype or attrs:
            signode += nodes.emphasis(']', ']')

    def add_target_and_index(self, name, sig, signode):
        #modname = self.options.get(
        #'module', self.env.temp_data.get('f:module'))
        modname = signode.get('module', self.env.temp_data.get('f:module'))
        #        fullname = (modname and modname + '/' or '') + name[0]
        fullname = 'f' + f_sep + name[0]

        # note target
        if fullname not in self.state.document.ids:
            signode['names'].append(fullname)
            signode['ids'].append(fullname)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)
            objects = self.env.domaindata['f']['objects']
            if fullname in objects:
                self.env.warn(
                    self.env.docname,
                    'duplicate object description of %s, ' % fullname +
                    'other instance in ' +
                    self.env.doc2path(objects[fullname][0]), self.lineno)
            objects[fullname] = (self.env.docname, self.objtype)
        indextext = self.get_index_text(modname, fullname)
        if indextext:
            self.indexnode['entries'].append(
                ('single', indextext, fullname, fullname))

    def before_content(self):
        # needed for automatic qualification of fields (reset in subclasses)
        self.typename_set = False

    def after_content(self):
        if self.typename_set:
            self.env.temp_data['f:type'] = None

    def get_index_text(self, modname, name):
        add_modules = self.env.config.add_module_names
        if name.startswith('f' + f_sep): name = name[2:]
        mn = modname or '_'
        sobj = ''
        if name.startswith(mn + f_sep):
            name = name[len(mn) + 1:]
        if self.objtype == 'type':
            sobj = _('fortran type')
        if self.objtype == 'typefield':
            sobj = _('fortran type field')
        elif self.objtype == 'variable':
            sobj = _('fortran variable')
        elif self.objtype == 'subroutine':
            sobj = _('fortran subroutine')
        elif self.objtype == 'function':
            sobj = _('fortran function')
        elif self.objtype == 'module':
            sobj = _('fortran module')
            modname = ''
        elif self.objtype == 'program':
            sobj = _('fortran program')
            modname = ''
        sinmodule = (_(' in module %s') %
                     modname) if modname and add_modules else ''
        return '%s%s (%s%s)' % (name, self._parens, sobj, sinmodule)