txtwrap 3.0.0__tar.gz → 3.0.1__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-3.0.0/txtwrap.egg-info → txtwrap-3.0.1}/PKG-INFO +41 -31
- {txtwrap-3.0.0 → txtwrap-3.0.1}/README.md +37 -30
- {txtwrap-3.0.0 → txtwrap-3.0.1}/setup.py +7 -3
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/__init__.py +3 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/__init__.pyi +2 -2
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/_utils.py +2 -2
- txtwrap-3.0.1/txtwrap/identities.py +3 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/wrapper.py +33 -35
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/wrapper.pyi +13 -12
- {txtwrap-3.0.0 → txtwrap-3.0.1/txtwrap.egg-info}/PKG-INFO +41 -31
- txtwrap-3.0.0/txtwrap/identities.py +0 -3
- {txtwrap-3.0.0 → txtwrap-3.0.1}/MANIFEST.in +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/setup.cfg +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/constants.py +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/constants.pyi +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap/identities.pyi +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap.egg-info/SOURCES.txt +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap.egg-info/dependency_links.txt +0 -0
- {txtwrap-3.0.0 → txtwrap-3.0.1}/txtwrap.egg-info/top_level.txt +0 -0
@@ -1,11 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: txtwrap
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.1
|
4
4
|
Summary: A tool for wrapping and filling text.
|
5
5
|
Home-page: https://github.com/azzammuhyala/txtwrap
|
6
6
|
Author: azzammuhyala
|
7
7
|
Author-email: azzammuhyala@gmail.com
|
8
8
|
License: MIT
|
9
|
+
Project-URL: Source, https://github.com/azzammuhyala/txtwrap
|
10
|
+
Project-URL: Bug Tracker, https://github.com/azzammuhyala/txtwrap/issues
|
9
11
|
Keywords: wrap,wrapper,wrapping,wrapped,text wrap,text wrapper,text wrapping,text wrapped
|
10
12
|
Classifier: Programming Language :: Python
|
11
13
|
Classifier: Programming Language :: Python :: 3
|
@@ -22,24 +24,25 @@ Dynamic: description-content-type
|
|
22
24
|
Dynamic: home-page
|
23
25
|
Dynamic: keywords
|
24
26
|
Dynamic: license
|
27
|
+
Dynamic: project-url
|
25
28
|
Dynamic: requires-python
|
26
29
|
Dynamic: summary
|
27
30
|
|
28
31
|
# TxTWrap🔡
|
29
32
|
A tool for wrapping and filling text.🔨
|
30
33
|
|
31
|
-
Package version: **3.0.
|
34
|
+
Package version: **3.0.1** <br>
|
32
35
|
Python requires version: **>=3.0.0** <br>
|
33
36
|
Python stub file requires version: **>=3.5.0** <br>
|
34
37
|
|
35
38
|
- [`LOREM_IPSUM_WORDS`](#lorem-ipsum)
|
36
39
|
- [`LOREM_IPSUM_SENTENCES`](#lorem-ipsum)
|
37
40
|
- [`LOREM_IPSUM_PARAGRAPHS`](#lorem-ipsum)
|
38
|
-
- [`SEPARATOR_WHITESPACE`](#separators)
|
39
|
-
- [`SEPARATOR_ESCAPE`](#separators)
|
40
|
-
- [`TextWrapper`](#textwrapper) (
|
41
|
+
- [`SEPARATOR_WHITESPACE`](#separators)
|
42
|
+
- [`SEPARATOR_ESCAPE`](#separators)
|
43
|
+
- [`TextWrapper`](#textwrapper) (🛠️ Fixed)
|
41
44
|
- [`sanitize`](#sanitizetext) (🛠️ Fixed)
|
42
|
-
- [`wrap`](#wraptext-return_detailsfalse) (
|
45
|
+
- [`wrap`](#wraptext-return_detailsfalse) (🛠️ Fixed)
|
43
46
|
- [`align`](#aligntext-return_detailsfalse) (🛠️ Fixed)
|
44
47
|
- [`fillstr`](#fillstrtext) (🛠️ Fixed)
|
45
48
|
- [`shorten`](#shortentext) (🛠️ Fixed)
|
@@ -55,6 +58,7 @@ filling _monospace fonts_ but also for other font types, such as _Arial_, _Times
|
|
55
58
|
<h1></h1>
|
56
59
|
|
57
60
|
## Constants
|
61
|
+
_File: **txtwrap.constants**_
|
58
62
|
|
59
63
|
### Lorem ipsum
|
60
64
|
```py
|
@@ -83,6 +87,8 @@ To use this, assign this constant to the [`separator`](#separator) parameter.
|
|
83
87
|
<h1></h1>
|
84
88
|
|
85
89
|
## `TextWrapper`
|
90
|
+
_File: **txtwrap.wrapper**_
|
91
|
+
|
86
92
|
```py
|
87
93
|
class TextWrapper:
|
88
94
|
|
@@ -191,7 +197,7 @@ enabling this attribute removes unnecessary empty space.
|
|
191
197
|
<h1></h1>
|
192
198
|
|
193
199
|
#### **`drop_separator`**
|
194
|
-
(Default: `False`) Removes
|
200
|
+
(Default: `False`) Removes excess separators from between words one at a time.
|
195
201
|
|
196
202
|
<h1></h1>
|
197
203
|
|
@@ -233,17 +239,17 @@ is equivalent to:
|
|
233
239
|
<h1></h1>
|
234
240
|
|
235
241
|
#### **`copy`**
|
236
|
-
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object.
|
242
|
+
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object. (External function using `copy.copy`)
|
237
243
|
|
238
244
|
<h1></h1>
|
239
245
|
|
240
246
|
#### **`sanitize(text)`**
|
241
247
|
Removes excessive characters from [`separator`](#separator) and replaces them with the [`fillchar`](#fillchar)
|
242
|
-
character.
|
248
|
+
character. (It doesn't matter whether [`drop_separator`](#drop_separator) is `False` or `True`)
|
243
249
|
|
244
250
|
For example:
|
245
251
|
```py
|
246
|
-
>>>
|
252
|
+
>>> txtwrap.sanitize("\tHello \nWorld!\r ")
|
247
253
|
'Hello World!'
|
248
254
|
```
|
249
255
|
|
@@ -252,20 +258,22 @@ For example:
|
|
252
258
|
#### **`wrap(text, return_details=False)`**
|
253
259
|
Returns a list of wrapped text strings. If `return_details=True`, returns a dictionary containing:
|
254
260
|
- `'wrapped'`: A list of wrapped text fragments.
|
255
|
-
- `'start_lines'`: A
|
256
|
-
- `'end_lines'`: A
|
261
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
262
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
257
263
|
|
258
264
|
For example:
|
259
265
|
```py
|
260
|
-
>>>
|
261
|
-
['Lorem ipsum', '
|
262
|
-
>>>
|
263
|
-
>>>
|
264
|
-
|
265
|
-
>>>
|
266
|
-
'Lorem ipsum'
|
267
|
-
>>>
|
268
|
-
'
|
266
|
+
>>> txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
267
|
+
['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.']
|
268
|
+
>>> wrapped_info = txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
269
|
+
>>> start_lines = wrapped_info['start_lines']
|
270
|
+
>>> end_lines = wrapped_info['end_lines']
|
271
|
+
>>> wrapped_info
|
272
|
+
{'wrapped': ['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3]}
|
273
|
+
>>> wrapped_info['wrapped'][start_lines[0] - 1]
|
274
|
+
'Lorem ipsum odor'
|
275
|
+
>>> wrapped_info['wrapped'][end_lines[0] - 1]
|
276
|
+
'adipiscing elit.'
|
269
277
|
```
|
270
278
|
|
271
279
|
<h1></h1>
|
@@ -278,21 +286,23 @@ with its coordinates.
|
|
278
286
|
If `return_details=True`, returns a dictionary containing:
|
279
287
|
- `'aligned'`: A list of wrapped text with coordinate data.
|
280
288
|
- `'wrapped'`: A list of wrapped text fragments.
|
281
|
-
- `'start_lines'`: A
|
282
|
-
- `'end_lines'`: A
|
289
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
290
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
283
291
|
- `'size'`: A calculated text size.
|
284
292
|
|
285
293
|
For example:
|
286
294
|
```py
|
287
|
-
>>>
|
295
|
+
>>> txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
288
296
|
[(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')]
|
289
|
-
>>>
|
290
|
-
>>>
|
297
|
+
>>> aligned_info = txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
298
|
+
>>> start_lines = aligned_info['start_lines']
|
299
|
+
>>> end_lines = aligned_info['end_lines']
|
300
|
+
>>> aligned_info
|
291
301
|
{'aligned': [(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')], 'wrapped': [
|
292
|
-
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines':
|
293
|
-
>>>
|
302
|
+
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3], 'size': (18, 3)}
|
303
|
+
>>> aligned_info['wrapped'][start_lines[0] - 1]
|
294
304
|
'Lorem ipsum odor'
|
295
|
-
>>>
|
305
|
+
>>> aligned_info['wrapped'][end_lines[0] - 1]
|
296
306
|
'adipiscing elit.'
|
297
307
|
```
|
298
308
|
|
@@ -305,7 +315,7 @@ Returns a string with wrapped text formatted for monospace fonts.
|
|
305
315
|
|
306
316
|
For example:
|
307
317
|
```py
|
308
|
-
>>> s =
|
318
|
+
>>> s = txtwrap.fillstr(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
309
319
|
>>> s
|
310
320
|
'Lorem ipsum odor \namet, consectetuer\nadipiscing elit. '
|
311
321
|
>>> print(s)
|
@@ -322,7 +332,7 @@ if truncated.
|
|
322
332
|
|
323
333
|
For example:
|
324
334
|
```py
|
325
|
-
>>>
|
335
|
+
>>> txtwrap.shorten(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
326
336
|
'Lorem ipsum odor...'
|
327
337
|
```
|
328
338
|
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# TxTWrap🔡
|
2
2
|
A tool for wrapping and filling text.🔨
|
3
3
|
|
4
|
-
Package version: **3.0.
|
4
|
+
Package version: **3.0.1** <br>
|
5
5
|
Python requires version: **>=3.0.0** <br>
|
6
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
|
-
- [`SEPARATOR_WHITESPACE`](#separators)
|
12
|
-
- [`SEPARATOR_ESCAPE`](#separators)
|
13
|
-
- [`TextWrapper`](#textwrapper) (
|
11
|
+
- [`SEPARATOR_WHITESPACE`](#separators)
|
12
|
+
- [`SEPARATOR_ESCAPE`](#separators)
|
13
|
+
- [`TextWrapper`](#textwrapper) (🛠️ Fixed)
|
14
14
|
- [`sanitize`](#sanitizetext) (🛠️ Fixed)
|
15
|
-
- [`wrap`](#wraptext-return_detailsfalse) (
|
15
|
+
- [`wrap`](#wraptext-return_detailsfalse) (🛠️ Fixed)
|
16
16
|
- [`align`](#aligntext-return_detailsfalse) (🛠️ Fixed)
|
17
17
|
- [`fillstr`](#fillstrtext) (🛠️ Fixed)
|
18
18
|
- [`shorten`](#shortentext) (🛠️ Fixed)
|
@@ -28,6 +28,7 @@ filling _monospace fonts_ but also for other font types, such as _Arial_, _Times
|
|
28
28
|
<h1></h1>
|
29
29
|
|
30
30
|
## Constants
|
31
|
+
_File: **txtwrap.constants**_
|
31
32
|
|
32
33
|
### Lorem ipsum
|
33
34
|
```py
|
@@ -56,6 +57,8 @@ To use this, assign this constant to the [`separator`](#separator) parameter.
|
|
56
57
|
<h1></h1>
|
57
58
|
|
58
59
|
## `TextWrapper`
|
60
|
+
_File: **txtwrap.wrapper**_
|
61
|
+
|
59
62
|
```py
|
60
63
|
class TextWrapper:
|
61
64
|
|
@@ -164,7 +167,7 @@ enabling this attribute removes unnecessary empty space.
|
|
164
167
|
<h1></h1>
|
165
168
|
|
166
169
|
#### **`drop_separator`**
|
167
|
-
(Default: `False`) Removes
|
170
|
+
(Default: `False`) Removes excess separators from between words one at a time.
|
168
171
|
|
169
172
|
<h1></h1>
|
170
173
|
|
@@ -206,17 +209,17 @@ is equivalent to:
|
|
206
209
|
<h1></h1>
|
207
210
|
|
208
211
|
#### **`copy`**
|
209
|
-
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object.
|
212
|
+
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object. (External function using `copy.copy`)
|
210
213
|
|
211
214
|
<h1></h1>
|
212
215
|
|
213
216
|
#### **`sanitize(text)`**
|
214
217
|
Removes excessive characters from [`separator`](#separator) and replaces them with the [`fillchar`](#fillchar)
|
215
|
-
character.
|
218
|
+
character. (It doesn't matter whether [`drop_separator`](#drop_separator) is `False` or `True`)
|
216
219
|
|
217
220
|
For example:
|
218
221
|
```py
|
219
|
-
>>>
|
222
|
+
>>> txtwrap.sanitize("\tHello \nWorld!\r ")
|
220
223
|
'Hello World!'
|
221
224
|
```
|
222
225
|
|
@@ -225,20 +228,22 @@ For example:
|
|
225
228
|
#### **`wrap(text, return_details=False)`**
|
226
229
|
Returns a list of wrapped text strings. If `return_details=True`, returns a dictionary containing:
|
227
230
|
- `'wrapped'`: A list of wrapped text fragments.
|
228
|
-
- `'start_lines'`: A
|
229
|
-
- `'end_lines'`: A
|
231
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
232
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
230
233
|
|
231
234
|
For example:
|
232
235
|
```py
|
233
|
-
>>>
|
234
|
-
['Lorem ipsum', '
|
235
|
-
>>>
|
236
|
-
>>>
|
237
|
-
|
238
|
-
>>>
|
239
|
-
'Lorem ipsum'
|
240
|
-
>>>
|
241
|
-
'
|
236
|
+
>>> txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
237
|
+
['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.']
|
238
|
+
>>> wrapped_info = txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
239
|
+
>>> start_lines = wrapped_info['start_lines']
|
240
|
+
>>> end_lines = wrapped_info['end_lines']
|
241
|
+
>>> wrapped_info
|
242
|
+
{'wrapped': ['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3]}
|
243
|
+
>>> wrapped_info['wrapped'][start_lines[0] - 1]
|
244
|
+
'Lorem ipsum odor'
|
245
|
+
>>> wrapped_info['wrapped'][end_lines[0] - 1]
|
246
|
+
'adipiscing elit.'
|
242
247
|
```
|
243
248
|
|
244
249
|
<h1></h1>
|
@@ -251,21 +256,23 @@ with its coordinates.
|
|
251
256
|
If `return_details=True`, returns a dictionary containing:
|
252
257
|
- `'aligned'`: A list of wrapped text with coordinate data.
|
253
258
|
- `'wrapped'`: A list of wrapped text fragments.
|
254
|
-
- `'start_lines'`: A
|
255
|
-
- `'end_lines'`: A
|
259
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
260
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
256
261
|
- `'size'`: A calculated text size.
|
257
262
|
|
258
263
|
For example:
|
259
264
|
```py
|
260
|
-
>>>
|
265
|
+
>>> txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
261
266
|
[(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')]
|
262
|
-
>>>
|
263
|
-
>>>
|
267
|
+
>>> aligned_info = txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
268
|
+
>>> start_lines = aligned_info['start_lines']
|
269
|
+
>>> end_lines = aligned_info['end_lines']
|
270
|
+
>>> aligned_info
|
264
271
|
{'aligned': [(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')], 'wrapped': [
|
265
|
-
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines':
|
266
|
-
>>>
|
272
|
+
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3], 'size': (18, 3)}
|
273
|
+
>>> aligned_info['wrapped'][start_lines[0] - 1]
|
267
274
|
'Lorem ipsum odor'
|
268
|
-
>>>
|
275
|
+
>>> aligned_info['wrapped'][end_lines[0] - 1]
|
269
276
|
'adipiscing elit.'
|
270
277
|
```
|
271
278
|
|
@@ -278,7 +285,7 @@ Returns a string with wrapped text formatted for monospace fonts.
|
|
278
285
|
|
279
286
|
For example:
|
280
287
|
```py
|
281
|
-
>>> s =
|
288
|
+
>>> s = txtwrap.fillstr(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
282
289
|
>>> s
|
283
290
|
'Lorem ipsum odor \namet, consectetuer\nadipiscing elit. '
|
284
291
|
>>> print(s)
|
@@ -295,7 +302,7 @@ if truncated.
|
|
295
302
|
|
296
303
|
For example:
|
297
304
|
```py
|
298
|
-
>>>
|
305
|
+
>>> txtwrap.shorten(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
299
306
|
'Lorem ipsum odor...'
|
300
307
|
```
|
301
308
|
|
@@ -1,17 +1,21 @@
|
|
1
1
|
from setuptools import find_packages, setup
|
2
2
|
|
3
|
-
with open('README.md', encoding='utf-8') as
|
4
|
-
long_description =
|
3
|
+
with open('README.md', 'r', encoding='utf-8') as file:
|
4
|
+
long_description = file.read()
|
5
5
|
|
6
6
|
setup(
|
7
7
|
name='txtwrap',
|
8
|
-
version='3.0.
|
8
|
+
version='3.0.1',
|
9
9
|
description='A tool for wrapping and filling text.',
|
10
10
|
long_description=long_description,
|
11
11
|
long_description_content_type='text/markdown',
|
12
12
|
author='azzammuhyala',
|
13
13
|
author_email='azzammuhyala@gmail.com',
|
14
14
|
url='https://github.com/azzammuhyala/txtwrap',
|
15
|
+
project_urls={
|
16
|
+
'Source': 'https://github.com/azzammuhyala/txtwrap',
|
17
|
+
'Bug Tracker': 'https://github.com/azzammuhyala/txtwrap/issues'
|
18
|
+
},
|
15
19
|
license='MIT',
|
16
20
|
python_requires='>=3.0',
|
17
21
|
packages=find_packages(),
|
@@ -1,10 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# define the packages
|
2
2
|
|
3
3
|
from . import constants as constants
|
4
4
|
from . import identities as identities
|
5
5
|
from . import wrapper as wrapper
|
6
6
|
|
7
|
-
#
|
7
|
+
# define the main variables, functions, classes to be exported
|
8
8
|
|
9
9
|
from .constants import (
|
10
10
|
LOREM_IPSUM_WORDS as LOREM_IPSUM_WORDS,
|
@@ -28,7 +28,7 @@ def fillstr_right(justified_lines, text, width, text_width, fillchar):
|
|
28
28
|
justified_lines.append(fillchar * (width - text_width) + text)
|
29
29
|
|
30
30
|
hyphenate_parrent = r'''
|
31
|
-
(?<=-) #
|
32
|
-
(?=(?!-).) #
|
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
33
|
'''
|
34
34
|
split_hyphenated = re.compile(hyphenate_parrent, re.VERBOSE).split
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import copy
|
1
2
|
import re
|
2
3
|
|
3
4
|
from .constants import SEPARATOR_WHITESPACE
|
@@ -10,13 +11,8 @@ class TextWrapper:
|
|
10
11
|
__slots__ = ('_d',)
|
11
12
|
|
12
13
|
def __init__(self, width=70, line_padding=0, mode='word', alignment='left', placeholder='...', fillchar=' ',
|
13
|
-
separator=None, max_lines=None, preserve_empty_lines=True, minimum_width=True,
|
14
|
-
|
15
|
-
|
16
|
-
"""
|
17
|
-
See txtwrap module documentation on [GitHub](https://github.com/azzammuhyala/txtwrap) or on
|
18
|
-
[PyPi](https://pypi.org/project/txtwrap) for details.
|
19
|
-
"""
|
14
|
+
separator=None, max_lines=None, preserve_empty_lines=True, minimum_width=True, drop_separator=False,
|
15
|
+
justify_last_line=False, break_on_hyphens=True, sizefunc=None):
|
20
16
|
|
21
17
|
# dictionary to store a metadata and private variables
|
22
18
|
self._d = _utils.pdict()
|
@@ -31,19 +27,16 @@ class TextWrapper:
|
|
31
27
|
self.max_lines = max_lines
|
32
28
|
self.preserve_empty_lines = preserve_empty_lines
|
33
29
|
self.minimum_width = minimum_width
|
30
|
+
self.drop_separator = drop_separator
|
34
31
|
self.justify_last_line = justify_last_line
|
35
32
|
self.break_on_hyphens = break_on_hyphens
|
36
|
-
self.drop_separator = drop_separator
|
37
33
|
self.sizefunc = sizefunc
|
38
34
|
|
39
35
|
def __repr__(self):
|
40
36
|
return '{}({})'.format(
|
41
37
|
type(self).__name__,
|
42
38
|
', '.join(
|
43
|
-
'{}={!r}'.format(
|
44
|
-
name,
|
45
|
-
getattr(self, name, None) # if did't find the attribute, use the default None
|
46
|
-
)
|
39
|
+
'{}={!r}'.format(name, getattr(self, name, None))
|
47
40
|
for i, name in enumerate(self.__init__.__code__.co_varnames)
|
48
41
|
if i != 0 # skip self
|
49
42
|
)
|
@@ -57,10 +50,18 @@ class TextWrapper:
|
|
57
50
|
)
|
58
51
|
|
59
52
|
def __copy__(self):
|
60
|
-
return
|
53
|
+
return TextWrapper(**{
|
54
|
+
name: getattr(self, name)
|
55
|
+
for i, name in enumerate(self.__init__.__code__.co_varnames)
|
56
|
+
if i != 0 # skip self
|
57
|
+
})
|
61
58
|
|
62
|
-
def __deepcopy__(self, memo):
|
63
|
-
return
|
59
|
+
def __deepcopy__(self, memo=None):
|
60
|
+
return TextWrapper(**{
|
61
|
+
name: copy.deepcopy(getattr(self, name), memo)
|
62
|
+
for i, name in enumerate(self.__init__.__code__.co_varnames)
|
63
|
+
if i != 0 # skip self
|
64
|
+
})
|
64
65
|
|
65
66
|
@property
|
66
67
|
def width(self):
|
@@ -351,11 +352,7 @@ class TextWrapper:
|
|
351
352
|
return wrapped
|
352
353
|
|
353
354
|
def copy(self):
|
354
|
-
return
|
355
|
-
name: getattr(self, name)
|
356
|
-
for i, name in enumerate(self.__init__.__code__.co_varnames)
|
357
|
-
if i != 0 # skip self
|
358
|
-
})
|
355
|
+
return self.__copy__()
|
359
356
|
|
360
357
|
def sanitize(self, text):
|
361
358
|
if not isinstance(text, str):
|
@@ -385,32 +382,32 @@ class TextWrapper:
|
|
385
382
|
raise ValueError("width must be greater than length of the placeholder")
|
386
383
|
|
387
384
|
wrapped = []
|
388
|
-
start_lines =
|
389
|
-
end_lines =
|
385
|
+
start_lines = []
|
386
|
+
end_lines = []
|
390
387
|
|
391
388
|
for line in text.splitlines():
|
392
389
|
wrapped_line = wrapfunc(line)
|
393
390
|
|
394
391
|
if wrapped_line:
|
395
|
-
start_lines.
|
392
|
+
start_lines.append(len(wrapped) + 1) # add 1 line for next wrapped_line were added
|
396
393
|
wrapped.extend(wrapped_line)
|
397
394
|
|
398
395
|
nline = len(wrapped)
|
399
396
|
|
400
397
|
if has_max_lines and nline <= max_lines:
|
401
398
|
# only added if it has the max_lines attribute and the current line is no more than max_lines
|
402
|
-
end_lines.
|
399
|
+
end_lines.append(nline)
|
403
400
|
elif not has_max_lines:
|
404
401
|
# if not set
|
405
|
-
end_lines.
|
402
|
+
end_lines.append(nline)
|
406
403
|
|
407
404
|
elif preserve_empty_lines:
|
408
405
|
wrapped.append('') # adding an empty string (usually occurs when encountering an empty line)
|
409
406
|
|
410
407
|
nline = len(wrapped)
|
411
408
|
|
412
|
-
start_lines.
|
413
|
-
end_lines.
|
409
|
+
start_lines.append(nline)
|
410
|
+
end_lines.append(nline)
|
414
411
|
|
415
412
|
if has_max_lines and len(wrapped) > max_lines:
|
416
413
|
# cut off the excess part of the wrapper and also add a placeholder to indicate that the wrapper has
|
@@ -425,7 +422,7 @@ class TextWrapper:
|
|
425
422
|
wrapped[max_lines - 1] = current_part + placeholder
|
426
423
|
wrapped = wrapped[:max_lines]
|
427
424
|
|
428
|
-
end_lines.
|
425
|
+
end_lines.append(max_lines)
|
429
426
|
break
|
430
427
|
|
431
428
|
if return_details:
|
@@ -454,7 +451,7 @@ class TextWrapper:
|
|
454
451
|
wrapped_info = self.wrap(text, True)
|
455
452
|
|
456
453
|
wrapped = wrapped_info['wrapped']
|
457
|
-
end_lines = wrapped_info['end_lines']
|
454
|
+
end_lines = set(wrapped_info['end_lines'])
|
458
455
|
|
459
456
|
aligned = []
|
460
457
|
offset_y = 0
|
@@ -510,7 +507,7 @@ class TextWrapper:
|
|
510
507
|
'aligned': aligned,
|
511
508
|
'wrapped': wrapped,
|
512
509
|
'start_lines': wrapped_info['start_lines'],
|
513
|
-
'end_lines': end_lines,
|
510
|
+
'end_lines': wrapped_info['end_lines'],
|
514
511
|
'size': (use_width, offset_y - line_padding)
|
515
512
|
}
|
516
513
|
|
@@ -531,7 +528,7 @@ class TextWrapper:
|
|
531
528
|
wrapped_info = self.wrap(text, True)
|
532
529
|
|
533
530
|
wrapped = wrapped_info['wrapped']
|
534
|
-
end_lines = wrapped_info['end_lines']
|
531
|
+
end_lines = set(wrapped_info['end_lines'])
|
535
532
|
|
536
533
|
justified_lines = []
|
537
534
|
|
@@ -634,7 +631,8 @@ def fillstr(text, width=70, line_padding=0, mode='word', alignment='left', place
|
|
634
631
|
drop_separator=drop_separator, justify_last_line=justify_last_line,
|
635
632
|
break_on_hyphens=break_on_hyphens, sizefunc=sizefunc).fillstr(text)
|
636
633
|
|
637
|
-
def shorten(text, width=70, mode='word',
|
638
|
-
sizefunc=None):
|
639
|
-
return TextWrapper(width=width, mode=mode,
|
640
|
-
drop_separator=drop_separator,
|
634
|
+
def shorten(text, width=70, mode='word', placeholder='...', fillchar=' ', separator=None, drop_separator=True,
|
635
|
+
break_on_hyphens=True, sizefunc=None):
|
636
|
+
return TextWrapper(width=width, mode=mode, placeholder=placeholder, fillchar=fillchar, separator=separator,
|
637
|
+
drop_separator=drop_separator, break_on_hyphens=break_on_hyphens,
|
638
|
+
sizefunc=sizefunc).shorten(text)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import overload, Callable, Dict, Iterable, List, Optional,
|
1
|
+
from typing import overload, Callable, Dict, Iterable, List, Optional, Tuple, Union
|
2
2
|
try:
|
3
3
|
from typing import Literal
|
4
4
|
except ImportError:
|
@@ -28,7 +28,7 @@ class TextWrapper:
|
|
28
28
|
def __repr__(self) -> str: ...
|
29
29
|
def __str__(self) -> str: ...
|
30
30
|
def __copy__(self) -> 'TextWrapper': ...
|
31
|
-
def __deepcopy__(self, memo: Dict) -> 'TextWrapper': ...
|
31
|
+
def __deepcopy__(self, memo: Optional[Dict] = None) -> 'TextWrapper': ...
|
32
32
|
|
33
33
|
# Properties -------------------------------------------------------------------------------------------------------
|
34
34
|
|
@@ -110,7 +110,7 @@ class TextWrapper:
|
|
110
110
|
self,
|
111
111
|
text: str,
|
112
112
|
return_details: Literal[True] = True
|
113
|
-
) -> Dict[Literal['wrapped', 'start_lines', 'end_lines'], Union[List[str],
|
113
|
+
) -> Dict[Literal['wrapped', 'start_lines', 'end_lines'], Union[List[str], List[int]]]: ...
|
114
114
|
@overload
|
115
115
|
def align(
|
116
116
|
self,
|
@@ -123,10 +123,10 @@ class TextWrapper:
|
|
123
123
|
text: str,
|
124
124
|
return_details: Literal[True] = True
|
125
125
|
) -> Dict[Literal['aligned', 'wrapped', 'start_lines', 'end_lines', 'size'],
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
Union[List[Tuple[Union[int, float], Union[int, float], str]],
|
127
|
+
List[str],
|
128
|
+
List[int],
|
129
|
+
Tuple[Union[int, float], Union[int, float]]]]: ...
|
130
130
|
def fillstr(self, text: str) -> str: ...
|
131
131
|
def shorten(self, text: str) -> str: ...
|
132
132
|
|
@@ -168,7 +168,7 @@ def wrap(
|
|
168
168
|
break_on_hyphens: bool = True,
|
169
169
|
return_details: Literal[True] = True,
|
170
170
|
sizefunc: Optional[Callable[[str], Union[int, float]]] = None,
|
171
|
-
) -> Dict[Literal['wrapped', 'start_lines', 'end_lines'], Union[List[str],
|
171
|
+
) -> Dict[Literal['wrapped', 'start_lines', 'end_lines'], Union[List[str], List[int]]]: ...
|
172
172
|
|
173
173
|
@overload
|
174
174
|
def align(
|
@@ -209,10 +209,10 @@ def align(
|
|
209
209
|
return_details: Literal[True] = True,
|
210
210
|
sizefunc: Optional[Callable[[str], Tuple[Union[int, float], Union[int, float]]]] = None
|
211
211
|
) -> Dict[Literal['aligned', 'wrapped', 'start_lines', 'end_lines', 'size'],
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
212
|
+
Union[List[Tuple[Union[int, float], Union[int, float], str]],
|
213
|
+
List[str],
|
214
|
+
List[int],
|
215
|
+
Tuple[Union[int, float], Union[int, float]]]]: ...
|
216
216
|
|
217
217
|
def fillstr(
|
218
218
|
text: str,
|
@@ -240,5 +240,6 @@ def shorten(
|
|
240
240
|
fillchar: str = ' ',
|
241
241
|
separator: Optional[Union[str, Iterable[str]]] = None,
|
242
242
|
drop_separator: bool = True,
|
243
|
+
break_on_hyphens: bool = True,
|
243
244
|
sizefunc: Optional[Callable[[str], Union[int, float]]] = None
|
244
245
|
) -> str: ...
|
@@ -1,11 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: txtwrap
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.1
|
4
4
|
Summary: A tool for wrapping and filling text.
|
5
5
|
Home-page: https://github.com/azzammuhyala/txtwrap
|
6
6
|
Author: azzammuhyala
|
7
7
|
Author-email: azzammuhyala@gmail.com
|
8
8
|
License: MIT
|
9
|
+
Project-URL: Source, https://github.com/azzammuhyala/txtwrap
|
10
|
+
Project-URL: Bug Tracker, https://github.com/azzammuhyala/txtwrap/issues
|
9
11
|
Keywords: wrap,wrapper,wrapping,wrapped,text wrap,text wrapper,text wrapping,text wrapped
|
10
12
|
Classifier: Programming Language :: Python
|
11
13
|
Classifier: Programming Language :: Python :: 3
|
@@ -22,24 +24,25 @@ Dynamic: description-content-type
|
|
22
24
|
Dynamic: home-page
|
23
25
|
Dynamic: keywords
|
24
26
|
Dynamic: license
|
27
|
+
Dynamic: project-url
|
25
28
|
Dynamic: requires-python
|
26
29
|
Dynamic: summary
|
27
30
|
|
28
31
|
# TxTWrap🔡
|
29
32
|
A tool for wrapping and filling text.🔨
|
30
33
|
|
31
|
-
Package version: **3.0.
|
34
|
+
Package version: **3.0.1** <br>
|
32
35
|
Python requires version: **>=3.0.0** <br>
|
33
36
|
Python stub file requires version: **>=3.5.0** <br>
|
34
37
|
|
35
38
|
- [`LOREM_IPSUM_WORDS`](#lorem-ipsum)
|
36
39
|
- [`LOREM_IPSUM_SENTENCES`](#lorem-ipsum)
|
37
40
|
- [`LOREM_IPSUM_PARAGRAPHS`](#lorem-ipsum)
|
38
|
-
- [`SEPARATOR_WHITESPACE`](#separators)
|
39
|
-
- [`SEPARATOR_ESCAPE`](#separators)
|
40
|
-
- [`TextWrapper`](#textwrapper) (
|
41
|
+
- [`SEPARATOR_WHITESPACE`](#separators)
|
42
|
+
- [`SEPARATOR_ESCAPE`](#separators)
|
43
|
+
- [`TextWrapper`](#textwrapper) (🛠️ Fixed)
|
41
44
|
- [`sanitize`](#sanitizetext) (🛠️ Fixed)
|
42
|
-
- [`wrap`](#wraptext-return_detailsfalse) (
|
45
|
+
- [`wrap`](#wraptext-return_detailsfalse) (🛠️ Fixed)
|
43
46
|
- [`align`](#aligntext-return_detailsfalse) (🛠️ Fixed)
|
44
47
|
- [`fillstr`](#fillstrtext) (🛠️ Fixed)
|
45
48
|
- [`shorten`](#shortentext) (🛠️ Fixed)
|
@@ -55,6 +58,7 @@ filling _monospace fonts_ but also for other font types, such as _Arial_, _Times
|
|
55
58
|
<h1></h1>
|
56
59
|
|
57
60
|
## Constants
|
61
|
+
_File: **txtwrap.constants**_
|
58
62
|
|
59
63
|
### Lorem ipsum
|
60
64
|
```py
|
@@ -83,6 +87,8 @@ To use this, assign this constant to the [`separator`](#separator) parameter.
|
|
83
87
|
<h1></h1>
|
84
88
|
|
85
89
|
## `TextWrapper`
|
90
|
+
_File: **txtwrap.wrapper**_
|
91
|
+
|
86
92
|
```py
|
87
93
|
class TextWrapper:
|
88
94
|
|
@@ -191,7 +197,7 @@ enabling this attribute removes unnecessary empty space.
|
|
191
197
|
<h1></h1>
|
192
198
|
|
193
199
|
#### **`drop_separator`**
|
194
|
-
(Default: `False`) Removes
|
200
|
+
(Default: `False`) Removes excess separators from between words one at a time.
|
195
201
|
|
196
202
|
<h1></h1>
|
197
203
|
|
@@ -233,17 +239,17 @@ is equivalent to:
|
|
233
239
|
<h1></h1>
|
234
240
|
|
235
241
|
#### **`copy`**
|
236
|
-
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object.
|
242
|
+
Creates and returns a copy of the [`TextWrapper`](#textwrapper) object. (External function using `copy.copy`)
|
237
243
|
|
238
244
|
<h1></h1>
|
239
245
|
|
240
246
|
#### **`sanitize(text)`**
|
241
247
|
Removes excessive characters from [`separator`](#separator) and replaces them with the [`fillchar`](#fillchar)
|
242
|
-
character.
|
248
|
+
character. (It doesn't matter whether [`drop_separator`](#drop_separator) is `False` or `True`)
|
243
249
|
|
244
250
|
For example:
|
245
251
|
```py
|
246
|
-
>>>
|
252
|
+
>>> txtwrap.sanitize("\tHello \nWorld!\r ")
|
247
253
|
'Hello World!'
|
248
254
|
```
|
249
255
|
|
@@ -252,20 +258,22 @@ For example:
|
|
252
258
|
#### **`wrap(text, return_details=False)`**
|
253
259
|
Returns a list of wrapped text strings. If `return_details=True`, returns a dictionary containing:
|
254
260
|
- `'wrapped'`: A list of wrapped text fragments.
|
255
|
-
- `'start_lines'`: A
|
256
|
-
- `'end_lines'`: A
|
261
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
262
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
257
263
|
|
258
264
|
For example:
|
259
265
|
```py
|
260
|
-
>>>
|
261
|
-
['Lorem ipsum', '
|
262
|
-
>>>
|
263
|
-
>>>
|
264
|
-
|
265
|
-
>>>
|
266
|
-
'Lorem ipsum'
|
267
|
-
>>>
|
268
|
-
'
|
266
|
+
>>> txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
267
|
+
['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.']
|
268
|
+
>>> wrapped_info = txtwrap.wrap(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
269
|
+
>>> start_lines = wrapped_info['start_lines']
|
270
|
+
>>> end_lines = wrapped_info['end_lines']
|
271
|
+
>>> wrapped_info
|
272
|
+
{'wrapped': ['Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3]}
|
273
|
+
>>> wrapped_info['wrapped'][start_lines[0] - 1]
|
274
|
+
'Lorem ipsum odor'
|
275
|
+
>>> wrapped_info['wrapped'][end_lines[0] - 1]
|
276
|
+
'adipiscing elit.'
|
269
277
|
```
|
270
278
|
|
271
279
|
<h1></h1>
|
@@ -278,21 +286,23 @@ with its coordinates.
|
|
278
286
|
If `return_details=True`, returns a dictionary containing:
|
279
287
|
- `'aligned'`: A list of wrapped text with coordinate data.
|
280
288
|
- `'wrapped'`: A list of wrapped text fragments.
|
281
|
-
- `'start_lines'`: A
|
282
|
-
- `'end_lines'`: A
|
289
|
+
- `'start_lines'`: A list of indices marking the start of line.
|
290
|
+
- `'end_lines'`: A list of indices marking the end of line.
|
283
291
|
- `'size'`: A calculated text size.
|
284
292
|
|
285
293
|
For example:
|
286
294
|
```py
|
287
|
-
>>>
|
295
|
+
>>> txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
288
296
|
[(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')]
|
289
|
-
>>>
|
290
|
-
>>>
|
297
|
+
>>> aligned_info = txtwrap.align(txtwrap.LOREM_IPSUM_WORDS, width=20, return_details=True)
|
298
|
+
>>> start_lines = aligned_info['start_lines']
|
299
|
+
>>> end_lines = aligned_info['end_lines']
|
300
|
+
>>> aligned_info
|
291
301
|
{'aligned': [(0, 0, 'Lorem ipsum odor'), (0, 1, 'amet, consectetuer'), (0, 2, 'adipiscing elit.')], 'wrapped': [
|
292
|
-
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines':
|
293
|
-
>>>
|
302
|
+
'Lorem ipsum odor', 'amet, consectetuer', 'adipiscing elit.'], 'start_lines': [1], 'end_lines': [3], 'size': (18, 3)}
|
303
|
+
>>> aligned_info['wrapped'][start_lines[0] - 1]
|
294
304
|
'Lorem ipsum odor'
|
295
|
-
>>>
|
305
|
+
>>> aligned_info['wrapped'][end_lines[0] - 1]
|
296
306
|
'adipiscing elit.'
|
297
307
|
```
|
298
308
|
|
@@ -305,7 +315,7 @@ Returns a string with wrapped text formatted for monospace fonts.
|
|
305
315
|
|
306
316
|
For example:
|
307
317
|
```py
|
308
|
-
>>> s =
|
318
|
+
>>> s = txtwrap.fillstr(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
309
319
|
>>> s
|
310
320
|
'Lorem ipsum odor \namet, consectetuer\nadipiscing elit. '
|
311
321
|
>>> print(s)
|
@@ -322,7 +332,7 @@ if truncated.
|
|
322
332
|
|
323
333
|
For example:
|
324
334
|
```py
|
325
|
-
>>>
|
335
|
+
>>> txtwrap.shorten(txtwrap.LOREM_IPSUM_WORDS, width=20)
|
326
336
|
'Lorem ipsum odor...'
|
327
337
|
```
|
328
338
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|