- Go 85.2%
- JavaScript 7.2%
- HTML 4.2%
- CSS 3.4%
Talk to the printer's ESCPL2 language directly over libusb, since the CUPS usb backend on current macOS no longer loads the vendor's USB print-class plugin. The core reads the installed cartridge from a vendor control transfer, which also carries the activity flag used to wait for a job to finish. Jobs carry a cut policy that makes the printer discard the blank tape ahead of the print, so a label starts at its cut edge, and a run of labels prints as one job that pays for that leader once. Measured on the printer: the head resolves 180 dpi across the tape while the tape advances about 0.136 mm per raster record, so label pixels are not square. The calibration profile carries the measured feed scale, and text is drawn at a square resolution and resampled onto the dot grid to keep glyph shapes right. Codes are composited at final resolution instead, so module edges land on dot boundaries, and a matrix code too small to scan is refused. A CLI covers text, codes, images, stored templates and CSV runs. The editor serves a local page whose preview is rendered by the same code that feeds the printer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| cmd/labeler | ||
| internal | ||
| .gitignore | ||
| DESIGN.md | ||
| go.mod | ||
| go.sum | ||
| README.md | ||
labeler
Print labels on an Epson LabelWorks LW-600P from macOS, over USB, without the Epson driver.
Epson's own stack no longer prints on current macOS: the CUPS usb backend
stopped loading third-party USB print-class plugins, and LWUSBPrintClass.plugin
is one. This talks to the printer's ESCPL2 language directly instead.
go build -o labeler ./cmd/labeler
./labeler status # 12 mm tape, ready
./labeler print "Rack A / Port 12"
./labeler edit # editor at http://127.0.0.1:8474/
What it does
- Senses the tape. Every print reads the installed cartridge and refuses a label too tall for it.
- Trims the leader. The printer's own cut policy discards the blank tape ahead of the print, so a label begins at its cut edge.
- Prints a run as one job. A batch pays for the leader once, however many labels it carries.
- Fits the type to the tape, with any installed font.
- Draws codes that scan. QR, Data Matrix, Aztec, PDF417 and the common linear symbologies, refused rather than printed when the tape is too narrow for a readable module.
Commands
labeler status tape width and ready state
labeler probe descriptors and raw status
labeler print "Rack A / Port 12" one label
labeler print -code qr -code-data URL TEXT a code beside the text
labeler print -image logo.png a picture, dithered to the tape
labeler print -template rack -set port=12 a stored layout, filled in
labeler batch -template rack -csv rows.csv one label per row, as one job
labeler templates [-save NAME ...] list or store layouts
labeler calibrate [-measured MM] measure the feed scale
labeler feed [-cut]
labeler edit the editor, in a browser
Add -dry-run FILE to write the printer stream to a file instead of printing,
and -preview FILE.png to save what the label will look like.
Templates
A template is a label with {field} placeholders, stored by name:
labeler templates -save rack -bold \
-code qr -code-data 'https://inv.local/{asset}' '{rack} / Port {port}'
labeler print -template rack -set rack=A -set port=12 -set asset=4711
labeler batch -template rack -csv racks.csv
The CSV's header row names the columns. A placeholder with no value fails the run before any tape is spent.
Calibration
The head resolves 180 dpi across the tape, and the tape advances a shorter step than that along it, so lengths need a measured correction:
labeler calibrate # prints an 80 mm span
labeler calibrate -measured 77.1 # folds the measurement in
The result lives in ~/Library/Application Support/labeler/profile.json,
along with the font the editor last chose, which the command line then uses as
its default.
Requirements
macOS, Go, and libusb (brew install libusb). The printer connects over USB
and needs no Epson software installed. A CUPS queue for the same printer must
stay idle while this holds the interface.
Protocol
DESIGN.md records the ESCPL2 command set, the status and tape-sensing requests, the cut model, and what was measured on hardware.