-
Notifications
You must be signed in to change notification settings - Fork 9
/
TextFormatter.py
169 lines (144 loc) · 5.45 KB
/
TextFormatter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#===================================================================
#!/usr/bin/env python
# File: TextFormatter.py
# Author: Hamish B Lawson
# Date: 19/11/1999
# from http://www.faqts.com/knowledge_base/view.phtml/aid/4517
"""
Here is TextFormatter, a simple module for formatting text into
columns of specified widths. It does multiline wrapping and supports
left, center and right alignment.
SKWM made filling & padding optional, tweaked some edge cases
"""
left = 0
center = centre = 1
right = 2
class TextFormatter:
"""
Formats text into columns.
Constructor takes a list of dictionaries that each specify the
properties for a column. Dictionary entries can be:
width the width within which the text will be wrapped
alignment left|center|right
margin amount of space to prefix in front of column
The compose() method takes a list of strings and returns a formatted
string consisting of each string wrapped within its respective column.
Example:
formatter = TextFormatter(
(
{'width': 10},
{'width': 12, 'margin': 4},
{'width': 20, 'margin': 8, 'alignment': right},
)
)
print formatter.compose(
(
"A rather short paragraph",
"Here is a paragraph containing a veryveryverylongwordindeed.",
"And now for something on the right-hand side.",
)
)
gives:
A rather Here is a And now for
short paragraph something on the
paragraph containing a right-hand side.
veryveryvery
longwordinde
ed.
"""
class Column:
def __init__(self, width=75, alignment=left, margin=0, fill=1, pad=1):
self.width = width
self.alignment = alignment
self.margin = margin
self.fill = fill
self.pad = pad
self.lines = []
def align(self, line):
if self.alignment == center:
return line.center(self.width)
elif self.alignment == right:
return line.rjust(self.width)
else:
if self.pad:
return line.ljust(self.width)
else:
return line
def wrap(self, text):
self.lines = []
words = []
if self.fill: # SKWM
for word in text.split():
if word <= self.width: # don't understand this
words.append(word)
else:
for i in range(0, len(word), self.width):
words.append(word[i:i+self.width])
else:
for line in text.split('\n'):
for word in line.split():
for i in range(0, len(word), self.width):
words.append(word[i:i+self.width])
words.append('\n')
if words[-1] == '\n': words.pop()
if words:
current = words.pop(0)
for word in words:
increment = 1 + len(word)
if word == '\n':
self.lines.append(self.align(current))
current = ''
elif len(current) + increment > self.width:
self.lines.append(self.align(current))
current = word
else:
if current:
current = current + ' ' + word
else:
current = word
if current: self.lines.append(self.align(current))
def getline(self, index):
if index < len(self.lines):
return ' '*self.margin + self.lines[index]
else:
if self.pad:
return ' ' * (self.margin + self.width)
else:
return ''
def numlines(self):
return len(self.lines)
def __init__(self, colspeclist):
self.columns = []
for colspec in colspeclist:
self.columns.append(apply(TextFormatter.Column, (), colspec))
def compose(self, textlist):
numlines = 0
textlist = list(textlist)
if len(textlist) != len(self.columns):
raise IndexError, "Number of text items does not match columns"
for text, column in map(None, textlist, self.columns):
column.wrap(text)
numlines = max(numlines, column.numlines())
complines = [''] * numlines
for ln in range(numlines):
for column in self.columns:
complines[ln] = complines[ln] + column.getline(ln)
#return string.join(complines, '\n') + '\n'
return '\n'.join(complines)
def test():
formatter = TextFormatter(
(
{'width': 10},
{'width': 12, 'margin': 4},
{'width': 20, 'margin': 8, 'alignment': right},
)
)
print formatter.compose(
(
"A rather short paragraph",
"Here is a paragraph containing a veryveryverylongwordindeed.",
"And now for something on the right-hand side.",
)
)
if __name__ == '__main__':
test()