txtwrap 1.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-1.0.0/MANIFEST.in +1 -0
- txtwrap-1.0.0/PKG-INFO +33 -0
- txtwrap-1.0.0/README.md +19 -0
- txtwrap-1.0.0/setup.cfg +4 -0
- txtwrap-1.0.0/setup.py +25 -0
- txtwrap-1.0.0/txtwrap/__init__.py +25 -0
- txtwrap-1.0.0/txtwrap/__main__.py +105 -0
- txtwrap-1.0.0/txtwrap/txtwrap.py +325 -0
- txtwrap-1.0.0/txtwrap.egg-info/PKG-INFO +33 -0
- txtwrap-1.0.0/txtwrap.egg-info/SOURCES.txt +10 -0
- txtwrap-1.0.0/txtwrap.egg-info/dependency_links.txt +1 -0
- txtwrap-1.0.0/txtwrap.egg-info/top_level.txt +1 -0
@@ -0,0 +1 @@
|
|
1
|
+
include README.md
|
txtwrap-1.0.0/PKG-INFO
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: txtwrap
|
3
|
+
Version: 1.0.0
|
4
|
+
Summary: A simple text wrapping tool.
|
5
|
+
Author: azzammuhyala
|
6
|
+
License: MIT
|
7
|
+
Keywords: wrap,wrapper,wrapping,wrapping tool,text wrap,text wrapper,simple wrap,align,aligner,aligning
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
10
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Requires-Python: >=3.8
|
13
|
+
Description-Content-Type: text/markdown
|
14
|
+
|
15
|
+
# TxTWrap 🔤
|
16
|
+
A tool for wrapping a text.🔨
|
17
|
+
|
18
|
+
> **⚠️All documents are in the each module.⚠️**
|
19
|
+
|
20
|
+
All constants and functionsâť•:
|
21
|
+
- `LOREM_IPSUM_W`
|
22
|
+
- `LOREM_IPSUM_S`
|
23
|
+
- `LOREM_IPSUM_P`
|
24
|
+
- `mono`
|
25
|
+
- `word`
|
26
|
+
- `wrap`
|
27
|
+
- `align`
|
28
|
+
- `shorten`
|
29
|
+
|
30
|
+
Mod `python -m txtwrap` Commandsâť—:
|
31
|
+
```shell
|
32
|
+
python -m txtwrap --help
|
33
|
+
```
|
txtwrap-1.0.0/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# TxTWrap 🔤
|
2
|
+
A tool for wrapping a text.🔨
|
3
|
+
|
4
|
+
> **⚠️All documents are in the each module.⚠️**
|
5
|
+
|
6
|
+
All constants and functionsâť•:
|
7
|
+
- `LOREM_IPSUM_W`
|
8
|
+
- `LOREM_IPSUM_S`
|
9
|
+
- `LOREM_IPSUM_P`
|
10
|
+
- `mono`
|
11
|
+
- `word`
|
12
|
+
- `wrap`
|
13
|
+
- `align`
|
14
|
+
- `shorten`
|
15
|
+
|
16
|
+
Mod `python -m txtwrap` Commandsâť—:
|
17
|
+
```shell
|
18
|
+
python -m txtwrap --help
|
19
|
+
```
|
txtwrap-1.0.0/setup.cfg
ADDED
txtwrap-1.0.0/setup.py
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
from setuptools import find_packages, setup
|
2
|
+
|
3
|
+
with open('README.md', encoding='utf-8') as readme:
|
4
|
+
long_description = readme.read()
|
5
|
+
|
6
|
+
setup(
|
7
|
+
name='txtwrap',
|
8
|
+
version='1.0.0',
|
9
|
+
description='A simple text wrapping tool.',
|
10
|
+
long_description=long_description,
|
11
|
+
long_description_content_type='text/markdown',
|
12
|
+
author='azzammuhyala',
|
13
|
+
license='MIT',
|
14
|
+
python_requires='>=3.8',
|
15
|
+
packages=find_packages(),
|
16
|
+
include_package_data=True,
|
17
|
+
keywords=['wrap', 'wrapper', 'wrapping', 'wrapping tool', 'text wrap', 'text wrapper',
|
18
|
+
'simple wrap', 'align', 'aligner', 'aligning'],
|
19
|
+
classifiers=[
|
20
|
+
'Programming Language :: Python :: 3',
|
21
|
+
'Programming Language :: Python :: 3.8',
|
22
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
23
|
+
'License :: OSI Approved :: MIT License',
|
24
|
+
]
|
25
|
+
)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"""
|
2
|
+
A simple text wrapping tool
|
3
|
+
"""
|
4
|
+
|
5
|
+
# Supports only in Python 3.8+
|
6
|
+
|
7
|
+
from .txtwrap import (
|
8
|
+
LOREM_IPSUM_W, LOREM_IPSUM_S, LOREM_IPSUM_P,
|
9
|
+
mono, word, wrap, align,
|
10
|
+
shorten
|
11
|
+
)
|
12
|
+
|
13
|
+
__version__ = '1.0.0'
|
14
|
+
__license__ = 'MIT'
|
15
|
+
__author__ = 'Azzam Muhyala'
|
16
|
+
__all__ = [
|
17
|
+
'LOREM_IPSUM_W',
|
18
|
+
'LOREM_IPSUM_S',
|
19
|
+
'LOREM_IPSUM_P',
|
20
|
+
'mono',
|
21
|
+
'word',
|
22
|
+
'wrap',
|
23
|
+
'align',
|
24
|
+
'shorten'
|
25
|
+
]
|
@@ -0,0 +1,105 @@
|
|
1
|
+
from argparse import ArgumentParser
|
2
|
+
from os import get_terminal_size
|
3
|
+
from txtwrap import wrap, shorten
|
4
|
+
|
5
|
+
parser = ArgumentParser(
|
6
|
+
description='Command-line tool for wrapping, aligning, or shortening text.'
|
7
|
+
)
|
8
|
+
|
9
|
+
parser.add_argument(
|
10
|
+
'text',
|
11
|
+
type=str,
|
12
|
+
help='Text to be wrapped, aligned, or shorted'
|
13
|
+
)
|
14
|
+
|
15
|
+
try:
|
16
|
+
width = get_terminal_size()[0]
|
17
|
+
except:
|
18
|
+
width = 70
|
19
|
+
|
20
|
+
parser.add_argument(
|
21
|
+
'-w', '--width',
|
22
|
+
type=int,
|
23
|
+
default=width,
|
24
|
+
metavar='<number>',
|
25
|
+
help='Width of the text wrapping (default: current width terminal or 70)'
|
26
|
+
)
|
27
|
+
|
28
|
+
parser.add_argument(
|
29
|
+
'-m', '--method',
|
30
|
+
type=str,
|
31
|
+
choices={'word', 'mono', 'shorten'},
|
32
|
+
default='word',
|
33
|
+
metavar='{word|mono|shorten}',
|
34
|
+
help='Method to be applied to the text (default: word)'
|
35
|
+
)
|
36
|
+
|
37
|
+
parser.add_argument(
|
38
|
+
'-a', '--alignment',
|
39
|
+
type=str,
|
40
|
+
choices={'left', 'center', 'right', 'fill'},
|
41
|
+
default='left',
|
42
|
+
metavar='{left|center|right|fill}',
|
43
|
+
help='Alignment of the text (default: left)'
|
44
|
+
)
|
45
|
+
|
46
|
+
parser.add_argument(
|
47
|
+
'-ne', '--neglect-empty',
|
48
|
+
action='store_false',
|
49
|
+
help='Neglect empty lines in the text'
|
50
|
+
)
|
51
|
+
|
52
|
+
parser.add_argument(
|
53
|
+
'-s', '--start',
|
54
|
+
type=int,
|
55
|
+
default=0,
|
56
|
+
metavar='<number>',
|
57
|
+
help='start index of the text to be shorten (default: 0)'
|
58
|
+
)
|
59
|
+
|
60
|
+
parser.add_argument(
|
61
|
+
'-ph', '--placeholder',
|
62
|
+
type=str,
|
63
|
+
default='...',
|
64
|
+
metavar='<str>',
|
65
|
+
help='Placeholder to be used when shortening the text (default: ...)'
|
66
|
+
)
|
67
|
+
|
68
|
+
args = parser.parse_args()
|
69
|
+
|
70
|
+
if args.method == 'shorten':
|
71
|
+
print(shorten(args.text, args.width, args.start, placeholder=args.placeholder))
|
72
|
+
else:
|
73
|
+
wrapped = wrap(args.text, args.width, method=args.method, preserve_empty=args.neglect_empty)
|
74
|
+
|
75
|
+
if args.alignment == 'left':
|
76
|
+
print('\n'.join(wrapped))
|
77
|
+
elif args.alignment == 'center':
|
78
|
+
print('\n'.join(line.center(args.width) for line in wrapped))
|
79
|
+
elif args.alignment == 'right':
|
80
|
+
print('\n'.join(line.rjust(args.width) for line in wrapped))
|
81
|
+
elif args.alignment == 'fill':
|
82
|
+
justified_lines = ''
|
83
|
+
|
84
|
+
for line in wrapped:
|
85
|
+
words = line.split()
|
86
|
+
total_words = len(words)
|
87
|
+
total_words_width = sum(len(w) for w in words)
|
88
|
+
extra_space = args.width - total_words_width
|
89
|
+
|
90
|
+
if total_words > 1:
|
91
|
+
space_between_words = extra_space // (total_words - 1)
|
92
|
+
extra_padding = extra_space % (total_words - 1)
|
93
|
+
else:
|
94
|
+
space_between_words = extra_space
|
95
|
+
extra_padding = 0
|
96
|
+
|
97
|
+
justified_line = ''
|
98
|
+
for i, word in enumerate(words):
|
99
|
+
justified_line += word
|
100
|
+
if i < total_words - 1:
|
101
|
+
justified_line += ' ' * (space_between_words + (1 if i < extra_padding else 0))
|
102
|
+
|
103
|
+
justified_lines += justified_line + '\n'
|
104
|
+
|
105
|
+
print(justified_lines, end='')
|
@@ -0,0 +1,325 @@
|
|
1
|
+
from typing import Callable, List, Literal, Tuple, Union
|
2
|
+
from re import compile
|
3
|
+
|
4
|
+
hyphenated_regex = compile(r'(?<=-)(?=(?!-).)')
|
5
|
+
|
6
|
+
LOREM_IPSUM_W = 'Lorem ipsum odor amet, consectetuer adipiscing elit.'
|
7
|
+
LOREM_IPSUM_S = ('Lorem ipsum odor amet, consectetuer adipiscing elit. In malesuada eros natoque '
|
8
|
+
'urna felis diam aptent donec. Cubilia libero morbi fusce tempus, luctus aenean '
|
9
|
+
'augue. Mus senectus rutrum phasellus fusce dictum platea. Eros a integer nec '
|
10
|
+
'fusce erat urna.')
|
11
|
+
LOREM_IPSUM_P = ('Lorem ipsum odor amet, consectetuer adipiscing elit. Nulla porta ex condimentum '
|
12
|
+
'velit facilisi; consequat congue. Tristique duis sociosqu aliquam semper sit id. '
|
13
|
+
'Nisi morbi purus, nascetur elit pellentesque venenatis. Velit commodo molestie '
|
14
|
+
'potenti placerat faucibus convallis. Himenaeos dapibus ipsum natoque nam dapibus '
|
15
|
+
'habitasse diam. Viverra ac porttitor cras tempor cras. Pharetra habitant nibh '
|
16
|
+
'dui ipsum scelerisque cras? Efficitur phasellus etiam congue taciti tortor quam. '
|
17
|
+
'Volutpat quam vulputate condimentum hendrerit justo congue iaculis nisl nullam.'
|
18
|
+
'\n\nInceptos tempus nostra fringilla arcu; tellus blandit facilisi risus. Platea '
|
19
|
+
'bibendum tristique lectus nunc placerat id aliquam. Eu arcu nisl mattis potenti '
|
20
|
+
'elementum. Dignissim vivamus montes volutpat litora felis fusce ultrices. '
|
21
|
+
'Vulputate magna nascetur bibendum inceptos scelerisque morbi posuere. Consequat '
|
22
|
+
'dolor netus augue augue tristique curabitur habitasse bibendum. Consectetur est '
|
23
|
+
'per eros semper, magnis interdum libero. Arcu adipiscing litora metus fringilla '
|
24
|
+
'varius gravida congue tellus adipiscing. Blandit nulla mauris nullam ante metus '
|
25
|
+
'curae scelerisque.\n\nSem varius sodales ut volutpat imperdiet turpis primis '
|
26
|
+
'nullam. At gravida tincidunt phasellus lacus duis integer eros penatibus. '
|
27
|
+
'Interdum mauris molestie posuere nascetur dignissim himenaeos; magna et quisque. '
|
28
|
+
'Dignissim malesuada etiam donec vehicula aliquet bibendum. Magna dapibus sapien '
|
29
|
+
'semper parturient id dis? Pretium orci ante leo, porta tincidunt molestie. '
|
30
|
+
'Malesuada dictumst commodo consequat interdum nisi fusce cras rhoncus feugiat.'
|
31
|
+
'\n\nHimenaeos mattis commodo suspendisse maecenas cras arcu. Habitasse id '
|
32
|
+
'facilisi praesent justo molestie felis luctus suspendisse. Imperdiet ipsum '
|
33
|
+
'praesent nunc mauris mattis curabitur. Et consectetur morbi auctor feugiat enim '
|
34
|
+
'ridiculus arcu. Ultricies magna blandit eget; vivamus sollicitudin nisl proin. '
|
35
|
+
'Sollicitudin sociosqu et finibus elit vestibulum sapien nec odio euismod. Turpis '
|
36
|
+
'eleifend amet quis auctor cursus. Vehicula pharetra sapien praesent amet purus '
|
37
|
+
'ante. Risus blandit cubilia lorem hendrerit penatibus in magnis.\n\nAmet posuere '
|
38
|
+
'nunc; maecenas consequat risus potenti. Volutpat leo lacinia sapien nulla '
|
39
|
+
'sagittis dignissim mauris ultrices aliquet. Nisi pretium interdum luctus donec '
|
40
|
+
'magna suscipit. Dapibus tristique felis natoque malesuada augue? Justo faucibus '
|
41
|
+
'tincidunt congue arcu sem; fusce aliquet proin. Commodo neque nibh; tempus ad '
|
42
|
+
'tortor netus. Mattis ultricies nec maximus porttitor non mauris?')
|
43
|
+
|
44
|
+
def mono(
|
45
|
+
|
46
|
+
text: str,
|
47
|
+
width: Union[int, float] = 70,
|
48
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
49
|
+
|
50
|
+
) -> List[str]:
|
51
|
+
|
52
|
+
"""
|
53
|
+
Wraps the given text into lines of specified width.
|
54
|
+
|
55
|
+
Parameters:
|
56
|
+
text (str): The text to be wrapped.
|
57
|
+
width (int | float, optional): The maximum width of each line. Defaults to 70.
|
58
|
+
lenfunc (Callable[[str], int | float], optional): A function to calculate
|
59
|
+
the length of a string. Defaults to len.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
list[str]: A list of strings, where each string is a line of the wrapped text.
|
63
|
+
"""
|
64
|
+
|
65
|
+
assert isinstance(text, str), "text must be a string"
|
66
|
+
assert isinstance(width, (int, float)), "width must be an integer or float"
|
67
|
+
assert callable(lenfunc), "lenfunc must be a callable function"
|
68
|
+
|
69
|
+
assert width > 0, "width must be greater than 0"
|
70
|
+
|
71
|
+
parts = []
|
72
|
+
current_char = ''
|
73
|
+
|
74
|
+
for char in text:
|
75
|
+
if lenfunc(current_char + char) <= width:
|
76
|
+
current_char += char
|
77
|
+
else:
|
78
|
+
parts.append(current_char)
|
79
|
+
current_char = char
|
80
|
+
|
81
|
+
if current_char:
|
82
|
+
parts.append(current_char)
|
83
|
+
|
84
|
+
return parts
|
85
|
+
|
86
|
+
def word(
|
87
|
+
|
88
|
+
text: str,
|
89
|
+
width: Union[int, float] = 70,
|
90
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
91
|
+
|
92
|
+
) -> List[str]:
|
93
|
+
|
94
|
+
"""
|
95
|
+
Wraps the input text into lines of specified width.
|
96
|
+
|
97
|
+
Parameters:
|
98
|
+
text (str): The input text to be wrapped.
|
99
|
+
width (int | float, optional): The maximum width of each line. Defaults to 70.
|
100
|
+
lenfunc (Callable[[str], int | float], optional): A function to calculate
|
101
|
+
the length of a string. Defaults to len.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
list[str]: A list of strings, where each string is a line of wrapped text.
|
105
|
+
"""
|
106
|
+
|
107
|
+
assert isinstance(text, str), "text must be a string"
|
108
|
+
assert isinstance(width, (int, float)), "width must be an integer or float"
|
109
|
+
assert callable(lenfunc), "lenfunc must be a callable function"
|
110
|
+
|
111
|
+
assert width > 0, "width must be greater than 0"
|
112
|
+
|
113
|
+
lines = []
|
114
|
+
current_line = ''
|
115
|
+
|
116
|
+
for word in text.split():
|
117
|
+
test_line = current_line + ' ' + word if current_line else word
|
118
|
+
|
119
|
+
if lenfunc(test_line) <= width:
|
120
|
+
current_line = test_line
|
121
|
+
else:
|
122
|
+
if current_line:
|
123
|
+
lines.append(current_line)
|
124
|
+
|
125
|
+
current_line = ''
|
126
|
+
|
127
|
+
for part in hyphenated_regex.split(word):
|
128
|
+
for wrapped_part in mono(part, width, lenfunc):
|
129
|
+
if lenfunc(current_line + wrapped_part) <= width:
|
130
|
+
current_line += wrapped_part
|
131
|
+
else:
|
132
|
+
if current_line:
|
133
|
+
lines.append(current_line)
|
134
|
+
current_line = wrapped_part
|
135
|
+
|
136
|
+
if current_line:
|
137
|
+
lines.append(current_line)
|
138
|
+
|
139
|
+
return lines
|
140
|
+
|
141
|
+
def wrap(
|
142
|
+
|
143
|
+
text: str,
|
144
|
+
width: Union[int, float] = 70,
|
145
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
146
|
+
method: Literal['mono', 'word'] = 'word',
|
147
|
+
preserve_empty: bool = True
|
148
|
+
|
149
|
+
) -> List[str]:
|
150
|
+
|
151
|
+
"""
|
152
|
+
Wraps the given text into lines of specified width.
|
153
|
+
|
154
|
+
Parameters:
|
155
|
+
text (str): The text to be wrapped.
|
156
|
+
width (int | float, optional): The maximum width of each line. Defaults to 70.
|
157
|
+
lenfunc (Callable[[str], int | float], optional): A function to calculate
|
158
|
+
the length of a string. Defaults to len.
|
159
|
+
method (Literal['mono', 'word'], optional): The method to use for wrapping.
|
160
|
+
'mono' for character-based wrapping, 'word'
|
161
|
+
for word-based wrapping. Defaults to 'word'.
|
162
|
+
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
list[str]: A list of wrapped lines.
|
166
|
+
"""
|
167
|
+
|
168
|
+
assert isinstance(text, str), "text must be a string"
|
169
|
+
assert isinstance(width, (int, float)), "width must be an integer or float"
|
170
|
+
assert callable(lenfunc), "lenfunc must be a callable function"
|
171
|
+
|
172
|
+
assert width > 0, "width must be greater than 0"
|
173
|
+
|
174
|
+
wrapped_lines = []
|
175
|
+
|
176
|
+
if method == 'mono':
|
177
|
+
wrapfunc = mono
|
178
|
+
elif method == 'word':
|
179
|
+
wrapfunc = word
|
180
|
+
else:
|
181
|
+
raise ValueError(f"{method=} is invalid, must be 'mono' or 'word'")
|
182
|
+
|
183
|
+
for line in text.splitlines():
|
184
|
+
wrapped_line = wrapfunc(line, width, lenfunc)
|
185
|
+
if wrapped_line:
|
186
|
+
wrapped_lines.extend(wrapped_line)
|
187
|
+
elif preserve_empty:
|
188
|
+
wrapped_lines.append('')
|
189
|
+
|
190
|
+
return wrapped_lines
|
191
|
+
|
192
|
+
def align(
|
193
|
+
|
194
|
+
text: str,
|
195
|
+
width: Union[int, float] = 70,
|
196
|
+
linegap: Union[int, float] = 0,
|
197
|
+
sizefunc: Callable[[str], Tuple[Union[int, float], Union[int, float]]] = lambda s : (len(s), 1),
|
198
|
+
method: Literal['mono', 'word'] = 'word',
|
199
|
+
alignment: Literal['left', 'center', 'right', 'fill'] = 'left',
|
200
|
+
preserve_empty: bool = True
|
201
|
+
|
202
|
+
) -> List[Tuple[Union[int, float], Union[int, float], str]]:
|
203
|
+
|
204
|
+
"""
|
205
|
+
Wraps and aligns text within a specified width and yields the position and content of each line.
|
206
|
+
|
207
|
+
Parameters:
|
208
|
+
text (str): The text to be wrapped and aligned.
|
209
|
+
width (int | float, optional): The maximum width of each line. Defaults to 70.
|
210
|
+
linegap (int | float, optional): The vertical gap between lines. Defaults to 0.
|
211
|
+
sizefunc (Callable[[str], tuple[int | float, int | float]], optional): A function that
|
212
|
+
returns the width and
|
213
|
+
height of a given
|
214
|
+
string. Defaults to a
|
215
|
+
lambda function that
|
216
|
+
returns the length of
|
217
|
+
the string and 1.
|
218
|
+
method (Literal['mono', 'word'], optional): The method to use for wrapping.
|
219
|
+
'mono' for character-based wrapping, 'word'
|
220
|
+
for word-based wrapping. Defaults to 'word'.
|
221
|
+
alignment (Literal['left', 'center', 'right', 'fill'], optional): The alignment of the text.
|
222
|
+
'left', 'center', 'right',
|
223
|
+
or 'fill'.
|
224
|
+
Defaults to 'left'.
|
225
|
+
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
226
|
+
|
227
|
+
Returns:
|
228
|
+
list[tuple[int | float, int | float, str]]: A list of tuples containing the position and
|
229
|
+
content of each line.
|
230
|
+
"""
|
231
|
+
|
232
|
+
assert isinstance(linegap, (int, float)), "linegap must be an integer or float"
|
233
|
+
assert callable(sizefunc), "sizefunc must be a callable function"
|
234
|
+
|
235
|
+
assert linegap >= 0, "linegap must be equal to or greater than 0"
|
236
|
+
|
237
|
+
wrapped = []
|
238
|
+
offset_y = 0
|
239
|
+
|
240
|
+
for line in wrap(text, width, lambda s : sizefunc(s)[0], method, preserve_empty):
|
241
|
+
|
242
|
+
width_line, height_line = sizefunc(line)
|
243
|
+
|
244
|
+
if alignment == 'left':
|
245
|
+
wrapped.append((0, offset_y, line))
|
246
|
+
|
247
|
+
elif alignment == 'center':
|
248
|
+
wrapped.append(((width - width_line) / 2, offset_y, line))
|
249
|
+
|
250
|
+
elif alignment == 'right':
|
251
|
+
wrapped.append((width - width_line, offset_y, line))
|
252
|
+
|
253
|
+
elif alignment == 'fill':
|
254
|
+
offset_x = 0
|
255
|
+
words = line.split()
|
256
|
+
total_words = len(words)
|
257
|
+
widths = {i: sizefunc(w)[0] for i, w in enumerate(words)}
|
258
|
+
total_words_width = sum(widths.values())
|
259
|
+
extra_space = width - total_words_width
|
260
|
+
|
261
|
+
if total_words > 1:
|
262
|
+
space_between_words = extra_space / (total_words - 1)
|
263
|
+
else:
|
264
|
+
space_between_words = extra_space
|
265
|
+
|
266
|
+
for i, w in enumerate(words):
|
267
|
+
wrapped.append((offset_x, offset_y, w))
|
268
|
+
offset_x += widths[i] + space_between_words
|
269
|
+
|
270
|
+
else:
|
271
|
+
raise ValueError(
|
272
|
+
f"{alignment=} is invalid, must be 'left', 'center', 'right', or 'fill'"
|
273
|
+
)
|
274
|
+
|
275
|
+
offset_y += height_line + linegap
|
276
|
+
|
277
|
+
return wrapped
|
278
|
+
|
279
|
+
def shorten(
|
280
|
+
|
281
|
+
text: str,
|
282
|
+
width: Union[int, float] = 70,
|
283
|
+
start: int = 0,
|
284
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
285
|
+
placeholder: str = '...'
|
286
|
+
|
287
|
+
) -> str:
|
288
|
+
|
289
|
+
"""
|
290
|
+
Shortens the given text to fit within the specified width, optionally including a placeholder.
|
291
|
+
|
292
|
+
Parameters:
|
293
|
+
text (str): The text to be shortened.
|
294
|
+
width (int | float, optional): The maximum width of the shortened text. Defaults to 70.
|
295
|
+
start (int, optional): The starting index of the text to be shortened. Defaults to 0.
|
296
|
+
lenfunc (Callable[[str], int | float], optional): A function to calculate
|
297
|
+
the length of a string. Defaults to len.
|
298
|
+
placeholder (str, optional): The placeholder to append to the shortened text.
|
299
|
+
Defaults to '...'.
|
300
|
+
|
301
|
+
Returns:
|
302
|
+
str: The shortened text with the placeholder appended if necessary.
|
303
|
+
"""
|
304
|
+
|
305
|
+
assert isinstance(text, str), "text must be a string"
|
306
|
+
assert isinstance(width, (int, float)), "width must be an integer or float"
|
307
|
+
assert isinstance(start, int), "start must be an integer"
|
308
|
+
assert callable(lenfunc), "lenfunc must be a callable function"
|
309
|
+
assert isinstance(placeholder, str), "placeholder must be a string"
|
310
|
+
|
311
|
+
assert width >= lenfunc(placeholder), "width must be greater than length of the placeholder"
|
312
|
+
assert start >= 0, "start must be equal to or greater than 0"
|
313
|
+
|
314
|
+
if start == 0:
|
315
|
+
current_char = ''
|
316
|
+
else:
|
317
|
+
current_char = placeholder
|
318
|
+
|
319
|
+
for char in text[start:]:
|
320
|
+
if lenfunc(current_char + char + placeholder) <= width:
|
321
|
+
current_char += char
|
322
|
+
else:
|
323
|
+
return current_char + placeholder
|
324
|
+
|
325
|
+
return current_char
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: txtwrap
|
3
|
+
Version: 1.0.0
|
4
|
+
Summary: A simple text wrapping tool.
|
5
|
+
Author: azzammuhyala
|
6
|
+
License: MIT
|
7
|
+
Keywords: wrap,wrapper,wrapping,wrapping tool,text wrap,text wrapper,simple wrap,align,aligner,aligning
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
10
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Requires-Python: >=3.8
|
13
|
+
Description-Content-Type: text/markdown
|
14
|
+
|
15
|
+
# TxTWrap 🔤
|
16
|
+
A tool for wrapping a text.🔨
|
17
|
+
|
18
|
+
> **⚠️All documents are in the each module.⚠️**
|
19
|
+
|
20
|
+
All constants and functionsâť•:
|
21
|
+
- `LOREM_IPSUM_W`
|
22
|
+
- `LOREM_IPSUM_S`
|
23
|
+
- `LOREM_IPSUM_P`
|
24
|
+
- `mono`
|
25
|
+
- `word`
|
26
|
+
- `wrap`
|
27
|
+
- `align`
|
28
|
+
- `shorten`
|
29
|
+
|
30
|
+
Mod `python -m txtwrap` Commandsâť—:
|
31
|
+
```shell
|
32
|
+
python -m txtwrap --help
|
33
|
+
```
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
txtwrap
|