Skip to content

Commit 4f4bef9

Browse files
authored
Merge pull request #72 from jgoerzen/main
Add new --batch option to read batch commands from stdin
2 parents 6baba88 + 9e2e7b4 commit 4f4bef9

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,45 @@ Any picture with JPEG standard may be printed. Beware it will be downsized to ta
180180
Take care of the trailing "" - you may enter text here which gets printed in
181181
front of the image
182182

183+
### More control with batch mode
184+
185+
When run with `--batch`, labelle gives you more control over the output. As the
186+
UI does, this mode allows multiple blocks of each type. `--batch` reads from
187+
stdin. Each line must begin with a command, a colon, and then details. The
188+
commands are:
189+
190+
* `LABELLE-LABEL-SPEC-VERSION:1` must be the first line.
191+
* `TEXT`: Starts a new text block. Any previous text lines will be printed
192+
first.
193+
* `NEWLINE`: Adds an additional line to the current block of text or QR. Used to
194+
create multiline blocks.
195+
* `QR`: Creates a QR code block
196+
197+
For instance, this input:
198+
199+
```text
200+
LABELLE-LABEL-SPEC-VERSION:1
201+
TEXT:FD12
202+
NEWLINE:2013
203+
QR:1234
204+
TEXT:BIG
205+
TEXT:LINE1
206+
NEWLINE:LINE2
207+
QR:12345
208+
```
209+
210+
Creates a label with:
211+
212+
* A 2-line text block (first line `FD12`, second line `2013`)
213+
* Then, a QR code for 1234
214+
* Then, a line-line text block with the text `BIG`
215+
* Then, another 2-line text block
216+
* Finally, a QR code
217+
218+
Which looks like this:
219+
220+
![Batch mode example](doc/batch-example.png)
221+
183222
## GUI
184223

185224
### Run Labelle GUI

doc/batch-example.png

1.8 KB
Loading

src/labelle/cli/cli.py

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# this notice are preserved.
77
# === END LICENSE STATEMENT ===
88
import logging
9+
import sys
910
from pathlib import Path
1011
from typing import List, NoReturn, Optional
1112

@@ -200,6 +201,10 @@ def default(
200201
"--qr", callback=qr_callback, help="QR code", rich_help_panel="Elements"
201202
),
202203
] = None,
204+
batch: Annotated[
205+
bool,
206+
typer.Option(help="Read batch commands from stdin", rich_help_panel="Elements"),
207+
] = False,
203208
barcode_content: Annotated[
204209
Optional[str],
205210
typer.Option("--barcode", help="Barcode", rich_help_panel="Elements"),
@@ -482,20 +487,67 @@ def default(
482487
BarcodeRenderEngine(content=barcode_content, barcode_type=barcode_type)
483488
)
484489

485-
if text:
490+
def render_text(lines):
486491
render_engines.append(
487492
TextRenderEngine(
488-
text_lines=text,
493+
text_lines=lines,
489494
font_file_name=font_path,
490495
frame_width_px=frame_width_px,
491496
font_size_ratio=int(font_scale) / 100.0,
492497
align=align,
493498
)
494499
)
495500

501+
if text:
502+
render_text(text)
503+
496504
if picture:
497505
render_engines.append(PictureRenderEngine(picture))
498506

507+
if batch:
508+
accumulator: List[str] = []
509+
accumulator_type: str = "empty"
510+
511+
def flush_all():
512+
nonlocal accumulator
513+
nonlocal accumulator_type
514+
if accumulator_type == "text":
515+
render_text(accumulator)
516+
elif accumulator_type == "qr":
517+
render_engines.append(
518+
QrRenderEngine(qr_callback("\n".join(accumulator)))
519+
)
520+
521+
accumulator = []
522+
accumulator_type = "empty"
523+
524+
# Verify version
525+
line = sys.stdin.readline().strip()
526+
parts = line.split(":", 1)
527+
if not (parts[0] == "LABELLE-LABEL-SPEC-VERSION" and parts[1] == "1"):
528+
err_console = Console(stderr=True)
529+
err_console.print(
530+
"Error: Batch doesn't begin with LABELLE-LABEL-SPEC-VERSION:1"
531+
)
532+
raise typer.Exit()
533+
534+
for line in sys.stdin:
535+
line = line.rstrip("\r\n")
536+
parts = line.split(":", 1)
537+
if parts[0] == "TEXT":
538+
flush_all()
539+
accumulator_type = "text"
540+
accumulator.append(parts[1])
541+
elif parts[0] == "QR":
542+
flush_all()
543+
accumulator_type = "qr"
544+
accumulator.append(parts[1])
545+
elif parts[0] == "NEWLINE":
546+
accumulator.append(parts[1])
547+
else:
548+
print("WARNING: invalid command", line)
549+
flush_all()
550+
499551
if fixed_length is None:
500552
min_label_mm_len = min_length
501553
max_label_mm_len = max_length

0 commit comments

Comments
 (0)