Merge pull request #1 from OliverFriedrich/main

Alignment for print and small layout improvements

options to handle invalid vertical and/or horizontal printer alignment
remove additional padding from qr code
use qr code margin option also as minimum spacing to upper and lower label border
fix positioning of ASN number
Add Avery L7871 label definition (it's a clone of 4731)
This commit is contained in:
aborelis 2025-09-21 15:13:26 +02:00 committed by GitHub
commit 75e39bf8a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 32 deletions

View file

@ -26,6 +26,7 @@ labelInfo = {
3044: (2, 11, (32, 10), (2, 2), (1, 1), (66.5 * mm, 120.5 * mm)), 3044: (2, 11, (32, 10), (2, 2), (1, 1), (66.5 * mm, 120.5 * mm)),
# 189x 25.4mm x 10mm mini labels # 189x 25.4mm x 10mm mini labels
4731: (7, 27, (25.4 * mm, 10 * mm), (2.5 * mm, 0), (9 * mm, 13.5 * mm), A4), 4731: (7, 27, (25.4 * mm, 10 * mm), (2.5 * mm, 0), (9 * mm, 13.5 * mm), A4),
7871: (7, 27, (25.4 * mm, 10 * mm), (2.5 * mm, 0), (9 * mm, 13.5 * mm), A4),
# 2.6 x 1 address labels # 2.6 x 1 address labels
5160: (3, 10, (187, 72), (11, 0), (14, 36), A4), 5160: (3, 10, (187, 72), (11, 0), (14, 36), A4),
5161: (2, 10, (288, 72), (0, 0), (18, 36), A4), 5161: (2, 10, (288, 72), (0, 0), (18, 36), A4),
@ -44,7 +45,7 @@ labelInfo = {
class AveryLabel: class AveryLabel:
def __init__(self, label, **kwargs): def __init__(self, label, pageoffset, **kwargs):
data = labelInfo[label] data = labelInfo[label]
self.across = data[0] self.across = data[0]
self.down = data[1] self.down = data[1]
@ -55,6 +56,8 @@ class AveryLabel:
self.debug = False self.debug = False
self.pagesize = data[5] self.pagesize = data[5]
self.position = 0 self.position = 0
self.pageoffset = pageoffset
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
def open(self, filename): def open(self, filename):
@ -76,8 +79,8 @@ class AveryLabel:
y, x = divmod(x, self.across) y, x = divmod(x, self.across)
return ( return (
self.margins[0] + x * self.labelsep[0], self.margins[0] + x * self.labelsep[0] + self.pageoffset[0],
self.pagesize[1] - self.margins[1] - (y + 1) * self.labelsep[1], self.pagesize[1] - self.margins[1] - (y + 1) * self.labelsep[1] - self.pageoffset[1],
) )
def advance(self): def advance(self):
@ -101,7 +104,7 @@ class AveryLabel:
# Or, pass a callable and an iterator. We'll do one label # Or, pass a callable and an iterator. We'll do one label
# per iteration of the iterator. # per iteration of the iterator.
def render(self, thing, count, offset=0, *args): def render(self, thing, count, offset=0, pageshift=(0 * mm, 0 * mm), *args):
""" render loop""" """ render loop"""
assert callable(thing) or isinstance(thing, str) assert callable(thing) or isinstance(thing, str)
if isinstance(count, Iterator): if isinstance(count, Iterator):
@ -128,6 +131,7 @@ class AveryLabel:
canv = self.canvas canv = self.canvas
for chunk in iterator: for chunk in iterator:
canv.saveState() canv.saveState()
canv.translate(*self.top_left()) canv.translate(*self.top_left())
if self.debug: if self.debug:
canv.setLineWidth(0.25) canv.setLineWidth(0.25)

View file

@ -65,31 +65,38 @@ Usage: asn-gen.py [OPTIONS] [filename]
ASN Label Generator ASN Label Generator
Arguments: Arguments:
filename output filename of PDF file generated filename output filename of PDF file generated, if .pdf extension is missing the string will be used
as directory
Options: Options:
-l, --labeltype=STR Type of label, e.g. 4731, get a list of supported labels with --labels (default: 4731) -l, --labeltype=STR Type of label, e.g. 4731, get a list of supported labels with --labels (default: 4731)
-n, --number=INT number of labels to generate (default: 189) -n, --number=INT number of labels to generate (default: 189)
-o, --offset=INT Number of labels to skip on the first sheet (e.g. already used) (default: 0) -o, --offset=INT Number of labels to skip on the first sheet (e.g. already used) (default: 0)
-d, --num-digits=INT Number of digits for the ASN, e.g. 000001 (default: 6) -d, --num-digits=INT Number of digits for the ASN, e.g. 000001 (default: 6)
-s, --first-asn=INT First ASN to use, e.g. 100001 (default: 1) -s, --first-asn=INT First ASN to use, e.g. 100001 (default: 1)
-f, --font-size=STR Fontsize with a unit, e.g. 2mm, 0.4cm (default: 2mm) -f, --font-size=STR Fontsize with a unit, e.g. 2mm, 0.4cm (default: 2mm)
-q, --qr-size=FLOAT Size of the QR-Code as percentage of the label hight (default: 0.9) -q, --qr-size=FLOAT Size of the QR-Code as percentage of the label hight (default: 0.9)
-m, --qr-margin=STR Margin around the QR-Code with a unit, e.g. 1mm (default: 1mm) -m, --qr-margin=STR Margin around the QR-Code with a unit, e.g. 1mm (default: 1mm)
--sub-labels-x, --lx=INT How many labels to put on a phyical label horizontally (default: 1) --sub-labels-x, --lx=INT How many labels to put on a phyical label horizontally (default: 1)
--sub-labels-y, --ly=INT How many labels to put on a phyical label vertically (default: 1) --sub-labels-y, --ly=INT How many labels to put on a phyical label vertically (default: 1)
--debug enable debug mode --debug enable debug mode
--position-helper enable position helpers, e.g. as cutting guides when using sub labels --position-helper enable position helpers, e.g. as cutting guides when using sub labels
--bar-width, --bw=INT Show a colored bar on the right of the label (0 = no bar) (default: 0) --bar-width, --bw=INT Show a colored bar on the right of the label (0 = no bar) (default: 0)
--bar-color, --bc=STR Color of the bar, HEX notation (default: d2dede) --bar-color, --bc=STR Color of the bar, HEX notation (default: d2dede)
--highlight-bar-width, --hw=INT add a colored highlight bar on the right of the label (0 = no bar) (default: 0) --highlight-bar-width, --hw=INT
--highlight-bar-color, --hc=STR Color of the highlight bar, HEX notation (default: d9a4a6) add a colored highlight bar on the right of the label (0 = no bar) (default: 0)
-p, --prefix=STR Prefix to the actual ASN number (default: ASN) --highlight-bar-color, --hc=STR
Color of the highlight bar, HEX notation (default: d9a4a6)
-p, --prefix=STR Prefix to the actual ASN number (default: ASN)
--page-offset-x, --dx=STR Print offset of the labels on the page to handle horizontal printer alignment with unit
(e.g. -2mm) (default: 0mm)
--page-offset-y, --dy=STR Print offset of the labels on the page to handle vertical printer alignment with unit (e.g.
-1.5mm) (default: 0mm)
Other actions: Other actions:
-h, --help Show the help -h, --help Show the help
--labels Shows a list of supported labels --labels Shows a list of supported labels
--version Show the version --version Show the version
``` ```
#### Testing your printer settings #### Testing your printer settings

View file

@ -55,6 +55,9 @@ class LabelContext:
self.highlight_bar_color = HexColor("#d9a4a6") self.highlight_bar_color = HexColor("#d9a4a6")
self.prefix = "ASN" self.prefix = "ASN"
self.page_offset_x = 0 * mm
self.page_offset_y = 0 * mm
self.__dict__.update(data) self.__dict__.update(data)
self.current_asn = self.first_asn self.current_asn = self.first_asn
@ -84,13 +87,14 @@ def render(context: LabelContext, c: canvas.Canvas, width: float, height: float)
) )
context.inc_asn() context.inc_asn()
qr = QRCodeImage(barcode_value, size=sub_labelheight * context.qr_size) qr_width = min(sub_labelheight * context.qr_size, sub_labelheight - 2 * context.qr_margin)
qr = QRCodeImage(barcode_value, size=qr_width, border=0)
qr.drawOn( qr.drawOn(
c, x=context.qr_margin, y=sub_labelheight * ((1 - context.qr_size) / 2) c, x=context.qr_margin, y=(sub_labelheight - qr_width) / 2
) )
c.setFont("Helvetica", size=context.font_size) c.setFont("Helvetica", size=context.font_size)
c.drawString( c.drawString(
x=sub_labelheight, x= qr_width + 2 * context.qr_margin,
y=(sub_labelheight - context.font_size) / 2, y=(sub_labelheight - context.font_size) / 2,
text=barcode_value, text=barcode_value,
) )
@ -161,6 +165,8 @@ def generate(
highlight_bar_width: "hw" = 0, # type: ignore highlight_bar_width: "hw" = 0, # type: ignore
highlight_bar_color: "hc" = "d9a4a6", # type: ignore highlight_bar_color: "hc" = "d9a4a6", # type: ignore
prefix: "p" = "ASN", # type: ignore prefix: "p" = "ASN", # type: ignore
page_offset_x: "dx" = "0mm", # type: ignore
page_offset_y: "dy" = "0mm", # type: ignore
): # pylint: disable=too-many-locals ): # pylint: disable=too-many-locals
# pylint: disable=unused-argument # pylint: disable=unused-argument
"""ASN Label Generator """ASN Label Generator
@ -193,6 +199,9 @@ def generate(
:param prefix: Prefix to the actual ASN number :param prefix: Prefix to the actual ASN number
:param page_offset_x: Print offset of the labels on the page to handle horizontal printer alignment with unit (e.g. -2mm)
:param page_offset_y: Print offset of the labels on the page to handle vertical printer alignment with unit (e.g. -1.5mm)
""" """
parm = locals() parm = locals()
@ -201,6 +210,8 @@ def generate(
parm["bar_color"] = HexColor("#" + parm["bar_color"]) parm["bar_color"] = HexColor("#" + parm["bar_color"])
parm["highlight_bar_color"] = HexColor("#" + parm["highlight_bar_color"]) parm["highlight_bar_color"] = HexColor("#" + parm["highlight_bar_color"])
parm["labeltype"] = int(parm["labeltype"]) parm["labeltype"] = int(parm["labeltype"])
parm["page_offset_x"] = toLength(parm["page_offset_x"])
parm["page_offset_y"] = toLength(parm["page_offset_y"])
if parm["filename"] is None: if parm["filename"] is None:
parm["filename"] = gen_filename(parm) parm["filename"] = gen_filename(parm)
@ -211,7 +222,7 @@ def generate(
context = LabelContext(parm) context = LabelContext(parm)
label = AveryLabels.AveryLabel(context.labeltype) label = AveryLabels.AveryLabel(context.labeltype, (context.page_offset_x, context.page_offset_y))
label.debug = context.debug label.debug = context.debug
@ -226,8 +237,7 @@ def generate(
def labels(): def labels():
"""Shows a list of supported labels""" """Shows a list of supported labels"""
print("Supported Labels: " + ", ".join(map(str, labelInfo.keys()))) print("Supported Labels: " + ", ".join(map(str, sorted(labelInfo.keys()))))
def version(): def version():
"""Show the version""" """Show the version"""