hpgl-buddy 1.0.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.
Files changed (44) hide show
  1. hpgl_buddy-1.0.0/LICENSE +21 -0
  2. hpgl_buddy-1.0.0/PKG-INFO +200 -0
  3. hpgl_buddy-1.0.0/README.md +172 -0
  4. hpgl_buddy-1.0.0/pyproject.toml +49 -0
  5. hpgl_buddy-1.0.0/setup.cfg +4 -0
  6. hpgl_buddy-1.0.0/src/hpgl_buddy/__init__.py +17 -0
  7. hpgl_buddy-1.0.0/src/hpgl_buddy/cli.py +325 -0
  8. hpgl_buddy-1.0.0/src/hpgl_buddy/demo/__init__.py +6 -0
  9. hpgl_buddy-1.0.0/src/hpgl_buddy/demo/generator.py +256 -0
  10. hpgl_buddy-1.0.0/src/hpgl_buddy/demo/scene.py +162 -0
  11. hpgl_buddy-1.0.0/src/hpgl_buddy/devices/__init__.py +19 -0
  12. hpgl_buddy-1.0.0/src/hpgl_buddy/devices/base.py +122 -0
  13. hpgl_buddy-1.0.0/src/hpgl_buddy/devices/profiles/hp7475a.toml +50 -0
  14. hpgl_buddy-1.0.0/src/hpgl_buddy/devices/registry.py +73 -0
  15. hpgl_buddy-1.0.0/src/hpgl_buddy/errors.py +70 -0
  16. hpgl_buddy-1.0.0/src/hpgl_buddy/execution/__init__.py +19 -0
  17. hpgl_buddy-1.0.0/src/hpgl_buddy/execution/executor.py +368 -0
  18. hpgl_buddy-1.0.0/src/hpgl_buddy/execution/flow_control.py +117 -0
  19. hpgl_buddy-1.0.0/src/hpgl_buddy/execution/planner.py +125 -0
  20. hpgl_buddy-1.0.0/src/hpgl_buddy/execution/progress.py +107 -0
  21. hpgl_buddy-1.0.0/src/hpgl_buddy/hpgl/__init__.py +19 -0
  22. hpgl_buddy-1.0.0/src/hpgl_buddy/hpgl/instruction.py +71 -0
  23. hpgl_buddy-1.0.0/src/hpgl_buddy/hpgl/parser.py +158 -0
  24. hpgl_buddy-1.0.0/src/hpgl_buddy/hpgl/syntax_check.py +180 -0
  25. hpgl_buddy-1.0.0/src/hpgl_buddy/hpgl/tokens.py +107 -0
  26. hpgl_buddy-1.0.0/src/hpgl_buddy/interface/__init__.py +11 -0
  27. hpgl_buddy-1.0.0/src/hpgl_buddy/interface/base.py +99 -0
  28. hpgl_buddy-1.0.0/src/hpgl_buddy/interface/serial_rs232.py +147 -0
  29. hpgl_buddy-1.0.0/src/hpgl_buddy/logging_setup.py +88 -0
  30. hpgl_buddy-1.0.0/src/hpgl_buddy/status/__init__.py +19 -0
  31. hpgl_buddy-1.0.0/src/hpgl_buddy/status/adhoc.py +167 -0
  32. hpgl_buddy-1.0.0/src/hpgl_buddy/status/escape.py +151 -0
  33. hpgl_buddy-1.0.0/src/hpgl_buddy/status/exchange.py +122 -0
  34. hpgl_buddy-1.0.0/src/hpgl_buddy/status/monitor.py +57 -0
  35. hpgl_buddy-1.0.0/src/hpgl_buddy/status/status_codes.py +136 -0
  36. hpgl_buddy-1.0.0/src/hpgl_buddy/version.py +9 -0
  37. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/PKG-INFO +200 -0
  38. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/SOURCES.txt +42 -0
  39. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/dependency_links.txt +1 -0
  40. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/entry_points.txt +2 -0
  41. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/requires.txt +4 -0
  42. hpgl_buddy-1.0.0/src/hpgl_buddy.egg-info/top_level.txt +1 -0
  43. hpgl_buddy-1.0.0/tests/test_basic.py +128 -0
  44. hpgl_buddy-1.0.0/tests/test_execution.py +325 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pavel Kim
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: hpgl-buddy
3
+ Version: 1.0.0
4
+ Summary: Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232.
5
+ Author-email: Pavel Kim <hello@pavelkim.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/hpgl-buddy/hpgl-buddy
8
+ Project-URL: Repository, https://github.com/hpgl-buddy/hpgl-buddy
9
+ Project-URL: Issues, https://github.com/hpgl-buddy/hpgl-buddy/issues
10
+ Keywords: hpgl,plotter,hp7475a,rs232,pen-plotter
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Printing
20
+ Classifier: Topic :: System :: Hardware :: Hardware Drivers
21
+ Requires-Python: >=3.13
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: pyserial>=3.5
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8; extra == "dev"
27
+ Dynamic: license-file
28
+
29
+ # hpgl-buddy
30
+
31
+ Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232.
32
+
33
+ It does not just shove a file at the plotter: it validates the file, splits it to fit
34
+ the device buffer, feeds it so the buffer never overflows and an inked pen never stalls
35
+ mid-stroke, watches the device for faults the whole time, and logs every exchange so a
36
+ run can be understood and troubleshooted from the log alone.
37
+
38
+ **Supported device:** HP 7475A (RS-232). New devices are added as declarative profiles
39
+ (see [Extending](#extending)); HP-IB is planned.
40
+
41
+ ---
42
+
43
+ ## Install
44
+
45
+ Requires Python 3.13 and a USB-serial adapter (macOS: use the `/dev/cu.*` device).
46
+
47
+ ```bash
48
+ pip install -e . # editable, for development
49
+ # or build a wheel:
50
+ python -m build --wheel # -> dist/hpgl_buddy-*.whl (or: tox -e build)
51
+ ```
52
+
53
+ `pyserial` is the only runtime dependency.
54
+
55
+ ---
56
+
57
+ ## Quick start
58
+
59
+ ```bash
60
+ # 1. Validate a file offline (no plotter needed)
61
+ hpgl-buddy check drawing.hpgl
62
+
63
+ # 2. Check the plotter is alive and interpret its status
64
+ hpgl-buddy status --port /dev/cu.usbserial-XXXX
65
+
66
+ # 3. Plot it (verbose shows every byte/ESC exchange)
67
+ hpgl-buddy -v plot drawing.hpgl --port /dev/cu.usbserial-XXXX
68
+
69
+ # 4. Generate and plot a built-in demo
70
+ hpgl-buddy demo --pens 6 --out demo.hpgl
71
+ hpgl-buddy plot demo.hpgl --port /dev/cu.usbserial-XXXX
72
+ ```
73
+
74
+ Serial defaults: **9600 8N1, no flow control** (configurable). Flow control is off by
75
+ default because XON/XOFF corrupted the exchange on the on-site adapter; enable it with
76
+ `--xonxoff` if your cabling needs it.
77
+
78
+ ---
79
+
80
+ ## Commands
81
+
82
+ | Command | What it does |
83
+ |---|---|
84
+ | `check FILE` | Offline HP-GL syntax check. No device. Exit non-zero on errors. |
85
+ | `status` | Ad-hoc healthcheck: identification, buffer, status byte, errors, limits - all interpreted. |
86
+ | `plot FILE` | Safe, buffer-aware plotting with progress + end-of-run report. |
87
+ | `monitor on\|off\|watch` | Switch monitor mode (computer port) or stream the echoed bytes (terminal port). |
88
+ | `demo` | Generate demo HP-GL (`--scene card` shapes/fills/labels/colours, or `--scene house` a continuous one-line drawing). |
89
+
90
+ Global: `-v/--verbose` (DEBUG, incl. raw ASCII+hex wire dumps), `--version`.
91
+
92
+ Serial options (on `status`/`plot`/`monitor`): `--port`, `--model` (default `hp7475a`),
93
+ `--baud`, `--framing` (e.g. `8N1`), `--timeout`, `--xonxoff`, `--rtscts`.
94
+
95
+ ### plot options
96
+
97
+ - `--on-error abort|prompt|continue` - on a reported error: stop and park the pen
98
+ (default), ask interactively, or auto-recover (`ESC.K` discard -> `IN` -> replay the
99
+ tracked state preamble -> carry on).
100
+ - `--live-hpgl-verify off|chunk|pu` - optional on-device HP-GL error checking (see
101
+ [Verification](#verification)). Default `off`.
102
+ - `--ignore-syntax-errors` - plot even if the offline check found errors.
103
+ - `--stats-json PATH` - write run statistics as JSON (`-` for stdout).
104
+
105
+ ### monitor (two ports)
106
+
107
+ The 7475A enables monitor mode via an ESC sequence on the **computer** (data) port, then
108
+ echoes received bytes out a separate **terminal** port. So:
109
+
110
+ ```bash
111
+ # stream the echo on the terminal port, enabling monitor on the computer port first
112
+ hpgl-buddy monitor watch --port /dev/cu.TERMINAL --command-port /dev/cu.COMPUTER --enable
113
+ ```
114
+
115
+ `watch` prints every byte as binary, hex, decimal, and ASCII/control-name.
116
+
117
+ ---
118
+
119
+ ## How plotting works
120
+
121
+ ```
122
+ file -> parse -> offline syntax check -> plan into chunks -> stream to device -> report
123
+ ```
124
+
125
+ 1. **Parse** the bytes into instructions, each tagged with its source line and sequence
126
+ index (so any error names the exact command).
127
+ 2. **Syntax check** offline; `plot` refuses a file with errors unless `--ignore-syntax-errors`.
128
+ 3. **Plan** into chunks of <=256 bytes, split only at instruction boundaries (never inside
129
+ a command), each tagged whether it ends with the pen up.
130
+ 4. **Stream**: a chunk is sent only when `ESC.B` reports enough free buffer space. This one
131
+ gate both prevents overflow and keeps the buffer fed, so a long pen-down stroke spanning
132
+ several chunks never underruns (an underrun would park an inked pen and blot).
133
+ 5. **Watch** (always on, after each chunk): `ESC.E` for I/O faults (overflow / framing /
134
+ data loss) and `ESC.O` for environmental faults (paper lever or pinch wheels raised ->
135
+ abort; VIEW pressed -> warn). Both are immediate and never stall the pen.
136
+ 6. **Confirm**: a final `OS;OE;OI;` tailgate waits for the pen to physically finish and
137
+ reports the end status / any HP-GL error.
138
+ 7. **Report** instructions/chunks/bytes sent, elapsed time, recovered errors, and warnings
139
+ (and the same as JSON via `--stats-json`).
140
+
141
+ ### Verification
142
+
143
+ HP-GL/syntax errors are a property of the *file* (already validated offline), so on-device
144
+ HP-GL error checking is **optional** and off by default. When enabled it never stalls the
145
+ pen - it uses a *one-deep* tailgate: the `OS;OE;OI;` query is prefixed to the chunk after a
146
+ pen-up, so its verdict reports the *previous* chunk while the current one is already drawing.
147
+
148
+ - `chunk` - check at pen-up chunk boundaries.
149
+ - `pu` - break a chunk at every pen-up so each completed stroke is checked (more, smaller
150
+ chunks).
151
+
152
+ Either way you learn a chunk is clean within ~1 chunk, and a reported error names the span
153
+ of chunks it could belong to with all candidate instructions.
154
+
155
+ ### Limits to know
156
+
157
+ - **No pen sensing on the 7475A**: a missing or fallen pen plots dry and is *not* detectable
158
+ by any status query. Pre-load the pens your file uses. (`plot` warns about this.)
159
+
160
+ ---
161
+
162
+ ## Architecture
163
+
164
+ Thoroughly separated layers, each replaceable on its own:
165
+
166
+ ```
167
+ hpgl/ parse HP-GL bytes into a Program; offline syntax check
168
+ devices/ declarative TOML profiles + abstract Device base (registry)
169
+ interface/ Transport abstraction + pyserial RS-232 implementation
170
+ status/ ESC + HP-GL command builders, response parsers, status interpretation, monitor
171
+ execution/ planner (Program -> chunks) + flow control + executor + progress/report
172
+ demo/ demo HP-GL generators
173
+ ```
174
+
175
+ The authoritative design rationale (with HP manual citations) lives in `DESIGN.md`; the
176
+ running decision log is the "Follow-up steering" section of `TASK-1-BASIC-IMPLEMENTATION.md`.
177
+
178
+ ### Extending
179
+
180
+ Add a simple device by dropping a `<model>.toml` into `devices/profiles/` (buffer size,
181
+ pen count, serial defaults, capabilities, `pen_sensing`). A device with unusual behavior
182
+ can subclass `Device` and register it. The interface layer is transport-agnostic, so HP-IB
183
+ can be added as another `Transport` without touching the rest.
184
+
185
+ ---
186
+
187
+ ## Development
188
+
189
+ ```bash
190
+ tox # run the test suite (Python 3.13)
191
+ tox -e build # build the wheel
192
+ ```
193
+
194
+ Dependencies are managed two-file style: `requirements-rough.txt` (hand-maintained,
195
+ loose top-level) is frozen into a fully-pinned `requirements.txt` by the
196
+ `dependencies_update` GitHub Actions workflow. A `Dockerfile` provides a reproducible
197
+ build/test image (not for serial I/O - hardware is not reachable from a container).
198
+
199
+ Conventions: extensive logging (no `print`), ASCII-only output, descriptive names, and
200
+ errors that state what happened, where, and why.
@@ -0,0 +1,172 @@
1
+ # hpgl-buddy
2
+
3
+ Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232.
4
+
5
+ It does not just shove a file at the plotter: it validates the file, splits it to fit
6
+ the device buffer, feeds it so the buffer never overflows and an inked pen never stalls
7
+ mid-stroke, watches the device for faults the whole time, and logs every exchange so a
8
+ run can be understood and troubleshooted from the log alone.
9
+
10
+ **Supported device:** HP 7475A (RS-232). New devices are added as declarative profiles
11
+ (see [Extending](#extending)); HP-IB is planned.
12
+
13
+ ---
14
+
15
+ ## Install
16
+
17
+ Requires Python 3.13 and a USB-serial adapter (macOS: use the `/dev/cu.*` device).
18
+
19
+ ```bash
20
+ pip install -e . # editable, for development
21
+ # or build a wheel:
22
+ python -m build --wheel # -> dist/hpgl_buddy-*.whl (or: tox -e build)
23
+ ```
24
+
25
+ `pyserial` is the only runtime dependency.
26
+
27
+ ---
28
+
29
+ ## Quick start
30
+
31
+ ```bash
32
+ # 1. Validate a file offline (no plotter needed)
33
+ hpgl-buddy check drawing.hpgl
34
+
35
+ # 2. Check the plotter is alive and interpret its status
36
+ hpgl-buddy status --port /dev/cu.usbserial-XXXX
37
+
38
+ # 3. Plot it (verbose shows every byte/ESC exchange)
39
+ hpgl-buddy -v plot drawing.hpgl --port /dev/cu.usbserial-XXXX
40
+
41
+ # 4. Generate and plot a built-in demo
42
+ hpgl-buddy demo --pens 6 --out demo.hpgl
43
+ hpgl-buddy plot demo.hpgl --port /dev/cu.usbserial-XXXX
44
+ ```
45
+
46
+ Serial defaults: **9600 8N1, no flow control** (configurable). Flow control is off by
47
+ default because XON/XOFF corrupted the exchange on the on-site adapter; enable it with
48
+ `--xonxoff` if your cabling needs it.
49
+
50
+ ---
51
+
52
+ ## Commands
53
+
54
+ | Command | What it does |
55
+ |---|---|
56
+ | `check FILE` | Offline HP-GL syntax check. No device. Exit non-zero on errors. |
57
+ | `status` | Ad-hoc healthcheck: identification, buffer, status byte, errors, limits - all interpreted. |
58
+ | `plot FILE` | Safe, buffer-aware plotting with progress + end-of-run report. |
59
+ | `monitor on\|off\|watch` | Switch monitor mode (computer port) or stream the echoed bytes (terminal port). |
60
+ | `demo` | Generate demo HP-GL (`--scene card` shapes/fills/labels/colours, or `--scene house` a continuous one-line drawing). |
61
+
62
+ Global: `-v/--verbose` (DEBUG, incl. raw ASCII+hex wire dumps), `--version`.
63
+
64
+ Serial options (on `status`/`plot`/`monitor`): `--port`, `--model` (default `hp7475a`),
65
+ `--baud`, `--framing` (e.g. `8N1`), `--timeout`, `--xonxoff`, `--rtscts`.
66
+
67
+ ### plot options
68
+
69
+ - `--on-error abort|prompt|continue` - on a reported error: stop and park the pen
70
+ (default), ask interactively, or auto-recover (`ESC.K` discard -> `IN` -> replay the
71
+ tracked state preamble -> carry on).
72
+ - `--live-hpgl-verify off|chunk|pu` - optional on-device HP-GL error checking (see
73
+ [Verification](#verification)). Default `off`.
74
+ - `--ignore-syntax-errors` - plot even if the offline check found errors.
75
+ - `--stats-json PATH` - write run statistics as JSON (`-` for stdout).
76
+
77
+ ### monitor (two ports)
78
+
79
+ The 7475A enables monitor mode via an ESC sequence on the **computer** (data) port, then
80
+ echoes received bytes out a separate **terminal** port. So:
81
+
82
+ ```bash
83
+ # stream the echo on the terminal port, enabling monitor on the computer port first
84
+ hpgl-buddy monitor watch --port /dev/cu.TERMINAL --command-port /dev/cu.COMPUTER --enable
85
+ ```
86
+
87
+ `watch` prints every byte as binary, hex, decimal, and ASCII/control-name.
88
+
89
+ ---
90
+
91
+ ## How plotting works
92
+
93
+ ```
94
+ file -> parse -> offline syntax check -> plan into chunks -> stream to device -> report
95
+ ```
96
+
97
+ 1. **Parse** the bytes into instructions, each tagged with its source line and sequence
98
+ index (so any error names the exact command).
99
+ 2. **Syntax check** offline; `plot` refuses a file with errors unless `--ignore-syntax-errors`.
100
+ 3. **Plan** into chunks of <=256 bytes, split only at instruction boundaries (never inside
101
+ a command), each tagged whether it ends with the pen up.
102
+ 4. **Stream**: a chunk is sent only when `ESC.B` reports enough free buffer space. This one
103
+ gate both prevents overflow and keeps the buffer fed, so a long pen-down stroke spanning
104
+ several chunks never underruns (an underrun would park an inked pen and blot).
105
+ 5. **Watch** (always on, after each chunk): `ESC.E` for I/O faults (overflow / framing /
106
+ data loss) and `ESC.O` for environmental faults (paper lever or pinch wheels raised ->
107
+ abort; VIEW pressed -> warn). Both are immediate and never stall the pen.
108
+ 6. **Confirm**: a final `OS;OE;OI;` tailgate waits for the pen to physically finish and
109
+ reports the end status / any HP-GL error.
110
+ 7. **Report** instructions/chunks/bytes sent, elapsed time, recovered errors, and warnings
111
+ (and the same as JSON via `--stats-json`).
112
+
113
+ ### Verification
114
+
115
+ HP-GL/syntax errors are a property of the *file* (already validated offline), so on-device
116
+ HP-GL error checking is **optional** and off by default. When enabled it never stalls the
117
+ pen - it uses a *one-deep* tailgate: the `OS;OE;OI;` query is prefixed to the chunk after a
118
+ pen-up, so its verdict reports the *previous* chunk while the current one is already drawing.
119
+
120
+ - `chunk` - check at pen-up chunk boundaries.
121
+ - `pu` - break a chunk at every pen-up so each completed stroke is checked (more, smaller
122
+ chunks).
123
+
124
+ Either way you learn a chunk is clean within ~1 chunk, and a reported error names the span
125
+ of chunks it could belong to with all candidate instructions.
126
+
127
+ ### Limits to know
128
+
129
+ - **No pen sensing on the 7475A**: a missing or fallen pen plots dry and is *not* detectable
130
+ by any status query. Pre-load the pens your file uses. (`plot` warns about this.)
131
+
132
+ ---
133
+
134
+ ## Architecture
135
+
136
+ Thoroughly separated layers, each replaceable on its own:
137
+
138
+ ```
139
+ hpgl/ parse HP-GL bytes into a Program; offline syntax check
140
+ devices/ declarative TOML profiles + abstract Device base (registry)
141
+ interface/ Transport abstraction + pyserial RS-232 implementation
142
+ status/ ESC + HP-GL command builders, response parsers, status interpretation, monitor
143
+ execution/ planner (Program -> chunks) + flow control + executor + progress/report
144
+ demo/ demo HP-GL generators
145
+ ```
146
+
147
+ The authoritative design rationale (with HP manual citations) lives in `DESIGN.md`; the
148
+ running decision log is the "Follow-up steering" section of `TASK-1-BASIC-IMPLEMENTATION.md`.
149
+
150
+ ### Extending
151
+
152
+ Add a simple device by dropping a `<model>.toml` into `devices/profiles/` (buffer size,
153
+ pen count, serial defaults, capabilities, `pen_sensing`). A device with unusual behavior
154
+ can subclass `Device` and register it. The interface layer is transport-agnostic, so HP-IB
155
+ can be added as another `Transport` without touching the rest.
156
+
157
+ ---
158
+
159
+ ## Development
160
+
161
+ ```bash
162
+ tox # run the test suite (Python 3.13)
163
+ tox -e build # build the wheel
164
+ ```
165
+
166
+ Dependencies are managed two-file style: `requirements-rough.txt` (hand-maintained,
167
+ loose top-level) is frozen into a fully-pinned `requirements.txt` by the
168
+ `dependencies_update` GitHub Actions workflow. A `Dockerfile` provides a reproducible
169
+ build/test image (not for serial I/O - hardware is not reachable from a container).
170
+
171
+ Conventions: extensive logging (no `print`), ASCII-only output, descriptive names, and
172
+ errors that state what happened, where, and why.
@@ -0,0 +1,49 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hpgl-buddy"
7
+ dynamic = ["version"]
8
+ description = "Carefree, observable plotting of HP-GL files on HP pen plotters over RS-232."
9
+ readme = "README.md"
10
+ requires-python = ">=3.13"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Pavel Kim", email = "hello@pavelkim.com" }]
13
+ keywords = ["hpgl", "plotter", "hp7475a", "rs232", "pen-plotter"]
14
+ classifiers = [
15
+ "Development Status :: 5 - Production/Stable",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Printing",
24
+ "Topic :: System :: Hardware :: Hardware Drivers",
25
+ ]
26
+
27
+ # pyserial is the sole runtime dependency. TOML profiles are read with the
28
+ # standard-library tomllib (Python 3.11+), so no extra parser is needed.
29
+ dependencies = ["pyserial>=3.5"]
30
+
31
+ [project.optional-dependencies]
32
+ dev = ["pytest>=8"]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/hpgl-buddy/hpgl-buddy"
36
+ Repository = "https://github.com/hpgl-buddy/hpgl-buddy"
37
+ Issues = "https://github.com/hpgl-buddy/hpgl-buddy/issues"
38
+
39
+ [project.scripts]
40
+ hpgl-buddy = "hpgl_buddy.cli:main"
41
+
42
+ [tool.setuptools.dynamic]
43
+ version = { attr = "hpgl_buddy.version.__version__" }
44
+
45
+ [tool.setuptools.packages.find]
46
+ where = ["src"]
47
+
48
+ [tool.setuptools.package-data]
49
+ hpgl_buddy = ["devices/profiles/*.toml"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,17 @@
1
+ """hpgl-buddy - carefree, observable plotting of HP-GL files on HP pen plotters.
2
+
3
+ The package is split into thoroughly isolated layers so that new devices,
4
+ interfaces, or protocols can be added without disturbing the others:
5
+
6
+ hpgl - parse HP-GL bytes into a Program and validate it offline.
7
+ devices - declarative device profiles plus the abstract Device base.
8
+ interface - the Transport abstraction and its RS-232 implementation.
9
+ status - ESC command builders, response parsers, status interpretation.
10
+ execution - planning a Program into safe chunks and feeding the device.
11
+
12
+ See DESIGN.md at the repository root for the rationale behind each layer.
13
+ """
14
+
15
+ from .version import __version__
16
+
17
+ __all__ = ["__version__"]