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.
@@ -1,11 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: txtwrap
3
- Version: 3.0.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.0** <br>
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) (➕ New)
39
- - [`SEPARATOR_ESCAPE`](#separators) (➕ New)
40
- - [`TextWrapper`](#textwrapper) ( Updated)
41
+ - [`SEPARATOR_WHITESPACE`](#separators)
42
+ - [`SEPARATOR_ESCAPE`](#separators)
43
+ - [`TextWrapper`](#textwrapper) (🛠️ Fixed)
41
44
  - [`sanitize`](#sanitizetext) (🛠️ Fixed)
42
- - [`wrap`](#wraptext-return_detailsfalse) ( Updated)
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 the separator between more than one word at a time.
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
- >>> TextWrapper().sanitize("\tHello \nWorld!\r ")
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 set of indices marking the start of line.
256
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS)
261
- ['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.']
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.'
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 set of indices marking the start of line.
282
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS)
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
- >>> info = TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
290
- >>> info
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': {1}, 'end_lines': {3}, 'size': (18, 3)}
293
- >>> info['wrapped'][next(iter(info['start_lines'])) - 1]
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
- >>> info['wrapped'][next(iter(info['end_lines'])) - 1]
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 = TextWrapper(width=20).fillstr(LOREM_IPSUM_WORDS)
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
- >>> TextWrapper(width=20).shorten(LOREM_IPSUM_WORDS)
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.0** <br>
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) (➕ New)
12
- - [`SEPARATOR_ESCAPE`](#separators) (➕ New)
13
- - [`TextWrapper`](#textwrapper) ( Updated)
11
+ - [`SEPARATOR_WHITESPACE`](#separators)
12
+ - [`SEPARATOR_ESCAPE`](#separators)
13
+ - [`TextWrapper`](#textwrapper) (🛠️ Fixed)
14
14
  - [`sanitize`](#sanitizetext) (🛠️ Fixed)
15
- - [`wrap`](#wraptext-return_detailsfalse) ( Updated)
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 the separator between more than one word at a time.
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
- >>> TextWrapper().sanitize("\tHello \nWorld!\r ")
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 set of indices marking the start of line.
229
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS)
234
- ['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.']
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.'
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 set of indices marking the start of line.
255
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS)
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
- >>> info = TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
263
- >>> info
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': {1}, 'end_lines': {3}, 'size': (18, 3)}
266
- >>> info['wrapped'][next(iter(info['start_lines'])) - 1]
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
- >>> info['wrapped'][next(iter(info['end_lines'])) - 1]
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 = TextWrapper(width=20).fillstr(LOREM_IPSUM_WORDS)
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
- >>> TextWrapper(width=20).shorten(LOREM_IPSUM_WORDS)
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 readme:
4
- long_description = readme.read()
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.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,5 +1,8 @@
1
1
  """
2
2
  A tool for wrapping and filling text.
3
+
4
+ See txtwrap module documentation on [GitHub](https://github.com/azzammuhyala/txtwrap) or on
5
+ [PyPi](https://pypi.org/project/txtwrap) for details.
3
6
  """
4
7
 
5
8
  # Supports only in Python>=3.0.0
@@ -1,10 +1,10 @@
1
- # Define the packages
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
- # Define the main variables, functions, classes to be exported
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
- (?<=-) # 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
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
@@ -0,0 +1,3 @@
1
+ __version__ = '3.0.1'
2
+ __author__ = 'azzammuhyala'
3
+ __license__ = 'MIT'
@@ -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, justify_last_line=False,
14
- break_on_hyphens=True, drop_separator=False, sizefunc=None):
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 self.copy()
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 self.copy()
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 TextWrapper(**{
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 = set()
389
- end_lines = set()
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.add(len(wrapped) + 1) # add 1 line for next wrapped_line were added
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.add(nline)
399
+ end_lines.append(nline)
403
400
  elif not has_max_lines:
404
401
  # if not set
405
- end_lines.add(nline)
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.add(nline)
413
- end_lines.add(nline)
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.add(max_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', fillchar=' ', placeholder='...', separator=None, drop_separator=True,
638
- sizefunc=None):
639
- return TextWrapper(width=width, mode=mode, fillchar=fillchar, placeholder=placeholder, separator=separator,
640
- drop_separator=drop_separator, sizefunc=sizefunc).shorten(text)
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, Set, Tuple, Union
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], Set[int]]]: ...
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
- Union[List[Tuple[Union[int, float], Union[int, float], str]],
127
- List[str],
128
- Set[int],
129
- Tuple[Union[int, float], Union[int, float]]]]: ...
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], Set[int]]]: ...
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
- Union[List[Tuple[Union[int, float], Union[int, float], str]],
213
- List[str],
214
- Set[int],
215
- Tuple[Union[int, float], Union[int, float]]]]: ...
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.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.0** <br>
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) (➕ New)
39
- - [`SEPARATOR_ESCAPE`](#separators) (➕ New)
40
- - [`TextWrapper`](#textwrapper) ( Updated)
41
+ - [`SEPARATOR_WHITESPACE`](#separators)
42
+ - [`SEPARATOR_ESCAPE`](#separators)
43
+ - [`TextWrapper`](#textwrapper) (🛠️ Fixed)
41
44
  - [`sanitize`](#sanitizetext) (🛠️ Fixed)
42
- - [`wrap`](#wraptext-return_detailsfalse) ( Updated)
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 the separator between more than one word at a time.
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
- >>> TextWrapper().sanitize("\tHello \nWorld!\r ")
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 set of indices marking the start of line.
256
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=15).wrap(LOREM_IPSUM_WORDS)
261
- ['Lorem ipsum', 'odor amet,', 'consectetuer', 'adipiscing', 'elit.']
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.'
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 set of indices marking the start of line.
282
- - `'end_lines'`: A set of indices marking the end of line.
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
- >>> TextWrapper(width=20).align(LOREM_IPSUM_WORDS)
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
- >>> info = TextWrapper(width=20).align(LOREM_IPSUM_WORDS, return_details=True)
290
- >>> info
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': {1}, 'end_lines': {3}, 'size': (18, 3)}
293
- >>> info['wrapped'][next(iter(info['start_lines'])) - 1]
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
- >>> info['wrapped'][next(iter(info['end_lines'])) - 1]
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 = TextWrapper(width=20).fillstr(LOREM_IPSUM_WORDS)
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
- >>> TextWrapper(width=20).shorten(LOREM_IPSUM_WORDS)
335
+ >>> txtwrap.shorten(txtwrap.LOREM_IPSUM_WORDS, width=20)
326
336
  'Lorem ipsum odor...'
327
337
  ```
328
338
 
@@ -1,3 +0,0 @@
1
- __version__ = '3.0.0'
2
- __author__ = 'azzammuhyala'
3
- __license__ = 'MIT'
File without changes
File without changes
File without changes
File without changes
File without changes