mirror of
https://github.com/python-escpos/python-escpos
synced 2025-08-24 09:03:34 +00:00
* Add method: justify * Add justify test * Add another justify test * Please the linter * Allow single-item text_list in _rearrange_into_cols() * Add parameter checks to software_columns * Test for specific errors
This commit is contained in:
@@ -11,6 +11,7 @@ This module contains the abstract base class :py:class:`Escpos`.
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
import warnings
|
import warnings
|
||||||
@@ -108,7 +109,7 @@ SW_BARCODE_NAMES = {
|
|||||||
for name in barcode.PROVIDED_BARCODES
|
for name in barcode.PROVIDED_BARCODES
|
||||||
}
|
}
|
||||||
|
|
||||||
Alignment = Union[Literal["center", "left", "right"], str]
|
Alignment = Union[Literal["center", "left", "right", "justify"], str]
|
||||||
|
|
||||||
|
|
||||||
class Escpos(object, metaclass=ABCMeta):
|
class Escpos(object, metaclass=ABCMeta):
|
||||||
@@ -920,7 +921,21 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
self.text(textwrap.fill(txt, col_count))
|
self.text(textwrap.fill(txt, col_count))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
def _justify(txt: str, width: int) -> str:
|
||||||
|
"""Justify-text on left AND right sides by padding spaces.
|
||||||
|
|
||||||
|
code by: Georgina Skibinski https://stackoverflow.com/a/66087666
|
||||||
|
suggested by agordon @https://github.com/python-escpos/python-escpos/pull/652
|
||||||
|
"""
|
||||||
|
prev_txt = txt
|
||||||
|
while (length := width - len(txt)) > 0:
|
||||||
|
txt = re.sub(r"(\s+)", r"\1 ", txt, count=length)
|
||||||
|
if txt == prev_txt:
|
||||||
|
break
|
||||||
|
return txt.rjust(width)
|
||||||
|
|
||||||
def _padding(
|
def _padding(
|
||||||
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
width: int,
|
width: int,
|
||||||
align: Alignment = "center",
|
align: Alignment = "center",
|
||||||
@@ -936,6 +951,10 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
text = f"{text:<{width}}"
|
text = f"{text:<{width}}"
|
||||||
elif align == "right":
|
elif align == "right":
|
||||||
text = f"{text:>{width}}"
|
text = f"{text:>{width}}"
|
||||||
|
elif align == "justify":
|
||||||
|
text = self._justify(text, width)
|
||||||
|
else:
|
||||||
|
raise ValueError("Expected a valid alignment: center|left|right|justify")
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@@ -972,7 +991,7 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
textwrap.wrap(text, widths[i], break_long_words=False)
|
textwrap.wrap(text, widths[i], break_long_words=False)
|
||||||
for i, text in enumerate(text_list)
|
for i, text in enumerate(text_list)
|
||||||
]
|
]
|
||||||
max_len = max(*[len(text_group) for text_group in wrapped])
|
max_len = max(0, *[len(text_group) for text_group in wrapped])
|
||||||
text_colums = []
|
text_colums = []
|
||||||
for i in range(max_len):
|
for i in range(max_len):
|
||||||
row = ["" for _ in range(n_cols)]
|
row = ["" for _ in range(n_cols)]
|
||||||
@@ -1013,6 +1032,9 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
If the list of alignment items is shorter than the list of strings then
|
If the list of alignment items is shorter than the list of strings then
|
||||||
the last alignment of the list will be applied till the last string (column).
|
the last alignment of the list will be applied till the last string (column).
|
||||||
"""
|
"""
|
||||||
|
if not all([text_list, widths, align]):
|
||||||
|
raise TypeError("Value can't be of type None")
|
||||||
|
|
||||||
n_cols = len(text_list)
|
n_cols = len(text_list)
|
||||||
|
|
||||||
if isinstance(widths, int):
|
if isinstance(widths, int):
|
||||||
|
@@ -33,11 +33,11 @@ def test_add_padding_into_cols(driver) -> None:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
output = driver._add_padding_into_cols(
|
output = driver._add_padding_into_cols(
|
||||||
text_list=["col1", "col2", "col3"],
|
text_list=["col1", "col2", "col3", "col 4"],
|
||||||
widths=[6, 6, 6],
|
widths=[6, 6, 6, 6],
|
||||||
align=["center", "left", "right"],
|
align=["center", "left", "right", "justify"],
|
||||||
)
|
)
|
||||||
assert output == [" col1 ", "col2 ", " col3"]
|
assert output == [" col1 ", "col2 ", " col3", "col 4"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("text_list", ["", [], None])
|
@pytest.mark.parametrize("text_list", ["", [], None])
|
||||||
@@ -55,7 +55,7 @@ def test_software_columns_invalid_args(driver, text_list, widths, align) -> None
|
|||||||
|
|
||||||
bad_args = [bad_text_list, bad_widths, bad_align]
|
bad_args = [bad_text_list, bad_widths, bad_align]
|
||||||
for kwargs in bad_args:
|
for kwargs in bad_args:
|
||||||
with pytest.raises(Exception):
|
with pytest.raises((TypeError, ValueError)):
|
||||||
driver.software_columns(**kwargs)
|
driver.software_columns(**kwargs)
|
||||||
driver.close()
|
driver.close()
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ def test_software_columns_invalid_args(driver, text_list, widths, align) -> None
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
|
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
|
||||||
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "center"])
|
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "justify"])
|
||||||
def test_software_columns_valid_args(driver, text_list, widths, align) -> None:
|
def test_software_columns_valid_args(driver, text_list, widths, align) -> None:
|
||||||
"""
|
"""
|
||||||
GIVEN a dummy printer object
|
GIVEN a dummy printer object
|
||||||
|
Reference in New Issue
Block a user