txtwrap 1.1.1__tar.gz → 1.2.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.1.1/txtwrap.egg-info → txtwrap-1.2.0}/PKG-INFO +26 -28
- {txtwrap-1.1.1 → txtwrap-1.2.0}/README.md +25 -27
- {txtwrap-1.1.1 → txtwrap-1.2.0}/setup.py +1 -1
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap/__init__.py +7 -4
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap/__main__.py +30 -8
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap/txtwrap.py +200 -100
- {txtwrap-1.1.1 → txtwrap-1.2.0/txtwrap.egg-info}/PKG-INFO +26 -28
- {txtwrap-1.1.1 → txtwrap-1.2.0}/MANIFEST.in +0 -0
- {txtwrap-1.1.1 → txtwrap-1.2.0}/setup.cfg +0 -0
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap.egg-info/SOURCES.txt +0 -0
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap.egg-info/dependency_links.txt +0 -0
- {txtwrap-1.1.1 → txtwrap-1.2.0}/txtwrap.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: txtwrap
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.2.0
|
4
4
|
Summary: A simple text wrapping tool.
|
5
5
|
Author: azzammuhyala
|
6
6
|
License: MIT
|
@@ -18,16 +18,18 @@ A tool for wrapping a text.🔨
|
|
18
18
|
> **⚠️All documents are in the each module.⚠️**
|
19
19
|
|
20
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
|
-
- `
|
21
|
+
- `LOREM_IPSUM_WORDS` (same as `LOREM_IPSUM_W`)
|
22
|
+
- `LOREM_IPSUM_SENTENCES` (same as `LOREM_IPSUM_S`)
|
23
|
+
- `LOREM_IPSUM_PARAGRAPHS` (same as `LOREM_IPSUM_P`)
|
24
|
+
- `mono` (Fixed)
|
25
|
+
- `word` (Fixed)
|
26
|
+
- `wrap` (Fixed)
|
27
|
+
- `align` (Updated)
|
28
|
+
- `fillstr` (Updated)
|
29
|
+
- `printwrap` (Updated)
|
30
|
+
- `indent` (New)
|
31
|
+
- `dedent` (New)
|
32
|
+
- `shorten` (Fixed)
|
31
33
|
|
32
34
|
Mod `python -m txtwrap` Commands❗:
|
33
35
|
```shell
|
@@ -38,7 +40,7 @@ Examples❓:
|
|
38
40
|
## Render a wrap text in PyGame🎮
|
39
41
|
```py
|
40
42
|
from typing import Literal, Optional
|
41
|
-
from txtwrap import align,
|
43
|
+
from txtwrap import align, LOREM_IPSUM_PARAGRAPHS
|
42
44
|
import pygame
|
43
45
|
|
44
46
|
def render_wrap(
|
@@ -57,9 +59,8 @@ def render_wrap(
|
|
57
59
|
|
58
60
|
) -> pygame.Surface:
|
59
61
|
|
60
|
-
# Only supports in txtwrap 1.1.1+
|
61
62
|
align_info = align(
|
62
|
-
|
63
|
+
text_or_wrapped=str(text),
|
63
64
|
width=width,
|
64
65
|
linegap=linegap,
|
65
66
|
sizefunc=font.size,
|
@@ -90,7 +91,7 @@ screen = pygame.display.set_mode((wscrn, hscrn))
|
|
90
91
|
clock = pygame.time.Clock()
|
91
92
|
surface = render_wrap(
|
92
93
|
font=pygame.font.Font(None, 20),
|
93
|
-
text=
|
94
|
+
text=LOREM_IPSUM_PARAGRAPHS,
|
94
95
|
width=wscrn,
|
95
96
|
antialias=True,
|
96
97
|
color='#ffffff',
|
@@ -113,24 +114,22 @@ while running:
|
|
113
114
|
|
114
115
|
## Print a wrap text to terminal🔡
|
115
116
|
```py
|
116
|
-
|
117
|
-
from txtwrap import printwrap, LOREM_IPSUM_W
|
117
|
+
from txtwrap import printwrap, LOREM_IPSUM_WORDS
|
118
118
|
|
119
|
-
printwrap(
|
119
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='left')
|
120
120
|
print('=' * 20)
|
121
|
-
printwrap(
|
121
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='center')
|
122
122
|
print('=' * 20)
|
123
|
-
printwrap(
|
123
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='right')
|
124
124
|
print('=' * 20)
|
125
|
-
printwrap(
|
125
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='fill')
|
126
126
|
```
|
127
127
|
|
128
128
|
## Short a long text🔤
|
129
129
|
```py
|
130
|
-
from txtwrap import shorten,
|
130
|
+
from txtwrap import shorten, LOREM_IPSUM_SENTENCES
|
131
131
|
|
132
|
-
short_lorem = shorten(
|
133
|
-
# Only supports in txtwrap 1.1.0+
|
132
|
+
short_lorem = shorten(LOREM_IPSUM_SENTENCES, width=20, placeholder='…')
|
134
133
|
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
135
134
|
|
136
135
|
print(short_lorem)
|
@@ -143,18 +142,17 @@ print(test)
|
|
143
142
|
|
144
143
|
from re import compile
|
145
144
|
from random import randint
|
146
|
-
from txtwrap import printwrap,
|
145
|
+
from txtwrap import printwrap, LOREM_IPSUM_PARAGRAPHS
|
147
146
|
|
148
147
|
# Set the text to be printed here
|
149
|
-
text =
|
148
|
+
text = LOREM_IPSUM_PARAGRAPHS
|
150
149
|
|
151
|
-
remove_ansi_regex = compile(r'\x1b\[
|
150
|
+
remove_ansi_regex = compile(r'\x1b\[(K|.*?m)').sub
|
152
151
|
|
153
152
|
def ralen(s: str) -> int:
|
154
153
|
return len(remove_ansi_regex('', s))
|
155
154
|
|
156
155
|
while True:
|
157
|
-
# Only supports in txtwrap 1.1.0+
|
158
156
|
printwrap(
|
159
157
|
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
160
158
|
end='\x1b[H\x1b[J',
|
@@ -4,16 +4,18 @@ A tool for wrapping a text.🔨
|
|
4
4
|
> **⚠️All documents are in the each module.⚠️**
|
5
5
|
|
6
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
|
-
- `
|
7
|
+
- `LOREM_IPSUM_WORDS` (same as `LOREM_IPSUM_W`)
|
8
|
+
- `LOREM_IPSUM_SENTENCES` (same as `LOREM_IPSUM_S`)
|
9
|
+
- `LOREM_IPSUM_PARAGRAPHS` (same as `LOREM_IPSUM_P`)
|
10
|
+
- `mono` (Fixed)
|
11
|
+
- `word` (Fixed)
|
12
|
+
- `wrap` (Fixed)
|
13
|
+
- `align` (Updated)
|
14
|
+
- `fillstr` (Updated)
|
15
|
+
- `printwrap` (Updated)
|
16
|
+
- `indent` (New)
|
17
|
+
- `dedent` (New)
|
18
|
+
- `shorten` (Fixed)
|
17
19
|
|
18
20
|
Mod `python -m txtwrap` Commands❗:
|
19
21
|
```shell
|
@@ -24,7 +26,7 @@ Examples❓:
|
|
24
26
|
## Render a wrap text in PyGame🎮
|
25
27
|
```py
|
26
28
|
from typing import Literal, Optional
|
27
|
-
from txtwrap import align,
|
29
|
+
from txtwrap import align, LOREM_IPSUM_PARAGRAPHS
|
28
30
|
import pygame
|
29
31
|
|
30
32
|
def render_wrap(
|
@@ -43,9 +45,8 @@ def render_wrap(
|
|
43
45
|
|
44
46
|
) -> pygame.Surface:
|
45
47
|
|
46
|
-
# Only supports in txtwrap 1.1.1+
|
47
48
|
align_info = align(
|
48
|
-
|
49
|
+
text_or_wrapped=str(text),
|
49
50
|
width=width,
|
50
51
|
linegap=linegap,
|
51
52
|
sizefunc=font.size,
|
@@ -76,7 +77,7 @@ screen = pygame.display.set_mode((wscrn, hscrn))
|
|
76
77
|
clock = pygame.time.Clock()
|
77
78
|
surface = render_wrap(
|
78
79
|
font=pygame.font.Font(None, 20),
|
79
|
-
text=
|
80
|
+
text=LOREM_IPSUM_PARAGRAPHS,
|
80
81
|
width=wscrn,
|
81
82
|
antialias=True,
|
82
83
|
color='#ffffff',
|
@@ -99,24 +100,22 @@ while running:
|
|
99
100
|
|
100
101
|
## Print a wrap text to terminal🔡
|
101
102
|
```py
|
102
|
-
|
103
|
-
from txtwrap import printwrap, LOREM_IPSUM_W
|
103
|
+
from txtwrap import printwrap, LOREM_IPSUM_WORDS
|
104
104
|
|
105
|
-
printwrap(
|
105
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='left')
|
106
106
|
print('=' * 20)
|
107
|
-
printwrap(
|
107
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='center')
|
108
108
|
print('=' * 20)
|
109
|
-
printwrap(
|
109
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='right')
|
110
110
|
print('=' * 20)
|
111
|
-
printwrap(
|
111
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='fill')
|
112
112
|
```
|
113
113
|
|
114
114
|
## Short a long text🔤
|
115
115
|
```py
|
116
|
-
from txtwrap import shorten,
|
116
|
+
from txtwrap import shorten, LOREM_IPSUM_SENTENCES
|
117
117
|
|
118
|
-
short_lorem = shorten(
|
119
|
-
# Only supports in txtwrap 1.1.0+
|
118
|
+
short_lorem = shorten(LOREM_IPSUM_SENTENCES, width=20, placeholder='…')
|
120
119
|
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
121
120
|
|
122
121
|
print(short_lorem)
|
@@ -129,18 +128,17 @@ print(test)
|
|
129
128
|
|
130
129
|
from re import compile
|
131
130
|
from random import randint
|
132
|
-
from txtwrap import printwrap,
|
131
|
+
from txtwrap import printwrap, LOREM_IPSUM_PARAGRAPHS
|
133
132
|
|
134
133
|
# Set the text to be printed here
|
135
|
-
text =
|
134
|
+
text = LOREM_IPSUM_PARAGRAPHS
|
136
135
|
|
137
|
-
remove_ansi_regex = compile(r'\x1b\[
|
136
|
+
remove_ansi_regex = compile(r'\x1b\[(K|.*?m)').sub
|
138
137
|
|
139
138
|
def ralen(s: str) -> int:
|
140
139
|
return len(remove_ansi_regex('', s))
|
141
140
|
|
142
141
|
while True:
|
143
|
-
# Only supports in txtwrap 1.1.0+
|
144
142
|
printwrap(
|
145
143
|
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
146
144
|
end='\x1b[H\x1b[J',
|
@@ -6,8 +6,9 @@ A simple text wrapping tool
|
|
6
6
|
|
7
7
|
from .txtwrap import (
|
8
8
|
version,
|
9
|
-
|
9
|
+
LOREM_IPSUM_WORDS, LOREM_IPSUM_SENTENCES, LOREM_IPSUM_PARAGRAPHS,
|
10
10
|
mono, word, wrap, align, fillstr, printwrap,
|
11
|
+
indent, dedent,
|
11
12
|
shorten
|
12
13
|
)
|
13
14
|
|
@@ -15,14 +16,16 @@ __version__ = version
|
|
15
16
|
__author__ = 'azzammuhyala'
|
16
17
|
__license__ = 'MIT'
|
17
18
|
__all__ = [
|
18
|
-
'
|
19
|
-
'
|
20
|
-
'
|
19
|
+
'LOREM_IPSUM_WORDS',
|
20
|
+
'LOREM_IPSUM_SENTENCES',
|
21
|
+
'LOREM_IPSUM_PARAGRAPHS',
|
21
22
|
'mono',
|
22
23
|
'word',
|
23
24
|
'wrap',
|
24
25
|
'align',
|
25
26
|
'fillstr',
|
26
27
|
'printwrap',
|
28
|
+
'indent',
|
29
|
+
'dedent',
|
27
30
|
'shorten'
|
28
31
|
]
|
@@ -1,8 +1,19 @@
|
|
1
1
|
from argparse import ArgumentParser
|
2
|
-
from
|
2
|
+
from os import name, get_terminal_size
|
3
|
+
from txtwrap import version, printwrap, indent, dedent, shorten
|
4
|
+
|
5
|
+
if name == 'nt':
|
6
|
+
pyname = 'python|py'
|
7
|
+
elif name == 'posix':
|
8
|
+
pyname = 'python3'
|
9
|
+
else:
|
10
|
+
pyname = 'python'
|
3
11
|
|
4
12
|
parser = ArgumentParser(
|
5
|
-
|
13
|
+
prog='txtwrap',
|
14
|
+
description='Command-line tool for wrapping, aligning, or shortening text.',
|
15
|
+
epilog=f'for example: {pyname} -m txtwrap "Lorem ipsum odor amet, consectetuer adipiscing '
|
16
|
+
'elit." -w 20 -m word -a center'
|
6
17
|
)
|
7
18
|
|
8
19
|
parser.add_argument(
|
@@ -37,9 +48,9 @@ parser.add_argument(
|
|
37
48
|
parser.add_argument(
|
38
49
|
'-m', '--method',
|
39
50
|
type=str,
|
40
|
-
choices={'word', 'mono', 'shorten'},
|
51
|
+
choices={'word', 'mono', 'indent', 'dedent', 'shorten'},
|
41
52
|
default='word',
|
42
|
-
metavar='{word|mono|shorten}',
|
53
|
+
metavar='{word|mono|indent|dedent|shorten}',
|
43
54
|
help='Method to be applied to the text (default: "word")'
|
44
55
|
)
|
45
56
|
|
@@ -58,6 +69,14 @@ parser.add_argument(
|
|
58
69
|
help='Neglect empty lines in the text'
|
59
70
|
)
|
60
71
|
|
72
|
+
parser.add_argument(
|
73
|
+
'-x', '--prefix',
|
74
|
+
type=str,
|
75
|
+
default=None,
|
76
|
+
metavar='<str>',
|
77
|
+
help='Prefix to be added (indent) or remove (dedent) to the text'
|
78
|
+
)
|
79
|
+
|
61
80
|
parser.add_argument(
|
62
81
|
'-s', '--start',
|
63
82
|
type=int,
|
@@ -82,15 +101,18 @@ parser.add_argument(
|
|
82
101
|
|
83
102
|
args = parser.parse_args()
|
84
103
|
|
85
|
-
if args.method == '
|
86
|
-
|
87
|
-
|
104
|
+
if args.method == 'indent':
|
105
|
+
if args.prefix is None:
|
106
|
+
raise ValueError('The prefix (-x, --prefix) is required for the indent method')
|
107
|
+
print(indent(args.text, args.prefix))
|
108
|
+
elif args.method == 'dedent':
|
109
|
+
print(dedent(args.text, args.prefix))
|
110
|
+
elif args.method == 'shorten':
|
88
111
|
if args.width is None:
|
89
112
|
try:
|
90
113
|
args.width = get_terminal_size().columns
|
91
114
|
except:
|
92
115
|
args.width = 70
|
93
|
-
|
94
116
|
print(
|
95
117
|
shorten(
|
96
118
|
text=args.text,
|
@@ -1,47 +1,46 @@
|
|
1
|
-
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union
|
1
|
+
from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union
|
2
2
|
from os import get_terminal_size
|
3
3
|
from re import compile
|
4
4
|
|
5
5
|
hyphenated_regex = compile(r'(?<=-)(?=(?!-).)')
|
6
|
-
version = '1.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
'tortor netus. Mattis ultricies nec maximus porttitor non mauris?')
|
6
|
+
version = '1.2.0'
|
7
|
+
|
8
|
+
LOREM_IPSUM_WORDS = 'Lorem ipsum odor amet, consectetuer adipiscing elit.'
|
9
|
+
LOREM_IPSUM_SENTENCES = (
|
10
|
+
'Lorem ipsum odor amet, consectetuer adipiscing elit. In malesuada eros natoque urna felis '
|
11
|
+
'diam aptent donec. Cubilia libero morbi fusce tempus, luctus aenean augue. Mus senectus '
|
12
|
+
'rutrum phasellus fusce dictum platea. Eros a integer nec fusce erat urna.'
|
13
|
+
)
|
14
|
+
LOREM_IPSUM_PARAGRAPHS = (
|
15
|
+
'Lorem ipsum odor amet, consectetuer adipiscing elit. Nulla porta ex condimentum velit '
|
16
|
+
'facilisi; consequat congue. Tristique duis sociosqu aliquam semper sit id. Nisi morbi purus, '
|
17
|
+
'nascetur elit pellentesque venenatis. Velit commodo molestie potenti placerat faucibus '
|
18
|
+
'convallis. Himenaeos dapibus ipsum natoque nam dapibus habitasse diam. Viverra ac porttitor '
|
19
|
+
'cras tempor cras. Pharetra habitant nibh dui ipsum scelerisque cras? Efficitur phasellus '
|
20
|
+
'etiam congue taciti tortor quam. Volutpat quam vulputate condimentum hendrerit justo congue '
|
21
|
+
'iaculis nisl nullam.\n\nInceptos tempus nostra fringilla arcu; tellus blandit facilisi risus. '
|
22
|
+
'Platea bibendum tristique lectus nunc placerat id aliquam. Eu arcu nisl mattis potenti '
|
23
|
+
'elementum. Dignissim vivamus montes volutpat litora felis fusce ultrices. Vulputate magna '
|
24
|
+
'nascetur bibendum inceptos scelerisque morbi posuere. Consequat dolor netus augue augue '
|
25
|
+
'tristique curabitur habitasse bibendum. Consectetur est per eros semper, magnis interdum '
|
26
|
+
'libero. Arcu adipiscing litora metus fringilla varius gravida congue tellus adipiscing. '
|
27
|
+
'Blandit nulla mauris nullam ante metus curae scelerisque.\n\nSem varius sodales ut volutpat '
|
28
|
+
'imperdiet turpis primis nullam. At gravida tincidunt phasellus lacus duis integer eros '
|
29
|
+
'penatibus. Interdum mauris molestie posuere nascetur dignissim himenaeos; magna et quisque. '
|
30
|
+
'Dignissim malesuada etiam donec vehicula aliquet bibendum. Magna dapibus sapien semper '
|
31
|
+
'parturient id dis? Pretium orci ante leo, porta tincidunt molestie. Malesuada dictumst '
|
32
|
+
'commodo consequat interdum nisi fusce cras rhoncus feugiat.\n\nHimenaeos mattis commodo '
|
33
|
+
'suspendisse maecenas cras arcu. Habitasse id facilisi praesent justo molestie felis luctus '
|
34
|
+
'suspendisse. Imperdiet ipsum praesent nunc mauris mattis curabitur. Et consectetur morbi '
|
35
|
+
'auctor feugiat enim ridiculus arcu. Ultricies magna blandit eget; vivamus sollicitudin nisl '
|
36
|
+
'proin. Sollicitudin sociosqu et finibus elit vestibulum sapien nec odio euismod. Turpis '
|
37
|
+
'eleifend amet quis auctor cursus. Vehicula pharetra sapien praesent amet purus ante. Risus '
|
38
|
+
'blandit cubilia lorem hendrerit penatibus in magnis.\n\nAmet posuere nunc; maecenas consequat '
|
39
|
+
'risus potenti. Volutpat leo lacinia sapien nulla sagittis dignissim mauris ultrices aliquet. '
|
40
|
+
'Nisi pretium interdum luctus donec magna suscipit. Dapibus tristique felis natoque malesuada '
|
41
|
+
'augue? Justo faucibus tincidunt congue arcu sem; fusce aliquet proin. Commodo neque nibh; '
|
42
|
+
'tempus ad tortor netus. Mattis ultricies nec maximus porttitor non mauris?'
|
43
|
+
)
|
45
44
|
|
46
45
|
def mono(
|
47
46
|
|
@@ -64,11 +63,14 @@ def mono(
|
|
64
63
|
list[str]: A list of strings, where each string is a line of the wrapped text.
|
65
64
|
"""
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
if not isinstance(text, str):
|
67
|
+
raise TypeError("text must be a string")
|
68
|
+
if not isinstance(width, (int, float)):
|
69
|
+
raise TypeError("width must be an integer or float")
|
70
|
+
if not callable(lenfunc):
|
71
|
+
raise TypeError("lenfunc must be a callable function")
|
72
|
+
if width <= 0:
|
73
|
+
raise ValueError("width must be greater than 0")
|
72
74
|
|
73
75
|
parts = []
|
74
76
|
current_char = ''
|
@@ -106,11 +108,14 @@ def word(
|
|
106
108
|
list[str]: A list of strings, where each string is a line of wrapped text.
|
107
109
|
"""
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
if not isinstance(text, str):
|
112
|
+
raise TypeError("text must be a string")
|
113
|
+
if not isinstance(width, (int, float)):
|
114
|
+
raise TypeError("width must be an integer or float")
|
115
|
+
if not callable(lenfunc):
|
116
|
+
raise TypeError("lenfunc must be a callable function")
|
117
|
+
if width <= 0:
|
118
|
+
raise ValueError("width must be greater than 0")
|
114
119
|
|
115
120
|
lines = []
|
116
121
|
current_line = ''
|
@@ -167,11 +172,14 @@ def wrap(
|
|
167
172
|
list[str]: A list of wrapped lines.
|
168
173
|
"""
|
169
174
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
+
if not isinstance(text, str):
|
176
|
+
raise TypeError("text must be a string")
|
177
|
+
if not isinstance(width, (int, float)):
|
178
|
+
raise TypeError("width must be an integer or float")
|
179
|
+
if not callable(lenfunc):
|
180
|
+
raise TypeError("lenfunc must be a callable function")
|
181
|
+
if width <= 0:
|
182
|
+
raise ValueError("width must be greater than 0")
|
175
183
|
|
176
184
|
wrapped_lines = []
|
177
185
|
|
@@ -193,7 +201,7 @@ def wrap(
|
|
193
201
|
|
194
202
|
def align(
|
195
203
|
|
196
|
-
|
204
|
+
text_or_wrapped: Union[str, Sequence[str]],
|
197
205
|
width: Union[int, float] = 70,
|
198
206
|
linegap: Union[int, float] = 0,
|
199
207
|
sizefunc: Callable[[str], Tuple[Union[int, float], Union[int, float]]] = lambda s : (len(s), 1),
|
@@ -210,7 +218,8 @@ def align(
|
|
210
218
|
Wraps and aligns text within a specified width and yields the position and content of each line.
|
211
219
|
|
212
220
|
Parameters:
|
213
|
-
|
221
|
+
text_or_wrapped (str | Sequence[str]): The text to be wrapped and aligned, or a sequence of
|
222
|
+
wrapped lines.
|
214
223
|
width (int | float, optional): The maximum width of each line. Defaults to 70.
|
215
224
|
linegap (int | float, optional): The vertical gap between lines. Defaults to 0.
|
216
225
|
sizefunc (Callable[[str], tuple[int | float, int | float]], optional): A function that
|
@@ -235,20 +244,28 @@ def align(
|
|
235
244
|
Defaults to False.
|
236
245
|
|
237
246
|
Returns:
|
238
|
-
list[tuple[int | float, int | float, str] |
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
247
|
+
list[tuple[int | float, int | float, str]] |
|
248
|
+
dict[Literal['aligned', 'wrapped', 'size'], Any]: A list of tuples containing the position
|
249
|
+
and content of each line.
|
250
|
+
If return_details, a dictionary containing
|
251
|
+
the wrapped text, and the size is
|
252
|
+
returned.
|
244
253
|
"""
|
245
254
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
255
|
+
if not isinstance(linegap, (int, float)):
|
256
|
+
raise TypeError("linegap must be an integer or a float")
|
257
|
+
if not callable(sizefunc):
|
258
|
+
raise TypeError("sizefunc must be a callable function")
|
259
|
+
if linegap < 0:
|
260
|
+
raise ValueError("linegap must be equal to or greater than 0")
|
261
|
+
|
262
|
+
if isinstance(text_or_wrapped, str):
|
263
|
+
wrapped = wrap(text_or_wrapped, width, lambda s : sizefunc(s)[0], method, preserve_empty)
|
264
|
+
elif isinstance(text_or_wrapped, Sequence):
|
265
|
+
wrapped = text_or_wrapped
|
266
|
+
else:
|
267
|
+
raise TypeError("text_or_wrapped must be a string or a sequence of strings")
|
250
268
|
|
251
|
-
wrapped = wrap(text, width, lambda s : sizefunc(s)[0], method, preserve_empty)
|
252
269
|
size_wrapped = {i: sizefunc(line) for i, line in enumerate(wrapped)}
|
253
270
|
aligned_positions = []
|
254
271
|
offset_y = 0
|
@@ -306,7 +323,7 @@ def align(
|
|
306
323
|
if use_min_width and alignment == 'fill':
|
307
324
|
if no_spaces:
|
308
325
|
size_width = max_width
|
309
|
-
elif
|
326
|
+
elif text_or_wrapped:
|
310
327
|
size_width = width
|
311
328
|
else:
|
312
329
|
size_width = 0
|
@@ -323,10 +340,10 @@ def align(
|
|
323
340
|
|
324
341
|
def fillstr(
|
325
342
|
|
326
|
-
|
327
|
-
width:
|
343
|
+
text_or_wrapped: Union[str, Sequence[str]],
|
344
|
+
width: int = 70,
|
328
345
|
fill: str = ' ',
|
329
|
-
lenfunc: Callable[[str],
|
346
|
+
lenfunc: Callable[[str], int] = len,
|
330
347
|
method: Literal['mono', 'word'] = 'word',
|
331
348
|
alignment: Union[Callable[[str], str], Literal['left', 'center', 'right', 'fill']] = 'left',
|
332
349
|
preserve_empty: bool = True
|
@@ -337,30 +354,39 @@ def fillstr(
|
|
337
354
|
String formats a given text to fit within a specified width, using various alignment methods.
|
338
355
|
|
339
356
|
Parameters:
|
340
|
-
|
341
|
-
|
357
|
+
text_or_wrapped (str | Sequence[str]): The text to be formatted, or a sequence of wrapped
|
358
|
+
lines.
|
359
|
+
width (int, optional): The width of the formatted text. Defaults to 70.
|
342
360
|
fill (str, optional): The character used to fill the space. Must be a single character.
|
343
361
|
Defaults to ' '.
|
344
|
-
lenfunc (Callable[[str],
|
345
|
-
|
362
|
+
lenfunc (Callable[[str], int], optional): A function to calculate the length of a string.
|
363
|
+
Defaults to len.
|
346
364
|
method (Literal['mono', 'word'], optional): The method to use for wrapping.
|
347
365
|
'mono' for character-based wrapping, 'word'
|
348
366
|
for word-based wrapping. Defaults to 'word'.
|
349
|
-
alignment (
|
350
|
-
Literal['left', 'center', 'right', 'fill']
|
351
|
-
|
352
|
-
|
353
|
-
|
367
|
+
alignment (Callable[[str], str] |
|
368
|
+
Literal['left', 'center', 'right', 'fill'], optional): The alignment of the
|
369
|
+
text. 'left', 'center',
|
370
|
+
'right', or 'fill'.
|
371
|
+
Defaults to 'left'.
|
354
372
|
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
355
373
|
|
356
374
|
Returns:
|
357
375
|
str: The formatted text.
|
358
376
|
"""
|
359
377
|
|
360
|
-
|
361
|
-
|
378
|
+
if not isinstance(fill, str):
|
379
|
+
raise TypeError("fill must be a string")
|
380
|
+
if lenfunc(fill) != 1:
|
381
|
+
raise ValueError("fill must be a single character")
|
382
|
+
|
383
|
+
if isinstance(text_or_wrapped, str):
|
384
|
+
wrapped = wrap(text_or_wrapped, width, lenfunc, method, preserve_empty)
|
385
|
+
elif isinstance(text_or_wrapped, Sequence):
|
386
|
+
wrapped = text_or_wrapped
|
387
|
+
else:
|
388
|
+
raise TypeError("text_or_wrapped must be a string or a sequence of strings")
|
362
389
|
|
363
|
-
wrapped = wrap(text, width, lenfunc, method, preserve_empty)
|
364
390
|
justified_lines = ''
|
365
391
|
|
366
392
|
if callable(alignment):
|
@@ -417,12 +443,13 @@ def printwrap(
|
|
417
443
|
end: Optional[str] = '\n',
|
418
444
|
fill: str = ' ',
|
419
445
|
width: Optional[int] = None,
|
420
|
-
lenfunc: Callable[[str],
|
446
|
+
lenfunc: Callable[[str], int] = len,
|
421
447
|
method: Literal['word', 'mono'] = 'word',
|
422
448
|
alignment: Union[Callable[[str], str], Literal['left', 'center', 'right', 'fill']] = 'left',
|
423
449
|
file: Optional[object] = None,
|
424
450
|
flush: bool = False,
|
425
|
-
preserve_empty: bool = True
|
451
|
+
preserve_empty: bool = True,
|
452
|
+
is_wrapped: bool = False
|
426
453
|
|
427
454
|
) -> None:
|
428
455
|
|
@@ -436,18 +463,19 @@ def printwrap(
|
|
436
463
|
fill (str): Fill character for padding. Default to ' '.
|
437
464
|
width (Optional[int]): Width of the output. If None, it tries to use the terminal width or
|
438
465
|
defaults to 70.
|
439
|
-
lenfunc (Callable[[str],
|
440
|
-
|
466
|
+
lenfunc (Callable[[str], int]): Function to calculate the length of a string.
|
467
|
+
Default is len.
|
441
468
|
method (Literal['word', 'mono']): The method to use for wrapping. 'mono' for character-based
|
442
469
|
wrapping, 'word' for word-based wrapping.
|
443
470
|
Defaults to 'word'.
|
444
|
-
alignment (
|
445
|
-
Literal['left', 'center', 'right', 'fill']
|
446
|
-
|
471
|
+
alignment (Callable[[str], str] |
|
472
|
+
Literal['left', 'center', 'right', 'fill']): Alignment of the text.
|
473
|
+
Default is 'left'.
|
447
474
|
file (Optional[object]): A file-like object (stream) to write the output to.
|
448
475
|
Default is None, which means sys.stdout.
|
449
476
|
flush (bool): Whether to forcibly flush the stream. Default is False.
|
450
477
|
preserve_empty (bool, optional): Whether to preserve empty lines. Defaults to True.
|
478
|
+
is_wrapped (bool, optional): Whether the values are already wrapped. Defaults to False.
|
451
479
|
"""
|
452
480
|
|
453
481
|
if width is None:
|
@@ -456,9 +484,11 @@ def printwrap(
|
|
456
484
|
except:
|
457
485
|
width = 70
|
458
486
|
|
487
|
+
map_values = map(str, values)
|
488
|
+
|
459
489
|
print(
|
460
490
|
fillstr(
|
461
|
-
(' ' if sep is None else sep).join(
|
491
|
+
map_values if is_wrapped else (' ' if sep is None else sep).join(map_values),
|
462
492
|
width,
|
463
493
|
fill,
|
464
494
|
lenfunc,
|
@@ -471,6 +501,70 @@ def printwrap(
|
|
471
501
|
flush=flush
|
472
502
|
)
|
473
503
|
|
504
|
+
def indent(
|
505
|
+
|
506
|
+
text: str,
|
507
|
+
prefix: str,
|
508
|
+
predicate: Callable[[str], bool] = lambda line: line.strip()
|
509
|
+
|
510
|
+
) -> str:
|
511
|
+
|
512
|
+
"""
|
513
|
+
Adds a specified prefix to each line of the given text that satisfies the predicate.
|
514
|
+
|
515
|
+
Parameters:
|
516
|
+
text (str): The input text to be processed.
|
517
|
+
prefix (str): The prefix to add to each line.
|
518
|
+
predicate (Callable[[str], bool], optional): A function that determines whether a line
|
519
|
+
should be prefixed. Defaults to a lambda
|
520
|
+
function that returns True for non-empty lines.
|
521
|
+
|
522
|
+
Returns:
|
523
|
+
str: The processed text with the prefix added to each line that satisfies the predicate.
|
524
|
+
"""
|
525
|
+
|
526
|
+
if not isinstance(text, str):
|
527
|
+
raise TypeError("text must be a string")
|
528
|
+
if not isinstance(prefix, str):
|
529
|
+
raise TypeError("prefix must be a string")
|
530
|
+
if not callable(predicate):
|
531
|
+
raise TypeError("predicate must be a callable function")
|
532
|
+
|
533
|
+
return '\n'.join(prefix + line for line in text.splitlines() if predicate(line))
|
534
|
+
|
535
|
+
def dedent(
|
536
|
+
|
537
|
+
text: str,
|
538
|
+
prefix: Optional[str] = None,
|
539
|
+
predicate: Callable[[str], bool] = lambda line: line.strip()
|
540
|
+
|
541
|
+
) -> str:
|
542
|
+
|
543
|
+
"""
|
544
|
+
Remove any leading whitespace from each line in the given text.
|
545
|
+
|
546
|
+
Parameters:
|
547
|
+
text (str): The input text from which to remove leading whitespace.
|
548
|
+
prefix (Optional[str], optional): A prefix to remove from the start of each line.
|
549
|
+
Defaults to None (remove all leading whitespace).
|
550
|
+
predicate (Callable[[str], bool], optional): A function that determines whether a line
|
551
|
+
should be processed. Defaults to a
|
552
|
+
lambda function that returns True for
|
553
|
+
non-empty lines.
|
554
|
+
|
555
|
+
Returns:
|
556
|
+
str: The text with leading whitespace removed from each line.
|
557
|
+
"""
|
558
|
+
|
559
|
+
if not isinstance(text, str):
|
560
|
+
raise TypeError("text must be a string")
|
561
|
+
if not isinstance(prefix, (str, type(None))):
|
562
|
+
raise TypeError("prefix must be a string")
|
563
|
+
if not callable(predicate):
|
564
|
+
raise TypeError("predicate must be a callable function")
|
565
|
+
|
566
|
+
return '\n'.join(line.lstrip(prefix) for line in text.splitlines() if predicate(line))
|
567
|
+
|
474
568
|
def shorten(
|
475
569
|
|
476
570
|
text: str,
|
@@ -499,14 +593,20 @@ def shorten(
|
|
499
593
|
str: The shortened text with the placeholder appended if necessary.
|
500
594
|
"""
|
501
595
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
596
|
+
if not isinstance(text, str):
|
597
|
+
raise TypeError("text must be a string")
|
598
|
+
if not isinstance(width, (int, float)):
|
599
|
+
raise TypeError("width must be an integer or float")
|
600
|
+
if not isinstance(start, int):
|
601
|
+
raise TypeError("start must be an integer")
|
602
|
+
if not callable(lenfunc):
|
603
|
+
raise TypeError("lenfunc must be a callable function")
|
604
|
+
if not isinstance(placeholder, str):
|
605
|
+
raise TypeError("placeholder must be a string")
|
606
|
+
if width < lenfunc(placeholder):
|
607
|
+
raise ValueError("width must be greater than length of the placeholder")
|
608
|
+
if start < 0:
|
609
|
+
raise ValueError("start must be equal to or greater than 0")
|
510
610
|
|
511
611
|
if strip_space:
|
512
612
|
text = ' '.join(text.split())
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: txtwrap
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.2.0
|
4
4
|
Summary: A simple text wrapping tool.
|
5
5
|
Author: azzammuhyala
|
6
6
|
License: MIT
|
@@ -18,16 +18,18 @@ A tool for wrapping a text.🔨
|
|
18
18
|
> **⚠️All documents are in the each module.⚠️**
|
19
19
|
|
20
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
|
-
- `
|
21
|
+
- `LOREM_IPSUM_WORDS` (same as `LOREM_IPSUM_W`)
|
22
|
+
- `LOREM_IPSUM_SENTENCES` (same as `LOREM_IPSUM_S`)
|
23
|
+
- `LOREM_IPSUM_PARAGRAPHS` (same as `LOREM_IPSUM_P`)
|
24
|
+
- `mono` (Fixed)
|
25
|
+
- `word` (Fixed)
|
26
|
+
- `wrap` (Fixed)
|
27
|
+
- `align` (Updated)
|
28
|
+
- `fillstr` (Updated)
|
29
|
+
- `printwrap` (Updated)
|
30
|
+
- `indent` (New)
|
31
|
+
- `dedent` (New)
|
32
|
+
- `shorten` (Fixed)
|
31
33
|
|
32
34
|
Mod `python -m txtwrap` Commands❗:
|
33
35
|
```shell
|
@@ -38,7 +40,7 @@ Examples❓:
|
|
38
40
|
## Render a wrap text in PyGame🎮
|
39
41
|
```py
|
40
42
|
from typing import Literal, Optional
|
41
|
-
from txtwrap import align,
|
43
|
+
from txtwrap import align, LOREM_IPSUM_PARAGRAPHS
|
42
44
|
import pygame
|
43
45
|
|
44
46
|
def render_wrap(
|
@@ -57,9 +59,8 @@ def render_wrap(
|
|
57
59
|
|
58
60
|
) -> pygame.Surface:
|
59
61
|
|
60
|
-
# Only supports in txtwrap 1.1.1+
|
61
62
|
align_info = align(
|
62
|
-
|
63
|
+
text_or_wrapped=str(text),
|
63
64
|
width=width,
|
64
65
|
linegap=linegap,
|
65
66
|
sizefunc=font.size,
|
@@ -90,7 +91,7 @@ screen = pygame.display.set_mode((wscrn, hscrn))
|
|
90
91
|
clock = pygame.time.Clock()
|
91
92
|
surface = render_wrap(
|
92
93
|
font=pygame.font.Font(None, 20),
|
93
|
-
text=
|
94
|
+
text=LOREM_IPSUM_PARAGRAPHS,
|
94
95
|
width=wscrn,
|
95
96
|
antialias=True,
|
96
97
|
color='#ffffff',
|
@@ -113,24 +114,22 @@ while running:
|
|
113
114
|
|
114
115
|
## Print a wrap text to terminal🔡
|
115
116
|
```py
|
116
|
-
|
117
|
-
from txtwrap import printwrap, LOREM_IPSUM_W
|
117
|
+
from txtwrap import printwrap, LOREM_IPSUM_WORDS
|
118
118
|
|
119
|
-
printwrap(
|
119
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='left')
|
120
120
|
print('=' * 20)
|
121
|
-
printwrap(
|
121
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='center')
|
122
122
|
print('=' * 20)
|
123
|
-
printwrap(
|
123
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='right')
|
124
124
|
print('=' * 20)
|
125
|
-
printwrap(
|
125
|
+
printwrap(LOREM_IPSUM_WORDS, width=20, alignment='fill')
|
126
126
|
```
|
127
127
|
|
128
128
|
## Short a long text🔤
|
129
129
|
```py
|
130
|
-
from txtwrap import shorten,
|
130
|
+
from txtwrap import shorten, LOREM_IPSUM_SENTENCES
|
131
131
|
|
132
|
-
short_lorem = shorten(
|
133
|
-
# Only supports in txtwrap 1.1.0+
|
132
|
+
short_lorem = shorten(LOREM_IPSUM_SENTENCES, width=20, placeholder='…')
|
134
133
|
test = shorten(' Helllo, \t\r\n World!! \f', width=20, placeholder='…', strip_space=True)
|
135
134
|
|
136
135
|
print(short_lorem)
|
@@ -143,18 +142,17 @@ print(test)
|
|
143
142
|
|
144
143
|
from re import compile
|
145
144
|
from random import randint
|
146
|
-
from txtwrap import printwrap,
|
145
|
+
from txtwrap import printwrap, LOREM_IPSUM_PARAGRAPHS
|
147
146
|
|
148
147
|
# Set the text to be printed here
|
149
|
-
text =
|
148
|
+
text = LOREM_IPSUM_PARAGRAPHS
|
150
149
|
|
151
|
-
remove_ansi_regex = compile(r'\x1b\[
|
150
|
+
remove_ansi_regex = compile(r'\x1b\[(K|.*?m)').sub
|
152
151
|
|
153
152
|
def ralen(s: str) -> int:
|
154
153
|
return len(remove_ansi_regex('', s))
|
155
154
|
|
156
155
|
while True:
|
157
|
-
# Only supports in txtwrap 1.1.0+
|
158
156
|
printwrap(
|
159
157
|
''.join(f'\x1b[{randint(31, 36)}m{char}' for char in text) + '\x1b[0m',
|
160
158
|
end='\x1b[H\x1b[J',
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|