From 04da984731f3572ef0d053b2ab0f25cdf1b0c63c Mon Sep 17 00:00:00 2001 From: belono Date: Mon, 4 Aug 2025 17:37:28 +0200 Subject: [PATCH 1/7] Add method: justify --- src/escpos/escpos.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index fb2e7b87..0a11f23a 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -11,6 +11,7 @@ """ from __future__ import annotations +import re import textwrap import time import warnings @@ -108,7 +109,7 @@ 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): @@ -920,7 +921,21 @@ def block_text(self, txt, font="0", columns=None) -> None: self.text(textwrap.fill(txt, col_count)) @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 (l := width - len(txt)) > 0: + txt = re.sub(r"(\s+)", r"\1 ", txt, count=l) + if txt == prev_txt: + break + return txt.rjust(width) + def _padding( + self, text: str, width: int, align: Alignment = "center", @@ -936,6 +951,8 @@ def _padding( text = f"{text:<{width}}" elif align == "right": text = f"{text:>{width}}" + elif align == "justify": + text = self._justify(text, width) return text From a72f28ecd1b5be810ea36aef057514ff7abb22ba Mon Sep 17 00:00:00 2001 From: belono Date: Tue, 5 Aug 2025 00:18:19 +0200 Subject: [PATCH 2/7] Add justify test --- test/test_functions/test_function_software_columns.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_functions/test_function_software_columns.py b/test/test_functions/test_function_software_columns.py index 9ec1771d..f8a5f01b 100644 --- a/test/test_functions/test_function_software_columns.py +++ b/test/test_functions/test_function_software_columns.py @@ -33,11 +33,11 @@ def test_add_padding_into_cols(driver) -> None: """ output = driver._add_padding_into_cols( - text_list=["col1", "col2", "col3"], - widths=[6, 6, 6], - align=["center", "left", "right"], + text_list=["col1", "col2", "col3", "col 4"], + widths=[6, 6, 6, 6], + align=["center", "left", "right", "justify"], ) - assert output == [" col1 ", "col2 ", " col3"] + assert output == [" col1 ", "col2 ", " col3", "col 4"] @pytest.mark.parametrize("text_list", ["", [], None]) From b1ff5b281db2983a78e9fd58806b11f8a97b59e9 Mon Sep 17 00:00:00 2001 From: belono Date: Tue, 5 Aug 2025 01:07:30 +0200 Subject: [PATCH 3/7] Add another justify test --- test/test_functions/test_function_software_columns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_functions/test_function_software_columns.py b/test/test_functions/test_function_software_columns.py index f8a5f01b..ccf032dc 100644 --- a/test/test_functions/test_function_software_columns.py +++ b/test/test_functions/test_function_software_columns.py @@ -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("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: """ GIVEN a dummy printer object From 1f94b39406ef4763b58cab6bee6b96d6bdbc0743 Mon Sep 17 00:00:00 2001 From: belono Date: Tue, 5 Aug 2025 01:09:37 +0200 Subject: [PATCH 4/7] Please the linter --- src/escpos/escpos.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 0a11f23a..399d4283 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -928,8 +928,8 @@ def _justify(txt: str, width: int) -> str: suggested by agordon @https://github.com/python-escpos/python-escpos/pull/652 """ prev_txt = txt - while (l := width - len(txt)) > 0: - txt = re.sub(r"(\s+)", r"\1 ", txt, count=l) + 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) From c11030e705c8efaa375a1da029c7ab50f859b1b9 Mon Sep 17 00:00:00 2001 From: belono Date: Thu, 7 Aug 2025 18:28:27 +0200 Subject: [PATCH 5/7] Allow single-item text_list in _rearrange_into_cols() --- src/escpos/escpos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 399d4283..832fc8d2 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -989,7 +989,7 @@ def _rearrange_into_cols(self, text_list: list, widths: list[int]) -> list: textwrap.wrap(text, widths[i], break_long_words=False) 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 = [] for i in range(max_len): row = ["" for _ in range(n_cols)] From 40e315ea4f16a5f5f9eb564971ee0bc4105f3fdf Mon Sep 17 00:00:00 2001 From: belono Date: Thu, 7 Aug 2025 23:45:10 +0200 Subject: [PATCH 6/7] Add parameter checks to software_columns --- src/escpos/escpos.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/escpos/escpos.py b/src/escpos/escpos.py index 832fc8d2..fc00e713 100644 --- a/src/escpos/escpos.py +++ b/src/escpos/escpos.py @@ -953,6 +953,8 @@ def _padding( 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 @@ -1030,6 +1032,9 @@ def software_columns( 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). """ + if not all([text_list, widths, align]): + raise TypeError("Value can't be of type None") + n_cols = len(text_list) if isinstance(widths, int): From e453f36c034781c4191e1ff522bd5a4f4b815b1f Mon Sep 17 00:00:00 2001 From: belono Date: Thu, 7 Aug 2025 23:58:24 +0200 Subject: [PATCH 7/7] Test for specific errors --- test/test_functions/test_function_software_columns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_functions/test_function_software_columns.py b/test/test_functions/test_function_software_columns.py index ccf032dc..0eb10c59 100644 --- a/test/test_functions/test_function_software_columns.py +++ b/test/test_functions/test_function_software_columns.py @@ -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] for kwargs in bad_args: - with pytest.raises(Exception): + with pytest.raises((TypeError, ValueError)): driver.software_columns(**kwargs) driver.close()