<dtml-comment>
converts barcode into an isbn
expects "barcode" to be bound to a string
representing the barcode
derived from code by Andrew Plotkin ([email protected])
http://www.eblong.com/zarf/bookscan/
</dtml-comment>
<dtml-let linelen="_.len(barcode)"
tt="_.string.maketrans('', '')"
isbndigits="_.string.digits+'xX'"
bardigits="_.string.digits+' '"
justdigits="_.string.digits">
<dtml-if "linelen==10 and not
_.string.translate(barcode, tt, isbndigits)">
<dtml-return barcode>
</dtml-if>
<dtml-if "(linelen==13 or linelen==19) and not
_.string.translate(barcode, tt, bardigits)">
<dtml-if "barcode[0:3]!='978'">
<dtml-raise type='ISBNError'>
<dtml-var barcode> is not a 978 EAN
</dtml-raise>
</dtml-if>
<dtml-let line="barcode[3:12]">
<dtml-comment> isbn checksum </dtml-comment>
<dtml-if "not (_.len(line)==9 or _.len(line)==10)">
<dtml-raise type='ISBNError'>
<dtml-var barcode> ISBN should be 9 digits, excluding checksum!
</dtml-raise>
</dtml-if>
<dtml-let line="line[:9]"
sum="[0]">
<dtml-in "_.range(9)">
<dtml-let count=sequence-index>
<dtml-call "sum.append(sum.pop()+
(10-count)*_.string.atoi(line[count]))">
</dtml-let count>
</dtml-in>
<dtml-let sum="sum[0] % 11"
sum="sum and 11-sum"
line="line+(sum==10 and 'X' or _.string.digits[sum])">
<dtml-return line>
</dtml-let>
</dtml-let line>
<dtml-comment>end of checksum code</dtml-comment>
</dtml-let line>
</dtml-if>
<dtml-if "linelen==12 and not
_.string.translate(barcode, tt, bardigits)">
<dtml-raise type='ISBNError'>
<dtml-var barcode> UPC barcode requires five-digit extension
</dtml-raise>
</dtml-if>
<dtml-if "linelen==18 and not
_.string.translate(barcode, tt, bardigits)">
<dtml-let prefix="barcode[0:6]"
suffix="barcode[13:18]"
upcmap="{
'014794':'08041',
'018926':'0445',
'027778':'0449',
'037145':'0812',
'042799':'0785',
'043144':'0688',
'044903':'0312',
'045863':'0517',
'046594':'0064',
'047132':'0152',
'051487':'08167',
'051488':'0140',
'060771':'0002',
'065373':'0373',
'070992':'0523',
'070993':'0446',
'070999':'0345',
'071001':'0380',
'071009':'0440',
'071125':'088677',
'071136':'0451',
'071149':'0451',
'071152':'0515',
'071162':'0451',
'071268':'08217',
'071831':'0425',
'071842':'08439',
'072742':'0441',
'076714':'0671',
'076783':'0553',
'076814':'0449',
'078021':'0872',
'079808':'0394',
'090129':'0679',
'099455':'0061',
'099769':'0451'
}"
>
<dtml-if "not upcmap.has_key(prefix)">
<dtml-raise type='ISBNError'>
<dtml-var prefix> Unknown UPC prefix
</dtml-raise>
</dtml-if>
<dtml-let ipref="upcmap(prefix)"
line="ipref+suffix[_.len(ipref)-4:]">
<dtml-comment> isbnchecksum on line</dtml-comment>
<dtml-comment> isbn checksum </dtml-comment>
<dtml-if "not (_.len(line)==9 or _.len(line)==10)">
<dtml-raise type='ISBNError'>
<dtml-var barcode> ISBN should be 9 digits, excluding checksum!
</dtml-raise>
</dtml-if>
<dtml-let line="line[:9]"
sum="[0]">
<dtml-in "_.range(9)">
<dtml-let count=sequence-index>
<dtml-call "sum.append(sum.pop()+
(10-count)*_.string.atoi(line[count]))">
</dtml-let count>
</dtml-in>
<dtml-let sum="sum[0] % 11"
sum="sum and 11-sum"
line="line+(sum==10 and 'X' or _.string.digits[sum])">
<dtml-return line>
</dtml-let>
</dtml-let line>
<dtml-comment>end of checksum code</dtml-comment>
</dtml-let ipref line>
</dtml-let prefix suffix>
</dtml-if linelen18>
</dtml-let linelen>
<dtml-raise 'ISBNError'>
<dtml-var barcode> Unrecognized format
</dtml-raise>