txtwrap 1.0.0__tar.gz → 1.1.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-1.1.1/PKG-INFO +164 -0
- txtwrap-1.1.1/README.md +150 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/setup.py +3 -3
- {txtwrap-1.0.0 → txtwrap-1.1.1}/txtwrap/__init__.py +6 -3
- txtwrap-1.1.1/txtwrap/__main__.py +111 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/txtwrap/txtwrap.py +235 -30
- txtwrap-1.1.1/txtwrap.egg-info/PKG-INFO +164 -0
- txtwrap-1.0.0/PKG-INFO +0 -33
- txtwrap-1.0.0/README.md +0 -19
- txtwrap-1.0.0/txtwrap/__main__.py +0 -105
- txtwrap-1.0.0/txtwrap.egg-info/PKG-INFO +0 -33
- {txtwrap-1.0.0 → txtwrap-1.1.1}/MANIFEST.in +0 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/setup.cfg +0 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/txtwrap.egg-info/SOURCES.txt +0 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/txtwrap.egg-info/dependency_links.txt +0 -0
- {txtwrap-1.0.0 → txtwrap-1.1.1}/txtwrap.egg-info/top_level.txt +0 -0
txtwrap-1.1.1/PKG-INFO
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: txtwrap
|
3
|
+
Version: 1.1.1
|
4
|
+
Summary: A simple text wrapping tool.
|
5
|
+
Author: azzammuhyala
|
6
|
+
License: MIT
|
7
|
+
Keywords: wrap,wrapper,wrapping,wrapped,wrapping tool,text wrap,text wrapper,simple wrap,align,aligner,aligning,aligned
|
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` (Updated!)
|
28
|
+
- `fillstr`
|
29
|
+
- `printwrap`
|
30
|
+
- `shorten`
|
31
|
+
|
32
|
+
Mod `python -m txtwrap` Commands❗:
|
33
|
+
```shell
|
34
|
+
python -m txtwrap --help
|
35
|
+
```
|
36
|
+
|
37
|
+
Examples❓:
|
38
|
+
## Render a wrap text in PyGame🎮
|
39
|
+
```py
|
40
|
+
from typing import Literal, Optional
|
41
|
+
from txtwrap import align, LOREM_IPSUM_P
|
42
|
+
import pygame
|
43
|
+
|
44
|
+
def render_wrap(
|
45
|
+
|
46
|
+
font: pygame.Font,
|
47
|
+
text: str,
|
48
|
+
width: int,
|
49
|
+
antialias: bool,
|
50
|
+
color: pygame.Color,
|
51
|
+
background: Optional[pygame.Color] = None,
|
52
|
+
linegap: int = 0,
|
53
|
+
alignment: Literal['left', 'center', 'right', 'fill'] = 'left',
|
54
|
+
method: Literal['word', 'mono'] = 'word',
|
55
|
+
preserve_empty: bool = True,
|
56
|
+
use_min_width: bool = True
|
57
|
+
|
58
|
+
) -> pygame.Surface:
|
59
|
+
|
60
|
+
# Only supports in txtwrap 1.1.1+
|
61
|
+
align_info = align(
|
62
|
+
text=text,
|
63
|
+
width=width,
|
64
|
+
linegap=linegap,
|
65
|
+
sizefunc=font.size,
|
66
|
+
method=method,
|
67
|
+
alignment=alignment,
|
68
|
+
preserve_empty=preserve_empty,
|
69
|
+
use_min_width=use_min_width,
|
70
|
+
return_details=True
|
71
|
+
)
|
72
|
+
|
73
|
+
surface = pygame.Surface(align_info['size'], pygame.SRCALPHA)
|
74
|
+
|
75
|
+
if background is not None:
|
76
|
+
surface.fill(background)
|
77
|
+
|
78
|
+
for x, y, text in align_info['aligned']:
|
79
|
+
surface.blit(font.render(text, antialias, color), (x, y))
|
80
|
+
|
81
|
+
return surface
|
82
|
+
|
83
|
+
# Example usage:
|
84
|
+
pygame.init()
|
85
|
+
pygame.display.set_caption("Lorem Ipsum")
|
86
|
+
|
87
|
+
running = True
|
88
|
+
wscrn, hscrn = 600, 600
|
89
|
+
screen = pygame.display.set_mode((wscrn, hscrn))
|
90
|
+
clock = pygame.time.Clock()
|
91
|
+
surface = render_wrap(
|
92
|
+
font=pygame.font.Font(None, 20),
|
93
|
+
text=LOREM_IPSUM_P,
|
94
|
+
width=wscrn,
|
95
|
+
antialias=True,
|
96
|
+
color='#ffffff',
|
97
|
+
background='#303030',
|
98
|
+
alignment='fill'
|
99
|
+
)
|
100
|
+
|
101
|
+
wsurf, hsurf = surface.get_size()
|
102
|
+
pos = ((wscrn - wsurf) / 2, (hscrn - hsurf) / 2)
|
103
|
+
|
104
|
+
while running:
|
105
|
+
for event in pygame.event.get():
|
106
|
+
if event.type == pygame.QUIT:
|
107
|
+
running = False
|
108
|
+
screen.fill('#000000')
|
109
|
+
screen.blit(surface, pos)
|
110
|
+
pygame.display.flip()
|
111
|
+
clock.tick(60)
|
112
|
+
```
|
113
|
+
|
114
|
+
## Print a wrap text to terminal🔡
|
115
|
+
```py
|
116
|
+
# Only supports in txtwrap 1.1.0+
|
117
|
+
from txtwrap import printwrap, LOREM_IPSUM_W
|
118
|
+
|
119
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='left')
|
120
|
+
print('=' * 20)
|
121
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='center')
|
122
|
+
print('=' * 20)
|
123
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='right')
|
124
|
+
print('=' * 20)
|
125
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='fill')
|
126
|
+
```
|
127
|
+
|
128
|
+
## Short a long text🔤
|
129
|
+
```py
|
130
|
+
from txtwrap import shorten, LOREM_IPSUM_S
|
131
|
+
|
132
|
+
short_lorem = shorten(LOREM_IPSUM_S, width=20, placeholder='…')
|
133
|
+
# Only supports in txtwrap 1.1.0+
|
134
|
+
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
135
|
+
|
136
|
+
print(short_lorem)
|
137
|
+
print(test)
|
138
|
+
```
|
139
|
+
|
140
|
+
## Bonus🎁 - Print a colorfull text to terminal🔥
|
141
|
+
```py
|
142
|
+
# Run this code in a terminal that supports ansi characters
|
143
|
+
|
144
|
+
from re import compile
|
145
|
+
from random import randint
|
146
|
+
from txtwrap import printwrap, LOREM_IPSUM_P
|
147
|
+
|
148
|
+
# Set the text to be printed here
|
149
|
+
text = LOREM_IPSUM_P
|
150
|
+
|
151
|
+
remove_ansi_regex = compile(r'\x1b\[[0-9;]*[mK]').sub
|
152
|
+
|
153
|
+
def ralen(s: str) -> int:
|
154
|
+
return len(remove_ansi_regex('', s))
|
155
|
+
|
156
|
+
while True:
|
157
|
+
# Only supports in txtwrap 1.1.0+
|
158
|
+
printwrap(
|
159
|
+
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
160
|
+
end='\x1b[H\x1b[J',
|
161
|
+
alignment='fill',
|
162
|
+
lenfunc=ralen
|
163
|
+
)
|
164
|
+
```
|
txtwrap-1.1.1/README.md
ADDED
@@ -0,0 +1,150 @@
|
|
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` (Updated!)
|
14
|
+
- `fillstr`
|
15
|
+
- `printwrap`
|
16
|
+
- `shorten`
|
17
|
+
|
18
|
+
Mod `python -m txtwrap` Commands❗:
|
19
|
+
```shell
|
20
|
+
python -m txtwrap --help
|
21
|
+
```
|
22
|
+
|
23
|
+
Examples❓:
|
24
|
+
## Render a wrap text in PyGame🎮
|
25
|
+
```py
|
26
|
+
from typing import Literal, Optional
|
27
|
+
from txtwrap import align, LOREM_IPSUM_P
|
28
|
+
import pygame
|
29
|
+
|
30
|
+
def render_wrap(
|
31
|
+
|
32
|
+
font: pygame.Font,
|
33
|
+
text: str,
|
34
|
+
width: int,
|
35
|
+
antialias: bool,
|
36
|
+
color: pygame.Color,
|
37
|
+
background: Optional[pygame.Color] = None,
|
38
|
+
linegap: int = 0,
|
39
|
+
alignment: Literal['left', 'center', 'right', 'fill'] = 'left',
|
40
|
+
method: Literal['word', 'mono'] = 'word',
|
41
|
+
preserve_empty: bool = True,
|
42
|
+
use_min_width: bool = True
|
43
|
+
|
44
|
+
) -> pygame.Surface:
|
45
|
+
|
46
|
+
# Only supports in txtwrap 1.1.1+
|
47
|
+
align_info = align(
|
48
|
+
text=text,
|
49
|
+
width=width,
|
50
|
+
linegap=linegap,
|
51
|
+
sizefunc=font.size,
|
52
|
+
method=method,
|
53
|
+
alignment=alignment,
|
54
|
+
preserve_empty=preserve_empty,
|
55
|
+
use_min_width=use_min_width,
|
56
|
+
return_details=True
|
57
|
+
)
|
58
|
+
|
59
|
+
surface = pygame.Surface(align_info['size'], pygame.SRCALPHA)
|
60
|
+
|
61
|
+
if background is not None:
|
62
|
+
surface.fill(background)
|
63
|
+
|
64
|
+
for x, y, text in align_info['aligned']:
|
65
|
+
surface.blit(font.render(text, antialias, color), (x, y))
|
66
|
+
|
67
|
+
return surface
|
68
|
+
|
69
|
+
# Example usage:
|
70
|
+
pygame.init()
|
71
|
+
pygame.display.set_caption("Lorem Ipsum")
|
72
|
+
|
73
|
+
running = True
|
74
|
+
wscrn, hscrn = 600, 600
|
75
|
+
screen = pygame.display.set_mode((wscrn, hscrn))
|
76
|
+
clock = pygame.time.Clock()
|
77
|
+
surface = render_wrap(
|
78
|
+
font=pygame.font.Font(None, 20),
|
79
|
+
text=LOREM_IPSUM_P,
|
80
|
+
width=wscrn,
|
81
|
+
antialias=True,
|
82
|
+
color='#ffffff',
|
83
|
+
background='#303030',
|
84
|
+
alignment='fill'
|
85
|
+
)
|
86
|
+
|
87
|
+
wsurf, hsurf = surface.get_size()
|
88
|
+
pos = ((wscrn - wsurf) / 2, (hscrn - hsurf) / 2)
|
89
|
+
|
90
|
+
while running:
|
91
|
+
for event in pygame.event.get():
|
92
|
+
if event.type == pygame.QUIT:
|
93
|
+
running = False
|
94
|
+
screen.fill('#000000')
|
95
|
+
screen.blit(surface, pos)
|
96
|
+
pygame.display.flip()
|
97
|
+
clock.tick(60)
|
98
|
+
```
|
99
|
+
|
100
|
+
## Print a wrap text to terminal🔡
|
101
|
+
```py
|
102
|
+
# Only supports in txtwrap 1.1.0+
|
103
|
+
from txtwrap import printwrap, LOREM_IPSUM_W
|
104
|
+
|
105
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='left')
|
106
|
+
print('=' * 20)
|
107
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='center')
|
108
|
+
print('=' * 20)
|
109
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='right')
|
110
|
+
print('=' * 20)
|
111
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='fill')
|
112
|
+
```
|
113
|
+
|
114
|
+
## Short a long text🔤
|
115
|
+
```py
|
116
|
+
from txtwrap import shorten, LOREM_IPSUM_S
|
117
|
+
|
118
|
+
short_lorem = shorten(LOREM_IPSUM_S, width=20, placeholder='…')
|
119
|
+
# Only supports in txtwrap 1.1.0+
|
120
|
+
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
121
|
+
|
122
|
+
print(short_lorem)
|
123
|
+
print(test)
|
124
|
+
```
|
125
|
+
|
126
|
+
## Bonus🎁 - Print a colorfull text to terminal🔥
|
127
|
+
```py
|
128
|
+
# Run this code in a terminal that supports ansi characters
|
129
|
+
|
130
|
+
from re import compile
|
131
|
+
from random import randint
|
132
|
+
from txtwrap import printwrap, LOREM_IPSUM_P
|
133
|
+
|
134
|
+
# Set the text to be printed here
|
135
|
+
text = LOREM_IPSUM_P
|
136
|
+
|
137
|
+
remove_ansi_regex = compile(r'\x1b\[[0-9;]*[mK]').sub
|
138
|
+
|
139
|
+
def ralen(s: str) -> int:
|
140
|
+
return len(remove_ansi_regex('', s))
|
141
|
+
|
142
|
+
while True:
|
143
|
+
# Only supports in txtwrap 1.1.0+
|
144
|
+
printwrap(
|
145
|
+
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
146
|
+
end='\x1b[H\x1b[J',
|
147
|
+
alignment='fill',
|
148
|
+
lenfunc=ralen
|
149
|
+
)
|
150
|
+
```
|
@@ -5,7 +5,7 @@ with open('README.md', encoding='utf-8') as readme:
|
|
5
5
|
|
6
6
|
setup(
|
7
7
|
name='txtwrap',
|
8
|
-
version='1.
|
8
|
+
version='1.1.1',
|
9
9
|
description='A simple text wrapping tool.',
|
10
10
|
long_description=long_description,
|
11
11
|
long_description_content_type='text/markdown',
|
@@ -14,8 +14,8 @@ setup(
|
|
14
14
|
python_requires='>=3.8',
|
15
15
|
packages=find_packages(),
|
16
16
|
include_package_data=True,
|
17
|
-
keywords=['wrap', 'wrapper', 'wrapping', '
|
18
|
-
'simple wrap', 'align', 'aligner', 'aligning'],
|
17
|
+
keywords=['wrap', 'wrapper', 'wrapping', 'wrapped', 'wrapping tool', 'text wrap',
|
18
|
+
'text wrapper', 'simple wrap', 'align', 'aligner', 'aligning', 'aligned'],
|
19
19
|
classifiers=[
|
20
20
|
'Programming Language :: Python :: 3',
|
21
21
|
'Programming Language :: Python :: 3.8',
|
@@ -5,14 +5,15 @@ A simple text wrapping tool
|
|
5
5
|
# Supports only in Python 3.8+
|
6
6
|
|
7
7
|
from .txtwrap import (
|
8
|
+
version,
|
8
9
|
LOREM_IPSUM_W, LOREM_IPSUM_S, LOREM_IPSUM_P,
|
9
|
-
mono, word, wrap, align,
|
10
|
+
mono, word, wrap, align, fillstr, printwrap,
|
10
11
|
shorten
|
11
12
|
)
|
12
13
|
|
13
|
-
__version__ =
|
14
|
+
__version__ = version
|
15
|
+
__author__ = 'azzammuhyala'
|
14
16
|
__license__ = 'MIT'
|
15
|
-
__author__ = 'Azzam Muhyala'
|
16
17
|
__all__ = [
|
17
18
|
'LOREM_IPSUM_W',
|
18
19
|
'LOREM_IPSUM_S',
|
@@ -21,5 +22,7 @@ __all__ = [
|
|
21
22
|
'word',
|
22
23
|
'wrap',
|
23
24
|
'align',
|
25
|
+
'fillstr',
|
26
|
+
'printwrap',
|
24
27
|
'shorten'
|
25
28
|
]
|
@@ -0,0 +1,111 @@
|
|
1
|
+
from argparse import ArgumentParser
|
2
|
+
from txtwrap import version, printwrap, shorten
|
3
|
+
|
4
|
+
parser = ArgumentParser(
|
5
|
+
description='Command-line tool for wrapping, aligning, or shortening text.'
|
6
|
+
)
|
7
|
+
|
8
|
+
parser.add_argument(
|
9
|
+
'text',
|
10
|
+
type=str,
|
11
|
+
help='Text to be wrapped, aligned, or shorted'
|
12
|
+
)
|
13
|
+
|
14
|
+
parser.add_argument(
|
15
|
+
'-v', '--version',
|
16
|
+
action='version',
|
17
|
+
version=version,
|
18
|
+
help='Show the version of the txtwrap'
|
19
|
+
)
|
20
|
+
|
21
|
+
parser.add_argument(
|
22
|
+
'-f', '--fill',
|
23
|
+
type=str,
|
24
|
+
default=' ',
|
25
|
+
metavar='<str (1 character)>',
|
26
|
+
help='Fill character (default: " ")'
|
27
|
+
)
|
28
|
+
|
29
|
+
parser.add_argument(
|
30
|
+
'-w', '--width',
|
31
|
+
type=int,
|
32
|
+
default=None,
|
33
|
+
metavar='<int>',
|
34
|
+
help='Width of the text wrapping (default: current width terminal or 70)'
|
35
|
+
)
|
36
|
+
|
37
|
+
parser.add_argument(
|
38
|
+
'-m', '--method',
|
39
|
+
type=str,
|
40
|
+
choices={'word', 'mono', 'shorten'},
|
41
|
+
default='word',
|
42
|
+
metavar='{word|mono|shorten}',
|
43
|
+
help='Method to be applied to the text (default: "word")'
|
44
|
+
)
|
45
|
+
|
46
|
+
parser.add_argument(
|
47
|
+
'-a', '--alignment',
|
48
|
+
type=str,
|
49
|
+
choices={'left', 'center', 'right', 'fill'},
|
50
|
+
default='left',
|
51
|
+
metavar='{left|center|right|fill}',
|
52
|
+
help='Alignment of the text (default: "left")'
|
53
|
+
)
|
54
|
+
|
55
|
+
parser.add_argument(
|
56
|
+
'-n', '--neglect-empty',
|
57
|
+
action='store_false',
|
58
|
+
help='Neglect empty lines in the text'
|
59
|
+
)
|
60
|
+
|
61
|
+
parser.add_argument(
|
62
|
+
'-s', '--start',
|
63
|
+
type=int,
|
64
|
+
default=0,
|
65
|
+
metavar='<int>',
|
66
|
+
help='start index of the text to be shorten (default: 0)'
|
67
|
+
)
|
68
|
+
|
69
|
+
parser.add_argument(
|
70
|
+
'-p', '--placeholder',
|
71
|
+
type=str,
|
72
|
+
default='...',
|
73
|
+
metavar='<str>',
|
74
|
+
help='Placeholder to be used when shortening the text (default: "...")'
|
75
|
+
)
|
76
|
+
|
77
|
+
parser.add_argument(
|
78
|
+
'-r', '--no-strip',
|
79
|
+
action='store_false',
|
80
|
+
help='Do not strip the space in the text'
|
81
|
+
)
|
82
|
+
|
83
|
+
args = parser.parse_args()
|
84
|
+
|
85
|
+
if args.method == 'shorten':
|
86
|
+
from os import get_terminal_size
|
87
|
+
|
88
|
+
if args.width is None:
|
89
|
+
try:
|
90
|
+
args.width = get_terminal_size().columns
|
91
|
+
except:
|
92
|
+
args.width = 70
|
93
|
+
|
94
|
+
print(
|
95
|
+
shorten(
|
96
|
+
text=args.text,
|
97
|
+
width=args.width,
|
98
|
+
start=args.start,
|
99
|
+
placeholder=args.placeholder,
|
100
|
+
strip_space=args.no_strip
|
101
|
+
)
|
102
|
+
)
|
103
|
+
else:
|
104
|
+
printwrap(
|
105
|
+
args.text,
|
106
|
+
fill=args.fill,
|
107
|
+
width=args.width,
|
108
|
+
method=args.method,
|
109
|
+
alignment=args.alignment,
|
110
|
+
preserve_empty=args.neglect_empty
|
111
|
+
)
|
@@ -1,7 +1,9 @@
|
|
1
|
-
from typing import Callable, List, Literal, Tuple, Union
|
1
|
+
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union
|
2
|
+
from os import get_terminal_size
|
2
3
|
from re import compile
|
3
4
|
|
4
5
|
hyphenated_regex = compile(r'(?<=-)(?=(?!-).)')
|
6
|
+
version = '1.1.1'
|
5
7
|
|
6
8
|
LOREM_IPSUM_W = 'Lorem ipsum odor amet, consectetuer adipiscing elit.'
|
7
9
|
LOREM_IPSUM_S = ('Lorem ipsum odor amet, consectetuer adipiscing elit. In malesuada eros natoque '
|
@@ -197,9 +199,12 @@ def align(
|
|
197
199
|
sizefunc: Callable[[str], Tuple[Union[int, float], Union[int, float]]] = lambda s : (len(s), 1),
|
198
200
|
method: Literal['mono', 'word'] = 'word',
|
199
201
|
alignment: Literal['left', 'center', 'right', 'fill'] = 'left',
|
200
|
-
preserve_empty: bool = True
|
202
|
+
preserve_empty: bool = True,
|
203
|
+
use_min_width: bool = True,
|
204
|
+
return_details: bool = False
|
201
205
|
|
202
|
-
) -> List[Tuple[Union[int, float], Union[int, float], str]
|
206
|
+
) -> List[Union[Tuple[Union[int, float], Union[int, float], str],
|
207
|
+
Dict[Literal['aligned', 'wrapped', 'size'], Any]]]:
|
203
208
|
|
204
209
|
"""
|
205
210
|
Wraps and aligns text within a specified width and yields the position and content of each line.
|
@@ -223,10 +228,19 @@ def align(
|
|
223
228
|
or 'fill'.
|
224
229
|
Defaults to 'left'.
|
225
230
|
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
231
|
+
use_min_width (bool, optional): Whether to use the manimum width of the wrapped text.
|
232
|
+
Defaults to True.
|
233
|
+
return_details (bool, optional): Whether to return the aligned text, wrapped text, and
|
234
|
+
the size.
|
235
|
+
Defaults to False.
|
226
236
|
|
227
237
|
Returns:
|
228
|
-
list[tuple[int | float, int | float, str]
|
229
|
-
|
238
|
+
list[tuple[int | float, int | float, str] |
|
239
|
+
dict[Literal['aligned', 'wrapped', 'size'], Any]]: A list of tuples containing the
|
240
|
+
position and content of each line.
|
241
|
+
If return_details, a dictionary
|
242
|
+
containing the wrapped text, and
|
243
|
+
the size is returned.
|
230
244
|
"""
|
231
245
|
|
232
246
|
assert isinstance(linegap, (int, float)), "linegap must be an integer or float"
|
@@ -234,47 +248,228 @@ def align(
|
|
234
248
|
|
235
249
|
assert linegap >= 0, "linegap must be equal to or greater than 0"
|
236
250
|
|
237
|
-
wrapped = []
|
251
|
+
wrapped = wrap(text, width, lambda s : sizefunc(s)[0], method, preserve_empty)
|
252
|
+
size_wrapped = {i: sizefunc(line) for i, line in enumerate(wrapped)}
|
253
|
+
aligned_positions = []
|
238
254
|
offset_y = 0
|
239
255
|
|
240
|
-
|
256
|
+
if use_min_width:
|
257
|
+
max_width = max(size[0] for size in size_wrapped.values())
|
258
|
+
use_width = max_width
|
259
|
+
else:
|
260
|
+
use_width = width
|
261
|
+
|
262
|
+
if alignment == 'left':
|
263
|
+
for i, line in enumerate(wrapped):
|
264
|
+
height_line = size_wrapped[i][1]
|
265
|
+
aligned_positions.append((0, offset_y, line))
|
266
|
+
offset_y += height_line + linegap
|
267
|
+
|
268
|
+
elif alignment == 'center':
|
269
|
+
for i, line in enumerate(wrapped):
|
270
|
+
width_line, height_line = size_wrapped[i]
|
271
|
+
aligned_positions.append(((use_width - width_line) / 2, offset_y, line))
|
272
|
+
offset_y += height_line + linegap
|
273
|
+
|
274
|
+
elif alignment == 'right':
|
275
|
+
for i, line in enumerate(wrapped):
|
276
|
+
width_line, height_line = size_wrapped[i]
|
277
|
+
aligned_positions.append((use_width - width_line, offset_y, line))
|
278
|
+
offset_y += height_line + linegap
|
279
|
+
|
280
|
+
elif alignment == 'fill':
|
281
|
+
no_spaces = True
|
282
|
+
for i, line in enumerate(wrapped):
|
283
|
+
height_line = size_wrapped[i][1]
|
284
|
+
words = line.split()
|
285
|
+
total_words = len(words)
|
286
|
+
word_widths = {i: sizefunc(w)[0] for i, w in enumerate(words)}
|
287
|
+
extra_space = width - sum(word_widths.values())
|
288
|
+
offset_x = 0
|
241
289
|
|
242
|
-
|
290
|
+
if total_words > 1:
|
291
|
+
space_between_words = extra_space / (total_words - 1)
|
292
|
+
no_spaces = False
|
293
|
+
else:
|
294
|
+
space_between_words = extra_space
|
243
295
|
|
244
|
-
|
245
|
-
|
296
|
+
for i, w in enumerate(words):
|
297
|
+
aligned_positions.append((offset_x, offset_y, w))
|
298
|
+
offset_x += word_widths[i] + space_between_words
|
246
299
|
|
247
|
-
|
248
|
-
wrapped.append(((width - width_line) / 2, offset_y, line))
|
300
|
+
offset_y += height_line + linegap
|
249
301
|
|
250
|
-
|
251
|
-
|
302
|
+
else:
|
303
|
+
raise ValueError(f"{alignment=} is invalid, must be 'left', 'center', 'right', or 'fill'")
|
304
|
+
|
305
|
+
if return_details:
|
306
|
+
if use_min_width and alignment == 'fill':
|
307
|
+
if no_spaces:
|
308
|
+
size_width = max_width
|
309
|
+
elif text:
|
310
|
+
size_width = width
|
311
|
+
else:
|
312
|
+
size_width = 0
|
313
|
+
else:
|
314
|
+
size_width = use_width
|
252
315
|
|
253
|
-
|
254
|
-
|
316
|
+
return {
|
317
|
+
'aligned': aligned_positions,
|
318
|
+
'wrapped': wrapped,
|
319
|
+
'size': (size_width, offset_y - linegap)
|
320
|
+
}
|
321
|
+
|
322
|
+
return aligned_positions
|
323
|
+
|
324
|
+
def fillstr(
|
325
|
+
|
326
|
+
text: str,
|
327
|
+
width: Union[int, float] = 70,
|
328
|
+
fill: str = ' ',
|
329
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
330
|
+
method: Literal['mono', 'word'] = 'word',
|
331
|
+
alignment: Union[Callable[[str], str], Literal['left', 'center', 'right', 'fill']] = 'left',
|
332
|
+
preserve_empty: bool = True
|
333
|
+
|
334
|
+
) -> str:
|
335
|
+
|
336
|
+
"""
|
337
|
+
String formats a given text to fit within a specified width, using various alignment methods.
|
338
|
+
|
339
|
+
Parameters:
|
340
|
+
text (str): The text to be formatted.
|
341
|
+
width (Union[int, float], optional): The width of the formatted text. Defaults to 70.
|
342
|
+
fill (str, optional): The character used to fill the space. Must be a single character.
|
343
|
+
Defaults to ' '.
|
344
|
+
lenfunc (Callable[[str], Union[int, float]], optional): A function to calculate the
|
345
|
+
length of a string. Defaults to len.
|
346
|
+
method (Literal['mono', 'word'], optional): The method to use for wrapping.
|
347
|
+
'mono' for character-based wrapping, 'word'
|
348
|
+
for word-based wrapping. Defaults to 'word'.
|
349
|
+
alignment (Union[Callable[[str], str],
|
350
|
+
Literal['left', 'center', 'right', 'fill']], optional): The alignment of the
|
351
|
+
text. 'left', 'center',
|
352
|
+
'right', or 'fill'.
|
353
|
+
Defaults to 'left'.
|
354
|
+
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
355
|
+
|
356
|
+
Returns:
|
357
|
+
str: The formatted text.
|
358
|
+
"""
|
359
|
+
|
360
|
+
assert isinstance(fill, str), "fill must be a string"
|
361
|
+
assert len(fill) == 1, "fill must be a single character"
|
362
|
+
|
363
|
+
wrapped = wrap(text, width, lenfunc, method, preserve_empty)
|
364
|
+
justified_lines = ''
|
365
|
+
|
366
|
+
if callable(alignment):
|
367
|
+
return '\n'.join(alignment(line) for line in wrapped)
|
368
|
+
|
369
|
+
elif alignment == 'left':
|
370
|
+
for line in wrapped:
|
371
|
+
justified_lines += line + fill * (width - lenfunc(line)) + '\n'
|
372
|
+
|
373
|
+
elif alignment == 'center':
|
374
|
+
for line in wrapped:
|
375
|
+
extra_space = width - lenfunc(line)
|
376
|
+
left_space = extra_space // 2
|
377
|
+
justified_lines += fill * left_space + line + fill * (extra_space - left_space) + '\n'
|
378
|
+
|
379
|
+
elif alignment == 'right':
|
380
|
+
for line in wrapped:
|
381
|
+
justified_lines += fill * (width - lenfunc(line)) + line + '\n'
|
382
|
+
|
383
|
+
elif alignment == 'fill':
|
384
|
+
for line in wrapped:
|
255
385
|
words = line.split()
|
256
386
|
total_words = len(words)
|
257
|
-
|
258
|
-
total_words_width = sum(widths.values())
|
387
|
+
total_words_width = sum(lenfunc(w) for w in words)
|
259
388
|
extra_space = width - total_words_width
|
260
389
|
|
261
390
|
if total_words > 1:
|
262
|
-
space_between_words = extra_space
|
391
|
+
space_between_words = extra_space // (total_words - 1)
|
392
|
+
extra_padding = extra_space % (total_words - 1)
|
263
393
|
else:
|
264
394
|
space_between_words = extra_space
|
395
|
+
extra_padding = 0
|
265
396
|
|
266
|
-
|
267
|
-
|
268
|
-
|
397
|
+
justified_line = ''
|
398
|
+
for i, word in enumerate(words):
|
399
|
+
justified_line += word
|
400
|
+
if i < total_words - 1:
|
401
|
+
justified_line += fill * (space_between_words + (1 if i < extra_padding else 0))
|
269
402
|
|
270
|
-
|
271
|
-
raise ValueError(
|
272
|
-
f"{alignment=} is invalid, must be 'left', 'center', 'right', or 'fill'"
|
273
|
-
)
|
403
|
+
justified_lines += justified_line + '\n'
|
274
404
|
|
275
|
-
|
405
|
+
else:
|
406
|
+
raise ValueError(
|
407
|
+
f"{alignment=} is invalid, must be 'left', 'center', 'right', 'fill' or "
|
408
|
+
'a callable function'
|
409
|
+
)
|
410
|
+
|
411
|
+
return justified_lines[:-1]
|
412
|
+
|
413
|
+
def printwrap(
|
414
|
+
|
415
|
+
*values: object,
|
416
|
+
sep: Optional[str] = ' ',
|
417
|
+
end: Optional[str] = '\n',
|
418
|
+
fill: str = ' ',
|
419
|
+
width: Optional[int] = None,
|
420
|
+
lenfunc: Callable[[str], Union[int, float]] = len,
|
421
|
+
method: Literal['word', 'mono'] = 'word',
|
422
|
+
alignment: Union[Callable[[str], str], Literal['left', 'center', 'right', 'fill']] = 'left',
|
423
|
+
file: Optional[object] = None,
|
424
|
+
flush: bool = False,
|
425
|
+
preserve_empty: bool = True
|
426
|
+
|
427
|
+
) -> None:
|
276
428
|
|
277
|
-
|
429
|
+
"""
|
430
|
+
Print the given values with word wrapping and alignment.
|
431
|
+
|
432
|
+
Parameters:
|
433
|
+
*values (object): Values to be printed.
|
434
|
+
sep (Optional[str]): Separator between values. Default to ' '.
|
435
|
+
end (Optional[str]): String appended after the last value. Default to '\\n'.
|
436
|
+
fill (str): Fill character for padding. Default to ' '.
|
437
|
+
width (Optional[int]): Width of the output. If None, it tries to use the terminal width or
|
438
|
+
defaults to 70.
|
439
|
+
lenfunc (Callable[[str], Union[int, float]]): Function to calculate the length of a string.
|
440
|
+
Default is len.
|
441
|
+
method (Literal['word', 'mono']): The method to use for wrapping. 'mono' for character-based
|
442
|
+
wrapping, 'word' for word-based wrapping.
|
443
|
+
Defaults to 'word'.
|
444
|
+
alignment (Union[Callable[[str], str],
|
445
|
+
Literal['left', 'center', 'right', 'fill']]): Alignment of the text.
|
446
|
+
Default is 'left'.
|
447
|
+
file (Optional[object]): A file-like object (stream) to write the output to.
|
448
|
+
Default is None, which means sys.stdout.
|
449
|
+
flush (bool): Whether to forcibly flush the stream. Default is False.
|
450
|
+
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
451
|
+
"""
|
452
|
+
|
453
|
+
if width is None:
|
454
|
+
try:
|
455
|
+
width = get_terminal_size().columns
|
456
|
+
except:
|
457
|
+
width = 70
|
458
|
+
|
459
|
+
print(
|
460
|
+
fillstr(
|
461
|
+
(' ' if sep is None else sep).join(map(str, values)),
|
462
|
+
width,
|
463
|
+
fill,
|
464
|
+
lenfunc,
|
465
|
+
method,
|
466
|
+
alignment,
|
467
|
+
preserve_empty
|
468
|
+
),
|
469
|
+
end=end,
|
470
|
+
file=file,
|
471
|
+
flush=flush
|
472
|
+
)
|
278
473
|
|
279
474
|
def shorten(
|
280
475
|
|
@@ -282,7 +477,8 @@ def shorten(
|
|
282
477
|
width: Union[int, float] = 70,
|
283
478
|
start: int = 0,
|
284
479
|
lenfunc: Callable[[str], Union[int, float]] = len,
|
285
|
-
placeholder: str = '...'
|
480
|
+
placeholder: str = '...',
|
481
|
+
strip_space: bool = True
|
286
482
|
|
287
483
|
) -> str:
|
288
484
|
|
@@ -297,6 +493,7 @@ def shorten(
|
|
297
493
|
the length of a string. Defaults to len.
|
298
494
|
placeholder (str, optional): The placeholder to append to the shortened text.
|
299
495
|
Defaults to '...'.
|
496
|
+
strip_space (bool, optional): Whether to strip extra spaces in the text. Defaults to True.
|
300
497
|
|
301
498
|
Returns:
|
302
499
|
str: The shortened text with the placeholder appended if necessary.
|
@@ -311,8 +508,13 @@ def shorten(
|
|
311
508
|
assert width >= lenfunc(placeholder), "width must be greater than length of the placeholder"
|
312
509
|
assert start >= 0, "start must be equal to or greater than 0"
|
313
510
|
|
511
|
+
if strip_space:
|
512
|
+
text = ' '.join(text.split())
|
513
|
+
|
314
514
|
if start == 0:
|
315
515
|
current_char = ''
|
516
|
+
elif start >= len(text):
|
517
|
+
return ''
|
316
518
|
else:
|
317
519
|
current_char = placeholder
|
318
520
|
|
@@ -320,6 +522,9 @@ def shorten(
|
|
320
522
|
if lenfunc(current_char + char + placeholder) <= width:
|
321
523
|
current_char += char
|
322
524
|
else:
|
323
|
-
|
525
|
+
current_char += placeholder
|
526
|
+
if lenfunc(current_char) > width:
|
527
|
+
return placeholder
|
528
|
+
return current_char
|
324
529
|
|
325
530
|
return current_char
|
@@ -0,0 +1,164 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: txtwrap
|
3
|
+
Version: 1.1.1
|
4
|
+
Summary: A simple text wrapping tool.
|
5
|
+
Author: azzammuhyala
|
6
|
+
License: MIT
|
7
|
+
Keywords: wrap,wrapper,wrapping,wrapped,wrapping tool,text wrap,text wrapper,simple wrap,align,aligner,aligning,aligned
|
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` (Updated!)
|
28
|
+
- `fillstr`
|
29
|
+
- `printwrap`
|
30
|
+
- `shorten`
|
31
|
+
|
32
|
+
Mod `python -m txtwrap` Commands❗:
|
33
|
+
```shell
|
34
|
+
python -m txtwrap --help
|
35
|
+
```
|
36
|
+
|
37
|
+
Examples❓:
|
38
|
+
## Render a wrap text in PyGame🎮
|
39
|
+
```py
|
40
|
+
from typing import Literal, Optional
|
41
|
+
from txtwrap import align, LOREM_IPSUM_P
|
42
|
+
import pygame
|
43
|
+
|
44
|
+
def render_wrap(
|
45
|
+
|
46
|
+
font: pygame.Font,
|
47
|
+
text: str,
|
48
|
+
width: int,
|
49
|
+
antialias: bool,
|
50
|
+
color: pygame.Color,
|
51
|
+
background: Optional[pygame.Color] = None,
|
52
|
+
linegap: int = 0,
|
53
|
+
alignment: Literal['left', 'center', 'right', 'fill'] = 'left',
|
54
|
+
method: Literal['word', 'mono'] = 'word',
|
55
|
+
preserve_empty: bool = True,
|
56
|
+
use_min_width: bool = True
|
57
|
+
|
58
|
+
) -> pygame.Surface:
|
59
|
+
|
60
|
+
# Only supports in txtwrap 1.1.1+
|
61
|
+
align_info = align(
|
62
|
+
text=text,
|
63
|
+
width=width,
|
64
|
+
linegap=linegap,
|
65
|
+
sizefunc=font.size,
|
66
|
+
method=method,
|
67
|
+
alignment=alignment,
|
68
|
+
preserve_empty=preserve_empty,
|
69
|
+
use_min_width=use_min_width,
|
70
|
+
return_details=True
|
71
|
+
)
|
72
|
+
|
73
|
+
surface = pygame.Surface(align_info['size'], pygame.SRCALPHA)
|
74
|
+
|
75
|
+
if background is not None:
|
76
|
+
surface.fill(background)
|
77
|
+
|
78
|
+
for x, y, text in align_info['aligned']:
|
79
|
+
surface.blit(font.render(text, antialias, color), (x, y))
|
80
|
+
|
81
|
+
return surface
|
82
|
+
|
83
|
+
# Example usage:
|
84
|
+
pygame.init()
|
85
|
+
pygame.display.set_caption("Lorem Ipsum")
|
86
|
+
|
87
|
+
running = True
|
88
|
+
wscrn, hscrn = 600, 600
|
89
|
+
screen = pygame.display.set_mode((wscrn, hscrn))
|
90
|
+
clock = pygame.time.Clock()
|
91
|
+
surface = render_wrap(
|
92
|
+
font=pygame.font.Font(None, 20),
|
93
|
+
text=LOREM_IPSUM_P,
|
94
|
+
width=wscrn,
|
95
|
+
antialias=True,
|
96
|
+
color='#ffffff',
|
97
|
+
background='#303030',
|
98
|
+
alignment='fill'
|
99
|
+
)
|
100
|
+
|
101
|
+
wsurf, hsurf = surface.get_size()
|
102
|
+
pos = ((wscrn - wsurf) / 2, (hscrn - hsurf) / 2)
|
103
|
+
|
104
|
+
while running:
|
105
|
+
for event in pygame.event.get():
|
106
|
+
if event.type == pygame.QUIT:
|
107
|
+
running = False
|
108
|
+
screen.fill('#000000')
|
109
|
+
screen.blit(surface, pos)
|
110
|
+
pygame.display.flip()
|
111
|
+
clock.tick(60)
|
112
|
+
```
|
113
|
+
|
114
|
+
## Print a wrap text to terminal🔡
|
115
|
+
```py
|
116
|
+
# Only supports in txtwrap 1.1.0+
|
117
|
+
from txtwrap import printwrap, LOREM_IPSUM_W
|
118
|
+
|
119
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='left')
|
120
|
+
print('=' * 20)
|
121
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='center')
|
122
|
+
print('=' * 20)
|
123
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='right')
|
124
|
+
print('=' * 20)
|
125
|
+
printwrap(LOREM_IPSUM_W, width=20, alignment='fill')
|
126
|
+
```
|
127
|
+
|
128
|
+
## Short a long text🔤
|
129
|
+
```py
|
130
|
+
from txtwrap import shorten, LOREM_IPSUM_S
|
131
|
+
|
132
|
+
short_lorem = shorten(LOREM_IPSUM_S, width=20, placeholder='…')
|
133
|
+
# Only supports in txtwrap 1.1.0+
|
134
|
+
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
135
|
+
|
136
|
+
print(short_lorem)
|
137
|
+
print(test)
|
138
|
+
```
|
139
|
+
|
140
|
+
## Bonus🎁 - Print a colorfull text to terminal🔥
|
141
|
+
```py
|
142
|
+
# Run this code in a terminal that supports ansi characters
|
143
|
+
|
144
|
+
from re import compile
|
145
|
+
from random import randint
|
146
|
+
from txtwrap import printwrap, LOREM_IPSUM_P
|
147
|
+
|
148
|
+
# Set the text to be printed here
|
149
|
+
text = LOREM_IPSUM_P
|
150
|
+
|
151
|
+
remove_ansi_regex = compile(r'\x1b\[[0-9;]*[mK]').sub
|
152
|
+
|
153
|
+
def ralen(s: str) -> int:
|
154
|
+
return len(remove_ansi_regex('', s))
|
155
|
+
|
156
|
+
while True:
|
157
|
+
# Only supports in txtwrap 1.1.0+
|
158
|
+
printwrap(
|
159
|
+
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
160
|
+
end='\x1b[H\x1b[J',
|
161
|
+
alignment='fill',
|
162
|
+
lenfunc=ralen
|
163
|
+
)
|
164
|
+
```
|
txtwrap-1.0.0/PKG-INFO
DELETED
@@ -1,33 +0,0 @@
|
|
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
DELETED
@@ -1,19 +0,0 @@
|
|
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
|
-
```
|
@@ -1,105 +0,0 @@
|
|
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='')
|
@@ -1,33 +0,0 @@
|
|
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
|
-
```
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|