1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-09-13 09:09:58 +00:00

37 Commits

Author SHA1 Message Date
dependabot[bot]
1d70acdab5 Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 18:06:42 +00:00
Benito López
00d3a1301f Switch to python 3.13 (#693)
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-08-11 01:25:11 +02:00
Benito López
ebd6f88acf Add justify to text alignment of software_columns() Fixes #689 (#690)
* 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
2025-08-11 01:21:29 +02:00
dependabot[bot]
b85d5b907d Bump actions/setup-python from 5.5.0 to 5.6.0 (#682)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.5.0 to 5.6.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.5.0...v5.6.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 5.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 18:13:59 +02:00
dependabot[bot]
3dfbf15fa5 Bump actions/setup-python from 5.4.0 to 5.5.0 (#681)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.4.0...v5.5.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 13:16:11 +01:00
Patrick Kanzler
9b695d698b exclude .venv from flake8 2025-03-16 15:52:23 +01:00
dependabot[bot]
7ec59c41a2 Bump jinja2 from 3.1.5 to 3.1.6 in /examples/docker-flask (#679)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.5 to 3.1.6.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.5...3.1.6)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-06 13:35:25 +01:00
Benito López
a394826d69 Docs: profile usage additions and clarifications (#677)
* Add link to github

* Add profile params to 'Documentation and Usage'

* More profile additions and clarifications

* Fix code style

* Fix Include link to github in documentation topbar

* Fix Black code style

* Fix GH link

* Fix GH link path

---------

Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-02-21 21:01:40 +01:00
Benito López
e383b7a397 Fix wrong font choices (#676)
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-02-21 10:59:43 +01:00
dependabot[bot]
e39ec9e50d Bump codecov/codecov-action from 4 to 5 (#668)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 10:53:59 +01:00
dependabot[bot]
dc0d9e6bf6 Bump jinja2 from 3.1.4 to 3.1.5 in /examples/docker-flask (#671)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 10:45:27 +01:00
dependabot[bot]
5d943566c9 Bump actions/setup-python from 5.3.0 to 5.4.0 (#674)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.3.0...v5.4.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2025-02-21 10:37:15 +01:00
Benito López
3e8525673b New feature: Software columns - Part 4: Examples (#673)
* Add software_colums example

* Fix docs build
2025-02-21 10:33:28 +01:00
dependabot[bot]
0a1d3841f1 Bump sphinx-rtd-theme from 3.0.1 to 3.0.2 (#666)
Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 3.0.1 to 3.0.2.
- [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst)
- [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/3.0.1...3.0.2)

---
updated-dependencies:
- dependency-name: sphinx-rtd-theme
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-15 16:40:30 +01:00
dependabot[bot]
27def759ba Bump werkzeug from 3.0.3 to 3.0.6 in /examples/docker-flask (#664)
Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.3 to 3.0.6.
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.0.3...3.0.6)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-26 05:51:10 +02:00
dependabot[bot]
8c44d8e64e Bump actions/setup-python from 5.2.0 to 5.3.0 (#663)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.2.0...v5.3.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-25 20:51:49 +02:00
dependabot[bot]
7d42f11716 Bump sphinx-rtd-theme from 2.0.0 to 3.0.1 (#661)
* Bump sphinx-rtd-theme from 2.0.0 to 3.0.1

Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 2.0.0 to 3.0.1.
- [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst)
- [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/2.0.0...3.0.1)

---
updated-dependencies:
- dependency-name: sphinx-rtd-theme
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* remove call to get_html_theme_path

according to deprection warning of sphinx-rtd-theme>=3

* disable broken spelling integration (pypi) and fix spelling

* fix spelling

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrick Kanzler <dev@pkanzler.de>
2024-10-10 15:00:28 +02:00
dependabot[bot]
5cdff0b56e Bump actions/setup-python from 5.1.1 to 5.2.0 (#655)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.1 to 5.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.1.1...v5.2.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-30 14:52:10 +02:00
aerialist
f42410603d Add sleep in sending fragments (#624)
* Add sleep in sending fragments

Adding sleep prevents "USBTimeoutError: [Errno 110] Operation timed out".

* change sorting

* make sleep configurable

* add spelling

---------

Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
Co-authored-by: Patrick Kanzler <dev@pkanzler.de>
2024-08-25 00:50:27 +02:00
Patrick Kanzler
22982fbd12 update organize import trigger, update capabilities data, fix mypy (#654)
* update organize import trigger

* update capabilities data

* fix mypy error (jaconv is using a import hack)
2024-08-25 00:21:47 +02:00
Benito López
82386f7496 New feature: Software columns - Part 3: Tests (#651)
* Add test_function_software_columns.py

* Improve coverage
2024-08-24 23:29:00 +02:00
Benito López
99501cc2c1 New feature: Software columns - Part 2: CLI (#649)
* Add software_columns CLI parameter

* Fix sorting

---------

Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2024-07-19 22:23:52 +02:00
Psychpsyo
3aaf203ceb Fix typo in README (#650) 2024-07-19 22:18:09 +02:00
Benito López
a8753a1121 New feature: Software columns (#645)
* add type hint Alignment

* Add static method padding()

* Add static method truncate()

* Add static method _repeat_last()

* Add private method _rearrange_into_cols()

* Add private method _add_padding_into_cols()

* Add public method software_columns

* Make truncate and padding private staticmethods

* Revert "add type hint Alignment"

This reverts commit 546391cb9c.

* Add type hint Alignment

* Fix typo in docstring

---------

Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
2024-07-11 17:13:34 +02:00
dependabot[bot]
5af01641d9 Bump actions/setup-python from 5.1.0 to 5.1.1 (#648)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.1.0...v5.1.1)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-11 16:41:42 +02:00
Benito López
fe3cdde424 Clarify set() width and height documentation (#644) 2024-05-24 23:21:54 +02:00
dependabot[bot]
4c02881fe7 Bump jinja2 from 3.1.3 to 3.1.4 in /examples/docker-flask (#642)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 22:54:24 +02:00
dependabot[bot]
82f5a00b8d Bump werkzeug from 3.0.1 to 3.0.3 in /examples/docker-flask (#641)
Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.1 to 3.0.3.
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.0.1...3.0.3)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 21:40:03 +02:00
Benito López
1e9adb80f3 Fix CLI not working for some connectors Fixes #639 (#640) 2024-04-29 23:50:52 +02:00
dependabot[bot]
640f6089ac Bump pillow from 10.2.0 to 10.3.0 in /examples/docker-flask (#634)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.2.0 to 10.3.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 21:04:35 +02:00
dependabot[bot]
a8a9d0f0ad Bump codecov/codecov-action from 3 to 4 (#625)
* Bump codecov/codecov-action from 3 to 4

Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* add codecov token

* add codecov token

* remove directory config

* adapt excludes

* exclude mypy_cache

* glob

* exclude

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
Co-authored-by: Patrick Kanzler <dev@pkanzler.de>
2024-04-02 01:23:56 +02:00
dependabot[bot]
f781e28a69 Bump actions/setup-python from 5.0.0 to 5.1.0 (#632)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.0.0...v5.1.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-02 00:03:22 +02:00
dependabot[bot]
62c234f6f1 Bump pillow from 10.0.1 to 10.2.0 in /examples/docker-flask (#623)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.0.1 to 10.2.0.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/10.0.1...10.2.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-22 23:25:38 +01:00
dependabot[bot]
4ba98c0017 Bump jinja2 from 3.1.2 to 3.1.3 in /examples/docker-flask (#620)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-12 12:24:41 +01:00
Wesley Appler
a865b715f3 Fixed lack of spacing for multi-line strings (#619)
Co-authored-by: Wes Appler <wes@lamemakes>
2024-01-11 12:35:03 +01:00
dependabot[bot]
776b8a26ad Bump capabilities-data from 4006299 to 375135d (#616)
Bumps [capabilities-data](https://github.com/receipt-print-hq/escpos-printer-db) from `4006299` to `375135d`.
- [Commits](4006299c0f...375135d552)

---
updated-dependencies:
- dependency-name: capabilities-data
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-18 12:37:20 +01:00
Patrick Kanzler
9b0d126da2 prepare for new development (#615) 2023-12-17 23:10:44 +01:00
35 changed files with 460 additions and 99 deletions

View File

@@ -6,7 +6,7 @@ jobs:
black-code-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: psf/black@stable
with:
version: "23.12.0"

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.

View File

@@ -19,7 +19,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Install packages
@@ -27,6 +27,6 @@ jobs:
sudo apt-get update -y &&
sudo apt-get install -y git python3-sphinx graphviz libenchant-2-2 &&
sudo apt-get install -y gcc libcups2-dev python3-dev python3-setuptools &&
sudo pip install tox pycups
sudo pip install --ignore-installed tox pycups
- name: Test doc build
run: tox -e docs

View File

@@ -12,14 +12,14 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
python-version: ['3.11', '3.12']
python-version: ['3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5.0.0
uses: actions/setup-python@v5.6.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
@@ -44,12 +44,14 @@ jobs:
env:
ESCPOS_CAPABILITIES_FILE: D:\a\python-escpos\python-escpos\capabilities-data\dist\capabilities.json
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
directory: ./coverage/reports/
env_vars: OS,PYTHON
fail_ci_if_error: true
files: ./coverage.xml,!./cache
files: ./coverage.xml
exclude: "**/.mypy_cache"
flags: unittests
name: coverage-tox-${{ matrix.python-version }}
verbose: true

View File

@@ -15,14 +15,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: 'recursive'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5.0.0
uses: actions/setup-python@v5.6.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
@@ -54,12 +54,14 @@ jobs:
env:
ESCPOS_CAPABILITIES_FILE: /home/runner/work/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
directory: ./coverage/reports/
env_vars: OS,PYTHON
fail_ci_if_error: true
files: ./coverage.xml,!./cache
files: ./coverage.xml
exclude: "**/.mypy_cache"
flags: unittests
name: coverage-tox-${{ matrix.python-version }}
verbose: true

View File

@@ -12,7 +12,7 @@
"editor.formatOnPaste": true,
"python.formatting.provider": "black",
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,

View File

@@ -1,6 +1,18 @@
Changelog
=========
202x-xx-xx - Version 3.x - ""
-------------------------------------------
changes
^^^^^^^
contributors
^^^^^^^^^^^^
2023-12-17 - Version 3.1 - "Rubric Of Ruin"
-------------------------------------------
This is the minor release of the new version 3.1.
@@ -57,8 +69,8 @@ changes
- change the project's license to MIT in accordance with the contributors (see python-escpos/python-escpos#171)
- feature: add "capabilities" which are shared with escpos-php, capabilities are stored in
`escpos-printer-db <https://github.com/receipt-print-hq/escpos-printer-db>`_
- feature: the driver tries now to guess the appropriate codepage and sets it automatically (called "magic encode")
- as an alternative you can force the codepage with the old API
- feature: the driver tries now to guess the appropriate code page and sets it automatically (called "magic encode")
- as an alternative you can force the code page with the old API
- fix the encoding search so that lower encodings are found first
- automatically handle cases where full cut or partial cut is not available
- refactor of the set-method
@@ -323,14 +335,14 @@ changes
- change the project's license to MIT in accordance with the contributors (see python-escpos/python-escpos#171)
- feature: add "capabilities" which are shared with escpos-php, capabilities are stored in
`escpos-printer-db <https://github.com/receipt-print-hq/escpos-printer-db>`_
- feature: the driver tries now to guess the appropriate codepage and sets it automatically (called "magic encode")
- as an alternative you can force the codepage with the old API
- feature: the driver tries now to guess the appropriate code page and sets it automatically (called "magic encode")
- as an alternative you can force the code page with the old API
- updated and improved documentation
- changed constructor of main class due to introduction of capabilities
- changed interface of method `blocktext`, changed behavior of multiple methods, for details refer to the documentation
on `python-escpos.readthedocs.io <https://python-escpos.readthedocs.io>`_
- add support for custom cash drawer sequence
- enforce flake8 on the src-files, test py36 and py37 on travis
- enforce flake8 on the src-files, test py36 and py37 on Travis
contributors
^^^^^^^^^^^^
@@ -363,7 +375,7 @@ contributors
changes
^^^^^^^
- configure readthedocs and travis
- configure readthedocs and Travis
- update doc with hint on image preprocessing
- add fix for printing large images (by splitting them into multiple images)
@@ -428,8 +440,8 @@ changes
- improve the documentation
- extend support of barcode-codes to type B
- add function to disable panel-buttons
- the text-functions are now intended for unicode, the driver will automatically encode the string based on the selected
codepage
- the text-functions are now intended for Unicode, the driver will automatically encode the string based on the selected
code page
- the image-functions are now much more flexible
- added a CLI
- restructured the constants
@@ -467,7 +479,7 @@ contributors
--------------------------
- Merge pull request #53 from ldos/master
- Extended params for serial printers
- Extended parameters for serial printers
- Sent by ldos <cafeteria.ldosalzira@gmail.com>
2015-04-21 - Version 1.0.5

View File

@@ -59,7 +59,7 @@ Another example based on the Network printer class:
from escpos.printer import Network
kitchen = Network("192.168.1.100") #Printer IP Address
kitchen = Network("192.168.1.100", profile="TM-T88III") #Printer IP Address
kitchen.text("Hello World\n")
kitchen.barcode('4006381333931', 'EAN13', 64, 2, '', '')
kitchen.cut()
@@ -71,18 +71,22 @@ Another example based on the Serial printer class:
from escpos.printer import Serial
""" 9600 Baud, 8N1, Flow Control Enabled """
p = Serial(devfile='/dev/tty.usbserial',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
dsrdtr=True)
p = Serial(
devfile='/dev/tty.usbserial',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
dsrdtr=True,
profile="TM-T88III"
)
p.text("Hello World\n")
p.qr("You can readme from your smartphone")
p.cut()
.. note:: It is highly recommended to include a matching profile to inform python-escpos about the printer's capabilities.
The full project-documentation is available on
`Read the Docs <https://python-escpos.readthedocs.io>`_.
@@ -100,4 +104,4 @@ Disclaimer
None of the vendors cited in this project agree or endorse any of the
patterns or implementations.
Its names are used only to maintain context.
Their names are used only to maintain context.

View File

@@ -73,7 +73,7 @@ master_doc = "index"
# General information about the project.
project = "python-escpos"
copyright = "2023, python-escpos developers"
copyright = "2024, python-escpos developers"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -134,7 +134,6 @@ else:
import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
except ImportError:
print("no sphinx_rtd_theme found, switching to nature")
html_theme = "default"
@@ -144,6 +143,14 @@ else:
# documentation.
# html_theme_options = {}
# Show a 'Edit on GitHub' link instead of 'View page source'
html_context = {
"display_github": True,
"github_user": "python-escpos",
"github_repo": "python-escpos",
"github_version": "master/doc/",
}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
@@ -313,7 +320,7 @@ texinfo_documents = [
# texinfo_no_detailmenu = False
# spellchecker
spelling_ignore_pypi_package_names = True
spelling_ignore_pypi_package_names = False
spelling_ignore_wiki_words = True
spelling_ignore_python_builtins = True
spelling_ignore_importable_modules = True

View File

@@ -5,7 +5,7 @@ Release process
* Update authors file
* Update changelog
* Set annotated tag for release and push to public github
* Set annotated tag for release and push to public GitHub
* Build wheel
* Load wheel to PyPi
* Prepare project for next release with an empty changelog entry

View File

@@ -2,11 +2,11 @@ pyusb
Pillow>=2.0
qrcode>=4.0
pyserial
sphinx-rtd-theme==2.0.0
sphinx-rtd-theme==3.0.2
setuptools
setuptools-scm
docutils>=0.12
sphinxcontrib-spelling>=7.2.0
sphinxcontrib-spelling>=8.0.0
python-barcode>=0.15.0,<1
importlib-metadata
importlib_resources

View File

@@ -87,13 +87,18 @@ config
del
dev
dialout
docstring
docstrings
ean
Ean
encodable
Errno
fff
formatter
fullimage
hw
io
img
json
latin
libusb
@@ -103,16 +108,23 @@ natively
php
pre
prefilled
preprocess
preprocessing
printcap
programmatically
py
pypy
pyserial
pyusb
pyyaml
pywin
px
qrcode
Raspbian
readthedocs
rebase
rebased
renderer
resetted
rst
submodule
@@ -121,10 +133,13 @@ src
testcases
th
Todo
tox
traceback
udev
usb
USBTimeoutError
usec
virtualenvs
viivakoodi
whitespaces
xml

View File

@@ -1,7 +1,7 @@
Usage
=====
:Last Reviewed: 2023-08-10
:Last Reviewed: 2025-02-16
Define your printer
-------------------
@@ -113,7 +113,7 @@ on a USB interface.
from escpos import *
""" Seiko Epson Corp. Receipt Printer M129 Definitions (EPSON TM-T88IV) """
p = printer.Usb(0x04b8,0x0202)
p = printer.Usb(0x04b8,0x0202, profile="TM-T88IV")
# Print text
p.text("Hello World\n")
# Print image
@@ -142,7 +142,7 @@ format. For windows it is probably at::
%appdata%/python-escpos/config.yaml
And for linux::
And for Linux::
$HOME/.config/python-escpos/config.yaml
@@ -180,6 +180,7 @@ An example file printer::
printer:
type: File
devfile: /dev/someprinter
profile: TM-U220
And for a network printer::
@@ -187,6 +188,7 @@ And for a network printer::
type: Network
host: 127.0.0.1
port: 9000
profile: TM-U220
An USB-printer could be defined by::
@@ -196,23 +198,32 @@ An USB-printer could be defined by::
idProduct: 0x5678
in_ep: 0x66
out_ep: 0x01
profile: TM-U220
Printing text right
-------------------
Python-escpos is designed to accept unicode.
Python-escpos is designed to accept Unicode.
For normal usage you can simply pass your text to the printers ``text()``-function. It will automatically guess
the right codepage and then send the encoded data to the printer. If this feature does not work, please try to
the right code page and then send the encoded data to the printer. If this feature does not work, please try to
isolate the error and then create an issue on the GitHub project page.
If you want or need to you can manually set the codepage.
If you want or need to you can manually set the code page.
For this please use the ``charcode()``-function.
You can set any key-value that is in ``CHARCODE``.
If something is wrong, an ``CharCodeError`` will be raised.
After you have manually set the codepage the printer won't change it anymore.
After you have manually set the code page the printer won't change it anymore.
You can revert to normal behavior by setting charcode to ``AUTO``.
Resolving bus timeout issues during printing images
---------------------------------------------------
If an error message such as "USBTimeoutError: [Errno 110] Operation timed out" occurs,
setting a sleep time between printing fragments can help.
This can be done with the :meth:`.set_sleep_in_fragment()` method.
Advanced Usage: Print from binary blob
--------------------------------------
@@ -233,7 +244,7 @@ advantage of the fact that `_raw()` accepts binary strings.)
p._raw(data)
That's all, the printer should then print your data. You can also use this technique to let others reproduce an issue
that you have found. (Just "print" your commands to a File-printer on your local filesystem.)
that you have found. (Just "print" your commands to a File-printer on your local file system.)
However, please keep in mind, that often it is easier and better to just supply the code that you are using.
Here you can download an example, that will print a set of common barcodes:
@@ -242,8 +253,8 @@ Here you can download an example, that will print a set of common barcodes:
.. _advanced-usage-change-capabilities-profile:
Advanced Usage: change capabilities-profile
-------------------------------------------
Advanced Usage: change where is the capabilities-profile
--------------------------------------------------------
Packaged together with the escpos-code is a capabilities-file. This file in
JSON-format describes the capabilities of different printers. It is developed and hosted in

View File

@@ -33,7 +33,7 @@ def main():
def print_codepage(printer, codepage):
"""Print a codepage."""
"""Print a code page."""
if codepage.isdigit():
codepage = int(codepage)
printer._raw(CODEPAGE_CHANGE + bytes((codepage,)))

View File

@@ -4,9 +4,9 @@ blinker==1.6.2
click==8.1.3
Flask==2.3.2
itsdangerous==2.1.2
Jinja2==3.1.2
Jinja2==3.1.6
MarkupSafe==2.1.2
Pillow==10.0.1
Pillow==10.3.0
pycups==2.0.1
pypng==0.20220715.0
pyserial==3.5
@@ -17,4 +17,4 @@ PyYAML==6.0
qrcode==7.4.2
six==1.16.0
typing_extensions==4.5.0
Werkzeug==3.0.1
Werkzeug==3.0.6

View File

@@ -0,0 +1,25 @@
""" Example for software_columns: Print text arranged into columns."""
from escpos import printer
p = printer.Dummy(profile="TM-U220")
font = "a"
p.set(font=font)
# Default: Automatic column width given the characters per line of the printer.
text_list = ["col1", "col2", "col3"]
charsxline = p.profile.get_columns(font)
p.software_columns(text_list=text_list, widths=charsxline, align="center")
# Tuning some columns:
text_list = ["col1", "col2", "col3"]
widths = [5, 20] # col1 = 5 chars width, col2 + col3 = 20 chars width
align = ["left", "center"] # col1 = left aligned, col2 + col3 = center aligned
p.software_columns(text_list=text_list, widths=widths, align=align)
# Tuning them all:
text_list = ["col1", "col2", "col3"]
widths = [5, 20, 15]
align = ["left", "center", "right"]
p.software_columns(text_list=text_list, widths=widths, align=align)

View File

@@ -69,7 +69,7 @@ def forecast(idx):
printer.text(" high " + str(hi))
printer.text(deg)
printer.text("\n")
# take care of pesky unicode dash
# take care of pesky Unicode dash
printer.text(cond.replace("\u2013", "-").encode("utf-8"))
printer.text("\n \n")

View File

@@ -24,6 +24,7 @@ classifiers =
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: Implementation :: CPython
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Office/Business :: Financial :: Point-Of-Sale
@@ -75,6 +76,6 @@ all =
pywin32; platform_system=='Windows'
[flake8]
exclude = .git,.tox,.github,.eggs,__pycache__,doc/conf.py,build,dist,capabilities-data,test,src/escpos/constants.py
exclude = .git,.venv,.tox,.github,.eggs,__pycache__,doc/conf.py,build,dist,capabilities-data,test,src/escpos/constants.py
max-line-length = 120
extend-ignore = E203, W503

View File

@@ -209,6 +209,38 @@ ESCPOS_COMMANDS: List[Dict[str, Any]] = [
},
],
},
{
"parser": {
"name": "software_columns",
"help": "Print a list of texts arranged into columns",
},
"defaults": {
"func": "software_columns",
},
"arguments": [
{
"option_strings": ("--text_list",),
"help": "list of texts to print",
"nargs": "+",
"type": str,
"required": True,
},
{
"option_strings": ("--widths",),
"help": "list of column widths",
"nargs": "+",
"type": int,
"required": True,
},
{
"option_strings": ("--align",),
"help": "list of column alignments",
"nargs": "+",
"type": str,
"required": True,
},
],
},
{
"parser": {
"name": "cut",
@@ -341,7 +373,7 @@ ESCPOS_COMMANDS: List[Dict[str, Any]] = [
{
"option_strings": ("--font",),
"help": "Font choice",
"choices": ["left", "center", "right"],
"choices": ["A", "B"],
},
{
"option_strings": ("--text_type",),
@@ -490,7 +522,7 @@ def generate_parser() -> argparse.ArgumentParser:
"""Generate an argparse parser."""
parser = argparse.ArgumentParser(
description="CLI for python-escpos",
epilog="Printer configuration is defined in the python-escpos config"
epilog="Printer configuration is defined in the python-escpos configuration "
"file. See documentation for details.",
)

View File

@@ -1,4 +1,4 @@
"""Helper module for codepage handling."""
"""Helper module for code page handling."""
from .capabilities import CAPABILITIES
@@ -9,7 +9,7 @@ class CodePageManager:
"""
def __init__(self, data):
"""Initialize codepage manager."""
"""Initialize code page manager."""
self.data = data
@staticmethod

View File

@@ -76,7 +76,18 @@ class Config:
if "printer" in config:
self._printer_config = config["printer"]
self._printer_name = self._printer_config.pop("type").title()
printer_name = self._printer_config.pop("type")
class_names = {
"usb": "Usb",
"serial": "Serial",
"network": "Network",
"file": "File",
"dummy": "Dummy",
"cupsprinter": "CupsPrinter",
"lp": "LP",
"win32raw": "Win32Raw",
}
self._printer_name = class_names.get(printer_name.lower(), printer_name)
if not self._printer_name or not hasattr(printer, self._printer_name):
raise exceptions.ConfigSyntaxError(

View File

@@ -188,8 +188,8 @@ LINESPACING_FUNCS: Dict[int, bytes] = {
180: ESC + b"3", # line_spacing/180 of an inch, 0 <= line_spacing <= 255
}
#: Prefix to change the codepage. You need to attach a byte to indicate
#: the codepage to use. We use escpos-printer-db as the data source.
#: Prefix to change the code page. You need to attach a byte to indicate
#: the code page to use. We use escpos-printer-db as the data source.
CODEPAGE_CHANGE: bytes = ESC + b"\x74"
# Barcode format

View File

@@ -11,7 +11,9 @@ This module contains the abstract base class :py:class:`Escpos`.
"""
from __future__ import annotations
import re
import textwrap
import time
import warnings
from abc import ABCMeta, abstractmethod # abstract base class support
from re import match as re_match
@@ -107,6 +109,8 @@ SW_BARCODE_NAMES = {
for name in barcode.PROVIDED_BARCODES
}
Alignment = Union[Literal["center", "left", "right", "justify"], str]
class Escpos(object, metaclass=ABCMeta):
"""ESC/POS Printer object.
@@ -121,6 +125,9 @@ class Escpos(object, metaclass=ABCMeta):
# object -> The connection object (Usb(), Serial(), Network(), etc.)
_device: Union[Literal[False], Literal[None], object] = False
# sleep time in fragments:
_sleep_in_fragment_ms: int = 0
def __init__(self, profile=None, magic_encode_args=None, **kwargs) -> None:
"""Initialize ESCPOS Printer.
@@ -176,6 +183,21 @@ class Escpos(object, metaclass=ABCMeta):
"""
raise NotImplementedError()
def set_sleep_in_fragment(self, sleep_time_ms: int) -> None:
"""Configures the currently active sleep time after sending a fragment.
If during printing an image an issue like "USBTimeoutError: [Errno 110]
Operation timed out" occurs, setting this value to roughly 300
milliseconds can help resolve the issue.
:param sleep_time_ms: sleep time in milliseconds
"""
self._sleep_in_fragment_ms = sleep_time_ms
def _sleep_in_fragment(self) -> None:
"""Sleeps the preconfigured time after sending a fragment."""
time.sleep(self._sleep_in_fragment_ms / 1000)
def image(
self,
img_source,
@@ -244,6 +266,7 @@ class Escpos(object, metaclass=ABCMeta):
impl=impl,
fragment_height=fragment_height,
)
self._sleep_in_fragment()
return
if impl == "bitImageRaster":
@@ -438,7 +461,7 @@ class Escpos(object, metaclass=ABCMeta):
Sets the control sequence from ``CHARCODE`` in :py:mod:`escpos.constants` as active.
It will be sent with the next text sequence.
If you set the variable code to ``AUTO`` it will try to automatically guess the
right codepage.
right code page.
(This is the standard behavior.)
:param code: Name of CharCode
@@ -854,8 +877,8 @@ class Escpos(object, metaclass=ABCMeta):
def text(self, txt: str) -> None:
"""Print alpha-numeric text.
The text has to be encoded in the currently selected codepage.
The input text has to be encoded in unicode.
The text has to be encoded in the currently selected code page.
The input text has to be encoded in Unicode.
:param txt: text to be printed
:raises: :py:exc:`~escpos.exceptions.TextError`
@@ -865,8 +888,8 @@ class Escpos(object, metaclass=ABCMeta):
def textln(self, txt: str = "") -> None:
"""Print alpha-numeric text with a newline.
The text has to be encoded in the currently selected codepage.
The input text has to be encoded in unicode.
The text has to be encoded in the currently selected code page.
The input text has to be encoded in Unicode.
:param txt: text to be printed with a newline
:raises: :py:exc:`~escpos.exceptions.TextError`
@@ -887,7 +910,7 @@ class Escpos(object, metaclass=ABCMeta):
def block_text(self, txt, font="0", columns=None) -> None:
"""Print text wrapped to specific columns.
Text has to be encoded in unicode.
Text has to be encoded in Unicode.
:param txt: text to be printed
:param font: font to be used, can be :code:`a` or :code:`b`
@@ -897,6 +920,136 @@ class Escpos(object, metaclass=ABCMeta):
col_count = self.profile.get_columns(font) if columns is None else columns
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 (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(
self,
text: str,
width: int,
align: Alignment = "center",
) -> str:
"""Add fill space to meet the width.
The align parameter sets the alignment of the text in space.
"""
align = align.lower()
if align == "center":
text = f"{text:^{width}}"
elif align == "left":
text = f"{text:<{width}}"
elif align == "right":
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
@staticmethod
def _truncate(text: str, width: int, placeholder: str = ".") -> str:
"""Truncate an string at a max width or leave it untouched.
Add a placeholder at the end of the output text if it has been truncated.
"""
ph_len = len(placeholder)
max_len = width - ph_len
return f"{text[:max_len]}{placeholder}" if len(text) > width else text
@staticmethod
def _repeat_last(iterable, max_iterations: int = 1000):
"""Iterate over the items of a list repeating the last one until max_iterations."""
i = 0
while i < max_iterations:
try:
yield iterable[i]
except IndexError:
yield iterable[-1]
i += 1
def _rearrange_into_cols(self, text_list: list, widths: list[int]) -> list:
"""Wrap and convert a list of strings into an array of text columns.
Set the width of each column by passing a list of widths.
Wrap if possible and|or truncate strings longer than its column width.
Reorder the wrapped items into an array of text columns.
"""
n_cols = len(text_list)
wrapped = [
textwrap.wrap(text, widths[i], break_long_words=False)
for i, text in enumerate(text_list)
]
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)]
for j, item in enumerate(wrapped):
if i in range(len(item)):
row[j] = self._truncate(item[i], widths[j])
text_colums.append(row)
return text_colums
def _add_padding_into_cols(
self,
text_list: list[str],
widths: list[int],
align: list[Alignment],
) -> list:
"""Add padding, width and alignment into the items of a list of strings."""
return [
self._padding(text, widths[i], align[i]) for i, text in enumerate(text_list)
]
def software_columns(
self,
text_list: list,
widths: Union[list[int], int],
align: Union[list[Alignment], Alignment],
) -> None:
"""Print a list of strings arranged horizontally in columns.
:param text_list: list of strings, each item in the list will be printed as a column.
:param widths: width of each column by passing a list of widths,
or a single total width to arrange columns of the same size.
If the list of width items is shorter than the list of strings then
the last width of the list will be applied till the last string (column).
:param align: alignment of the text into each column by passing a list of alignments,
or a single alignment for all the 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):
widths = [round(widths / n_cols)]
widths = list(self._repeat_last(widths, max_iterations=n_cols))
if isinstance(align, str):
align = [align]
align = list(self._repeat_last(align, max_iterations=n_cols))
columns = self._rearrange_into_cols(text_list, widths)
for row in columns:
padded = self._add_padding_into_cols(row, widths, align)
self.textln("".join(padded))
def set(
self,
align: Optional[str] = None,
@@ -934,8 +1087,8 @@ class Escpos(object, metaclass=ABCMeta):
:param double_width: doubles the width of the text
:param custom_size: uses custom size specified by width and height
parameters. Cannot be used with double_width or double_height.
:param width: text width multiplier when custom_size is used, decimal range 1-8
:param height: text height multiplier when custom_size is used, decimal range 1-8
:param width: requires custom_size=True, text width multiplier when custom_size is used, decimal range 1-8
:param height: requires custom_size=True, text height multiplier when custom_size is used, decimal range 1-8
:param density: print density, value from 0-8, if something else is supplied the density remains unchanged
:param invert: True enables white on black printing
:param smooth: True enables text smoothing. Effective on 4x4 size text and larger
@@ -1424,7 +1577,7 @@ class EscposIO:
f"{text}",
]
# TODO check unicode handling
# TODO check Unicode handling
# TODO flush? or on print? (this should prob rather be handled by the _raw-method)
for line in lines:
self.printer.set(**params)

View File

@@ -4,7 +4,10 @@
I doubt that this currently works correctly.
"""
import types
import typing
jaconv: typing.Optional[types.ModuleType]
try:
import jaconv
except ImportError:

View File

@@ -3,7 +3,7 @@
"""Magic Encode.
This module tries to convert an UTF-8 string to an encoded string for the printer.
It uses trial and error in order to guess the right codepage.
It uses trial and error in order to guess the right code page.
The code is based on the encoding-code in py-xml-escpos by @fvdsn.
:author: `Patrick Kanzler <dev@pkanzler.de>`_
@@ -65,11 +65,11 @@ class Encoder:
@staticmethod
def _get_codepage_char_list(encoding):
"""Get codepage character list.
"""Get code page character list.
Gets characters 128-255 for a given code page, as an array.
:param encoding: The name of the encoding. This must appear in the CodePage list
:param encoding: The name of the encoding. This must appear in the code page list
"""
codepage = CodePages.get_encoding(encoding)
if "data" in codepage:
@@ -91,7 +91,7 @@ class Encoder:
raise LookupError(f"Can't find a known encoding for {encoding}")
def _get_codepage_char_map(self, encoding):
"""Get codepage character map.
"""Get code page character map.
Process an encoding and return a map of UTF-characters to code points
in this encoding.
@@ -166,7 +166,7 @@ class Encoder:
1. code pages that we already tried before; there is a good
chance they might work again, reducing the search space,
and by re-using already used encodings we might also
reduce the number of codepage change instruction we have
reduce the number of code page change instruction we have
to send. Still, any performance gains will presumably be
fairly minor.
@@ -225,7 +225,7 @@ class MagicEncode:
:param encoding: If you know the current encoding of the printer
when initializing this class, set it here. If the current
encoding is unknown, the first character emitted will be a
codepage switch.
code page switch.
:param disabled:
:param defaultsymbol:
:param encoder:
@@ -284,20 +284,20 @@ class MagicEncode:
def _handle_character_failed(self, char):
"""Write a default symbol.
Called when no codepage was found to render a character.
Called when no code page was found to render a character.
"""
# Writing the default symbol via write() allows us to avoid
# unnecesary codepage switches.
# unnecesary code page switches.
self.write(self.defaultsymbol)
def write_with_encoding(self, encoding, text):
"""Write the text and inject necessary codepage switches."""
"""Write the text and inject necessary code page switches."""
if text is not None and type(text) is not str:
raise Error(
f"The supplied text has to be unicode, but is of type {type(text)}."
f"The supplied text has to be Unicode, but is of type {type(text)}."
)
# We always know the current code page; if the new codepage
# We always know the current code page; if the new code page
# is different, emit a change command.
if encoding != self.encoding:
self.encoding = encoding

View File

@@ -49,8 +49,8 @@ def dependency_pycups(func):
"""Throw a RuntimeError if pycups is not imported."""
if not is_usable():
raise RuntimeError(
"Printing with PyCups requires the pycups library to"
"be installed. Please refer to the documentation on"
"Printing with PyCups requires the pycups library to "
"be installed. Please refer to the documentation on "
"what to install and install the dependencies for pycups."
)
return func(*args, **kwargs)

View File

@@ -23,7 +23,7 @@ def is_usable() -> bool:
class File(Escpos):
"""Generic file printer.
This class is used for parallel port printer or other printers that are directly attached to the filesystem.
This class is used for parallel port printer or other printers that are directly attached to the file system.
Note that you should stay away from using USB-to-Parallel-Adapter since they are unreliable
and produce arbitrary errors.
@@ -46,7 +46,7 @@ class File(Escpos):
def __init__(self, devfile: str = "", auto_flush: bool = True, *args, **kwargs):
"""Initialize file printer with device file.
:param devfile: Device file under dev filesystem
:param devfile: Device file under dev file system
:param auto_flush: automatically call flush after every call of _raw()
"""
Escpos.__init__(self, *args, **kwargs)

View File

@@ -34,7 +34,7 @@ def dependency_linux_lp(func):
"""Throw a RuntimeError if not on a non-Windows system."""
if not is_usable():
raise RuntimeError(
"This printer driver depends on LP which is not"
"This printer driver depends on LP which is not "
"available on Windows systems."
)
return func(*args, **kwargs)

View File

@@ -43,8 +43,8 @@ def dependency_pyserial(func):
"""Throw a RuntimeError if pyserial not installed."""
if not is_usable():
raise RuntimeError(
"Printing with Serial requires the pyserial library to"
"be installed. Please refer to the documentation on"
"Printing with Serial requires the pyserial library to "
"be installed. Please refer to the documentation on "
"what to install and install the dependencies for pyserial."
)
return func(*args, **kwargs)
@@ -89,7 +89,7 @@ class Serial(Escpos):
):
"""Initialize serial printer.
:param devfile: Device file under dev filesystem
:param devfile: Device file under dev file system
:param baudrate: Baud rate for serial transmission
:param bytesize: Serial buffer size
:param timeout: Read/Write timeout

View File

@@ -42,8 +42,8 @@ def dependency_usb(func):
"""Throw a RuntimeError if usb not installed."""
if not is_usable():
raise RuntimeError(
"Printing with USB connection requires a usb library to"
"be installed. Please refer to the documentation on"
"Printing with USB connection requires a usb library to "
"be installed. Please refer to the documentation on "
"what to install and install the dependencies for USB."
)
return func(*args, **kwargs)

View File

@@ -45,8 +45,8 @@ def dependency_win32print(func):
"""Throw a RuntimeError if win32print not installed."""
if not is_usable():
raise RuntimeError(
"Printing with Win32Raw requires a win32print library to"
"be installed. Please refer to the documentation on"
"Printing with Win32Raw requires a win32print library to "
"be installed. Please refer to the documentation on "
"what to install and install the dependencies for win32print."
)
return func(*args, **kwargs)

View File

@@ -0,0 +1,80 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for software_columns
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2024 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import pytest
def test_rearrange_into_cols(driver) -> None:
"""
GIVEN a list of columnable text
WHEN the column width is different for each column and some strings exceed the max width
THEN check the strings are properly wrapped, truncated and rearranged into some columns
"""
output = driver._rearrange_into_cols(
text_list=["fits", "row1 row2", "truncate and wrap"], widths=[4, 5, 6]
)
assert output == [["fits", "row1", "trunc."], ["", "row2", "and"], ["", "", "wrap"]]
def test_add_padding_into_cols(driver) -> None:
"""
GIVEN a list of strings
WHEN adding padding and different alignments to each string
THEN check the strings are correctly padded and aligned
"""
output = driver._add_padding_into_cols(
text_list=["col1", "col2", "col3", "col 4"],
widths=[6, 6, 6, 6],
align=["center", "left", "right", "justify"],
)
assert output == [" col1 ", "col2 ", " col3", "col 4"]
@pytest.mark.parametrize("text_list", ["", [], None])
@pytest.mark.parametrize("widths", [30.5, "30", None])
@pytest.mark.parametrize("align", ["invalid_align_name", "", None])
def test_software_columns_invalid_args(driver, text_list, widths, align) -> None:
"""
GIVEN a dummy printer object
WHEN non valid params are passed
THEN check raise exception
"""
bad_text_list = {"text_list": text_list, "widths": 5, "align": "left"}
bad_widths = {"text_list": ["valid"], "widths": widths, "align": "left"}
bad_align = {"text_list": ["valid"], "widths": 5, "align": align}
bad_args = [bad_text_list, bad_widths, bad_align]
for kwargs in bad_args:
with pytest.raises((TypeError, ValueError)):
driver.software_columns(**kwargs)
driver.close()
@pytest.mark.parametrize(
"text_list",
[
["col1", "col2", "col3"],
["wrap this string", "wrap this string", "wrap this string"],
["truncate_this_string", "truncate_this_string", "truncate_this_string"],
],
)
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
@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
WHEN valid params are passed
THEN check no errors
"""
driver.software_columns(text_list=text_list, widths=widths, align=align)
driver.close()

View File

@@ -7,7 +7,8 @@
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import types
import typing
import hypothesis.strategies as st
import pytest
@@ -111,6 +112,7 @@ class TestMagicEncode:
assert driver.output == b"\x1bt\x00? ist teuro."
jaconv: typing.Optional[types.ModuleType]
try:
import jaconv
except ImportError:

View File

@@ -1,5 +1,5 @@
[tox]
envlist = py38, py39, py310, py311, docs, flake8
envlist = py38, py39, py310, py311, py312, py313, docs, flake8
[gh-actions]
python =
@@ -11,6 +11,7 @@ python =
3.10: py310
3.11: py311
3.12: py312
3.13: py313
[testenv]
deps = jaconv