/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 breezy/utextwrap.py

  • Committer: Jelmer Vernooij
  • Date: 2018-02-18 21:42:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6859.
  • Revision ID: jelmer@jelmer.uk-20180218214257-jpevutp1wa30tz3v
Update TODO to reference Breezy, not Bazaar.

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
 
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)
72
73
        textwrap.TextWrapper.__init__(self, width, **kwargs)
73
74
 
74
75
    def _unicode_char_width(self, uc):
116
117
        to use unicode always.
117
118
        """
118
119
        i = 0
119
 
        L = len(chunks) - 1
 
120
        L = len(chunks)-1
120
121
        patsearch = self.sentence_end_re.search
121
122
        while i < L:
122
 
            if chunks[i + 1] == u" " and patsearch(chunks[i]):
123
 
                chunks[i + 1] = u"  "
 
123
            if chunks[i+1] == u" " and patsearch(chunks[i]):
 
124
                chunks[i+1] = u"  "
124
125
                i += 2
125
126
            else:
126
127
                i += 1
159
160
        lines = []
160
161
        if self.width <= 0:
161
162
            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
163
 
170
164
        # Arrange in reverse order so items can be efficiently popped
171
165
        # from a stack of chucks.
209
203
            # fit on *any* line (not just this one).
210
204
            if chunks and self._width(chunks[-1]) > width:
211
205
                self._handle_long_word(chunks, cur_line, cur_len, width)
212
 
                cur_len = sum(map(len, cur_line))
213
206
 
214
207
            # If the last chunk on this line is all whitespace, drop it.
215
208
            if self.drop_whitespace and cur_line and not cur_line[-1].strip():
218
211
            # Convert current line back to a string and store it in list
219
212
            # of all lines (return value).
220
213
            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
 
214
                lines.append(indent + u''.join(cur_line))
248
215
 
249
216
        return lines
250
217
 
251
218
    def _split(self, text):
252
 
        chunks = textwrap.TextWrapper._split(self, osutils.safe_unicode(text))
 
219
        chunks = textwrap.TextWrapper._split(self, unicode(text))
253
220
        cjk_split_chunks = []
254
221
        for chunk in chunks:
255
222
            prev_pos = 0
258
225
                    if prev_pos < pos:
259
226
                        cjk_split_chunks.append(chunk[prev_pos:pos])
260
227
                    cjk_split_chunks.append(char)
261
 
                    prev_pos = pos + 1
 
228
                    prev_pos = pos+1
262
229
            if prev_pos < len(chunk):
263
230
                cjk_split_chunks.append(chunk[prev_pos:])
264
231
        return cjk_split_chunks
265
232
 
266
233
    def wrap(self, text):
267
234
        # ensure text is unicode
268
 
        return textwrap.TextWrapper.wrap(self, osutils.safe_unicode(text))
 
235
        return textwrap.TextWrapper.wrap(self, unicode(text))
269
236
 
270
237
# -- Convenience interface ---------------------------------------------
271
238
 
272
 
 
273
239
def wrap(text, width=None, **kwargs):
274
240
    """Wrap a single paragraph of text, returning a list of wrapped lines.
275
241
 
282
248
    """
283
249
    return UTextWrapper(width=width, **kwargs).wrap(text)
284
250
 
285
 
 
286
251
def fill(text, width=None, **kwargs):
287
252
    """Fill a single paragraph of text, returning a new string.
288
253
 
293
258
    available keyword args to customize wrapping behaviour.
294
259
    """
295
260
    return UTextWrapper(width=width, **kwargs).fill(text)
 
261