txtwrap 2.3.2__tar.gz → 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {txtwrap-2.3.2/txtwrap.egg-info → txtwrap-3.0.0}/PKG-INFO +83 -37
- {txtwrap-2.3.2 → txtwrap-3.0.0}/README.md +81 -34
- {txtwrap-2.3.2 → txtwrap-3.0.0}/setup.py +2 -3
- txtwrap-3.0.0/txtwrap/__init__.py +35 -0
- txtwrap-3.0.0/txtwrap/__init__.pyi +30 -0
- txtwrap-3.0.0/txtwrap/_utils.py +34 -0
- txtwrap-3.0.0/txtwrap/constants.py +33 -0
- txtwrap-3.0.0/txtwrap/constants.pyi +8 -0
- txtwrap-3.0.0/txtwrap/identities.py +3 -0
- txtwrap-3.0.0/txtwrap/identities.pyi +3 -0
- txtwrap-2.3.2/txtwrap/_txtwrap.py → txtwrap-3.0.0/txtwrap/wrapper.py +235 -239
- txtwrap-2.3.2/txtwrap/__init__.pyi → txtwrap-3.0.0/txtwrap/wrapper.pyi +49 -51
- {txtwrap-2.3.2 → txtwrap-3.0.0/txtwrap.egg-info}/PKG-INFO +83 -37
- txtwrap-3.0.0/txtwrap.egg-info/SOURCES.txt +16 -0
- txtwrap-2.3.2/txtwrap/__init__.py +0 -24
- txtwrap-2.3.2/txtwrap.egg-info/SOURCES.txt +0 -10
- {txtwrap-2.3.2 → txtwrap-3.0.0}/MANIFEST.in +0 -0
- {txtwrap-2.3.2 → txtwrap-3.0.0}/setup.cfg +0 -0
- {txtwrap-2.3.2 → txtwrap-3.0.0}/txtwrap.egg-info/dependency_links.txt +0 -0
- {txtwrap-2.3.2 → txtwrap-3.0.0}/txtwrap.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: txtwrap
|
3
|
-
Version:
|
3
|
+
Version: 3.0.0
|
4
4
|
Summary: A tool for wrapping and filling text.
|
5
5
|
Home-page: https://github.com/azzammuhyala/txtwrap
|
6
6
|
Author: azzammuhyala
|
@@ -9,11 +9,10 @@ License: MIT
|
|
9
9
|
Keywords: wrap,wrapper,wrapping,wrapped,text wrap,text wrapper,text wrapping,text wrapped
|
10
10
|
Classifier: Programming Language :: Python
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
12
|
-
Classifier: Programming Language :: Python :: 3.3
|
13
12
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
14
13
|
Classifier: Topic :: Text Processing
|
15
14
|
Classifier: Topic :: Text Processing :: Filters
|
16
|
-
Requires-Python: >=3.
|
15
|
+
Requires-Python: >=3.0
|
17
16
|
Description-Content-Type: text/markdown
|
18
17
|
Dynamic: author
|
19
18
|
Dynamic: author-email
|
@@ -29,19 +28,21 @@ Dynamic: summary
|
|
29
28
|
# TxTWrap🔡
|
30
29
|
A tool for wrapping and filling text.🔨
|
31
30
|
|
32
|
-
|
33
|
-
Python requires version:
|
34
|
-
Python stub file requires version:
|
31
|
+
Package version: **3.0.0** <br>
|
32
|
+
Python requires version: **>=3.0.0** <br>
|
33
|
+
Python stub file requires version: **>=3.5.0** <br>
|
35
34
|
|
36
35
|
- [`LOREM_IPSUM_WORDS`](#lorem-ipsum)
|
37
36
|
- [`LOREM_IPSUM_SENTENCES`](#lorem-ipsum)
|
38
37
|
- [`LOREM_IPSUM_PARAGRAPHS`](#lorem-ipsum)
|
39
|
-
- [`
|
40
|
-
- [`
|
41
|
-
- [`
|
42
|
-
- [`
|
43
|
-
- [`
|
44
|
-
- [`
|
38
|
+
- [`SEPARATOR_WHITESPACE`](#separators) (➕ New)
|
39
|
+
- [`SEPARATOR_ESCAPE`](#separators) (➕ New)
|
40
|
+
- [`TextWrapper`](#textwrapper) (✅ Updated)
|
41
|
+
- [`sanitize`](#sanitizetext) (🛠️ Fixed)
|
42
|
+
- [`wrap`](#wraptext-return_detailsfalse) (✅ Updated)
|
43
|
+
- [`align`](#aligntext-return_detailsfalse) (🛠️ Fixed)
|
44
|
+
- [`fillstr`](#fillstrtext) (🛠️ Fixed)
|
45
|
+
- [`shorten`](#shortentext) (🛠️ Fixed)
|
45
46
|
|
46
47
|
# Documents📄
|
47
48
|
This module is inspired by the [`textwrap`](https://docs.python.org/3/library/textwrap.html) module, which provides
|
@@ -53,7 +54,9 @@ filling _monospace fonts_ but also for other font types, such as _Arial_, _Times
|
|
53
54
|
|
54
55
|
<h1></h1>
|
55
56
|
|
56
|
-
##
|
57
|
+
## Constants
|
58
|
+
|
59
|
+
### Lorem ipsum
|
57
60
|
```py
|
58
61
|
LOREM_IPSUM_WORDS
|
59
62
|
LOREM_IPSUM_SENTENCES
|
@@ -66,24 +69,39 @@ A _Lorem Ipsum_ collection of words, sentences, and paragraphs that can be used
|
|
66
69
|
|
67
70
|
<h1></h1>
|
68
71
|
|
72
|
+
### Separators
|
73
|
+
```py
|
74
|
+
SEPARATOR_WHITESPACE
|
75
|
+
SEPARATOR_ESCAPE
|
76
|
+
```
|
77
|
+
A collection of separators that can be used to separate text.
|
78
|
+
- `SEPARATOR_WHITESPACE` contains whitespace characters.
|
79
|
+
- `SEPARATOR_ESCAPE` contains whitespace characters including `'\0'`, `'\a'`, and `'\b'`.
|
80
|
+
|
81
|
+
To use this, assign this constant to the [`separator`](#separator) parameter.
|
82
|
+
|
83
|
+
<h1></h1>
|
84
|
+
|
69
85
|
## `TextWrapper`
|
70
86
|
```py
|
71
87
|
class TextWrapper:
|
88
|
+
|
72
89
|
def __init__(
|
73
90
|
self,
|
74
91
|
width: Union[int, float] = 70,
|
75
92
|
line_padding: Union[int, float] = 0,
|
76
|
-
|
93
|
+
mode: Literal['mono', 'word'] = 'word',
|
77
94
|
alignment: Literal['left', 'center', 'right', 'fill', 'fill-left', 'fill-center', 'fill-right'] = 'left',
|
78
95
|
placeholder: str = '...',
|
79
96
|
fillchar: str = ' ',
|
80
97
|
separator: Optional[Union[str, Iterable[str]]] = None,
|
81
98
|
max_lines: Optional[int] = None,
|
82
|
-
|
99
|
+
preserve_empty_lines: bool = True,
|
83
100
|
minimum_width: bool = True,
|
101
|
+
drop_separator: bool = False,
|
84
102
|
justify_last_line: bool = False,
|
85
103
|
break_on_hyphens: bool = True,
|
86
|
-
sizefunc: Optional[Callable[[str], Union[Tuple[Union[int, float], Union[int, float]], int, float]]] = None
|
104
|
+
sizefunc: Optional[Callable[[str], Union[Tuple[Union[int, float], Union[int, float]], int, float]]] = None
|
87
105
|
) -> None
|
88
106
|
```
|
89
107
|
A class that handles all functions available in this module. Each keyword argument corresponds to its attribute.
|
@@ -116,10 +134,10 @@ as each attribute has type checking, which may reduce performance.
|
|
116
134
|
|
117
135
|
<h1></h1>
|
118
136
|
|
119
|
-
#### **`
|
120
|
-
(Default: `'word'`) The wrapping
|
121
|
-
- `'mono'`
|
122
|
-
- `'word'`
|
137
|
+
#### **`mode`**
|
138
|
+
(Default: `'word'`) The wrapping mode. Available options:
|
139
|
+
- `'mono'` make text wraps character by character.
|
140
|
+
- `'word'` make text wraps word by word.
|
123
141
|
|
124
142
|
<h1></h1>
|
125
143
|
|
@@ -161,7 +179,7 @@ as each attribute has type checking, which may reduce performance.
|
|
161
179
|
|
162
180
|
<h1></h1>
|
163
181
|
|
164
|
-
#### **`
|
182
|
+
#### **`preserve_empty_lines`**
|
165
183
|
(Default: `True`) Retains empty lines in the wrapped text.
|
166
184
|
|
167
185
|
<h1></h1>
|
@@ -172,6 +190,11 @@ enabling this attribute removes unnecessary empty space.
|
|
172
190
|
|
173
191
|
<h1></h1>
|
174
192
|
|
193
|
+
#### **`drop_separator`**
|
194
|
+
(Default: `False`) Removes the separator between more than one word at a time.
|
195
|
+
|
196
|
+
<h1></h1>
|
197
|
+
|
175
198
|
#### **`justify_last_line`**
|
176
199
|
(Default: `False`) Determines whether the last line should also be justified
|
177
200
|
(applies only to `fill-...` alignments).
|
@@ -198,6 +221,15 @@ If the function calculates only the width, it must return a single value of type
|
|
198
221
|
|
199
222
|
> Note: All methods can be called outside the [`TextWrapper`](#textwrapper) like external functions.
|
200
223
|
|
224
|
+
For example:
|
225
|
+
```py
|
226
|
+
>>> txtwrap.TextWrapper(20, placeholder='[...]').shorten("Hello World!")
|
227
|
+
```
|
228
|
+
is equivalent to:
|
229
|
+
```py
|
230
|
+
>>> txtwrap.shorten("Hello World!", 20, placeholder='[...]')
|
231
|
+
```
|
232
|
+
|
201
233
|
<h1></h1>
|
202
234
|
|
203
235
|
#### **`copy`**
|
@@ -220,44 +252,56 @@ For example:
|
|
220
252
|
#### **`wrap(text, return_details=False)`**
|
221
253
|
Returns a list of wrapped text strings. If `return_details=True`, returns a dictionary containing:
|
222
254
|
- `'wrapped'`: A list of wrapped text fragments.
|
223
|
-
- `'
|
255
|
+
- `'start_lines'`: A set of indices marking the start of line.
|
256
|
+
- `'end_lines'`: A set of indices marking the end of line.
|
224
257
|
|
225
258
|
For example:
|
226
259
|
```py
|
227
260
|
>>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS)
|
228
261
|
['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.']
|
229
|
-
>>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS, return_details=True)
|
230
|
-
|
262
|
+
>>> info = TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS, return_details=True)
|
263
|
+
>>> info
|
264
|
+
{'wrapped': ['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.'], 'start_lines': {1}, 'end_lines': {5}}
|
265
|
+
>>> info['wrapped'][next(iter(info['start_lines'])) - 1]
|
266
|
+
'Lorem ipsum'
|
267
|
+
>>> info['wrapped'][next(iter(info['end_lines'])) - 1]
|
268
|
+
'elit.'
|
231
269
|
```
|
232
270
|
|
233
271
|
<h1></h1>
|
234
272
|
|
235
273
|
#### **`align(text, return_details=False)`**
|
236
|
-
Returns a list of tuples, where each tuple contains `(xPosition, yPosition, text)`, representing the wrapped text along
|
237
|
-
coordinates.
|
274
|
+
Returns a list of tuples, where each tuple contains `(xPosition, yPosition, text)`, representing the wrapped text along
|
275
|
+
with its coordinates.
|
238
276
|
> Note: [`sizefunc`](#sizefunc) must return both width and height.
|
239
277
|
|
240
278
|
If `return_details=True`, returns a dictionary containing:
|
241
279
|
- `'aligned'`: A list of wrapped text with coordinate data.
|
242
|
-
- `'wrapped'`:
|
243
|
-
- `'
|
244
|
-
- `'
|
280
|
+
- `'wrapped'`: A list of wrapped text fragments.
|
281
|
+
- `'start_lines'`: A set of indices marking the start of line.
|
282
|
+
- `'end_lines'`: A set of indices marking the end of line.
|
283
|
+
- `'size'`: A calculated text size.
|
245
284
|
|
246
285
|
For example:
|
247
286
|
```py
|
248
287
|
>>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS)
|
249
288
|
[(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')]
|
250
|
-
>>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
|
289
|
+
>>> info = TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
|
290
|
+
>>> info
|
251
291
|
{'aligned': [(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')], 'wrapped': [
|
252
|
-
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], '
|
292
|
+
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': {1}, 'end_lines': {3}, 'size': (18, 3)}
|
293
|
+
>>> info['wrapped'][next(iter(info['start_lines'])) - 1]
|
294
|
+
'Lorem ipsum odor'
|
295
|
+
>>> info['wrapped'][next(iter(info['end_lines'])) - 1]
|
296
|
+
'adipiscing elit.'
|
253
297
|
```
|
254
298
|
|
255
299
|
<h1></h1>
|
256
300
|
|
257
301
|
#### **`fillstr(text)`**
|
258
302
|
Returns a string with wrapped text formatted for monospace fonts.
|
259
|
-
> Note: [`width`](#width), [`line_padding`](#line_padding), and the output of [`sizefunc`](#sizefunc)
|
260
|
-
not `float`!
|
303
|
+
> Note: [`width`](#width), [`line_padding`](#line_padding), and the output of [`sizefunc`](#sizefunc)
|
304
|
+
(size or just length) must return `int`, not `float`!
|
261
305
|
|
262
306
|
For example:
|
263
307
|
```py
|
@@ -301,12 +345,13 @@ def render_wrap(
|
|
301
345
|
color: pygame.Color,
|
302
346
|
background: Optional[pygame.Color] = None,
|
303
347
|
line_padding: int = 0,
|
304
|
-
|
348
|
+
wrap_mode: Literal['word', 'mono'] = 'word',
|
305
349
|
alignment: Literal['left', 'center', 'right', 'fill', 'fill-left', 'fill-center', 'fill-right'] = 'left',
|
306
350
|
placeholder: str = '...',
|
307
351
|
max_lines: Optional[int] = None,
|
308
|
-
|
352
|
+
preserve_empty_lines: bool = True,
|
309
353
|
minimum_width: bool = True,
|
354
|
+
drop_separator: bool = False,
|
310
355
|
justify_last_line: bool = False,
|
311
356
|
break_on_hyphens: bool = True
|
312
357
|
|
@@ -316,12 +361,13 @@ def render_wrap(
|
|
316
361
|
text=text,
|
317
362
|
width=width,
|
318
363
|
line_padding=line_padding,
|
319
|
-
|
364
|
+
mode=wrap_mode,
|
320
365
|
alignment=alignment,
|
321
366
|
placeholder=placeholder,
|
322
367
|
max_lines=max_lines,
|
323
|
-
|
368
|
+
preserve_empty_lines=preserve_empty_lines,
|
324
369
|
minimum_width=minimum_width,
|
370
|
+
drop_separator=drop_separator,
|
325
371
|
justify_last_line=justify_last_line,
|
326
372
|
break_on_hyphens=break_on_hyphens,
|
327
373
|
return_details=True,
|
@@ -1,19 +1,21 @@
|
|
1
1
|
# TxTWrap🔡
|
2
2
|
A tool for wrapping and filling text.🔨
|
3
3
|
|
4
|
-
|
5
|
-
Python requires version:
|
6
|
-
Python stub file requires version:
|
4
|
+
Package version: **3.0.0** <br>
|
5
|
+
Python requires version: **>=3.0.0** <br>
|
6
|
+
Python stub file requires version: **>=3.5.0** <br>
|
7
7
|
|
8
8
|
- [`LOREM_IPSUM_WORDS`](#lorem-ipsum)
|
9
9
|
- [`LOREM_IPSUM_SENTENCES`](#lorem-ipsum)
|
10
10
|
- [`LOREM_IPSUM_PARAGRAPHS`](#lorem-ipsum)
|
11
|
-
- [`
|
12
|
-
- [`
|
13
|
-
- [`
|
14
|
-
- [`
|
15
|
-
- [`
|
16
|
-
- [`
|
11
|
+
- [`SEPARATOR_WHITESPACE`](#separators) (➕ New)
|
12
|
+
- [`SEPARATOR_ESCAPE`](#separators) (➕ New)
|
13
|
+
- [`TextWrapper`](#textwrapper) (✅ Updated)
|
14
|
+
- [`sanitize`](#sanitizetext) (🛠️ Fixed)
|
15
|
+
- [`wrap`](#wraptext-return_detailsfalse) (✅ Updated)
|
16
|
+
- [`align`](#aligntext-return_detailsfalse) (🛠️ Fixed)
|
17
|
+
- [`fillstr`](#fillstrtext) (🛠️ Fixed)
|
18
|
+
- [`shorten`](#shortentext) (🛠️ Fixed)
|
17
19
|
|
18
20
|
# Documents📄
|
19
21
|
This module is inspired by the [`textwrap`](https://docs.python.org/3/library/textwrap.html) module, which provides
|
@@ -25,7 +27,9 @@ filling _monospace fonts_ but also for other font types, such as _Arial_, _Times
|
|
25
27
|
|
26
28
|
<h1></h1>
|
27
29
|
|
28
|
-
##
|
30
|
+
## Constants
|
31
|
+
|
32
|
+
### Lorem ipsum
|
29
33
|
```py
|
30
34
|
LOREM_IPSUM_WORDS
|
31
35
|
LOREM_IPSUM_SENTENCES
|
@@ -38,24 +42,39 @@ A _Lorem Ipsum_ collection of words, sentences, and paragraphs that can be used
|
|
38
42
|
|
39
43
|
<h1></h1>
|
40
44
|
|
45
|
+
### Separators
|
46
|
+
```py
|
47
|
+
SEPARATOR_WHITESPACE
|
48
|
+
SEPARATOR_ESCAPE
|
49
|
+
```
|
50
|
+
A collection of separators that can be used to separate text.
|
51
|
+
- `SEPARATOR_WHITESPACE` contains whitespace characters.
|
52
|
+
- `SEPARATOR_ESCAPE` contains whitespace characters including `'\0'`, `'\a'`, and `'\b'`.
|
53
|
+
|
54
|
+
To use this, assign this constant to the [`separator`](#separator) parameter.
|
55
|
+
|
56
|
+
<h1></h1>
|
57
|
+
|
41
58
|
## `TextWrapper`
|
42
59
|
```py
|
43
60
|
class TextWrapper:
|
61
|
+
|
44
62
|
def __init__(
|
45
63
|
self,
|
46
64
|
width: Union[int, float] = 70,
|
47
65
|
line_padding: Union[int, float] = 0,
|
48
|
-
|
66
|
+
mode: Literal['mono', 'word'] = 'word',
|
49
67
|
alignment: Literal['left', 'center', 'right', 'fill', 'fill-left', 'fill-center', 'fill-right'] = 'left',
|
50
68
|
placeholder: str = '...',
|
51
69
|
fillchar: str = ' ',
|
52
70
|
separator: Optional[Union[str, Iterable[str]]] = None,
|
53
71
|
max_lines: Optional[int] = None,
|
54
|
-
|
72
|
+
preserve_empty_lines: bool = True,
|
55
73
|
minimum_width: bool = True,
|
74
|
+
drop_separator: bool = False,
|
56
75
|
justify_last_line: bool = False,
|
57
76
|
break_on_hyphens: bool = True,
|
58
|
-
sizefunc: Optional[Callable[[str], Union[Tuple[Union[int, float], Union[int, float]], int, float]]] = None
|
77
|
+
sizefunc: Optional[Callable[[str], Union[Tuple[Union[int, float], Union[int, float]], int, float]]] = None
|
59
78
|
) -> None
|
60
79
|
```
|
61
80
|
A class that handles all functions available in this module. Each keyword argument corresponds to its attribute.
|
@@ -88,10 +107,10 @@ as each attribute has type checking, which may reduce performance.
|
|
88
107
|
|
89
108
|
<h1></h1>
|
90
109
|
|
91
|
-
#### **`
|
92
|
-
(Default: `'word'`) The wrapping
|
93
|
-
- `'mono'`
|
94
|
-
- `'word'`
|
110
|
+
#### **`mode`**
|
111
|
+
(Default: `'word'`) The wrapping mode. Available options:
|
112
|
+
- `'mono'` make text wraps character by character.
|
113
|
+
- `'word'` make text wraps word by word.
|
95
114
|
|
96
115
|
<h1></h1>
|
97
116
|
|
@@ -133,7 +152,7 @@ as each attribute has type checking, which may reduce performance.
|
|
133
152
|
|
134
153
|
<h1></h1>
|
135
154
|
|
136
|
-
#### **`
|
155
|
+
#### **`preserve_empty_lines`**
|
137
156
|
(Default: `True`) Retains empty lines in the wrapped text.
|
138
157
|
|
139
158
|
<h1></h1>
|
@@ -144,6 +163,11 @@ enabling this attribute removes unnecessary empty space.
|
|
144
163
|
|
145
164
|
<h1></h1>
|
146
165
|
|
166
|
+
#### **`drop_separator`**
|
167
|
+
(Default: `False`) Removes the separator between more than one word at a time.
|
168
|
+
|
169
|
+
<h1></h1>
|
170
|
+
|
147
171
|
#### **`justify_last_line`**
|
148
172
|
(Default: `False`) Determines whether the last line should also be justified
|
149
173
|
(applies only to `fill-...` alignments).
|
@@ -170,6 +194,15 @@ If the function calculates only the width, it must return a single value of type
|
|
170
194
|
|
171
195
|
> Note: All methods can be called outside the [`TextWrapper`](#textwrapper) like external functions.
|
172
196
|
|
197
|
+
For example:
|
198
|
+
```py
|
199
|
+
>>> txtwrap.TextWrapper(20, placeholder='[...]').shorten("Hello World!")
|
200
|
+
```
|
201
|
+
is equivalent to:
|
202
|
+
```py
|
203
|
+
>>> txtwrap.shorten("Hello World!", 20, placeholder='[...]')
|
204
|
+
```
|
205
|
+
|
173
206
|
<h1></h1>
|
174
207
|
|
175
208
|
#### **`copy`**
|
@@ -192,44 +225,56 @@ For example:
|
|
192
225
|
#### **`wrap(text, return_details=False)`**
|
193
226
|
Returns a list of wrapped text strings. If `return_details=True`, returns a dictionary containing:
|
194
227
|
- `'wrapped'`: A list of wrapped text fragments.
|
195
|
-
- `'
|
228
|
+
- `'start_lines'`: A set of indices marking the start of line.
|
229
|
+
- `'end_lines'`: A set of indices marking the end of line.
|
196
230
|
|
197
231
|
For example:
|
198
232
|
```py
|
199
233
|
>>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS)
|
200
234
|
['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.']
|
201
|
-
>>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS, return_details=True)
|
202
|
-
|
235
|
+
>>> info = TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS, return_details=True)
|
236
|
+
>>> info
|
237
|
+
{'wrapped': ['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.'], 'start_lines': {1}, 'end_lines': {5}}
|
238
|
+
>>> info['wrapped'][next(iter(info['start_lines'])) - 1]
|
239
|
+
'Lorem ipsum'
|
240
|
+
>>> info['wrapped'][next(iter(info['end_lines'])) - 1]
|
241
|
+
'elit.'
|
203
242
|
```
|
204
243
|
|
205
244
|
<h1></h1>
|
206
245
|
|
207
246
|
#### **`align(text, return_details=False)`**
|
208
|
-
Returns a list of tuples, where each tuple contains `(xPosition, yPosition, text)`, representing the wrapped text along
|
209
|
-
coordinates.
|
247
|
+
Returns a list of tuples, where each tuple contains `(xPosition, yPosition, text)`, representing the wrapped text along
|
248
|
+
with its coordinates.
|
210
249
|
> Note: [`sizefunc`](#sizefunc) must return both width and height.
|
211
250
|
|
212
251
|
If `return_details=True`, returns a dictionary containing:
|
213
252
|
- `'aligned'`: A list of wrapped text with coordinate data.
|
214
|
-
- `'wrapped'`:
|
215
|
-
- `'
|
216
|
-
- `'
|
253
|
+
- `'wrapped'`: A list of wrapped text fragments.
|
254
|
+
- `'start_lines'`: A set of indices marking the start of line.
|
255
|
+
- `'end_lines'`: A set of indices marking the end of line.
|
256
|
+
- `'size'`: A calculated text size.
|
217
257
|
|
218
258
|
For example:
|
219
259
|
```py
|
220
260
|
>>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS)
|
221
261
|
[(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')]
|
222
|
-
>>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
|
262
|
+
>>> info = TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
|
263
|
+
>>> info
|
223
264
|
{'aligned': [(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')], 'wrapped': [
|
224
|
-
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], '
|
265
|
+
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': {1}, 'end_lines': {3}, 'size': (18, 3)}
|
266
|
+
>>> info['wrapped'][next(iter(info['start_lines'])) - 1]
|
267
|
+
'Lorem ipsum odor'
|
268
|
+
>>> info['wrapped'][next(iter(info['end_lines'])) - 1]
|
269
|
+
'adipiscing elit.'
|
225
270
|
```
|
226
271
|
|
227
272
|
<h1></h1>
|
228
273
|
|
229
274
|
#### **`fillstr(text)`**
|
230
275
|
Returns a string with wrapped text formatted for monospace fonts.
|
231
|
-
> Note: [`width`](#width), [`line_padding`](#line_padding), and the output of [`sizefunc`](#sizefunc)
|
232
|
-
not `float`!
|
276
|
+
> Note: [`width`](#width), [`line_padding`](#line_padding), and the output of [`sizefunc`](#sizefunc)
|
277
|
+
(size or just length) must return `int`, not `float`!
|
233
278
|
|
234
279
|
For example:
|
235
280
|
```py
|
@@ -273,12 +318,13 @@ def render_wrap(
|
|
273
318
|
color: pygame.Color,
|
274
319
|
background: Optional[pygame.Color] = None,
|
275
320
|
line_padding: int = 0,
|
276
|
-
|
321
|
+
wrap_mode: Literal['word', 'mono'] = 'word',
|
277
322
|
alignment: Literal['left', 'center', 'right', 'fill', 'fill-left', 'fill-center', 'fill-right'] = 'left',
|
278
323
|
placeholder: str = '...',
|
279
324
|
max_lines: Optional[int] = None,
|
280
|
-
|
325
|
+
preserve_empty_lines: bool = True,
|
281
326
|
minimum_width: bool = True,
|
327
|
+
drop_separator: bool = False,
|
282
328
|
justify_last_line: bool = False,
|
283
329
|
break_on_hyphens: bool = True
|
284
330
|
|
@@ -288,12 +334,13 @@ def render_wrap(
|
|
288
334
|
text=text,
|
289
335
|
width=width,
|
290
336
|
line_padding=line_padding,
|
291
|
-
|
337
|
+
mode=wrap_mode,
|
292
338
|
alignment=alignment,
|
293
339
|
placeholder=placeholder,
|
294
340
|
max_lines=max_lines,
|
295
|
-
|
341
|
+
preserve_empty_lines=preserve_empty_lines,
|
296
342
|
minimum_width=minimum_width,
|
343
|
+
drop_separator=drop_separator,
|
297
344
|
justify_last_line=justify_last_line,
|
298
345
|
break_on_hyphens=break_on_hyphens,
|
299
346
|
return_details=True,
|
@@ -5,7 +5,7 @@ with open('README.md', encoding='utf-8') as readme:
|
|
5
5
|
|
6
6
|
setup(
|
7
7
|
name='txtwrap',
|
8
|
-
version='
|
8
|
+
version='3.0.0',
|
9
9
|
description='A tool for wrapping and filling text.',
|
10
10
|
long_description=long_description,
|
11
11
|
long_description_content_type='text/markdown',
|
@@ -13,14 +13,13 @@ setup(
|
|
13
13
|
author_email='azzammuhyala@gmail.com',
|
14
14
|
url='https://github.com/azzammuhyala/txtwrap',
|
15
15
|
license='MIT',
|
16
|
-
python_requires='>=3.
|
16
|
+
python_requires='>=3.0',
|
17
17
|
packages=find_packages(),
|
18
18
|
include_package_data=True,
|
19
19
|
keywords=['wrap', 'wrapper', 'wrapping', 'wrapped', 'text wrap', 'text wrapper', 'text wrapping', 'text wrapped'],
|
20
20
|
classifiers=[
|
21
21
|
'Programming Language :: Python',
|
22
22
|
'Programming Language :: Python :: 3',
|
23
|
-
'Programming Language :: Python :: 3.3',
|
24
23
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
25
24
|
'Topic :: Text Processing',
|
26
25
|
'Topic :: Text Processing :: Filters'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
"""
|
2
|
+
A tool for wrapping and filling text.
|
3
|
+
"""
|
4
|
+
|
5
|
+
# Supports only in Python>=3.0.0
|
6
|
+
|
7
|
+
from . import constants as constants
|
8
|
+
from . import identities as identities
|
9
|
+
from . import wrapper as wrapper
|
10
|
+
|
11
|
+
from .identities import __version__, __author__, __license__
|
12
|
+
|
13
|
+
from .constants import (
|
14
|
+
LOREM_IPSUM_WORDS, LOREM_IPSUM_SENTENCES, LOREM_IPSUM_PARAGRAPHS,
|
15
|
+
SEPARATOR_WHITESPACE, SEPARATOR_ESCAPE
|
16
|
+
)
|
17
|
+
|
18
|
+
from .wrapper import (
|
19
|
+
TextWrapper,
|
20
|
+
sanitize, wrap, align, fillstr, shorten
|
21
|
+
)
|
22
|
+
|
23
|
+
__all__ = [
|
24
|
+
'LOREM_IPSUM_WORDS',
|
25
|
+
'LOREM_IPSUM_SENTENCES',
|
26
|
+
'LOREM_IPSUM_PARAGRAPHS',
|
27
|
+
'SEPARATOR_WHITESPACE',
|
28
|
+
'SEPARATOR_ESCAPE',
|
29
|
+
'TextWrapper',
|
30
|
+
'sanitize',
|
31
|
+
'wrap',
|
32
|
+
'align',
|
33
|
+
'fillstr',
|
34
|
+
'shorten'
|
35
|
+
]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Define the packages
|
2
|
+
|
3
|
+
from . import constants as constants
|
4
|
+
from . import identities as identities
|
5
|
+
from . import wrapper as wrapper
|
6
|
+
|
7
|
+
# Define the main variables, functions, classes to be exported
|
8
|
+
|
9
|
+
from .constants import (
|
10
|
+
LOREM_IPSUM_WORDS as LOREM_IPSUM_WORDS,
|
11
|
+
LOREM_IPSUM_SENTENCES as LOREM_IPSUM_SENTENCES,
|
12
|
+
LOREM_IPSUM_PARAGRAPHS as LOREM_IPSUM_PARAGRAPHS,
|
13
|
+
SEPARATOR_WHITESPACE as SEPARATOR_WHITESPACE,
|
14
|
+
SEPARATOR_ESCAPE as SEPARATOR_ESCAPE
|
15
|
+
)
|
16
|
+
|
17
|
+
from .identities import (
|
18
|
+
__version__ as __version__,
|
19
|
+
__author__ as __author__,
|
20
|
+
__license__ as __license__
|
21
|
+
)
|
22
|
+
|
23
|
+
from .wrapper import (
|
24
|
+
TextWrapper as TextWrapper,
|
25
|
+
sanitize as sanitize,
|
26
|
+
wrap as wrap,
|
27
|
+
align as align,
|
28
|
+
fillstr as fillstr,
|
29
|
+
shorten as shorten
|
30
|
+
)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
pdict = type('pdict', (dict,), {
|
4
|
+
'__repr__': lambda self : '{}({})'.format(type(self).__name__, dict.__repr__(self)),
|
5
|
+
'__getattr__': lambda self, key: self.get(key, None),
|
6
|
+
'__setattr__': dict.__setitem__,
|
7
|
+
'__delattr__': dict.__delitem__
|
8
|
+
})
|
9
|
+
|
10
|
+
def align_left(aligned, text, width, text_width, offset_y):
|
11
|
+
aligned.append((0, offset_y, text))
|
12
|
+
|
13
|
+
def align_center(aligned, text, width, text_width, offset_y):
|
14
|
+
aligned.append(((width - text_width) / 2, offset_y, text))
|
15
|
+
|
16
|
+
def align_right(aligned, text, width, text_width, offset_y):
|
17
|
+
aligned.append((width - text_width, offset_y, text))
|
18
|
+
|
19
|
+
def fillstr_left(justified_lines, text, width, text_width, fillchar):
|
20
|
+
justified_lines.append(text + fillchar * (width - text_width))
|
21
|
+
|
22
|
+
def fillstr_center(justified_lines, text, width, text_width, fillchar):
|
23
|
+
extra_space = width - text_width
|
24
|
+
left_space = extra_space // 2
|
25
|
+
justified_lines.append(fillchar * left_space + text + fillchar * (extra_space - left_space))
|
26
|
+
|
27
|
+
def fillstr_right(justified_lines, text, width, text_width, fillchar):
|
28
|
+
justified_lines.append(fillchar * (width - text_width) + text)
|
29
|
+
|
30
|
+
hyphenate_parrent = r'''
|
31
|
+
(?<=-) # Positive lookbehind -> make sure there is a '-' before the current position
|
32
|
+
(?=(?!-).) # Positive lookahead -> make sure the character after is NOT '-' (avoid '--'), but still have one character
|
33
|
+
'''
|
34
|
+
split_hyphenated = re.compile(hyphenate_parrent, re.VERBOSE).split
|
@@ -0,0 +1,33 @@
|
|
1
|
+
LOREM_IPSUM_WORDS = 'Lorem ipsum odor amet, consectetuer adipiscing elit.'
|
2
|
+
LOREM_IPSUM_SENTENCES = (
|
3
|
+
'Lorem ipsum odor amet, consectetuer adipiscing elit. In malesuada eros natoque urna felis diam aptent donec. Cubil'
|
4
|
+
'ia libero morbi fusce tempus, luctus aenean augue. Mus senectus rutrum phasellus fusce dictum platea. Eros a integ'
|
5
|
+
'er nec fusce erat urna.'
|
6
|
+
)
|
7
|
+
LOREM_IPSUM_PARAGRAPHS = (
|
8
|
+
'Lorem ipsum odor amet, consectetuer adipiscing elit. Nulla porta ex condimentum velit facilisi; consequat congue. '
|
9
|
+
'Tristique duis sociosqu aliquam semper sit id. Nisi morbi purus, nascetur elit pellentesque venenatis. Velit commo'
|
10
|
+
'do molestie potenti placerat faucibus convallis. Himenaeos dapibus ipsum natoque nam dapibus habitasse diam. Viver'
|
11
|
+
'ra ac porttitor cras tempor cras. Pharetra habitant nibh dui ipsum scelerisque cras? Efficitur phasellus etiam con'
|
12
|
+
'gue taciti tortor quam. Volutpat quam vulputate condimentum hendrerit justo congue iaculis nisl nullam.\n\nIncepto'
|
13
|
+
's tempus nostra fringilla arcu; tellus blandit facilisi risus. Platea bibendum tristique lectus nunc placerat id a'
|
14
|
+
'liquam. Eu arcu nisl mattis potenti elementum. Dignissim vivamus montes volutpat litora felis fusce ultrices. Vulp'
|
15
|
+
'utate magna nascetur bibendum inceptos scelerisque morbi posuere. Consequat dolor netus augue augue tristique cura'
|
16
|
+
'bitur habitasse bibendum. Consectetur est per eros semper, magnis interdum libero. Arcu adipiscing litora metus fr'
|
17
|
+
'ingilla varius gravida congue tellus adipiscing. Blandit nulla mauris nullam ante metus curae scelerisque.\n\nSem '
|
18
|
+
'varius sodales ut volutpat imperdiet turpis primis nullam. At gravida tincidunt phasellus lacus duis integer eros '
|
19
|
+
'penatibus. Interdum mauris molestie posuere nascetur dignissim himenaeos; magna et quisque. Dignissim malesuada et'
|
20
|
+
'iam donec vehicula aliquet bibendum. Magna dapibus sapien semper parturient id dis? Pretium orci ante leo, porta t'
|
21
|
+
'incidunt molestie. Malesuada dictumst commodo consequat interdum nisi fusce cras rhoncus feugiat.\n\nHimenaeos mat'
|
22
|
+
'tis commodo suspendisse maecenas cras arcu. Habitasse id facilisi praesent justo molestie felis luctus suspendisse'
|
23
|
+
'. Imperdiet ipsum praesent nunc mauris mattis curabitur. Et consectetur morbi auctor feugiat enim ridiculus arcu. '
|
24
|
+
'Ultricies magna blandit eget; vivamus sollicitudin nisl proin. Sollicitudin sociosqu et finibus elit vestibulum sa'
|
25
|
+
'pien nec odio euismod. Turpis eleifend amet quis auctor cursus. Vehicula pharetra sapien praesent amet purus ante.'
|
26
|
+
' Risus blandit cubilia lorem hendrerit penatibus in magnis.\n\nAmet posuere nunc; maecenas consequat risus potenti'
|
27
|
+
'. Volutpat leo lacinia sapien nulla sagittis dignissim mauris ultrices aliquet. Nisi pretium interdum luctus donec'
|
28
|
+
' magna suscipit. Dapibus tristique felis natoque malesuada augue? Justo faucibus tincidunt congue arcu sem; fusce '
|
29
|
+
'aliquet proin. Commodo neque nibh; tempus ad tortor netus. Mattis ultricies nec maximus porttitor non mauris?'
|
30
|
+
)
|
31
|
+
|
32
|
+
SEPARATOR_WHITESPACE = (' ', '\t', '\n', '\r', '\v', '\f')
|
33
|
+
SEPARATOR_ESCAPE = SEPARATOR_WHITESPACE + ('\a', '\b', '\0')
|