/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/utextwrap.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
# along with this program; if not, write to the Free Software
24
24
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
25
 
 
26
from __future__ import absolute_import
 
27
 
 
28
import sys
26
29
import textwrap
27
30
from unicodedata import east_asian_width as _eawidth
28
31
 
29
 
from . import osutils
 
32
from bzrlib import osutils
30
33
 
31
34
__all__ = ["UTextWrapper", "fill", "wrap"]
32
35
 
33
 
 
34
36
class UTextWrapper(textwrap.TextWrapper):
35
37
    """
36
38
    Extend TextWrapper for Unicode.
58
60
    def __init__(self, width=None, **kwargs):
59
61
        if width is None:
60
62
            width = (osutils.terminal_width() or
61
 
                     osutils.default_terminal_width) - 1
 
63
                        osutils.default_terminal_width) - 1
62
64
 
63
65
        ambi_width = kwargs.pop('ambiguous_width', 1)
64
66
        if ambi_width == 1:
68
70
        else:
69
71
            raise ValueError("ambiguous_width should be 1 or 2")
70
72
 
71
 
        self.max_lines = kwargs.get('max_lines', None)
 
73
        # No drop_whitespace param before Python 2.6 it was always dropped
 
74
        if sys.version_info < (2, 6):
 
75
            self.drop_whitespace = kwargs.pop("drop_whitespace", True)
 
76
            if not self.drop_whitespace:
 
77
                raise ValueError("TextWrapper version must drop whitespace")
72
78
        textwrap.TextWrapper.__init__(self, width, **kwargs)
73
79
 
74
80
    def _unicode_char_width(self, uc):
116
122
        to use unicode always.
117
123
        """
118
124
        i = 0
119
 
        L = len(chunks) - 1
 
125
        L = len(chunks)-1
120
126
        patsearch = self.sentence_end_re.search
121
127
        while i < L:
122
 
            if chunks[i + 1] == u" " and patsearch(chunks[i]):
123
 
                chunks[i + 1] = u"  "
 
128
            if chunks[i+1] == u" " and patsearch(chunks[i]):
 
129
                chunks[i+1] = u"  "
124
130
                i += 2
125
131
            else:
126
132
                i += 1
159
165
        lines = []
160
166
        if self.width <= 0:
161
167
            raise ValueError("invalid width %r (must be > 0)" % self.width)
162
 
        if self.max_lines is not None:
163
 
            if self.max_lines > 1:
164
 
                indent = self.subsequent_indent
165
 
            else:
166
 
                indent = self.initial_indent
167
 
            if self._width(indent) + self._width(self.placeholder.lstrip()) > self.width:
168
 
                raise ValueError("placeholder too large for max width")
169
168
 
170
169
        # Arrange in reverse order so items can be efficiently popped
171
170
        # from a stack of chucks.
209
208
            # fit on *any* line (not just this one).
210
209
            if chunks and self._width(chunks[-1]) > width:
211
210
                self._handle_long_word(chunks, cur_line, cur_len, width)
212
 
                cur_len = sum(map(len, cur_line))
213
211
 
214
212
            # If the last chunk on this line is all whitespace, drop it.
215
213
            if self.drop_whitespace and cur_line and not cur_line[-1].strip():
218
216
            # Convert current line back to a string and store it in list
219
217
            # of all lines (return value).
220
218
            if cur_line:
221
 
                if (self.max_lines is None or
222
 
                    len(lines) + 1 < self.max_lines or
223
 
                    (not chunks or
224
 
                        self.drop_whitespace and
225
 
                     len(chunks) == 1 and
226
 
                     not chunks[0].strip()) and cur_len <= width):
227
 
                    # Convert current line back to a string and store it in
228
 
                    # list of all lines (return value).
229
 
                    lines.append(indent + u''.join(cur_line))
230
 
                else:
231
 
                    while cur_line:
232
 
                        if (cur_line[-1].strip() and
233
 
                                cur_len + self._width(self.placeholder) <= width):
234
 
                            cur_line.append(self.placeholder)
235
 
                            lines.append(indent + ''.join(cur_line))
236
 
                            break
237
 
                        cur_len -= self._width(cur_line[-1])
238
 
                        del cur_line[-1]
239
 
                    else:
240
 
                        if lines:
241
 
                            prev_line = lines[-1].rstrip()
242
 
                            if (self._width(prev_line) + self._width(self.placeholder) <=
243
 
                                    self.width):
244
 
                                lines[-1] = prev_line + self.placeholder
245
 
                                break
246
 
                        lines.append(indent + self.placeholder.lstrip())
247
 
                    break
 
219
                lines.append(indent + u''.join(cur_line))
248
220
 
249
221
        return lines
250
222
 
251
223
    def _split(self, text):
252
 
        chunks = textwrap.TextWrapper._split(self, osutils.safe_unicode(text))
 
224
        chunks = textwrap.TextWrapper._split(self, unicode(text))
253
225
        cjk_split_chunks = []
254
226
        for chunk in chunks:
255
227
            prev_pos = 0
258
230
                    if prev_pos < pos:
259
231
                        cjk_split_chunks.append(chunk[prev_pos:pos])
260
232
                    cjk_split_chunks.append(char)
261
 
                    prev_pos = pos + 1
 
233
                    prev_pos = pos+1
262
234
            if prev_pos < len(chunk):
263
235
                cjk_split_chunks.append(chunk[prev_pos:])
264
236
        return cjk_split_chunks
265
237
 
266
238
    def wrap(self, text):
267
239
        # ensure text is unicode
268
 
        return textwrap.TextWrapper.wrap(self, osutils.safe_unicode(text))
 
240
        return textwrap.TextWrapper.wrap(self, unicode(text))
269
241
 
270
242
# -- Convenience interface ---------------------------------------------
271
243
 
272
 
 
273
244
def wrap(text, width=None, **kwargs):
274
245
    """Wrap a single paragraph of text, returning a list of wrapped lines.
275
246
 
282
253
    """
283
254
    return UTextWrapper(width=width, **kwargs).wrap(text)
284
255
 
285
 
 
286
256
def fill(text, width=None, **kwargs):
287
257
    """Fill a single paragraph of text, returning a new string.
288
258
 
293
263
    available keyword args to customize wrapping behaviour.
294
264
    """
295
265
    return UTextWrapper(width=width, **kwargs).fill(text)
 
266