~ubuntu-branches/ubuntu/trusty/python-docutils/trusty

« back to all changes in this revision

Viewing changes to .pc/python3-pil-no-bytestrings.diff/docutils/parsers/rst/directives/images.py

  • Committer: Package Import Robot
  • Author(s): Dmitry Shachnev
  • Date: 2013-05-17 16:47:30 UTC
  • mfrom: (20.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20130517164730-5ux7p59z0jdku6pf
Tags: 0.10-3ubuntu1
* Merge with Debian unstable, remaining changes:
  - Use dh_python2 instead of dh_pysupport.
  - Backport patch to support embedded aliases in references
    (support-aliases-in-references.diff).
* disable_py33_failing_tests.diff: dropped, the issue is now
  properly fixed in Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# $Id: images.py 7510 2012-09-12 07:22:25Z milde $
 
2
# Author: David Goodger <goodger@python.org>
 
3
# Copyright: This module has been placed in the public domain.
 
4
 
 
5
"""
 
6
Directives for figures and simple images.
 
7
"""
 
8
 
 
9
__docformat__ = 'reStructuredText'
 
10
 
 
11
 
 
12
import sys
 
13
import urllib
 
14
from docutils import nodes, utils
 
15
from docutils.parsers.rst import Directive
 
16
from docutils.parsers.rst import directives, states
 
17
from docutils.nodes import fully_normalize_name, whitespace_normalize_name
 
18
from docutils.parsers.rst.roles import set_classes
 
19
try: # check for the Python Imaging Library
 
20
    import PIL.Image
 
21
except ImportError:
 
22
    try:  # sometimes PIL modules are put in PYTHONPATH's root
 
23
        import Image
 
24
        class PIL(object): pass  # dummy wrapper
 
25
        PIL.Image = Image
 
26
    except ImportError:
 
27
        PIL = None
 
28
 
 
29
class Image(Directive):
 
30
 
 
31
    align_h_values = ('left', 'center', 'right')
 
32
    align_v_values = ('top', 'middle', 'bottom')
 
33
    align_values = align_v_values + align_h_values
 
34
 
 
35
    def align(argument):
 
36
        # This is not callable as self.align.  We cannot make it a
 
37
        # staticmethod because we're saving an unbound method in
 
38
        # option_spec below.
 
39
        return directives.choice(argument, Image.align_values)
 
40
 
 
41
    required_arguments = 1
 
42
    optional_arguments = 0
 
43
    final_argument_whitespace = True
 
44
    option_spec = {'alt': directives.unchanged,
 
45
                   'height': directives.length_or_unitless,
 
46
                   'width': directives.length_or_percentage_or_unitless,
 
47
                   'scale': directives.percentage,
 
48
                   'align': align,
 
49
                   'name': directives.unchanged,
 
50
                   'target': directives.unchanged_required,
 
51
                   'class': directives.class_option}
 
52
 
 
53
    def run(self):
 
54
        if 'align' in self.options:
 
55
            if isinstance(self.state, states.SubstitutionDef):
 
56
                # Check for align_v_values.
 
57
                if self.options['align'] not in self.align_v_values:
 
58
                    raise self.error(
 
59
                        'Error in "%s" directive: "%s" is not a valid value '
 
60
                        'for the "align" option within a substitution '
 
61
                        'definition.  Valid values for "align" are: "%s".'
 
62
                        % (self.name, self.options['align'],
 
63
                           '", "'.join(self.align_v_values)))
 
64
            elif self.options['align'] not in self.align_h_values:
 
65
                raise self.error(
 
66
                    'Error in "%s" directive: "%s" is not a valid value for '
 
67
                    'the "align" option.  Valid values for "align" are: "%s".'
 
68
                    % (self.name, self.options['align'],
 
69
                       '", "'.join(self.align_h_values)))
 
70
        messages = []
 
71
        reference = directives.uri(self.arguments[0])
 
72
        self.options['uri'] = reference
 
73
        reference_node = None
 
74
        if 'target' in self.options:
 
75
            block = states.escape2null(
 
76
                self.options['target']).splitlines()
 
77
            block = [line for line in block]
 
78
            target_type, data = self.state.parse_target(
 
79
                block, self.block_text, self.lineno)
 
80
            if target_type == 'refuri':
 
81
                reference_node = nodes.reference(refuri=data)
 
82
            elif target_type == 'refname':
 
83
                reference_node = nodes.reference(
 
84
                    refname=fully_normalize_name(data),
 
85
                    name=whitespace_normalize_name(data))
 
86
                reference_node.indirect_reference_name = data
 
87
                self.state.document.note_refname(reference_node)
 
88
            else:                           # malformed target
 
89
                messages.append(data)       # data is a system message
 
90
            del self.options['target']
 
91
        set_classes(self.options)
 
92
        image_node = nodes.image(self.block_text, **self.options)
 
93
        self.add_name(image_node)
 
94
        if reference_node:
 
95
            reference_node += image_node
 
96
            return messages + [reference_node]
 
97
        else:
 
98
            return messages + [image_node]
 
99
 
 
100
 
 
101
class Figure(Image):
 
102
 
 
103
    def align(argument):
 
104
        return directives.choice(argument, Figure.align_h_values)
 
105
 
 
106
    def figwidth_value(argument):
 
107
        if argument.lower() == 'image':
 
108
            return 'image'
 
109
        else:
 
110
            return directives.length_or_percentage_or_unitless(argument, 'px')
 
111
 
 
112
    option_spec = Image.option_spec.copy()
 
113
    option_spec['figwidth'] = figwidth_value
 
114
    option_spec['figclass'] = directives.class_option
 
115
    option_spec['align'] = align
 
116
    has_content = True
 
117
 
 
118
    def run(self):
 
119
        figwidth = self.options.pop('figwidth', None)
 
120
        figclasses = self.options.pop('figclass', None)
 
121
        align = self.options.pop('align', None)
 
122
        (image_node,) = Image.run(self)
 
123
        if isinstance(image_node, nodes.system_message):
 
124
            return [image_node]
 
125
        figure_node = nodes.figure('', image_node)
 
126
        if figwidth == 'image':
 
127
            if PIL and self.state.document.settings.file_insertion_enabled:
 
128
                imagepath = urllib.url2pathname(image_node['uri'])
 
129
                try:
 
130
                    img = PIL.Image.open(
 
131
                            imagepath.encode(sys.getfilesystemencoding()))
 
132
                except (IOError, UnicodeEncodeError):
 
133
                    pass # TODO: warn?
 
134
                else:
 
135
                    self.state.document.settings.record_dependencies.add(
 
136
                        imagepath.replace('\\', '/'))
 
137
                    figure_node['width'] = img.size[0]
 
138
                    del img
 
139
        elif figwidth is not None:
 
140
            figure_node['width'] = figwidth
 
141
        if figclasses:
 
142
            figure_node['classes'] += figclasses
 
143
        if align:
 
144
            figure_node['align'] = align
 
145
        if self.content:
 
146
            node = nodes.Element()          # anonymous container for parsing
 
147
            self.state.nested_parse(self.content, self.content_offset, node)
 
148
            first_node = node[0]
 
149
            if isinstance(first_node, nodes.paragraph):
 
150
                caption = nodes.caption(first_node.rawsource, '',
 
151
                                        *first_node.children)
 
152
                figure_node += caption
 
153
            elif not (isinstance(first_node, nodes.comment)
 
154
                      and len(first_node) == 0):
 
155
                error = self.state_machine.reporter.error(
 
156
                      'Figure caption must be a paragraph or empty comment.',
 
157
                      nodes.literal_block(self.block_text, self.block_text),
 
158
                      line=self.lineno)
 
159
                return [figure_node, error]
 
160
            if len(node) > 1:
 
161
                figure_node += nodes.legend('', *node[1:])
 
162
        return [figure_node]