def _directive_helper(self, obj, content=None, arguments=None, **options):
     if isinstance(obj, (types.FunctionType, types.MethodType)):
         obj.content = content
         obj.arguments = arguments or (0, 0, False)
         obj.options = options
         return convert_directive_function(obj)
     else:
         if content or arguments or options:
             raise ExtensionError("when adding directive classes, no " "additional arguments may be given")
         return obj
Esempio n. 2
0
 def run(self):
     """Dynamically create and register a custom interpreted text role."""
     if self.content_offset > self.lineno or not self.content:
         raise self.error('"%s" directive requires arguments on the first '
                          'line.' % self.name)
     args = self.content[0]
     match = self.argument_pattern.match(args)
     if not match:
         raise self.error('"%s" directive arguments not valid role names: '
                          '"%s".' % (self.name, args))
     new_role_name = match.group(1)
     base_role_name = match.group(3)
     messages = []
     if base_role_name:
         base_role, messages = roles.role(base_role_name,
                                          self.state_machine.language,
                                          self.lineno, self.state.reporter)
         if base_role is None:
             error = self.state.reporter.error(
                 'Unknown interpreted text role "%s".' % base_role_name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             return messages + [error]
     else:
         base_role = roles.generic_custom_role
     assert not hasattr(base_role, 'arguments'), (
         'Supplemental directive arguments for "%s" directive not '
         'supported (specified by "%r" role).' % (self.name, base_role))
     try:
         converted_role = convert_directive_function(base_role)
         (arguments, options, content,
          content_offset) = (self.state.parse_directive_block(
              self.content[1:],
              self.content_offset,
              converted_role,
              option_presets={}))
     except states.MarkupError as detail:
         error = self.state_machine.reporter.error(
             'Error in "%s" directive:\n%s.' % (self.name, detail),
             nodes.literal_block(self.block_text, self.block_text),
             line=self.lineno)
         return messages + [error]
     if 'class' not in options:
         try:
             options['class'] = directives.class_option(new_role_name)
         except ValueError as detail:
             error = self.state_machine.reporter.error(
                 'Invalid argument for "%s" directive:\n%s.' %
                 (self.name, SafeString(detail)),
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             return messages + [error]
     role = roles.CustomRole(new_role_name, base_role, options, content)
     roles.register_local_role(new_role_name, role)
     return messages
Esempio n. 3
0
 def _directive_helper(self, obj, content=None, arguments=None, **options):
     if isinstance(obj, (types.FunctionType, types.MethodType)):
         obj.content = content
         obj.arguments = arguments or (0, 0, False)
         obj.options = options
         return convert_directive_function(obj)
     else:
         if content or arguments or options:
             raise ExtensionError('when adding directive classes, no '
                                  'additional arguments may be given')
         return obj
Esempio n. 4
0
 def _directive_helper(self, obj, content=None, arguments=None, **options):
     # type: (Any, unicode, Any, Any) -> Any
     if isinstance(obj, (types.FunctionType, types.MethodType)):
         obj.content = content                       # type: ignore
         obj.arguments = arguments or (0, 0, False)  # type: ignore
         obj.options = options                       # type: ignore
         return convert_directive_function(obj)
     else:
         if content or arguments or options:
             raise ExtensionError('when adding directive classes, no '
                                  'additional arguments may be given')
         return obj
Esempio n. 5
0
def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
    # type: (Any, bool, Tuple[int, int, bool], Any) -> Any
    if isinstance(obj, (types.FunctionType, types.MethodType)):
        obj.content = has_content                       # type: ignore
        obj.arguments = argument_spec or (0, 0, False)  # type: ignore
        obj.options = option_spec                       # type: ignore
        return convert_directive_function(obj)
    else:
        if has_content or argument_spec or option_spec:
            raise ExtensionError(__('when adding directive classes, no '
                                    'additional arguments may be given'))
        return obj
Esempio n. 6
0
 def run(self):
     """Dynamically create and register a custom interpreted text role."""
     if self.content_offset > self.lineno or not self.content:
         raise self.error('"%s" directive requires arguments on the first '
                          'line.' % self.name)
     args = self.content[0]
     match = self.argument_pattern.match(args)
     if not match:
         raise self.error('"%s" directive arguments not valid role names: '
                          '"%s".' % (self.name, args))
     new_role_name = match.group(1)
     base_role_name = match.group(3)
     messages = []
     if base_role_name:
         base_role, messages = roles.role(
             base_role_name, self.state_machine.language, self.lineno,
             self.state.reporter)
         if base_role is None:
             error = self.state.reporter.error(
                 'Unknown interpreted text role "%s".' % base_role_name,
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             return messages + [error]
     else:
         base_role = roles.generic_custom_role
     assert not hasattr(base_role, 'arguments'), (
         'Supplemental directive arguments for "%s" directive not '
         'supported (specified by "%r" role).' % (self.name, base_role))
     try:
         converted_role = convert_directive_function(base_role)
         (arguments, options, content, content_offset) = (
             self.state.parse_directive_block(
             self.content[1:], self.content_offset, converted_role,
             option_presets={}))
     except states.MarkupError as detail:
         error = self.state_machine.reporter.error(
             'Error in "%s" directive:\n%s.' % (self.name, detail),
             nodes.literal_block(self.block_text, self.block_text),
             line=self.lineno)
         return messages + [error]
     if 'class' not in options:
         try:
             options['class'] = directives.class_option(new_role_name)
         except ValueError as detail:
             error = self.state_machine.reporter.error(
                 'Invalid argument for "%s" directive:\n%s.'
                 % (self.name, SafeString(detail)), nodes.literal_block(
                 self.block_text, self.block_text), line=self.lineno)
             return messages + [error]
     role = roles.CustomRole(new_role_name, base_role, options, content)
     roles.register_local_role(new_role_name, role)
     return messages
Esempio n. 7
0
 def run(self):
     """Dynamically create and register a custom interpreted text template."""
     try:
         new_role_name = self.arguments[0]
     except ValueError:
         raise self.error('Missing template name for directive: "%s".' %
                          (self.name))
     messages = []
     base_role = roles.raw_role
     converted_role = convert_directive_function(base_role)
     role = CustomTemplate(new_role_name, base_role, self.options)
     roles.register_local_role(new_role_name, role)
     return messages
Esempio n. 8
0
def directive_helper(obj: Any, has_content: bool = None, argument_spec: Tuple[int, int, bool] = None, **option_spec) -> Any:  # NOQA
    warnings.warn('function based directive support is now deprecated. '
                  'Use class based directive instead.',
                  RemovedInSphinx30Warning)

    if isinstance(obj, (types.FunctionType, types.MethodType)):
        obj.content = has_content                       # type: ignore
        obj.arguments = argument_spec or (0, 0, False)  # type: ignore
        obj.options = option_spec                       # type: ignore
        return convert_directive_function(obj)
    else:
        if has_content or argument_spec or option_spec:
            raise ExtensionError(__('when adding directive classes, no '
                                    'additional arguments may be given'))
        return obj
Esempio n. 9
0
def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
    # type: (Any, bool, Tuple[int, int, bool], Any) -> Any
    warnings.warn('function based directive support is now deprecated. '
                  'Use class based directive instead.',
                  RemovedInSphinx30Warning)

    if isinstance(obj, (types.FunctionType, types.MethodType)):
        obj.content = has_content                       # type: ignore
        obj.arguments = argument_spec or (0, 0, False)  # type: ignore
        obj.options = option_spec                       # type: ignore
        return convert_directive_function(obj)
    else:
        if has_content or argument_spec or option_spec:
            raise ExtensionError(__('when adding directive classes, no '
                                    'additional arguments may be given'))
        return obj
Esempio n. 10
0
    def run_directive(self, directive, match, type_name, option_presets):
        """
        Parse a directive then run its directive function.

        Parameters:

        - `directive`: The class implementing the directive.  Must be
            a subclass of `rst.Directive`.

        - `match`: A regular expression match object which matched the first
            line of the directive.

        - `type_name`: The directive name, as used in the source text.

        - `option_presets`: A dictionary of preset options, defaults for the
            directive options.  Currently, only an "alt" option is passed by
            substitution definitions (value: the substitution name), which may
            be used by an embedded image directive.

        Returns a 2-tuple: list of nodes, and a "blank finish" boolean.
        """
        if isinstance(directive, (FunctionType, MethodType)):
            from docutils.parsers.rst import convert_directive_function

            directive = convert_directive_function(directive)
        lineno = self.state_machine.abs_line_number()
        initial_line_offset = self.state_machine.line_offset
        (
            indented,
            indent,
            line_offset,
            blank_finish,
        ) = self.state_machine.get_first_known_indented(match.end(),
                                                        strip_top=0)
        block_text = "\n".join(
            self.state_machine.
            input_lines[initial_line_offset:self.state_machine.line_offset +
                        1])
        try:
            arguments, options, content, content_offset = self.parse_directive_block(
                indented, line_offset, directive, option_presets)
        except states.MarkupError as detail:
            error = self.reporter.error(
                'Error in "%s" directive:\n%s.' %
                (type_name, " ".join(detail.args)),
                nodes.literal_block(block_text, block_text),
                line=lineno,
            )
            return [error], blank_finish
        directive_instance = directive(
            type_name,
            arguments,
            options,
            content,
            lineno,
            content_offset,
            block_text,
            self,
            self.state_machine,
        )
        try:
            result = directive_instance.run()
        except DirectiveError as error:
            msg_node = self.reporter.system_message(error.level,
                                                    error.msg,
                                                    line=lineno)
            msg_node += nodes.literal_block(block_text, block_text)
            result = [msg_node]
        assert isinstance(
            result,
            list), ('Directive "%s" must return a list of nodes.' % type_name)
        for i in range(len(result)):
            assert isinstance(result[i], nodes.Node), (
                'Directive "%s" returned non-Node object (index %s): %r' %
                (type_name, i, result[i]))

        # NOTE it would be ideal to also record the start and end characters on lines?
        # However, it appears that nested state machine are initalised with
        # pre de-dented input lines, and do not record the initial indentation
        position = LSPDirective(
            rawsource=block_text,
            line_start=line_offset,
            line_end=self.state_machine.abs_line_number() - 1,
            # the line at which content starts
            line_content=content_offset if content else None,
            content_indent=indent
            if content else None,  # relative to initial indent of directive
            dtype=type_name,
            arguments=arguments,
            options=options,
            klass=f"{directive.__module__}.{directive.__name__}",
            children=result,
        )
        return (position, blank_finish
                or self.state_machine.is_next_line_blank())