Skip to content

Instantly share code, notes, and snippets.

@carlsmith
Last active March 27, 2018 11:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlsmith/643cefd7a4712f36cc8b to your computer and use it in GitHub Desktop.
Save carlsmith/643cefd7a4712f36cc8b to your computer and use it in GitHub Desktop.
Interleaved 2 of 5, SVG Barcode Generator
def render(digits):
'''This function converts its input, a string of decimal digits, into a
barcode, using the interleaved 2 of 5 format. The input string must not
contain an odd number of digits. The output is an SVG string.
Wikipedia [ITF Format]: http://en.wikipedia.org/wiki/Interleaved_2_of_5
'''
top = '<svg height="58" width="{0}" style="background:white">'
bar = '<rect x="{0}" y="4" width="{1}" height="50" style="fill:black"/>'
barcode = [top.format(len(digits) * 14 + 24)]
byte_map = {
'0': (2, 2, 4, 4, 2), '1': (4, 2, 2, 2, 4),
'2': (2, 4, 2, 2, 4), '3': (4, 4, 2, 2, 2),
'4': (2, 2, 4, 2, 4), '5': (4, 2, 4, 2, 2),
'6': (2, 4, 4, 2, 2), '7': (2, 2, 2, 4, 4),
'8': (4, 2, 2, 4, 2), '9': (2, 4, 2, 4, 2)
}
byte = lambda i: byte_map[digits[i]]
def encode(bits, i=0):
'''Encodes a string of decimal digits. The output's a binary string,
but as a list of ints, all 2s and 4s, rather than zeros and ones, as
the bars in the SVG barcode are rendered 2px wide for zeros, 4px for
ones.'''
if i == len(digits): return bits
for odd, even in zip(byte(i), byte(i+1)): bits.extend([odd, even])
return encode(bits, i+2)
def svg(bits, i=0, x=4):
'''Converts the list of ints returned by `encode` to a list of SVG
elements that can be joined to form an SVG string.'''
if i == len(bits): return barcode + ['</svg>']
odd, even = bits[i:i+2]
barcode.append(bar.format(x, odd))
return svg(bits, i+2, x+odd+even)
# The call to `encode` passes in the itf start code, and the itf end
# code's added to the list that `encode` returns. The complete list
# is passed to `svg`, which returns a list of SVG element strings
# that're joined with newlines to create the actual SVG output.
return '\n'.join(svg(encode([2, 2, 2, 2]) + [4, 2, 2, 0]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment