mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
[V3 Utils] Improve bordered function and add tests (#1206)
This commit is contained in:
parent
1c504f681e
commit
05c5c58eaf
@ -1,5 +1,5 @@
|
|||||||
import itertools
|
import itertools
|
||||||
from typing import List, Iterator
|
from typing import Sequence, Iterator
|
||||||
|
|
||||||
def error(text: str) -> str:
|
def error(text: str) -> str:
|
||||||
"""Get text prefixed with an error emoji.
|
"""Get text prefixed with an error emoji.
|
||||||
@ -120,7 +120,7 @@ def italics(text: str) -> str:
|
|||||||
return "*{}*".format(text)
|
return "*{}*".format(text)
|
||||||
|
|
||||||
|
|
||||||
def bordered(text1: List[str], text2: List[str]) -> str:
|
def bordered(*columns: Sequence[str], ascii_border: bool=False) -> str:
|
||||||
"""Get two blocks of text in a borders.
|
"""Get two blocks of text in a borders.
|
||||||
|
|
||||||
Note
|
Note
|
||||||
@ -129,10 +129,10 @@ def bordered(text1: List[str], text2: List[str]) -> str:
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
text1 : `list` of `str`
|
*columns : `sequence` of `str`
|
||||||
The 1st block of text, with each string being a new line.
|
The columns of text, each being a list of lines in that column.
|
||||||
text2 : `list` of `str`
|
ascii_border : bool
|
||||||
The 2nd block of text. Should not be longer than ``text1``.
|
Whether or not the border should be pure ASCII.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -140,24 +140,53 @@ def bordered(text1: List[str], text2: List[str]) -> str:
|
|||||||
The bordered text.
|
The bordered text.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
width1, width2 = max((len(s1) + 9, len(s2) + 9) for s1 in text1 for s2 in text2)
|
borders = {
|
||||||
res = ['┌{}┐{}┌{}┐'.format("─"*width1, " "*4, "─"*width2)]
|
'TL': '-' if ascii_border else '┌', # Top-left
|
||||||
flag = True
|
'TR': '-' if ascii_border else '┐', # Top-right
|
||||||
for x, y in itertools.zip_longest(text1, text2):
|
'BL': '-' if ascii_border else '└', # Bottom-left
|
||||||
if y:
|
'BR': '-' if ascii_border else '┘', # Bottom-right
|
||||||
m = "│{}│{}│{}│".format((x + " " * width1)[:width1], " "*4, (y + " " * width2)[:width2])
|
'HZ': '-' if ascii_border else '─', # Horizontal
|
||||||
elif x and flag and not y:
|
'VT': '|' if ascii_border else '│', # Vertical
|
||||||
m = "│{}│{}└{}┘".format((x + " " * width1)[:width1], " "*4, "─" * width2)
|
}
|
||||||
flag = False
|
|
||||||
|
sep = ' ' * 4 # Separator between boxes
|
||||||
|
widths = tuple(max(len(row) for row in column) + 9 for column in columns) # width of each col
|
||||||
|
colsdone = [False] * len(columns) # whether or not each column is done
|
||||||
|
lines = [sep.join('{TL}' + '{HZ}'*width + '{TR}' for width in widths)]
|
||||||
|
|
||||||
|
for line in itertools.zip_longest(*columns):
|
||||||
|
row = []
|
||||||
|
for colidx, column in enumerate(line):
|
||||||
|
width = widths[colidx]
|
||||||
|
done = colsdone[colidx]
|
||||||
|
if column is None:
|
||||||
|
if not done:
|
||||||
|
# bottom border of column
|
||||||
|
column = '{HZ}' * width
|
||||||
|
row.append('{BL}' + column + '{BR}')
|
||||||
|
colsdone[colidx] = True # mark column as done
|
||||||
|
else:
|
||||||
|
# leave empty
|
||||||
|
row.append(' ' * (width + 2))
|
||||||
|
else:
|
||||||
|
column += ' ' * (width - len(column)) # append padded spaces
|
||||||
|
row.append('{VT}' + column + '{VT}')
|
||||||
|
|
||||||
|
lines.append(sep.join(row))
|
||||||
|
|
||||||
|
final_row = []
|
||||||
|
for width, done in zip(widths, colsdone):
|
||||||
|
if not done:
|
||||||
|
final_row.append('{BL}' + '{HZ}' * width + '{BR}')
|
||||||
else:
|
else:
|
||||||
m = "│{}│".format((x + " " * width1)[:width1])
|
final_row.append(' ' * (width + 2))
|
||||||
res.append(m)
|
lines.append(sep.join(final_row))
|
||||||
res.append("└" + "─" * width1 + "┘")
|
|
||||||
return "\n".join(res)
|
return "\n".join(lines).format(**borders)
|
||||||
|
|
||||||
|
|
||||||
def pagify(text: str,
|
def pagify(text: str,
|
||||||
delims: List[str]=["\n"],
|
delims: Sequence[str]=["\n"],
|
||||||
*,
|
*,
|
||||||
priority: bool=False,
|
priority: bool=False,
|
||||||
escape_mass_mentions: bool=True,
|
escape_mass_mentions: bool=True,
|
||||||
@ -173,7 +202,7 @@ def pagify(text: str,
|
|||||||
----------
|
----------
|
||||||
text : str
|
text : str
|
||||||
The content to pagify and send.
|
The content to pagify and send.
|
||||||
delims : `list` of `str`, optional
|
delims : `sequence` of `str`, optional
|
||||||
Characters where page breaks will occur. If no delimiters are found
|
Characters where page breaks will occur. If no delimiters are found
|
||||||
in a page, the page will break after ``page_length`` characters.
|
in a page, the page will break after ``page_length`` characters.
|
||||||
By default this only contains the newline.
|
By default this only contains the newline.
|
||||||
|
|||||||
48
tests/core/test_utils.py
Normal file
48
tests/core/test_utils.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import textwrap
|
||||||
|
from redbot.core.utils import chat_formatting
|
||||||
|
|
||||||
|
|
||||||
|
def test_bordered_symmetrical():
|
||||||
|
expected = textwrap.dedent("""\
|
||||||
|
┌──────────────┐ ┌─────────────┐
|
||||||
|
│one │ │four │
|
||||||
|
│two │ │five │
|
||||||
|
│three │ │six │
|
||||||
|
└──────────────┘ └─────────────┘""")
|
||||||
|
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six']
|
||||||
|
assert chat_formatting.bordered(col1, col2) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_bordered_asymmetrical():
|
||||||
|
expected = textwrap.dedent("""\
|
||||||
|
┌──────────────┐ ┌──────────────┐
|
||||||
|
│one │ │four │
|
||||||
|
│two │ │five │
|
||||||
|
│three │ │six │
|
||||||
|
└──────────────┘ │seven │
|
||||||
|
└──────────────┘""")
|
||||||
|
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six', 'seven']
|
||||||
|
assert chat_formatting.bordered(col1, col2) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_bordered_asymmetrical_2():
|
||||||
|
expected = textwrap.dedent("""\
|
||||||
|
┌──────────────┐ ┌─────────────┐
|
||||||
|
│one │ │five │
|
||||||
|
│two │ │six │
|
||||||
|
│three │ └─────────────┘
|
||||||
|
│four │
|
||||||
|
└──────────────┘ """)
|
||||||
|
col1, col2 = ['one', 'two', 'three', 'four'], ['five', 'six']
|
||||||
|
assert chat_formatting.bordered(col1, col2) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_bordered_ascii():
|
||||||
|
expected = textwrap.dedent("""\
|
||||||
|
---------------- ---------------
|
||||||
|
|one | |four |
|
||||||
|
|two | |five |
|
||||||
|
|three | |six |
|
||||||
|
---------------- ---------------""")
|
||||||
|
col1, col2 = ['one', 'two', 'three'], ['four', 'five', 'six']
|
||||||
|
assert chat_formatting.bordered(col1, col2, ascii_border=True) == expected
|
||||||
Loading…
x
Reference in New Issue
Block a user