-6
-6
-7importclick
-7importclick
-8fromreedmullerimportreedmuller
-8fromreedmullerimportreedmuller
-9
-9
-10
-10
-11classTag:
-11classTag:
-12""" Helper class to ease creation of SVG. All API functions that create SVG allow you to substitute this with your
-12""" Helper class to ease creation of SVG. All API functions that create SVG allow you to substitute this with your
-13 own implementation by passing a ``tag`` parameter. """
-13 own implementation by passing a ``tag`` parameter. """
-14
-14
-15def__init__(self,name,children=None,root=False,**attrs):
-15def__init__(self,name,children=None,root=False,**attrs):
-16if(fill:=attrs.get('fill'))andisinstance(fill,tuple):
-16if(fill:=attrs.get('fill'))andisinstance(fill,tuple):
-17attrs['fill'],attrs['fill-opacity']=fill
-17attrs['fill'],attrs['fill-opacity']=fill
-18if(stroke:=attrs.get('stroke'))andisinstance(stroke,tuple):
-18if(stroke:=attrs.get('stroke'))andisinstance(stroke,tuple):
-19attrs['stroke'],attrs['stroke-opacity']=stroke
-19attrs['stroke'],attrs['stroke-opacity']=stroke
-20self.name,self.attrs=name,attrs
-20self.name,self.attrs=name,attrs
-21self.children=childrenor[]
-21self.children=childrenor[]
-22self.root=root
-22self.root=root
-23
-23
-24def__str__(self):
-24def__str__(self):
-25prefix='<?xml version="1.0" encoding="utf-8"?>\n'ifself.rootelse''
-25prefix='<?xml version="1.0" encoding="utf-8"?>\n'ifself.rootelse''
-26opening=''.join([self.name]+[f'{key.replace("__",":").replace("_","-")}="{value}"'forkey,valueinself.attrs.items()])
-26opening=''.join([self.name]+[f'{key.replace("__",":").replace("_","-")}="{value}"'forkey,valueinself.attrs.items()])
-27ifself.children:
-27ifself.children:
-28children='\n'.join(textwrap.indent(str(c),'')forcinself.children)
-28children='\n'.join(textwrap.indent(str(c),'')forcinself.children)
-29returnf'{prefix}<{opening}>\n{children}\n</{self.name}>'
-29returnf'{prefix}<{opening}>\n{children}\n</{self.name}>'
-
-56**namespaces,
-60**namespaces,
-57root=True)
-61root=True)
-58
-62
-59
-63
-60@click.command()
-64@click.command()
-61@click.option('-h','--height',type=float,default=20,help='Bar height in mm')
-65@click.option('-h','--height',type=float,default=20,help='Bar height in mm')
-62@click.option('-t/-n','--text/--no-text',default=True,help='Whether to add text containing the data under the bar code')
-66@click.option('-t/-n','--text/--no-text',default=True,help='Whether to add text containing the data under the bar code')
-63@click.option('-f','--font',default='sans-serif',help='Font for the text underneath the bar code')
-67@click.option('-f','--font',default='sans-serif',help='Font for the text underneath the bar code')
-64@click.option('-s','--font-size',type=float,default=12,help='Font size for the text underneath the bar code in points (pt)')
-68@click.option('-s','--font-size',type=float,default=12,help='Font size for the text underneath the bar code in points (pt)')
-65@click.option('-b','--bar-width',type=float,default=1.0,help='Bar width in mm')
-69@click.option('-b','--bar-width',type=float,default=1.0,help='Bar width in mm')
-66@click.option('-m','--margin',type=float,default=3.0,help='Margin around bar code in mm')
-70@click.option('-m','--margin',type=float,default=3.0,help='Margin around bar code in mm')
-67@click.option('-c','--color',default='black',help='SVG color for the bar code')
-71@click.option('-c','--color',default='black',help='SVG color for the bar code')
-68@click.option('--text-color',default=None,help='SVG color for the text (defaults to the bar code\'s color)')
-72@click.option('--text-color',default=None,help='SVG color for the text (defaults to the bar code\'s color)')
-69@click.option('--dpi',type=float,default=96,help='DPI value to assume for internal SVG unit conversions')
-73@click.option('--dpi',type=float,default=96,help='DPI value to assume for internal SVG unit conversions')
-70@click.argument('data')
-74@click.argument('data')
-71@click.argument('outfile',type=click.File('w'),default='-')
-75@click.argument('outfile',type=click.File('w'),default='-')
-72defcli(data,outfile,height,text,font,font_size,bar_width,margin,color,text_color,dpi):
-76defcli(data,outfile,height,text,font,font_size,bar_width,margin,color,text_color,dpi):
-73data=int(data,16)
-77data=int(data,16)
-74text_color=text_colororcolor
-78text_color=text_colororcolor
-75
-79
-76NUM_BITS=26
-80NUM_BITS=26
-77
-81
-78data_bits=[bool(data&(1<<i))foriinrange(NUM_BITS)]
-82data_bits=[bool(data&(1<<i))foriinrange(NUM_BITS)]
-79data_encoded=itertools.chain(*[
-83data_encoded=itertools.chain(*[
-80(a,nota)foraindata_bits
-84(a,nota)foraindata_bits
-81])
-85])
-82data_encoded=[True,False,True,False,*data_encoded,False,True,True,False,True]
-86data_encoded=[True,False,True,False,*data_encoded,False,True,True,False,True]
-83
-87
-84width=len(data_encoded)*bar_width
-88width=len(data_encoded)*bar_width
-85# 1 px = 0.75 pt
-89# 1 px = 0.75 pt
-86pt_to_mm=lambdapt:pt/0.75/dpi*25.4
-90pt_to_mm=lambdapt:pt/0.75/dpi*25.4
-87font_size=pt_to_mm(font_size)
-91font_size=pt_to_mm(font_size)
-88total_height=height+font_size*2
-92total_height=height+font_size*2
-89
-93
-90tags=[]
-94tags=[]
-91forkey,groupinitertools.groupby(enumerate(data_encoded),key=lambdax:x[1]):
-95forkey,groupinitertools.groupby(enumerate(data_encoded),key=lambdax:x[1]):
-92ifkey:
-96ifkey:
-93group=list(group)
-97group=list(group)
-94x0,_key=group[0]
-98x0,_key=group[0]
-95w=len(group)
-99w=len(group)
-96tags.append(Tag('path',stroke=color,stroke_width=w,d=f'M {(x0+w/2)*bar_width} 0 l 0 {height}'))
-100tags.append(Tag('path',stroke=color,stroke_width=w,d=f'M {(x0+w/2)*bar_width} 0 l 0 {height}'))
-97
-101
-98iftext:
-102iftext:
-99tags.append(Tag('text',children=[f'{data:07x}'],
-103tags.append(Tag('text',children=[f'{data:07x}'],
-100x=width/2,y=height+0.5*font_size,
-104x=width/2,y=height+0.5*font_size,
-101font_family=font,font_size=f'{font_size:.3f}px',
-105font_family=font,font_size=f'{font_size:.3f}px',
-102text_anchor='middle',dominant_baseline='hanging',
-106text_anchor='middle',dominant_baseline='hanging',
-103fill=text_color))
-107fill=text_color))
-104
-108
-