Beispiel #1
0
    def run(self):
        figclasses = self.options.pop('figclass', None)
        (image_node,) = Image.run(self)
        if isinstance(image_node, nodes.system_message):
            return [image_node]
        figure_node = nodes.figure('', image_node)
        if figclasses:
            figure_node['classes'] += figclasses
        figure_node['classes'] += ['m-figure']

        if self.content:
            node = nodes.Element()          # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, '',
                                        *first_node.children)
                caption.source = first_node.source
                caption.line = first_node.line
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                      'Figure caption must be a paragraph or empty comment.',
                      nodes.literal_block(self.block_text, self.block_text),
                      line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        return [figure_node]
Beispiel #2
0
    def run(self):
        set_classes(self.options)

        text = '\n'.join(self.content)
        figure_node = nodes.figure(text, **self.options)
        figure_node['classes'] += self.style_classes

        self.state.nested_parse(self.content, self.content_offset,
                                figure_node)

        # Insert the title node, if any, right after the code / math / graph.
        # There could be things like the class directive before, so be sure to
        # find the right node.
        if len(self.arguments) == 1:
            title_text = self.arguments[0]
            title_nodes, _ = self.state.inline_text(title_text, self.lineno)
            title_node = nodes.caption('', '', *title_nodes)

            for i, child in enumerate(figure_node):
                if isinstance(child, nodes.raw) or isinstance(child, nodes.literal_block):
                    figure_node.insert(i + 1, title_node)
                    break
            else: assert False # pragma: no cover

        return [figure_node]
Beispiel #3
0
    def run(self):
        try:
            data = retrieve_glue_data(self.document, self.arguments[0])
        except RetrievalError as exc:
            return [glue_warning(str(exc), self.document, self.line)]
        render: Dict[str, Any] = {}
        for key in ("alt", "height", "width", "scale", "class"):
            if key in self.options:
                render.setdefault("image",
                                  {})[key.replace("classes",
                                                  "class")] = self.options[key]
        paste_nodes = render_variable_output(data,
                                             self.document,
                                             self.line,
                                             self.source,
                                             render=render)

        # note: most of this is copied directly from sphinx.Figure

        # create figure node
        figure_node = nodes.figure("", *paste_nodes)
        self.set_source_info(figure_node)

        # add attributes
        figwidth = self.options.pop("figwidth", None)
        figclasses = self.options.pop("figclass", None)
        align = self.options.pop("align", None)
        if figwidth is not None:
            figure_node["width"] = figwidth
        if figclasses:
            figure_node["classes"] += figclasses
        if align:
            figure_node["align"] = align

        # add target
        self.add_name(figure_node)

        # create the caption and legend
        if self.content:
            node = nodes.Element()  # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, "",
                                        *first_node.children)
                caption.source = first_node.source
                caption.line = first_node.line
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = glue_warning(
                    "Figure caption must be a paragraph or empty comment.",
                    self.document,
                    self.lineno,
                )
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend("", *node[1:])

        return [figure_node]
Beispiel #4
0
    def run(self):
        results = super(BlockdiagDirective, self).run()

        node = results[0]
        if not isinstance(node, self.node_class):
            return results

        try:
            diagram = self.node2diagram(node)
        except Exception as e:
            raise self.warning(e.message)

        if 'desctable' in node['options']:
            del node['options']['desctable']
            results += self.description_tables(diagram)

        results[0] = self.node2image(node, diagram)

        if 'caption' in node:
            fig = nodes.figure()
            fig += results[0]
            fig += nodes.caption(text=node['caption'])
            results[0] = fig

        return results
Beispiel #5
0
    def run(self):
        node = dag()
        node['dag'] = '\n'.join(self.content)
        node['caption'] = '\n'.join(self.arguments)
        if not self.content:
            node['caption'] = ''
            node['dag'] = '\n'.join(self.arguments)

        node['bugfixed'] = False
        try:
            if sphinx.version_info[0] >= 1 and sphinx.version_info[1] >= 4:
                node['bugfixed'] = True
        except AttributeError:
            pass

        if node['bugfixed'] and node['caption']:
            figure_node = nodes.figure('', node)
            parsed = nodes.Element()
            self.state.nested_parse(ViewList([node['caption']], source=''),
                                    self.content_offset, parsed)
            caption_node = nodes.caption(parsed[0].rawsource, '',
                                         *parsed[0].children)
            caption_node.source = parsed[0].source
            caption_node.line = parsed[0].line
            figure_node += caption_node
            node = figure_node

        return [node]
Beispiel #6
0
    def run(self):
        figclasses = self.options.pop('figclass', None)
        (image_node, ) = Image.run(self)
        if isinstance(image_node, nodes.system_message):
            return [image_node]
        figure_node = nodes.figure('', image_node)
        if figclasses:
            figure_node['classes'] += figclasses
        figure_node['classes'] += ['m-figure']

        if self.content:
            node = nodes.Element()  # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, '',
                                        *first_node.children)
                caption.source = first_node.source
                caption.line = first_node.line
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                    'Figure caption must be a paragraph or empty comment.',
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        return [figure_node]
Beispiel #7
0
    def run(self):
        env = self.state.document.settings.env

        node = nodes.Element()
        node.document = self.state.document
        self.state.nested_parse(self.content, self.content_offset, node)

        images = []
        caption_and_legend = []
        for child in node:
            if isinstance(child, (nodes.target, nodes.image, nodes.figure)):
                images.append(child)
            else:
                caption_and_legend.append(child)

        items = []
        row_item_count = min(
            len(images), self.options.get('rowitems', DEFAULT_ROW_ITEM_COUNT))
        labels = self.options.get('labels', [])
        for img, label in itertools.zip_longest(images, labels):
            item_node = multifigure_item('', img)
            item_node['item-width'] = 100 // row_item_count
            if label is not None:
                item_node['label'] = label
            items.append(item_node)

        caption, legend = caption_and_legend[0], caption_and_legend[1:]

        resultnode = nodes.figure('', multifigure_content('', *items))
        resultnode['labels'] = labels
        resultnode.append(nodes.caption(caption.rawsource, '', *caption))
        if legend:
            resultnode.append(nodes.legend('', *legend))

        return [resultnode]
Beispiel #8
0
    def apply (self):

        if self.document.settings.no_images:
            return

        for image in self.document.traverse (nodes.image):

            # skip inline images
            # (See also: class `TextElement` in `docutils.nodes`.)
            if isinstance (image.parent, nodes.TextElement):
                continue

            # block images default align = center
            image['classes'].append ('block')
            image['align'] = image.attributes.get ('align', 'center')

            # wrap all images into figures
            if not isinstance (image.parent, nodes.figure):
                figure = nodes.figure ()
                figure['float'] = ['none'] # do not float bare images
                figure['width'] = image.attributes.get ('width', 'image')
                image['width'] = '100%'
                figure['align'] = image['align']
                image.replace_self (figure)
                figure.append (image)
            
            # set a default width for block images
            image['width'] = image.attributes.get ('width', '100%')

            figure = image.parent
            if figure['width'] == 'image':
                figure['width'] = self.get_width (image['uri'])
                figure['classes'].append ('auto-scaled')
Beispiel #9
0
    def run(self):
        set_classes(self.options)

        text = '\n'.join(self.content)
        figure_node = nodes.figure(text, **self.options)
        figure_node['classes'] += self.style_classes

        self.state.nested_parse(self.content, self.content_offset, figure_node)

        # Insert the title node, if any, right after the code / math / graph.
        # There could be things like the class directive before, so be sure to
        # find the right node.
        if len(self.arguments) == 1:
            title_text = self.arguments[0]
            title_nodes, _ = self.state.inline_text(title_text, self.lineno)
            title_node = nodes.caption('', '', *title_nodes)

            for i, child in enumerate(figure_node):
                if isinstance(child, nodes.raw) or isinstance(
                        child, nodes.literal_block):
                    figure_node.insert(i + 1, title_node)
                    break
            else:
                assert False  # pragma: no cover

        return [figure_node]
Beispiel #10
0
def run(self):
    from sphinx.util.nodes import set_source_info
    from sphinx.util.i18n import search_image_for_language
    warning = self.state.document.reporter.warning
    env = self.state.document.settings.env
    if self.arguments and self.content:
        return [
            warning(
                'uml directive cannot have both content and '
                'a filename argument',
                line=self.lineno)
        ]
    if self.arguments:
        fn = search_image_for_language(self.arguments[0], env)
        relfn, absfn = env.relfn2path(fn)
        env.note_dependency(relfn)
        try:
            umlcode = sphinxcontrib.plantuml._read_utf8(absfn)
        except (IOError, UnicodeDecodeError) as err:
            return [
                warning('PlantUML file "%s" cannot be read: %s' % (fn, err),
                        line=self.lineno)
            ]
        source = absfn
        line = 1
    else:
        relfn = env.doc2path(env.docname, base=None)
        umlcode = '\n'.join(self.content)
        source, line = self.state_machine.get_source_and_line(
            self.content_offset)

    node = sphinxcontrib.plantuml.plantuml(self.block_text, **self.options)
    node['uml'] = umlcode
    node['incdir'] = os.path.dirname(relfn)
    node['filename'] = os.path.split(relfn)[1]
    node.source, node.line = source, line

    # XXX maybe this should be moved to _visit_plantuml functions. it
    # seems wrong to insert "figure" node by "plantuml" directive.
    if 'caption' in self.options or 'align' in self.options:
        node = nodes.figure('', node)
        if 'align' in self.options:
            node['align'] = self.options['align']
    if 'caption' in self.options:
        inodes, messages = self.state.inline_text(self.options['caption'],
                                                  self.lineno)
        caption_node = nodes.caption(self.options['caption'], '', *inodes)
        caption_node.extend(messages)
        set_source_info(self, caption_node)
        node += caption_node
    self.add_name(node)
    if 'html_format' in self.options:
        node['html_format'] = self.options['html_format']
    if 'latex_format' in self.options:
        node['latex_format'] = self.options['latex_format']

    return [node]
Beispiel #11
0
    def run(self):
        set_classes(self.options)

        text = '\n'.join(self.content)
        figure_node = nodes.figure(text, **self.options)
        figure_node['classes'] += [self.style_class]

        self.state.nested_parse(self.content, self.content_offset, figure_node)
        return [figure_node]
Beispiel #12
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        figclasses = self.options.pop('figclass', None)
        align = self.options.pop('align', None)
        (media_node,) = Media.run(self)
        if isinstance(media_node, nodes.system_message):
            return [media_node]
        figure_node = nodes.figure('', media_node)
        if figwidth == 'image':
            if PIL and self.state.document.settings.file_insertion_enabled:
                # PIL doesn't like Unicode paths:
                try:
                    i = PIL.open(str(media_node['uri']))
                except (IOError, UnicodeError):
                    pass
                else:
                    self.state.document.settings.record_dependencies.add(
                        media_node['uri'])
                    figure_node['width'] = i.size[0]
        elif figwidth is not None:
            figure_node['width'] = figwidth
        if figclasses:
            figure_node['classes'] += figclasses
        if align:
            figure_node['align'] = align
        if self.content:
            node = nodes.Element()          # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, '',
                    *first_node.children)
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                    'Figure caption must be a paragraph or empty comment.',
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        node = figure_node

        node['label'] = self.options.get('label', None)
        if not node['label']:
            node['label'] = self.options.get('uri')
        node['number'] = None
        ret = [node]
        if node['label']:
            key = node['label']
            tnode = nodes.target('', '', ids=['figure-' + node['label']])
            self.state.document.note_explicit_target(tnode)
            ret.insert(0, tnode)
        return ret
Beispiel #13
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        figclasses = self.options.pop('figclass', ["right"])
        align = self.options.pop('align', None)
        (media_node, ) = Media.run(self)
        if isinstance(media_node, nodes.system_message):
            return [media_node]
        figure_node = nodes.figure('', media_node)
        if figwidth == 'image':
            if PIL and self.state.document.settings.file_insertion_enabled:
                # PIL doesn't like Unicode paths:
                try:
                    i = PIL.open(str(media_node['uri']))
                except (IOError, UnicodeError):
                    pass
                else:
                    self.state.document.settings.record_dependencies.add(
                        media_node['uri'])
                    figure_node['width'] = i.size[0]
        elif figwidth is not None:
            figure_node['width'] = figwidth
        if figclasses:
            figure_node['classes'] += figclasses
        if align:
            figure_node['align'] = align
        if self.content:
            node = nodes.Element()  # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, '',
                                        *first_node.children)
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                    'Figure caption must be a paragraph or empty comment.',
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        node = figure_node

        node['label'] = self.options.get('label', None)
        if not node['label']:
            node['label'] = self.options.get('uri')
        node['number'] = None
        ret = [node]
        if node['label']:
            key = node['label']
            tnode = nodes.target('', '', ids=['figure-' + node['label']])
            self.state.document.note_explicit_target(tnode)
            ret.insert(0, tnode)
        return ret
Beispiel #14
0
    def run(self):
        figure = nodes.figure()

        # Figure out what the show for this demo
        
        py_path = Path(self.arguments[0])
        zip_path = py_path.parent / (py_path.stem + '_assets.zip')
        png_path = py_path.parent / (py_path.stem + '.png')

        # Error out if the given python script doesn't exist.
        if py_path.suffix != '.py':
            raise self.error(f"'{py_path}' must be a python script.")

        if not py_path.exists():
            raise self.error(f"'{py_path}' doesn't exist.")
        
        if self.content:

            # Make sure the content is present in the given file.  Complain if 
            # there are differences.

            from textwrap import dedent

            with open(py_path) as py_file:
                py_code = [l.strip() for l in py_file.readlines()]

                for py_line in self.content:
                    if py_line.strip() not in py_code:
                        raise self.error(f"""\
Error in \"demo\" directive: The following line isn't present in '{py_path}':
{py_line}""")

            # Add a node for the code snippet

            from sphinx.directives.code import CodeBlock
            figure += self.make_snippet(self.content, png_path.exists())

        # Add a node for the screenshot

        if png_path.exists():
            figure += self.make_screenshot(png_path)

        # Add a node for the download links.
        
        caption = nodes.caption()
        caption += self.make_download_link(py_path)

        if zip_path.exists():
            caption += linebreak()
            caption += self.make_download_link(zip_path)

        figure += caption
        
        return [figure]
Beispiel #15
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        position = self.options.pop('position', None)
        figclasses = self.options.pop('figclass', None)
        align = self.options.pop('align', None)
        (image_node,) = Image.run(self)
        if isinstance(image_node, nodes.system_message):
            return [image_node]
        figure_node = nodes.figure('', image_node)
        if figwidth == 'image':
            if PIL and self.state.document.settings.file_insertion_enabled:
                # PIL doesn't like Unicode paths:
                try:
                    i = PIL.open(str(image_node['uri']))
                except (IOError, UnicodeError):
                    pass
                else:
                    self.state.document.settings.record_dependencies.add(
                        image_node['uri'])
                    figure_node['width'] = i.size[0]
        elif figwidth is not None:
            figure_node['width'] = figwidth            
        if figclasses:
            figure_node['classes'] += figclasses
        if align:
            figure_node['align'] = align
        if position:
            figure_node['position'] = position
        if self.content:
            node = nodes.Element()          # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]

            cap = first_node.astext().strip()
            if re.match('[Tt]he.*',cap):
                print >>sys.stderr, "WARNING: Style: Caption '%s' begins with 'The'" % cap

            if isinstance(first_node, nodes.paragraph):
                caption = nodes.caption(first_node.rawsource, '',
                                        *first_node.children)
                figure_node += caption
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                      'Figure caption must be a paragraph or empty comment.',
                      nodes.literal_block(self.block_text, self.block_text),
                      line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        else:
            self.state.document.reporter.error('Figure without caption\n',
                                               line = self.lineno)
        return [figure_node]
Beispiel #16
0
    def run(self):
        figure = nodes.figure()

        # Figure out what the show for this demo

        py_path = Path(self.arguments[0])
        zip_path = py_path.parent / (py_path.stem + '_assets.zip')
        png_path = py_path.parent / (py_path.stem + '.png')

        # Error out if the given python script doesn't exist.
        if py_path.suffix != '.py':
            raise self.error(f"'{py_path}' must be a python script.")

        if not py_path.exists():
            raise self.error(f"'{py_path}' doesn't exist.")

        if self.content:

            # Make sure the content is present in the given file.  Complain if
            # there are differences.

            from textwrap import dedent

            with open(py_path) as py_file:
                py_code = [l.strip() for l in py_file.readlines()]

                for py_line in self.content:
                    if py_line.strip() not in py_code:
                        raise self.error(f"""\
Error in \"demo\" directive: The following line isn't present in '{py_path}':
{py_line}""")

            # Add a node for the code snippet

            from sphinx.directives.code import CodeBlock
            figure += self.make_snippet(self.content, png_path.exists())

        # Add a node for the screenshot

        if png_path.exists():
            figure += self.make_screenshot(png_path)

        # Add a node for the download links.

        caption = nodes.caption()
        caption += self.make_download_link(py_path)

        if zip_path.exists():
            caption += linebreak()
            caption += self.make_download_link(zip_path)

        figure += caption

        return [figure]
Beispiel #17
0
def figure_wrapper(directive, node, caption):
    figure_node = nodes.figure('', node)

    parsed = nodes.Element()
    directive.state.nested_parse(ViewList([caption], source=''),
                                 directive.content_offset, parsed)
    caption_node = nodes.caption(parsed[0].rawsource, '', *parsed[0].children)
    caption_node.source = parsed[0].source
    caption_node.line = parsed[0].line
    figure_node += caption_node
    return figure_node
Beispiel #18
0
def figure_wrapper(directive: Directive, node: graphviz, caption: str) -> nodes.figure:
    figure_node = nodes.figure('', node)
    if 'align' in node:
        figure_node['align'] = node.attributes.pop('align')

    inodes, messages = directive.state.inline_text(caption, directive.lineno)
    caption_node = nodes.caption(caption, '', *inodes)
    caption_node.extend(messages)
    set_source_info(directive, caption_node)
    figure_node += caption_node
    return figure_node
Beispiel #19
0
def figure_wrapper(directive, node, caption):
    figure_node = nodes.figure('', node)

    parsed = nodes.Element()
    directive.state.nested_parse(ViewList([caption], source=''),
                                 directive.content_offset, parsed)
    caption_node = nodes.caption(parsed[0].rawsource, '',
                                 *parsed[0].children)
    caption_node.source = parsed[0].source
    caption_node.line = parsed[0].line
    figure_node += caption_node
    return figure_node
Beispiel #20
0
def figure_wrapper(directive, node, caption):
    # type: (Directive, graphviz, str) -> nodes.figure
    figure_node = nodes.figure('', node)
    if 'align' in node:
        figure_node['align'] = node.attributes.pop('align')

    inodes, messages = directive.state.inline_text(caption, directive.lineno)
    caption_node = nodes.caption(caption, '', *inodes)
    caption_node.extend(messages)
    set_source_info(directive, caption_node)
    figure_node += caption_node
    return figure_node
Beispiel #21
0
    def run(self):
        grid_node = nodes.container()
        grid_node['classes'] += ['m-imagegrid', 'm-container-inflate']

        rows = [[]]
        total_widths = [0]
        for uri in self.content:
            # New line, calculating width from 0 again
            if not uri:
                rows.append([])
                total_widths.append(0)
                continue

            # Open the files and calculate the overall width
            absuri = uri.format(
                filename=os.path.join(os.getcwd(), settings['PATH']))
            im = PIL.Image.open(absuri)
            exif = {
                PIL.ExifTags.TAGS[k]: v
                for k, v in im._getexif().items()
                if k in PIL.ExifTags.TAGS and len(str(v)) < 256
            }
            # Can't use just *exif['ExposureTime'] on Py3.4
            caption = "F{}, {}/{} s, ISO {}".format(
                float(exif['FNumber'][0]) / float(exif['FNumber'][1]),
                exif['ExposureTime'][0], exif['ExposureTime'][1],
                exif['ISOSpeedRatings'])
            rel_width = float(im.width) / im.height
            total_widths[-1] += rel_width
            rows[-1].append((uri, rel_width, len(total_widths) - 1, caption))

        for row in rows:
            row_node = nodes.container()

            for image in row:
                image_reference = rst.directives.uri(image[0])
                image_node = nodes.image('', uri=image_reference)
                text_nodes, _ = self.state.inline_text(image[3], self.lineno)
                text_node = nodes.paragraph('', '', *text_nodes)
                overlay_node = nodes.caption()
                overlay_node.append(text_node)
                link_node = nodes.reference('', refuri=image_reference)
                link_node.append(image_node)
                link_node.append(overlay_node)
                wrapper_node = nodes.figure(
                    width="{:.3f}%".format(image[1] * 100.0 /
                                           total_widths[image[2]]))
                wrapper_node.append(link_node)
                row_node.append(wrapper_node)

            grid_node.append(row_node)

        return [grid_node]
Beispiel #22
0
def figure_wrapper(directive, node, caption):
    figure_node = nodes.figure("", node)
    if "align" in node:
        figure_node["align"] = node.attributes.pop("align")

    parsed = nodes.Element()
    directive.state.nested_parse(ViewList([caption], source=""),
                                 directive.content_offset, parsed)
    caption_node = nodes.caption(parsed[0].rawsource, "", *parsed[0].children)
    caption_node.source = parsed[0].source
    caption_node.line = parsed[0].line
    figure_node += caption_node
    return figure_node
Beispiel #23
0
 def run(self):
     figwidth = self.options.pop('figwidth', None)
     figclasses = self.options.pop('figclass', None)
     align = self.options.pop('align', None)
     (image_node, ) = Image.run(self)
     if isinstance(image_node, nodes.system_message):
         return [image_node]
     figure_node = nodes.figure('', image_node)
     if figwidth == 'image':
         if PIL and self.state.document.settings.file_insertion_enabled:
             imagepath = urllib.url2pathname(image_node['uri'])
             try:
                 if isinstance(imagepath, str):
                     imagepath_str = imagepath
                 else:
                     imagepath_str = imagepath.encode(
                         sys.getfilesystemencoding())
                 img = PIL.Image.open(imagepath_str)
             except (IOError, UnicodeEncodeError):
                 pass  # TODO: warn?
             else:
                 self.state.document.settings.record_dependencies.add(
                     imagepath.replace('\\', '/'))
                 figure_node['width'] = '%dpx' % img.size[0]
                 del img
     elif figwidth is not None:
         figure_node['width'] = figwidth
     if figclasses:
         figure_node['classes'] += figclasses
     if align:
         figure_node['align'] = align
     if self.content:
         node = nodes.Element()  # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, '',
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                 'Figure caption must be a paragraph or empty comment.',
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend('', *node[1:])
     return [figure_node]
Beispiel #24
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        figclasses = self.options.pop('figclass', None)
        if self.options.get('caption'):
            align = self.options.pop('align', None)
        else:
            align = None

        results = super(BlockdiagDirective, self).run()

        node = results[0]
        if not isinstance(node, self.node_class):
            return results

        try:
            diagram = self.node2diagram(node)
        except Exception as e:
            raise self.warning(str(e))

        if 'desctable' in node['options']:
            results += self.description_tables(diagram)

        results[0] = self.node2image(node, diagram)
        self.add_name(results[0])

        if node.get('caption'):
            elem = nodes.Element()
            self.state.nested_parse(ViewList([node['caption']], source=''),
                                    self.content_offset, elem)
            caption_node = nodes.caption(elem[0].rawsource, '',
                                         *elem[0].children)
            caption_node.source = elem[0].source
            caption_node.line = elem[0].line

            fig = nodes.figure()
            fig += results[0]
            fig += caption_node

            if figwidth == 'image':
                width = self.get_actual_width(node, diagram)
                fig['width'] = str(width) + 'px'
            elif figwidth is not None:
                fig['width'] = figwidth
            if figclasses:
                fig['classes'] += figclasses
            if align:
                fig['align'] = align

            results[0] = fig

        return results
Beispiel #25
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        figclasses = self.options.pop('figclass', None)
        if self.options.get('caption'):
            align = self.options.pop('align', None)
        else:
            align = None

        results = super(BlockdiagDirective, self).run()

        node = results[0]
        if not isinstance(node, self.node_class):
            return results

        try:
            diagram = self.node2diagram(node)
        except Exception as e:
            raise self.warning(str(e))

        if 'desctable' in node['options']:
            results += self.description_tables(diagram)

        results[0] = self.node2image(node, diagram)
        self.add_name(results[0])

        if node.get('caption'):
            elem = nodes.Element()
            self.state.nested_parse(ViewList([node['caption']], source=''),
                                    self.content_offset, elem)
            caption_node = nodes.caption(elem[0].rawsource, '',
                                         *elem[0].children)
            caption_node.source = elem[0].source
            caption_node.line = elem[0].line

            fig = nodes.figure()
            fig += results[0]
            fig += caption_node

            if figwidth == 'image':
                width = self.get_actual_width(node, diagram)
                fig['width'] = str(width) + 'px'
            elif figwidth is not None:
                fig['width'] = figwidth
            if figclasses:
                fig['classes'] += figclasses
            if align:
                fig['align'] = align

            results[0] = fig

        return results
Beispiel #26
0
    def run(self):
        warning = self.state.document.reporter.warning
        env = self.state.document.settings.env
        if self.arguments and self.content:
            return [
                warning(
                    'uml directive cannot have both content and '
                    'a filename argument',
                    line=self.lineno)
            ]
        if self.arguments:
            fn = search_image_for_language(self.arguments[0], env)
            relfn, absfn = env.relfn2path(fn)
            env.note_dependency(relfn)
            try:
                umlcode = _read_utf8(absfn)
            except (IOError, UnicodeDecodeError) as err:
                return [
                    warning('PlantUML file "%s" cannot be read: %s' %
                            (fn, err),
                            line=self.lineno)
                ]
        else:
            relfn = env.doc2path(env.docname, base=None)
            umlcode = '\n'.join(self.content)

        node = plantuml(self.block_text, **self.options)
        node['uml'] = umlcode
        node['incdir'] = os.path.dirname(relfn)
        node['filename'] = os.path.split(relfn)[1]

        # XXX maybe this should be moved to _visit_plantuml functions. it
        # seems wrong to insert "figure" node by "plantuml" directive.
        if 'caption' in self.options or 'align' in self.options:
            node = nodes.figure('', node)
            if 'align' in self.options:
                node['align'] = self.options['align']
        if 'caption' in self.options:
            import docutils.statemachine
            cnode = nodes.Element()  # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options['caption']],
                                                  source='')
            self.state.nested_parse(sl, self.content_offset, cnode)
            caption = nodes.caption(self.options['caption'], '', *cnode)
            node += caption
        if 'html_format' in self.options:
            node['html_format'] = self.options['html_format']
        if 'latex_format' in self.options:
            node['latex_format'] = self.options['latex_format']

        return [node]
Beispiel #27
0
def figure(name, arguments, options, content, lineno, content_offset,
           block_text, state, state_machine):
    figwidth = options.get('figwidth')
    if figwidth:
        del options['figwidth']
    figclasses = options.get('figclass')
    if figclasses:
        del options['figclass']
    align = options.get('align')
    if align:
        del options['align']
    (image_node, ) = image(name, arguments, options, content, lineno,
                           content_offset, block_text, state, state_machine)
    if isinstance(image_node, nodes.system_message):
        return [image_node]
    figure_node = nodes.figure('', image_node)
    if figwidth == 'image':
        if Image and state.document.settings.file_insertion_enabled:
            # PIL doesn't like Unicode paths:
            try:
                i = Image.open(str(image_node['uri']))
            except (IOError, UnicodeError):
                pass
            else:
                state.document.settings.record_dependencies.add(
                    image_node['uri'])
                figure_node['width'] = i.size[0]
    elif figwidth is not None:
        figure_node['width'] = figwidth
    if figclasses:
        figure_node['classes'] += figclasses
    if align:
        figure_node['align'] = align
    if content:
        node = nodes.Element()  # anonymous container for parsing
        state.nested_parse(content, content_offset, node)
        first_node = node[0]
        if isinstance(first_node, nodes.paragraph):
            caption = nodes.caption(first_node.rawsource, '',
                                    *first_node.children)
            figure_node += caption
        elif not (isinstance(first_node, nodes.comment)
                  and len(first_node) == 0):
            error = state_machine.reporter.error(
                'Figure caption must be a paragraph or empty comment.',
                nodes.literal_block(block_text, block_text),
                line=lineno)
            return [figure_node, error]
        if len(node) > 1:
            figure_node += nodes.legend('', *node[1:])
    return [figure_node]
Beispiel #28
0
 def run(self):
     figwidth = self.options.pop('figwidth', None)
     figclasses = self.options.pop('figclass', None)
     align = self.options.pop('align', None)
     (image_node,) = Image.run(self)
     if isinstance(image_node, nodes.system_message):
         return [image_node]
     figure_node = nodes.figure('', image_node)
     if figwidth == 'image':
         if PIL and self.state.document.settings.file_insertion_enabled:
             imagepath = urllib.url2pathname(image_node['uri'])
             try:
                 if isinstance(imagepath, str):
                     imagepath_str = imagepath
                 else:
                     imagepath_str = imagepath.encode(sys.getfilesystemencoding())
                 img = PIL.Image.open(imagepath_str)
             except (IOError, UnicodeEncodeError):
                 pass # TODO: warn?
             else:
                 self.state.document.settings.record_dependencies.add(
                     imagepath.replace('\\', '/'))
                 figure_node['width'] = '%dpx' % img.size[0]
                 del img
     elif figwidth is not None:
         figure_node['width'] = figwidth
     if figclasses:
         figure_node['classes'] += figclasses
     if align:
         figure_node['align'] = align
     if self.content:
         node = nodes.Element()          # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, '',
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                   'Figure caption must be a paragraph or empty comment.',
                   nodes.literal_block(self.block_text, self.block_text),
                   line=self.lineno)
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend('', *node[1:])
     return [figure_node]
Beispiel #29
0
def figure_wrapper(directive, node, caption):
    # type: (Directive, nodes.Node, unicode) -> nodes.figure
    figure_node = nodes.figure('', node)
    if 'align' in node:
        figure_node['align'] = node.attributes.pop('align')

    parsed = nodes.Element()
    directive.state.nested_parse(ViewList([caption], source=''),
                                 directive.content_offset, parsed)
    caption_node = nodes.caption(parsed[0].rawsource, '', *parsed[0].children)
    caption_node.source = parsed[0].source
    caption_node.line = parsed[0].line
    figure_node += caption_node
    return figure_node
Beispiel #30
0
 def run(self):
     figwidth = self.options.get('figwidth')
     if figwidth:
         del self.options['figwidth']
     figclasses = self.options.get('figclass')
     if figclasses:
         del self.options['figclass']
     align = self.options.get('align')
     if align:
         del self.options['align']
     (image_node,) = Image.run(self)
     if isinstance(image_node, nodes.system_message):
         return [image_node]
     figure_node = nodes.figure('', image_node)
     if figwidth == 'image':
         if PIL and self.state.document.settings.file_insertion_enabled:
             # PIL doesn't like Unicode paths:
             try:
                 i = PIL.open(str(image_node['uri']))
             except (IOError, UnicodeError):
                 pass
             else:
                 self.state.document.settings.record_dependencies.add(
                     image_node['uri'])
                 figure_node['width'] = i.size[0]
     elif figwidth is not None:
         figure_node['width'] = figwidth
     if figclasses:
         figure_node['classes'] += figclasses
     if align:
         figure_node['align'] = align
     if self.content:
         node = nodes.Element()          # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, '',
                                     *first_node.children)
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                   'Figure caption must be a paragraph or empty comment.',
                   nodes.literal_block(self.block_text, self.block_text),
                   line=self.lineno)
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend('', *node[1:])
     return [figure_node]
Beispiel #31
0
    def run(self):
        node = plantuml(self.block_text, **self.options)
        node['uml'] = '\n'.join(self.content)

        # if a caption is defined, insert a 'figure' with this node and the caption
        if 'caption' in self.options:
            import docutils.statemachine
            cnode = nodes.Element()          # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options['caption']],source='')
            self.state.nested_parse(sl,self.content_offset, cnode)
            caption = nodes.caption(self.options['caption'], '', *cnode)
            fig = nodes.figure('',node)
            fig += caption
            node = fig
        return [node]
Beispiel #32
0
def figure_wrapper(directive, node, caption):
    # type: (Directive, nodes.Node, unicode) -> nodes.figure
    figure_node = nodes.figure('', node)
    if 'align' in node:
        figure_node['align'] = node.attributes.pop('align')

    parsed = nodes.Element()
    directive.state.nested_parse(ViewList([caption], source=''),
                                 directive.content_offset, parsed)
    caption_node = nodes.caption(parsed[0].rawsource, '',
                                 *parsed[0].children)
    caption_node.source = parsed[0].source
    caption_node.line = parsed[0].line
    figure_node += caption_node
    return figure_node
Beispiel #33
0
 def run(self):
     figwidth = self.options.pop("figwidth", None)
     figclasses = self.options.pop("figclass", None)
     align = self.options.pop("align", None)
     (image_node, ) = Image.run(self)
     if isinstance(image_node, nodes.system_message):
         return [image_node]
     figure_node = nodes.figure("", image_node)
     if figwidth == "image":
         if PIL and self.state.document.settings.file_insertion_enabled:
             imagepath = url2pathname(image_node["uri"])
             try:
                 img = PIL.Image.open(
                     imagepath.encode(sys.getfilesystemencoding()))
             except (IOError, UnicodeEncodeError):
                 pass  # TODO: warn?
             else:
                 self.state.document.settings.record_dependencies.add(
                     imagepath.replace("\\", "/"))
                 figure_node["width"] = "%dpx" % img.size[0]
                 del img
     elif figwidth is not None:
         figure_node["width"] = figwidth
     if figclasses:
         figure_node["classes"] += figclasses
     if align:
         figure_node["align"] = align
     if self.content:
         node = nodes.Element()  # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, "",
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                 "Figure caption must be a paragraph or empty comment.",
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno,
             )
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend("", *node[1:])
     return [figure_node]
Beispiel #34
0
    def run(self):
        node = plantuml(self.block_text, **self.options)
        node['uml'] = '\n'.join(self.content)

        # if a caption is defined, insert a 'figure' with this node and the caption
        if 'caption' in self.options:
            import docutils.statemachine
            cnode = nodes.Element()  # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options['caption']],
                                                  source='')
            self.state.nested_parse(sl, self.content_offset, cnode)
            caption = nodes.caption(self.options['caption'], '', *cnode)
            fig = nodes.figure('', node)
            fig += caption
            node = fig
        return [node]
    def run(self):
        self.options['width'] = '95%'
        label = self.options.get('label', None)

        (image_node, ) = Image.run(self)
        if isinstance(image_node, nodes.system_message):
            return [image_node]

        figure_node = nodes.figure('',
                                   image_node,
                                   ids=[label] if label is not None else [])
        figure_node['align'] = 'center'

        if self.content:
            node = nodes.Element()  # anonymous container for parsing
            self.state.nested_parse(self.content, self.content_offset, node)
            first_node = node[0]
            if isinstance(first_node, nodes.paragraph):
                caption_node = nodes.caption(first_node.rawsource, '',
                                             *first_node.children)
                caption_node.source = first_node.source
                caption_node.line = first_node.line
                figure_node += caption_node
            elif not (isinstance(first_node, nodes.comment)
                      and len(first_node) == 0):
                error = self.state_machine.reporter.error(
                    'Subfigure caption must be a paragraph or empty comment.',
                    nodes.literal_block(self.block_text, self.block_text),
                    line=self.lineno)
                return [figure_node, error]
            if len(node) > 1:
                figure_node += nodes.legend('', *node[1:])
        else:
            rst = ViewList()
            rst.append(self.options['caption'], "", 0)

            parsed_node = nodes.section()
            parsed_node.document = self.state.document
            nested_parse_with_titles(self.state, rst, parsed_node)

            node = parsed_node[0]
            caption_node = nodes.caption(node.rawsource, '', *node.children)
            caption_node.source = node.source
            caption_node.line = node.line
            figure_node += caption_node

        return [figure_node]
Beispiel #36
0
def sourcecode(
    name, arguments, options, content, lineno,
    content_offset, block_text, state, state_machine,
    ):
    filename = options.get('filename', None)
    if filename is None:
        code = u'\n'.join(content)
    else:
        source = state_machine.input_lines.source(
            lineno - state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        filename = os.path.normpath(os.path.join(source_dir, filename))
        filename = utils.relative_path(None, filename)
        state.document.settings.record_dependencies.add(filename)
        op = state.document.settings.roast_operation
        inp = op.open_input(filename)
        code = inp.read().decode('utf-8')
        inp.close()

    if arguments:
        (syntax,) = arguments
    else:
        syntax = 'text'
    lexer = lexers.get_lexer_by_name(syntax)
    formatter = formatters.HtmlFormatter()
    html = highlight(
        code=code,
        lexer=lexer,
        formatter=formatter,
        )

    title_text = options.get('title')
    if title_text:
        text_nodes, messages = state.inline_text(title_text, lineno)
        title = nodes.caption('', '# ', *text_nodes)
    else:
        messages = []
        title = None

    fig = nodes.figure('')
    fig['classes'].append('py-listing')
    if title is not None:
        fig += title

    fig += nodes.raw('', html, format='html')

    return [fig] + messages
Beispiel #37
0
    def run(self):
        name, = self.content
        source_name, scenario = name.rsplit("-", 1)
        source = source_name + ".sam"

        image_reference = directives.uri("_images/" + name + ".png")
        self.options["uri"] = image_reference

        source_link = nodes.reference(self.content, source, refuri="examples/" + source)
        # text = nodes.text('', 'Output from ' + source)
        image_node = nodes.image("_images/" + name + ".png", **self.options)
        figure_node = nodes.figure("", image_node)
        msg = "Output from "
        if scenario != "baseline":
            msg += "'" + scenario + "' in "
        caption = nodes.caption("hi", msg, source_link)
        figure_node += caption
        return [figure_node]
Beispiel #38
0
    def build_node(self):

        srclang = self.arguments[0].strip()
        if srclang not in RENDER_MARKUP_EXT.keys():
            return [
                self.state_machine.reporter.warning(
                    'Unknown source language "%s", use one of: %s.' %
                    (srclang, ",".join(RENDER_MARKUP_EXT.keys())),
                    line=self.lineno)
            ]

        code = '\n'.join(self.content)
        if not code.strip():
            return [
                self.state_machine.reporter.warning(
                    'Ignoring "%s" directive without content.' % (self.name),
                    line=self.lineno)
            ]

        node = kernel_render()
        node['alt'] = self.options.get('alt', '')
        node['srclang'] = srclang
        literal_node = nodes.literal_block(code, code)
        node += literal_node

        caption = self.options.get('caption')
        if caption:
            # parse caption's content
            parsed = nodes.Element()
            self.state.nested_parse(ViewList([caption], source=''),
                                    self.content_offset, parsed)
            caption_node = nodes.caption(parsed[0].rawsource, '',
                                         *parsed[0].children)
            caption_node.source = parsed[0].source
            caption_node.line = parsed[0].line

            figure_node = nodes.figure('', node)
            for k, v in self.options.items():
                figure_node[k] = v
            figure_node += caption_node

            node = figure_node

        return node
Beispiel #39
0
def figure(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):
    figwidth = options.setdefault("figwidth")
    figclasses = options.setdefault("figclass")
    align = options.setdefault("align")
    del options["figwidth"]
    del options["figclass"]
    del options["align"]
    (image_node,) = image(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
    if isinstance(image_node, nodes.system_message):
        return [image_node]
    figure_node = nodes.figure("", image_node)
    if figwidth == "image":
        if Image and state.document.settings.file_insertion_enabled:
            # PIL doesn't like Unicode paths:
            try:
                i = Image.open(str(image_node["uri"]))
            except (IOError, UnicodeError):
                pass
            else:
                state.document.settings.record_dependencies.add(image_node["uri"])
                figure_node["width"] = i.size[0]
    elif figwidth is not None:
        figure_node["width"] = figwidth
    if figclasses:
        figure_node["classes"] += figclasses
    if align:
        figure_node["align"] = align
    if content:
        node = nodes.Element()  # anonymous container for parsing
        state.nested_parse(content, content_offset, node)
        first_node = node[0]
        if isinstance(first_node, nodes.paragraph):
            caption = nodes.caption(first_node.rawsource, "", *first_node.children)
            figure_node += caption
        elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0):
            error = state_machine.reporter.error(
                "Figure caption must be a paragraph or empty comment.",
                nodes.literal_block(block_text, block_text),
                line=lineno,
            )
            return [figure_node, error]
        if len(node) > 1:
            figure_node += nodes.legend("", *node[1:])
    return [figure_node]
Beispiel #40
0
def test_process_doc_handle_figure_caption():
    env = mock.Mock(domaindata={})
    figure_node = nodes.figure(
        '',
        nodes.caption('caption text', 'caption text'),
    )
    document = mock.Mock(
        nametypes={'testname': True},
        nameids={'testname': 'testid'},
        ids={'testid': figure_node},
    )

    domain = StandardDomain(env)
    if 'testname' in domain.data['labels']:
        del domain.data['labels']['testname']
    domain.process_doc(env, 'testdoc', document)
    assert 'testname' in domain.data['labels']
    assert domain.data['labels']['testname'] == ('testdoc', 'testid',
                                                 'caption text')
Beispiel #41
0
    def run(self):
        figwidth = self.options.pop('figwidth', None)
        figclasses = self.options.pop('figclass', None)
        if self.options.get('caption'):
            align = self.options.pop('align', None)
        else:
            align = None

        results = super(BlockdiagDirective, self).run()

        node = results[0]
        if not isinstance(node, self.node_class):
            return results

        try:
            diagram = self.node2diagram(node)
        except Exception as e:
            raise self.warning(str(e))

        if 'desctable' in node['options']:
            results += self.description_tables(diagram)

        results[0] = self.node2image(node, diagram)
        self.add_name(results[0])

        if node.get('caption'):
            fig = nodes.figure()
            fig += results[0]
            fig += nodes.caption(text=node['caption'])

            if figwidth == 'image':
                width = self.get_actual_width(node, diagram)
                fig['width'] = str(width) + 'px'
            elif figwidth is not None:
                fig['width'] = figwidth
            if figclasses:
                fig['classes'] += figclasses
            if align:
                fig['align'] = align

            results[0] = fig

        return results
Beispiel #42
0
def test_process_doc_handle_figure_caption():
    env = mock.Mock(domaindata={})
    figure_node = nodes.figure(
        '',
        nodes.caption('caption text', 'caption text'),
    )
    document = mock.Mock(
        nametypes={'testname': True},
        nameids={'testname': 'testid'},
        ids={'testid': figure_node},
    )

    domain = StandardDomain(env)
    if 'testname' in domain.data['labels']:
        del domain.data['labels']['testname']
    domain.process_doc(env, 'testdoc', document)
    assert 'testname' in domain.data['labels']
    assert domain.data['labels']['testname'] == (
        'testdoc', 'testid', 'caption text')
Beispiel #43
0
 def run(self):
     figwidth = self.options.pop("figwidth", None)
     figclasses = self.options.pop("figclass", None)
     align = self.options.pop("align", None)
     # On the Paste node we should add an attribute to specify that only image
     # type mimedata is allowed, then this would be used by
     # PasteNodesToDocutils -> CellOutputsToNodes to alter the render priority
     # and/or log warnings if that type of mimedata is not available
     (paste_node, ) = Paste.run(self)
     if isinstance(paste_node, nodes.system_message):
         return [paste_node]
     figure_node = nodes.figure("", paste_node)
     figure_node.line = paste_node.line
     figure_node.source = paste_node.source
     if figwidth is not None:
         figure_node["width"] = figwidth
     if figclasses:
         figure_node["classes"] += figclasses
     if align:
         figure_node["align"] = align
     self.add_name(figure_node)
     # note: this is copied directly from sphinx.Figure
     if self.content:
         node = nodes.Element()  # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, "",
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                 "Figure caption must be a paragraph or empty comment.",
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno,
             )
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend("", *node[1:])
     return [figure_node]
Beispiel #44
0
    def run(self):
        id = self.arguments[0]

        [only_html, only_pdf] = youtube_embed(id)

        # TODO: should we skip figure if no caption?
        figure_node = nodes.figure("")

        figure_node += only_html
        figure_node += only_pdf

        has_caption = len(self.content) > 0

        if has_caption:
            caption = self.content[0]
            inodes, messages = self.state.inline_text(caption, self.lineno)
            caption_node = nodes.caption(caption, '', *inodes)
            figure_node += caption_node

        return [figure_node]
Beispiel #45
0
    def run(self):
        node = plantuml(self.block_text, **self.options)
        node['uml'] = '\n'.join(self.content)

        # XXX maybe this should be moved to _visit_plantuml functions. it
        # seems wrong to insert "figure" node by "plantuml" directive.
        if 'caption' in self.options or 'align' in self.options:
            node = nodes.figure('', node)
            if 'align' in self.options:
                node['align'] = self.options['align']
        if 'caption' in self.options:
            import docutils.statemachine
            cnode = nodes.Element()  # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options['caption']],
                                                  source='')
            self.state.nested_parse(sl, self.content_offset, cnode)
            caption = nodes.caption(self.options['caption'], '', *cnode)
            node += caption

        return [node]
Beispiel #46
0
    def run(self):
        node = plantuml(self.block_text, **self.options)
        node["uml"] = "\n".join(self.content)

        # XXX maybe this should be moved to _visit_plantuml functions. it
        # seems wrong to insert "figure" node by "plantuml" directive.
        if "caption" in self.options or "align" in self.options:
            node = nodes.figure("", node)
            if "align" in self.options:
                node["align"] = self.options["align"]
        if "caption" in self.options:
            import docutils.statemachine

            cnode = nodes.Element()  # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options["caption"]], source="")
            self.state.nested_parse(sl, self.content_offset, cnode)
            caption = nodes.caption(self.options["caption"], "", *cnode)
            node += caption

        return [node]
Beispiel #47
0
def figure(name, arguments, options, content, lineno,
           content_offset, block_text, state, state_machine):
    figwidth = options.setdefault('figwidth')
    figclass = options.setdefault('figclass')
    del options['figwidth']
    del options['figclass']
    (image_node,) = image(name, arguments, options, content, lineno,
                         content_offset, block_text, state, state_machine)
    if isinstance(image_node, nodes.system_message):
        return [image_node]
    figure_node = nodes.figure('', image_node)
    if figwidth == 'image':
        if Image:
            # PIL doesn't like Unicode paths:
            try:
                i = Image.open(str(image_node['uri']))
            except (IOError, UnicodeError):
                pass
            else:
                figure_node['width'] = i.size[0]
    elif figwidth is not None:
        figure_node['width'] = figwidth
    if figclass:
        figure_node.set_class(figclass)
    if content:
        node = nodes.Element()          # anonymous container for parsing
        state.nested_parse(content, content_offset, node)
        first_node = node[0]
        if isinstance(first_node, nodes.paragraph):
            caption = nodes.caption(first_node.rawsource, '',
                                    *first_node.children)
            figure_node += caption
        elif not (isinstance(first_node, nodes.comment)
                  and len(first_node) == 0):
            error = state_machine.reporter.error(
                  'Figure caption must be a paragraph or empty comment.',
                  nodes.literal_block(block_text, block_text), line=lineno)
            return [figure_node, error]
        if len(node) > 1:
            figure_node += nodes.legend('', *node[1:])
    return [figure_node]
Beispiel #48
0
    def build_node(self):

        srclang = self.arguments[0].strip()
        if srclang not in RENDER_MARKUP_EXT.keys():
            return [self.state_machine.reporter.warning(
                'Unknown source language "%s", use one of: %s.' % (
                    srclang, ",".join(RENDER_MARKUP_EXT.keys())),
                line=self.lineno)]

        code = '\n'.join(self.content)
        if not code.strip():
            return [self.state_machine.reporter.warning(
                'Ignoring "%s" directive without content.' % (
                    self.name),
                line=self.lineno)]

        node = kernel_render()
        node['alt'] = self.options.get('alt','')
        node['srclang'] = srclang
        literal_node = nodes.literal_block(code, code)
        node += literal_node

        caption = self.options.get('caption')
        if caption:
            # parse caption's content
            parsed = nodes.Element()
            self.state.nested_parse(
                ViewList([caption], source=''), self.content_offset, parsed)
            caption_node = nodes.caption(
                parsed[0].rawsource, '', *parsed[0].children)
            caption_node.source = parsed[0].source
            caption_node.line = parsed[0].line

            figure_node = nodes.figure('', node)
            for k,v in self.options.items():
                figure_node[k] = v
            figure_node += caption_node

            node = figure_node

        return node
Beispiel #49
0
 def _make_figure_node(self, *children):
     # Build figure node.
     if isinstance(children[0], nodes.system_message):
         return children[:1]
     figure_node = nodes.figure('', *children)
     # Pop options.
     figwidth = self.options.pop('figwidth', None)
     figclasses = self.options.pop('figclass', None)
     align = self.options.pop('align', None)
     # Figure property "figwidth".
     if figwidth:
         figure_node['width'] = figwidth
     # Figure property "figclass".
     if figclasses:
         figure_node['classes'] += figclasses
     # Figure property "align".
     if align:
         figure_node['align'] = align
     # Figure property "caption".  Only valid when texpath is used.
     if self.content:
         node = nodes.Element()  # Anonymous container for parsing.
         self.state.nested_parse(self.content, self.content_offset,
                                 node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, '',
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                 'Figure caption must be a paragraph or empty comment.',
                 nodes.literal_block(self.block_text, self.block_text),
                 line=self.lineno)
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend('', *node[1:])
     return [figure_node]
Beispiel #50
0
 def _make_figure_node(self, *children):
     # Build figure node.
     if isinstance(children[0], nodes.system_message):
         return children[:1]
     figure_node = nodes.figure('', *children)
     # Pop options.
     figwidth = self.options.pop('figwidth', None)
     figclasses = self.options.pop('figclass', None)
     align = self.options.pop('align', None)
     # Figure property "figwidth".
     if figwidth:
         figure_node['width'] = figwidth
     # Figure property "figclass".
     if figclasses:
         figure_node['classes'] += figclasses
     # Figure property "align".
     if align:
         figure_node['align'] = align
     # Figure property "caption".  Only valid when texpath is used.
     if self.content:
         node = nodes.Element() # anonymous container for parsing
         self.state.nested_parse(self.content, self.content_offset, node)
         first_node = node[0]
         if isinstance(first_node, nodes.paragraph):
             caption = nodes.caption(first_node.rawsource, '',
                                     *first_node.children)
             caption.source = first_node.source
             caption.line = first_node.line
             figure_node += caption
         elif not (isinstance(first_node, nodes.comment)
                   and len(first_node) == 0):
             error = self.state_machine.reporter.error(
                   'Figure caption must be a paragraph or empty comment.',
                   nodes.literal_block(self.block_text, self.block_text),
                   line=self.lineno)
             return [figure_node, error]
         if len(node) > 1:
             figure_node += nodes.legend('', *node[1:])
     return [figure_node]
Beispiel #51
0
def test_process_doc_handle_figure_caption():
    env = mock.Mock(domaindata={})
    env.app.registry.enumerable_nodes = {}
    figure_node = nodes.figure(
        '',
        nodes.caption('caption text', 'caption text'),
    )
    document = mock.Mock(
        nametypes={'testname': True},
        nameids={'testname': 'testid'},
        ids={'testid': figure_node},
        citation_refs={},
    )
    document.traverse.return_value = []

    domain = StandardDomain(env)
    if 'testname' in domain.data['labels']:
        del domain.data['labels']['testname']
    domain.process_doc(env, 'testdoc', document)
    assert 'testname' in domain.data['labels']
    assert domain.data['labels']['testname'] == (
        'testdoc', 'testid', 'caption text')
Beispiel #52
0
    def run(self):
        warning = self.state.document.reporter.warning
        env = self.state.document.settings.env
        if self.arguments and self.content:
            return [warning('uml directive cannot have both content and '
                            'a filename argument', line=self.lineno)]
        if self.arguments:
            fn = search_image_for_language(self.arguments[0], env)
            relfn, absfn = env.relfn2path(fn)
            env.note_dependency(relfn)
            try:
                umlcode = _read_utf8(absfn)
            except (IOError, UnicodeDecodeError) as err:
                return [warning('PlantUML file "%s" cannot be read: %s'
                                % (fn, err), line=self.lineno)]
        else:
            relfn = env.doc2path(env.docname, base=None)
            umlcode = '\n'.join(self.content)

        node = plantuml(self.block_text, **self.options)
        node['uml'] = umlcode
        node['incdir'] = os.path.dirname(relfn)

        # XXX maybe this should be moved to _visit_plantuml functions. it
        # seems wrong to insert "figure" node by "plantuml" directive.
        if 'caption' in self.options or 'align' in self.options:
            node = nodes.figure('', node)
            if 'align' in self.options:
                node['align'] = self.options['align']
        if 'caption' in self.options:
            import docutils.statemachine
            cnode = nodes.Element()  # anonymous container for parsing
            sl = docutils.statemachine.StringList([self.options['caption']],
                                                  source='')
            self.state.nested_parse(sl, self.content_offset, cnode)
            caption = nodes.caption(self.options['caption'], '', *cnode)
            node += caption

        return [node]
Beispiel #53
0
def test_process_doc_handle_figure_caption():
    env = mock.Mock(domaindata={})
    env.app.registry.enumerable_nodes = {}
    figure_node = nodes.figure(
        '',
        nodes.caption('caption text', 'caption text'),
    )
    document = mock.Mock(
        nametypes={'testname': True},
        nameids={'testname': 'testid'},
        ids={'testid': figure_node},
        citation_refs={},
    )
    document.traverse.return_value = []

    domain = StandardDomain(env)
    if 'testname' in domain.data['labels']:
        del domain.data['labels']['testname']
    domain.process_doc(env, 'testdoc', document)
    assert 'testname' in domain.data['labels']
    assert domain.data['labels']['testname'] == ('testdoc', 'testid',
                                                 'caption text')
Beispiel #54
0
    def apply(self):

        for image in self.document.traverse(nodes.image):

            # skip inline images
            # (See also: class `TextElement` in `docutils.nodes`.)
            if isinstance(image.parent, nodes.TextElement):
                continue

            # wrap all block images into figures
            if isinstance(image.parent, nodes.figure):
                figure = image.parent
            else:
                figure = nodes.figure()
                figure['float'] = ('none', )  # do not float bare images
                figure['width'] = image.attributes.get('width', 'image')
                figure['align'] = image.attributes.get('align', 'center')
                image['width'] = '100%'
                image.replace_self(figure)
                figure.append(image)

            # set default width, align for block images only
            image.setdefault('width', '100%')
            image.setdefault('align', 'center')
Beispiel #55
0
    def run(self):
        grid_node = nodes.container()
        grid_node['classes'] += ['m-imagegrid', 'm-container-inflate']

        rows = [[]]
        total_widths = [0]
        for uri_caption in self.content:
            # New line, calculating width from 0 again
            if not uri_caption:
                rows.append([])
                total_widths.append(0)
                continue

            uri, _, caption = uri_caption.partition(' ')

            # Open the files and calculate the overall width
            # Support both {filename} (3.7.1) and {static} (3.8) placeholders,
            # also prepend the absolute path in case we're not Pelican
            file = os.path.join(os.getcwd(), settings['INPUT'])
            absuri = os.path.join(file, uri.format(filename=file, static=file))
            im = PIL.Image.open(absuri)

            # If no caption provided, get EXIF info, if it's there
            if not caption and hasattr(im, '_getexif') and im._getexif() is not None:
                exif = {
                    PIL.ExifTags.TAGS[k]: v
                    for k, v in im._getexif().items()
                    if k in PIL.ExifTags.TAGS and len(str(v)) < 256
                }

                # Not all info might be present
                caption = []
                if 'FNumber' in exif:
                    caption += ["F{}".format(float(float(exif['FNumber'][0])/float(exif['FNumber'][1])))]
                if 'ExposureTime' in exif:
                    numerator, denominator = exif['ExposureTime']
                    if int(numerator) > int(denominator):
                        caption += ["{} s".format(float(numerator)/float(denominator))]
                    else:
                        caption += ["{}/{} s".format(numerator, denominator)]
                if 'ISOSpeedRatings' in exif:
                    caption += ["ISO {}".format(exif['ISOSpeedRatings'])]
                caption = ', '.join(caption)

            # If the caption is `..`, it's meant to be explicitly disabled
            if caption == '..': caption = ''

            rel_width = float(im.width)/im.height
            total_widths[-1] += rel_width
            rows[-1].append((uri, rel_width, caption))

        for i, row in enumerate(rows):
            row_node = nodes.container()

            for uri, rel_width, caption in row:
                image_reference = rst.directives.uri(uri)
                image_node = nodes.image('', uri=image_reference)

                # <figurecaption> in case there's a caption
                if caption:
                    text_nodes, _ = self.state.inline_text(caption, self.lineno)
                    text_node = nodes.paragraph('', '', *text_nodes)
                    overlay_node = nodes.caption()
                    overlay_node.append(text_node)

                # Otherwise an empty <div>
                else: overlay_node = nodes.container()

                link_node = nodes.reference('', refuri=image_reference)
                link_node.append(image_node)
                link_node.append(overlay_node)
                wrapper_node = nodes.figure(width="{:.3f}%".format(rel_width*100.0/total_widths[i]))
                wrapper_node.append(link_node)
                row_node.append(wrapper_node)

            grid_node.append(row_node)

        return [grid_node]
Beispiel #56
0
        def _render_image(output: NotebookNode, index: int):
            # Sphinx treats absolute paths as being rooted at the source
            # directory, so make a relative path, which Sphinx treats
            # as being relative to the current working directory.
            filename = os.path.basename(output.metadata["filenames"][mime_type])

            # checks if file dir path is inside a subdir of dir
            filedir = os.path.dirname(output.metadata["filenames"][mime_type])
            subpaths = filedir.split(self.sphinx_dir)
            final_dir = self.sphinx_dir
            if subpaths and len(subpaths) > 1:
                subpath = subpaths[1]
                final_dir += subpath

            uri = os.path.join(final_dir, filename)
            # TODO I'm not quite sure why, but as soon as you give it a width,
            # it becomes clickable?! (i.e. will open the image in the browser)
            image_node = nodes.image(uri=uri)

            myst_meta_img = self.node.metadata.get(
                self.env.config.nb_render_key, {}
            ).get("image", {})

            for key, spec in [
                ("classes", directives.class_option),
                ("alt", directives.unchanged),
                ("height", directives.length_or_unitless),
                ("width", directives.length_or_percentage_or_unitless),
                ("scale", directives.percentage),
                ("align", align),
            ]:
                if key in myst_meta_img:
                    value = myst_meta_img[key]
                    try:
                        image_node[key] = spec(value)
                    except (ValueError, TypeError) as error:
                        error_msg = (
                            "Invalid image attribute: "
                            "(key: '{}'; value: {})\n{}".format(key, value, error)
                        )
                        return [self.make_error(error_msg)]

            myst_meta_fig = self.node.metadata.get(
                self.env.config.nb_render_key, {}
            ).get("figure", {})
            if "caption" not in myst_meta_fig:
                return [image_node]

            figure_node = nodes.figure("", image_node)
            caption = nodes.caption(myst_meta_fig["caption"], "")
            figure_node += caption
            # TODO only contents of one paragraph? (and second should be a legend)
            self.parse_markdown(myst_meta_fig["caption"], caption)
            if "name" in myst_meta_fig:
                name = myst_meta_fig["name"]
                self.add_source_and_line(figure_node)
                self.add_name(figure_node, name)
                # The target should have already been processed by now, with
                # sphinx.transforms.references.SphinxDomains, which calls
                # sphinx.domains.std.StandardDomain.process_doc,
                # so we have to replicate that here
                std = self.env.get_domain("std")
                nametypes = self.document.nametypes.items()
                self.document.nametypes = {name: True}
                try:
                    std.process_doc(self.env, self.env.docname, self.document)
                finally:
                    self.document.nametypes = nametypes

            return [figure_node]