diff env/lib/python3.9/site-packages/docutils/parsers/rst/directives/images.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/docutils/parsers/rst/directives/images.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,171 @@
+# $Id: images.py 8370 2019-08-27 12:10:39Z milde $
+# Author: David Goodger <goodger@python.org>
+# Copyright: This module has been placed in the public domain.
+
+"""
+Directives for figures and simple images.
+"""
+
+__docformat__ = 'reStructuredText'
+
+
+import sys
+
+from docutils import nodes, utils
+from docutils.parsers.rst import Directive
+from docutils.parsers.rst import directives, states
+from docutils.nodes import fully_normalize_name, whitespace_normalize_name
+from docutils.parsers.rst.roles import set_classes
+
+try: # check for the Python Imaging Library
+    import PIL.Image
+except ImportError:
+    try:  # sometimes PIL modules are put in PYTHONPATH's root
+        import Image
+        class PIL(object): pass  # dummy wrapper
+        PIL.Image = Image
+    except ImportError:
+        PIL = None
+
+if sys.version_info >= (3, 0):
+    from urllib.request import url2pathname
+else:
+    from urllib import url2pathname
+
+
+class Image(Directive):
+
+    align_h_values = ('left', 'center', 'right')
+    align_v_values = ('top', 'middle', 'bottom')
+    align_values = align_v_values + align_h_values
+
+    def align(argument):
+        # This is not callable as self.align.  We cannot make it a
+        # staticmethod because we're saving an unbound method in
+        # option_spec below.
+        return directives.choice(argument, Image.align_values)
+
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = True
+    option_spec = {'alt': directives.unchanged,
+                   'height': directives.length_or_unitless,
+                   'width': directives.length_or_percentage_or_unitless,
+                   'scale': directives.percentage,
+                   'align': align,
+                   'name': directives.unchanged,
+                   'target': directives.unchanged_required,
+                   'class': directives.class_option}
+
+    def run(self):
+        if 'align' in self.options:
+            if isinstance(self.state, states.SubstitutionDef):
+                # Check for align_v_values.
+                if self.options['align'] not in self.align_v_values:
+                    raise self.error(
+                        'Error in "%s" directive: "%s" is not a valid value '
+                        'for the "align" option within a substitution '
+                        'definition.  Valid values for "align" are: "%s".'
+                        % (self.name, self.options['align'],
+                           '", "'.join(self.align_v_values)))
+            elif self.options['align'] not in self.align_h_values:
+                raise self.error(
+                    'Error in "%s" directive: "%s" is not a valid value for '
+                    'the "align" option.  Valid values for "align" are: "%s".'
+                    % (self.name, self.options['align'],
+                       '", "'.join(self.align_h_values)))
+        messages = []
+        reference = directives.uri(self.arguments[0])
+        self.options['uri'] = reference
+        reference_node = None
+        if 'target' in self.options:
+            block = states.escape2null(
+                self.options['target']).splitlines()
+            block = [line for line in block]
+            target_type, data = self.state.parse_target(
+                block, self.block_text, self.lineno)
+            if target_type == 'refuri':
+                reference_node = nodes.reference(refuri=data)
+            elif target_type == 'refname':
+                reference_node = nodes.reference(
+                    refname=fully_normalize_name(data),
+                    name=whitespace_normalize_name(data))
+                reference_node.indirect_reference_name = data
+                self.state.document.note_refname(reference_node)
+            else:                           # malformed target
+                messages.append(data)       # data is a system message
+            del self.options['target']
+        set_classes(self.options)
+        image_node = nodes.image(self.block_text, **self.options)
+        self.add_name(image_node)
+        if reference_node:
+            reference_node += image_node
+            return messages + [reference_node]
+        else:
+            return messages + [image_node]
+
+
+class Figure(Image):
+
+    def align(argument):
+        return directives.choice(argument, Figure.align_h_values)
+
+    def figwidth_value(argument):
+        if argument.lower() == 'image':
+            return 'image'
+        else:
+            return directives.length_or_percentage_or_unitless(argument, 'px')
+
+    option_spec = Image.option_spec.copy()
+    option_spec['figwidth'] = figwidth_value
+    option_spec['figclass'] = directives.class_option
+    option_spec['align'] = align
+    has_content = True
+
+    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]