'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.'

def run_directive(self, directive, match, type_name, option_presets):

    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 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 docutils.parsers.rst.DirectiveError as directive_error:
        msg_node = self.reporter.system_message(directive_error.level, directive_error.message)
        msg_node += nodes.literal_block(block_text, block_text)
        msg_node['line'] = lineno
        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]))
    return (result, (blank_finish or self.state_machine.is_next_line_blank()))
