Beispiel #1
0
    def run_directive(self, name,
                      arguments=[],
                      options={},
                      content=[]):
        """Generate directive node given arguments.

        Parameters
        ----------
        name : str
            name of directive.
        arguments : list
            list of positional arguments.
        options : dict
            key value arguments.
        content : content
            content of the directive

        Returns
        -------
        node : docutil Node
            Node generated by the arguments.
        """
        direc, msg = directive(name,
                               self.language,
                               self.document)
        direc = direc(name=name,
                      arguments=arguments,
                      options=options,
                      content=content,
                      lineno=self.node.line,
                      content_offset=0,
                      block_text='Dummy BlockText',
                      state=self.state,
                      state_machine=self)
        return direc.run()
 def test_directives(self):
     try:
         module = docutils.parsers.rst.languages.get_language(
             self.language)
         if not module:
             raise ImportError
     except ImportError:
         self.fail('No docutils.parsers.rst.languages.%s module.'
                   % self.language)
     failures = []
     for d in list(module.directives.keys()):
         try:
             func, msg = directives.directive(d, module, None)
             if not func:
                 failures.append('"%s": unknown directive' % d)
         except Exception as error:
             failures.append('"%s": %s' % (d, error))
     inverted = self._invert(module.directives)
     canonical = list(directives._directive_registry.keys())
     canonical.sort()
     canonical.remove('restructuredtext-test-directive')
     for name in canonical:
         if name not in inverted:
             failures.append('"%s": translation missing' % name)
     if failures:
         text = ('Module docutils.parsers.rst.languages.%s:\n    %s'
                 % (self.language, '\n    '.join(failures)))
         if type(text) is str:
             text = text.encode('raw_unicode_escape')
         self.fail(text)
 def test_directives(self):
     try:
         module = docutils.parsers.rst.languages.get_language(self.language)
         if not module:
             raise ImportError
     except ImportError:
         self.fail('No docutils.parsers.rst.languages.%s module.' %
                   self.language)
     failures = []
     for d in module.directives.keys():
         try:
             func, msg = directives.directive(d, module, None)
             if not func:
                 failures.append('"%s": unknown directive' % d)
         except Exception as error:
             failures.append('"%s": %s' % (d, error))
     inverted = self._invert(module.directives)
     canonical = sorted(directives._directive_registry.keys())
     canonical.remove('restructuredtext-test-directive')
     for name in canonical:
         if name not in inverted:
             failures.append('"%s": translation missing' % name)
     if failures:
         text = ('Module docutils.parsers.rst.languages.%s:\n    %s' %
                 (self.language, '\n    '.join(failures)))
         if isinstance(text, unicode):
             text = text.encode('raw_unicode_escape')
         self.fail(text)
Beispiel #4
0
def get_directive(name):
    from docutils.parsers.rst import directives
    try:
        return directives.directive(name, None, None)[0]
    except AttributeError:
        pass
    try:
        # docutils 0.4
        return directives._directives[name]
    except (AttributeError, KeyError):
        raise RuntimeError("No directive named '%s' found" % name)
def catchall_directive(self, match, **option_presets):
    """Directive dispatch method.

    Replacement for Body.directive(): if a directive is not known, build one
    on the fly instead of reporting an error.
    """
    type_name = match.group(1)
    directive_class, messages = directives.directive(
        type_name, self.memo.language, self.document)

    # in case it's missing, register a generic directive
    if not directive_class:
        directives.register_directive(type_name, AnyDirective)
        directive_class, messages = directives.directive(
            type_name, self.memo.language, self.document)
        assert directive_class, "can't find just defined directive"

    self.parent += messages
    return self.run_directive(
        directive_class, match, type_name, option_presets)
Beispiel #6
0
def get_directive(name):
    from docutils.parsers.rst import directives
    try:
        return directives.directive(name, None, None)[0]
    except AttributeError:
        pass
    try:
        # docutils 0.4
        return directives._directives[name]
    except (AttributeError, KeyError):
        raise RuntimeError("No directive named '%s' found" % name)
Beispiel #7
0
def catchall_directive(self, match, **option_presets):
    """Directive dispatch method.

    Replacement for Body.directive(): if a directive is not known, build one
    on the fly instead of reporting an error.
    """
    type_name = match.group(1)
    directive_class, messages = directives.directive(type_name,
                                                     self.memo.language,
                                                     self.document)

    # in case it's missing, register a generic directive
    if not directive_class:
        directives.register_directive(type_name, AnyDirective)
        directive_class, messages = directives.directive(
            type_name, self.memo.language, self.document)
        assert directive_class, "can't find just defined directive"

    self.parent += messages
    return self.run_directive(directive_class, match, type_name,
                              option_presets)
Beispiel #8
0
def run_directive(parent_directive, name, content='', options={}):
    """Run and render a directive.

    Args:
        parent_directive (docutils.parsers.rst.Directive):
            The directive running another directive.

        name (unicode):
            The name of the directive to run.

        content (unicode, optional):
            The content to pass to the directive.

        options (dict, optional):
            The options to pass to the directive.

    Returns:
        list of docutils.nodes.Node:
        The resulting list of nodes from the directive.
    """
    state = parent_directive.state
    directive_class, messages = directives.directive(name,
                                                     state.memo.language,
                                                     state.document)
    state.parent += messages

    if not directive_class:
        return state.unknown_directive(name)

    state_machine = state.state_machine
    lineno = state_machine.abs_line_number()

    directive = directive_class(
        name=name,
        arguments=[],
        options=options,
        content=content,
        lineno=lineno,
        content_offset=0,
        block_text='',
        state=parent_directive.state,
        state_machine=state_machine)

    try:
        return directive.run()
    except DirectiveError as e:
        return [
            parent_directive.reporter.system_message(e.level, e.msg,
                                                     line=lineno),
        ]
Beispiel #9
0
 def test_directives(self):
     try:
         module = docutils.parsers.rst.languages.get_language(self.language)
         if not module:
             raise ImportError
     except ImportError:
         self.fail('No docutils.parsers.rst.languages.%s module.' %
                   self.language)
     failures = []
     for d in module.directives.keys():
         try:
             func, msg = directives.directive(d, module, None)
             if not func:
                 failures.append('"%s": unknown directive' % d)
         except Exception, error:
             failures.append('"%s": %s' % (d, error))
Beispiel #10
0
 def test_directives(self):
     try:
         module = docutils.parsers.rst.languages.get_language(
             self.language)
         if not module:
             raise ImportError
     except ImportError:
         self.fail('No docutils.parsers.rst.languages.%s module.'
                   % self.language)
     failures = []
     for d in module.directives.keys():
         try:
             func, msg = directives.directive(d, module, None)
             if not func:
                 failures.append('"%s": unknown directive' % d)
         except Exception, error:
             failures.append('"%s": %s' % (d, error))
Beispiel #11
0
    def run_directive(self, lineno, state, state_machine):
        """Execute the directive generate a list of nodes."""

        name = self["{antidox}name"]

        directive_class, messages = directives.directive(
            name, state.memo.language, state.document)

        raw_options = self.attlist()
        options = {
            k: directive_class.option_spec[k](v)
            for k, v in raw_options if not k.startswith("{antidox}")
        }

        arguments = [
            n.astext() for n in self.children
            if n.tagname == "antidox_directive-argument"
        ]
        content = [
            n.astext() for n in self.children
            if n.tagname == "antidox_directive-content"
        ]

        # what about this?
        # content_offset = 0
        # block_text = ''

        directive_instance = directive_class(name, arguments, options, content,
                                             lineno, 0, "", state,
                                             state_machine)

        try:
            result = directive_instance.run()
            result += messages
        except DirectiveError as error:
            msg_node = state.reporter.system_message(error.level,
                                                     error.msg,
                                                     line=lineno)
            result = [msg_node]

        return result
Beispiel #12
0
    def run_directive(self, name,
                      arguments=None,
                      options=None,
                      content=None):
        """Generate directive node given arguments.

        Parameters
        ----------
        name : str
            name of directive.
        arguments : list
            list of positional arguments.
        options : dict
            key value arguments.
        content : content
            content of the directive

        Returns
        -------
        node : docutil Node
            Node generated by the arguments.
        """
        if options is None:
            options = {}
        if content is None:
            content = []
        if arguments is None:
            arguments = []
        direc, msg = directive(name,
                               self.language,
                               self.document)
        direc = direc(name=name,
                      arguments=arguments,
                      options=options,
                      content=content,
                      lineno=self.node.line,
                      content_offset=0,
                      block_text='Dummy BlockText',
                      state=self.state,
                      state_machine=self)
        return direc.run()
Beispiel #13
0
    def run(self):
        """Run the directive."""
        name = self.arguments[0]
        # load the directive class
        klass, _ = directives.directive(name, self.state.memo.language,
                                        self.state.document)
        if klass is None:
            logger.warning(f"Directive {name} not found.", line=self.lineno)
            return []
        content = " ".join(self.content)
        text = f"""\
:Name: `{name}`
:Description: {content}
:Arguments: {klass.required_arguments} required, {klass.optional_arguments} optional
:Content: {'yes' if klass.has_content else 'no'}
:Options:
"""
        if klass.option_spec:
            text += "  name | type\n  -----|------\n"
            for key, func in klass.option_spec.items():
                text += f"  {key} | {convert_opt(name, func)}\n"
        node = nodes.Element()
        self.state.nested_parse(text.splitlines(), 0, node)
        return node.children
Beispiel #14
0
    def run(self):
        language = self.state_machine.language
        document = self.state.document
        directive, messages = directives.directive("plot", language, document)
        self.state.parent += messages

        # Temporarily override template
        #   * Add target to figure
        #   * Add classes for Bootstrap
        target = ":target: " + self.options.pop("target", "")
        title = self.options["alt"]
        classes = " ".join(document.settings.env.config.gallery_plot_classes + ["thumbnail"])
        template = (
            """
{{ only_html }}

   {% for img in images %}
   .. figure:: {{ build_dir }}/{{ img.basename }}.png
      """
            + target
            + """
      :figclass: """
            + classes
            + """
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   {% if 'pdf' in img.formats -%}
   .. image:: {{ build_dir }}/{{ img.basename }}.pdf
      """
            + target
            + """
   {% endif -%}
   {% endfor %}

{{ only_texinfo }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.png
      """
            + target
            + """
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

"""
        )

        plot_template_orig = document.settings.env.config.plot_template
        document.settings.env.config.plot_template = template

        # Don't bother with the high resolution version
        plot_formats_orig = document.settings.env.config.plot_formats
        plot_formats = []
        for f in plot_formats_orig:
            if isinstance(f, str) and "hires" in f:
                continue
            elif isinstance(f, tuple) and "hires" in f[0]:
                continue
            plot_formats.append(f)
        document.settings.env.config.plot_formats = plot_formats

        options = {"alt": title}

        directive_instance = directive(
            "plot",
            self.arguments,
            options,
            self.content,
            self.lineno,
            self.content_offset,
            self.block_text,
            self.state,
            self.state_machine,
        )
        try:
            result = directive_instance.run()
        except DirectiveError as error:
            msg_node = self.reporter.system_message(error.level, error.msg, line=self.lineno)
            msg_node += nodes.literal_block(self.block_text, self.block_text)
            result = [msg_node]

        # Restore original settings
        document.settings.env.config.plot_template = plot_template_orig
        document.settings.env.config.plot_formats = plot_formats_orig

        return result
Beispiel #15
0
    def render_directive(self, token: Token):
        """Render special fenced code blocks as directives."""
        first_line = token.info.split(maxsplit=1)
        name = first_line[0][1:-1]
        arguments = "" if len(first_line) == 1 else first_line[1]
        # TODO directive name white/black lists
        content = token.content
        position = token.map[0]
        self.document.current_line = position

        # get directive class
        directive_class, messages = directives.directive(
            name, self.language_module,
            self.document)  # type: (Directive, list)
        if not directive_class:
            error = self.reporter.error(
                'Unknown directive type "{}".\n'.format(name),
                # nodes.literal_block(content, content),
                line=position,
            )
            self.current_node += [error] + messages
            return

        try:
            arguments, options, body_lines = parse_directive_text(
                directive_class, arguments, content)
        except DirectiveParsingError as error:
            error = self.reporter.error(
                "Directive '{}': {}".format(name, error),
                nodes.literal_block(content, content),
                line=position,
            )
            self.current_node += [error]
            return

        # initialise directive
        if issubclass(directive_class, Include):
            directive_instance = MockIncludeDirective(
                self,
                name=name,
                klass=directive_class,
                arguments=arguments,
                options=options,
                body=body_lines,
                token=token,
            )
        else:
            state_machine = MockStateMachine(self, position)
            state = MockState(self, state_machine, position)
            directive_instance = directive_class(
                name=name,
                # the list of positional arguments
                arguments=arguments,
                # a dictionary mapping option names to values
                options=options,
                # the directive content line by line
                content=StringList(body_lines, self.document["source"]),
                # the absolute line number of the first line of the directive
                lineno=position,
                # the line offset of the first line of the content
                content_offset=
                0,  # TODO get content offset from `parse_directive_text`
                # a string containing the entire directive
                block_text="\n".join(body_lines),
                state=state,
                state_machine=state_machine,
            )

        # run directive
        try:
            result = directive_instance.run()
        except DirectiveError as error:
            msg_node = self.reporter.system_message(error.level,
                                                    error.msg,
                                                    line=position)
            msg_node += nodes.literal_block(content, content)
            result = [msg_node]
        except MockingError as exc:
            error = self.reporter.error(
                "Directive '{}' cannot be mocked: {}: {}".format(
                    name, exc.__class__.__name__, exc),
                nodes.literal_block(content, content),
                line=position,
            )
            self.current_node += [error]
            return
        assert isinstance(
            result,
            list), 'Directive "{}" must return a list of nodes.'.format(name)
        for i in range(len(result)):
            assert isinstance(
                result[i], nodes.Node
            ), 'Directive "{}" returned non-Node object (index {}): {}'.format(
                name, i, result[i])
        self.current_node += result
Beispiel #16
0
    def run(self):
        language = self.state_machine.language
        document = self.state.document
        directive,messages = directives.directive('plot', language, document)
        self.state.parent += messages

        # Temporarily override template
        #   * Add target to figure
        #   * Add classes for Bootstrap
        target = ':target: ' + self.options.pop('target', '')
        title = self.options['alt']
        classes = ' '.join(document.settings.env.config.gallery_plot_classes +
                           ['thumbnail'])
        template = '''
{{ only_html }}

   {% for img in images %}
   .. figure:: {{ build_dir }}/{{ img.basename }}.png
      ''' + target + '''
      :figclass: ''' + classes + '''
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.pdf
      ''' + target + '''
   {% endfor %}

{{ only_texinfo }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.png
      ''' + target + '''
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

'''

        plot_template_orig = document.settings.env.config.plot_template
        document.settings.env.config.plot_template = template

        # Don't bother with the high resolution version
        plot_formats_orig = document.settings.env.config.plot_formats
        plot_formats = []
        for f in plot_formats_orig:
            if isinstance(f, str) and 'hires' in f:
                continue
            elif isinstance(f, tuple) and 'hires' in f[0]:
                continue
            plot_formats.append(f)
        document.settings.env.config.plot_formats = plot_formats

        options = {
            'alt': title,
        }

        directive_instance = directive('plot', self.arguments, options,
                                       self.content, self.lineno,
                                       self.content_offset, self.block_text,
                                       self.state, 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]

        # Restore original settings
        document.settings.env.config.plot_template = plot_template_orig
        document.settings.env.config.plot_formats = plot_formats_orig

        return result
Beispiel #17
0
def run_fence_as_directive(self, match, **option_presets):
    # NOTE(josh): copied from directive()
    type_name = "code"
    directive_class, messages = directives.directive(type_name,
                                                     self.memo.language,
                                                     self.document)
    self.parent += messages
    if not directive_class:
        return self.unknown_directive(type_name)

    # NOTE(josh): copied from run_directive():
    lineno = self.state_machine.abs_line_number()
    initial_line_offset = self.state_machine.line_offset
    # NOTE(josh): changed this from get_first_known_indented to
    # get_first_known_indented_until, which I wrote (well, sorta... I mean
    # I mostly copied the original function).
    indented, indent, line_offset, blank_finish \
              = self.state_machine.get_first_known_indented_until(
                    match.start(), match.group(0))

    padded = StringList()
    # padded += indented[0:1]
    # First line contains any optional arguments (in this case, language)
    padded += StringList([indented[0][3:]])
    # TODO(josh): check to see if there are any options specified, such
    # as :number-lines:, :class:, :name:.
    # Second line must be blank
    padded += StringList([""])
    padded += indented[1:-1]
    padded += StringList([""])
    # padded += indented[-1:]
    blank_finish = True

    # NOTE(josh): +1 to start, -1 to stop index, as compared to the usual
    # directive parsing. Also added a newline to the start
    block_text = '\n'.join(
        self.state_machine.input_lines[initial_line_offset +
                                       1:self.state_machine.line_offset])
    try:
        arguments, options, content, content_offset = (
            self.parse_directive_block(padded, line_offset, directive_class,
                                       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_class(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 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]))
    return (result, blank_finish or self.state_machine.is_next_line_blank())
Beispiel #18
0
    def run(self):
        language = self.state_machine.language
        document = self.state.document
        directive, messages = directives.directive('plot', language, document)
        self.state.parent += messages

        # Temporarily override template
        #   * Add target to figure
        #   * Add classes for Bootstrap
        target = ':target: ' + self.options.pop('target', '')
        title = self.options['alt']
        classes = ' '.join(document.settings.env.config.gallery_plot_classes +
                           ['thumbnail'])
        template = '''
{{ only_html }}

   {% for img in images %}
   .. figure:: {{ build_dir }}/{{ img.basename }}.png
      ''' + target + '''
      :figclass: ''' + classes + '''
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

{{ only_latex }}

   {% for img in images %}
   {% if 'pdf' in img.formats -%}
   .. image:: {{ build_dir }}/{{ img.basename }}.pdf
      ''' + target + '''
   {% endif -%}
   {% endfor %}

{{ only_texinfo }}

   {% for img in images %}
   .. image:: {{ build_dir }}/{{ img.basename }}.png
      ''' + target + '''
      {% for option in options -%}
      {{ option }}
      {% endfor %}

   {% endfor %}

'''

        plot_template_orig = document.settings.env.config.plot_template
        document.settings.env.config.plot_template = template

        # Don't bother with the high resolution version
        plot_formats_orig = document.settings.env.config.plot_formats
        plot_formats = []
        for f in plot_formats_orig:
            if isinstance(f, str) and 'hires' in f:
                continue
            elif isinstance(f, tuple) and 'hires' in f[0]:
                continue
            plot_formats.append(f)
        document.settings.env.config.plot_formats = plot_formats

        options = {
            'alt': title,
        }

        directive_instance = directive('plot', self.arguments, options,
                                       self.content, self.lineno,
                                       self.content_offset, self.block_text,
                                       self.state, self.state_machine)
        try:
            result = directive_instance.run()
        except DirectiveError as error:
            msg_node = self.reporter.system_message(error.level,
                                                    error.msg,
                                                    line=self.lineno)
            msg_node += nodes.literal_block(self.block_text, self.block_text)
            result = [msg_node]

        # Restore original settings
        document.settings.env.config.plot_template = plot_template_orig
        document.settings.env.config.plot_formats = plot_formats_orig

        return result
    def run_directive(self, name: str, first_line: str, content: str,
                      position: int) -> List[nodes.Element]:
        """Run a directive and return the generated nodes.

        :param name: the name of the directive
        :param first_line: The text on the same line as the directive name.
            May be an argument or body text, dependent on the directive
        :param content: All text after the first line. Can include options.
        :param position: The line number of the first line

        """
        # TODO directive name white/black lists

        self.document.current_line = position

        # get directive class
        directive_class, messages = directives.directive(
            name, self.language_module_rst,
            self.document)  # type: (Directive, list)
        if not directive_class:
            error = self.reporter.error(
                'Unknown directive type "{}".\n'.format(name),
                # nodes.literal_block(content, content),
                line=position,
            )
            return [error] + messages

        if issubclass(directive_class, Include):
            # this is a Markdown only option,
            # to allow for altering relative image reference links
            directive_class.option_spec["relative-images"] = directives.flag
            directive_class.option_spec["relative-docs"] = directives.path

        try:
            arguments, options, body_lines = parse_directive_text(
                directive_class, first_line, content)
        except DirectiveParsingError as error:
            error = self.reporter.error(
                "Directive '{}': {}".format(name, error),
                nodes.literal_block(content, content),
                line=position,
            )
            return [error]

        # initialise directive
        if issubclass(directive_class, Include):
            directive_instance = MockIncludeDirective(
                self,
                name=name,
                klass=directive_class,
                arguments=arguments,
                options=options,
                body=body_lines,
                lineno=position,
            )
        else:
            state_machine = MockStateMachine(self, position)
            state = MockState(self, state_machine, position)
            directive_instance = directive_class(
                name=name,
                # the list of positional arguments
                arguments=arguments,
                # a dictionary mapping option names to values
                options=options,
                # the directive content line by line
                content=StringList(body_lines, self.document["source"]),
                # the absolute line number of the first line of the directive
                lineno=position,
                # the line offset of the first line of the content
                content_offset=
                0,  # TODO get content offset from `parse_directive_text`
                # a string containing the entire directive
                block_text="\n".join(body_lines),
                state=state,
                state_machine=state_machine,
            )

        # run directive
        try:
            result = directive_instance.run()
        except DirectiveError as error:
            msg_node = self.reporter.system_message(error.level,
                                                    error.msg,
                                                    line=position)
            msg_node += nodes.literal_block(content, content)
            result = [msg_node]
        except MockingError as exc:
            error_msg = self.reporter.error(
                "Directive '{}' cannot be mocked: {}: {}".format(
                    name, exc.__class__.__name__, exc),
                nodes.literal_block(content, content),
                line=position,
            )
            return [error_msg]

        assert isinstance(
            result,
            list), 'Directive "{}" must return a list of nodes.'.format(name)
        for i in range(len(result)):
            assert isinstance(
                result[i], nodes.Node
            ), 'Directive "{}" returned non-Node object (index {}): {}'.format(
                name, i, result[i])
        return result