mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Make 'width' an instance attribute rather than an argument to the wrap()
and fill() methods. Keep interface of existing wrap() and fill() functions by going back to having them construct a new TextWrapper instance on each call, with the preferred width passed to the constructor.
This commit is contained in:
parent
4f7829e185
commit
d34c959140
1 changed files with 32 additions and 31 deletions
|
@ -18,8 +18,10 @@ class TextWrapper:
|
||||||
If you want to completely replace the main wrapping algorithm,
|
If you want to completely replace the main wrapping algorithm,
|
||||||
you'll probably have to override _wrap_chunks().
|
you'll probably have to override _wrap_chunks().
|
||||||
|
|
||||||
Several boolean instance attributes control various aspects of
|
Several instance attributes control various aspects of wrapping:
|
||||||
wrapping:
|
width (default: 70)
|
||||||
|
the maximum width of wrapped lines (unless break_long_words
|
||||||
|
is false)
|
||||||
expand_tabs (default: true)
|
expand_tabs (default: true)
|
||||||
Expand tabs in input text to spaces before further processing.
|
Expand tabs in input text to spaces before further processing.
|
||||||
Each tab will become 1 .. 8 spaces, depending on its position in
|
Each tab will become 1 .. 8 spaces, depending on its position in
|
||||||
|
@ -34,9 +36,8 @@ class TextWrapper:
|
||||||
by two spaces. Off by default becaus the algorithm is
|
by two spaces. Off by default becaus the algorithm is
|
||||||
(unavoidably) imperfect.
|
(unavoidably) imperfect.
|
||||||
break_long_words (default: true)
|
break_long_words (default: true)
|
||||||
Break words longer than the line width constraint. If false,
|
Break words longer than 'width'. If false, those words will not
|
||||||
those words will not be broken, and some lines might be longer
|
be broken, and some lines might be longer than 'width'.
|
||||||
than the width constraint.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
whitespace_trans = string.maketrans(string.whitespace,
|
whitespace_trans = string.maketrans(string.whitespace,
|
||||||
|
@ -61,10 +62,12 @@ class TextWrapper:
|
||||||
|
|
||||||
|
|
||||||
def __init__ (self,
|
def __init__ (self,
|
||||||
|
width=70,
|
||||||
expand_tabs=True,
|
expand_tabs=True,
|
||||||
replace_whitespace=True,
|
replace_whitespace=True,
|
||||||
fix_sentence_endings=False,
|
fix_sentence_endings=False,
|
||||||
break_long_words=True):
|
break_long_words=True):
|
||||||
|
self.width = width
|
||||||
self.expand_tabs = expand_tabs
|
self.expand_tabs = expand_tabs
|
||||||
self.replace_whitespace = replace_whitespace
|
self.replace_whitespace = replace_whitespace
|
||||||
self.fix_sentence_endings = fix_sentence_endings
|
self.fix_sentence_endings = fix_sentence_endings
|
||||||
|
@ -121,15 +124,15 @@ class TextWrapper:
|
||||||
else:
|
else:
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def _handle_long_word(self, chunks, cur_line, cur_len, width):
|
def _handle_long_word(self, chunks, cur_line, cur_len):
|
||||||
"""_handle_long_word(chunks : [string],
|
"""_handle_long_word(chunks : [string],
|
||||||
cur_line : [string],
|
cur_line : [string],
|
||||||
cur_len : int, width : int)
|
cur_len : int)
|
||||||
|
|
||||||
Handle a chunk of text (most likely a word, not whitespace) that
|
Handle a chunk of text (most likely a word, not whitespace) that
|
||||||
is too long to fit in any line.
|
is too long to fit in any line.
|
||||||
"""
|
"""
|
||||||
space_left = width - cur_len
|
space_left = self.width - cur_len
|
||||||
|
|
||||||
# If we're allowed to break long words, then do so: put as much
|
# If we're allowed to break long words, then do so: put as much
|
||||||
# of the next chunk onto the current line as will fit.
|
# of the next chunk onto the current line as will fit.
|
||||||
|
@ -149,20 +152,21 @@ class TextWrapper:
|
||||||
# cur_len will be zero, so the next line will be entirely
|
# cur_len will be zero, so the next line will be entirely
|
||||||
# devoted to the long word that we can't handle right now.
|
# devoted to the long word that we can't handle right now.
|
||||||
|
|
||||||
def _wrap_chunks(self, chunks, width):
|
def _wrap_chunks(self, chunks):
|
||||||
"""_wrap_chunks(chunks : [string], width : int) -> [string]
|
"""_wrap_chunks(chunks : [string]) -> [string]
|
||||||
|
|
||||||
Wrap a sequence of text chunks and return a list of lines of
|
Wrap a sequence of text chunks and return a list of lines of
|
||||||
length 'width' or less. (If 'break_long_words' is false, some
|
length 'self.width' or less. (If 'break_long_words' is false,
|
||||||
lines may be longer than 'width'.) Chunks correspond roughly to
|
some lines may be longer than this.) Chunks correspond roughly
|
||||||
words and the whitespace between them: each chunk is indivisible
|
to words and the whitespace between them: each chunk is
|
||||||
(modulo 'break_long_words'), but a line break can come between
|
indivisible (modulo 'break_long_words'), but a line break can
|
||||||
any two chunks. Chunks should not have internal whitespace;
|
come between any two chunks. Chunks should not have internal
|
||||||
ie. a chunk is either all whitespace or a "word". Whitespace
|
whitespace; ie. a chunk is either all whitespace or a "word".
|
||||||
chunks will be removed from the beginning and end of lines, but
|
Whitespace chunks will be removed from the beginning and end of
|
||||||
apart from that whitespace is preserved.
|
lines, but apart from that whitespace is preserved.
|
||||||
"""
|
"""
|
||||||
lines = []
|
lines = []
|
||||||
|
width = self.width
|
||||||
|
|
||||||
while chunks:
|
while chunks:
|
||||||
|
|
||||||
|
@ -188,7 +192,7 @@ class TextWrapper:
|
||||||
# The current line is full, and the next chunk is too big to
|
# The current line is full, and the next chunk is too big to
|
||||||
# fit on *any* line (not just this one).
|
# fit on *any* line (not just this one).
|
||||||
if chunks and len(chunks[0]) > width:
|
if chunks and len(chunks[0]) > width:
|
||||||
self._handle_long_word(chunks, cur_line, cur_len, width)
|
self._handle_long_word(chunks, cur_line, cur_len)
|
||||||
|
|
||||||
# If the last chunk on this line is all whitespace, drop it.
|
# If the last chunk on this line is all whitespace, drop it.
|
||||||
if cur_line and cur_line[-1].strip() == '':
|
if cur_line and cur_line[-1].strip() == '':
|
||||||
|
@ -204,26 +208,25 @@ class TextWrapper:
|
||||||
|
|
||||||
# -- Public interface ----------------------------------------------
|
# -- Public interface ----------------------------------------------
|
||||||
|
|
||||||
def wrap(self, text, width):
|
def wrap(self, text):
|
||||||
"""wrap(text : string, width : int) -> [string]
|
"""wrap(text : string) -> [string]
|
||||||
|
|
||||||
Split 'text' into multiple lines of no more than 'width'
|
Split 'text' into multiple lines of no more than 'self.width'
|
||||||
characters each, and return the list of strings that results.
|
characters each, and return the list of strings that results.
|
||||||
Tabs in 'text' are expanded with string.expandtabs(), and all
|
Tabs in 'text' are expanded with string.expandtabs(), and all
|
||||||
other whitespace characters (including newline) are converted to
|
other whitespace characters (including newline) are converted to
|
||||||
space.
|
space.
|
||||||
"""
|
"""
|
||||||
text = self._munge_whitespace(text)
|
text = self._munge_whitespace(text)
|
||||||
if len(text) <= width:
|
if len(text) <= self.width:
|
||||||
return [text]
|
return [text]
|
||||||
chunks = self._split(text)
|
chunks = self._split(text)
|
||||||
if self.fix_sentence_endings:
|
if self.fix_sentence_endings:
|
||||||
self._fix_sentence_endings(chunks)
|
self._fix_sentence_endings(chunks)
|
||||||
return self._wrap_chunks(chunks, width)
|
return self._wrap_chunks(chunks)
|
||||||
|
|
||||||
def fill(self, text, width, initial_tab="", subsequent_tab=""):
|
def fill(self, text, initial_tab="", subsequent_tab=""):
|
||||||
"""fill(text : string,
|
"""fill(text : string,
|
||||||
width : int,
|
|
||||||
initial_tab : string = "",
|
initial_tab : string = "",
|
||||||
subsequent_tab : string = "")
|
subsequent_tab : string = "")
|
||||||
-> string
|
-> string
|
||||||
|
@ -234,17 +237,15 @@ class TextWrapper:
|
||||||
lengths of the tab strings are accounted for when wrapping lines
|
lengths of the tab strings are accounted for when wrapping lines
|
||||||
to fit in 'width' columns.
|
to fit in 'width' columns.
|
||||||
"""
|
"""
|
||||||
lines = self.wrap(text, width)
|
lines = self.wrap(text)
|
||||||
sep = "\n" + subsequent_tab
|
sep = "\n" + subsequent_tab
|
||||||
return initial_tab + sep.join(lines)
|
return initial_tab + sep.join(lines)
|
||||||
|
|
||||||
|
|
||||||
# Convenience interface
|
# Convenience interface
|
||||||
|
|
||||||
_wrapper = TextWrapper()
|
|
||||||
|
|
||||||
def wrap(text, width):
|
def wrap(text, width):
|
||||||
return _wrapper.wrap(text, width)
|
return TextWrapper(width=width).wrap(text)
|
||||||
|
|
||||||
def fill(text, width, initial_tab="", subsequent_tab=""):
|
def fill(text, width, initial_tab="", subsequent_tab=""):
|
||||||
return _wrapper.fill(text, width, initial_tab, subsequent_tab)
|
return TextWrapper(width=width).fill(text, initial_tab, subsequent_tab)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue