#!/usr/bin/python # -*- coding: utf-8 -*- # # Converts cafix binary files (Casio programs) to various readable text formats. # # Copyright (C) 2011 Bauke Conijn # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # class translater: """Tool for translating casio binary files to a readable format.""" def __init__(self,colors=False, extended=False, html=False, css=False): self.errorstyle = '{%s}' def S(ascii, utf): """Get argument depending on the value of the 'extended' parameter.""" if extended: return utf else: return ascii def H(plain, htmlv): """Get argument depending on the value of the 'html' parameter.""" if html: return htmlv else: return plain self.html = html self.css = css self.table_special = { # 0x7f 0x20: 'Max(', 0x2c: 'Seq(', 0x2d: 'Min(', 0x34: 'Orange ', 0x36: 'Green ', 0x40: 'Mat ', 0x41: 'Trn ', 0x42: '*Row ', 0x43: '*Row+ ', 0x46: 'Dim ', 0x4b: S('Mat->List(','Mat→List('), 0x51: 'List ', 0x8f: 'Getkey', 0xb0: ' And ', 0xb1: ' Or ' } self.table_flow = { # 0xf7 0x00: 'If ', 0x01: 'Then ', 0x02: 'Else ', 0x03: 'IfEnd', 0x04: 'For ', 0x05: ' To ', 0x07: 'Next', 0x08: 'While ', 0x09: 'WhileEnd', 0x0a: 'Do', 0x0b: 'LpWhile ', 0x0e: 'Stop', 0x10: 'Locate ', 0x18: 'ClrText', 0x19: 'ClrGraph', 0x5e: 'Power', 0xa5: 'Text ', 0xa7: 'F-Line ', 0xb8: 'File1', 0xb9: 'File2', 0xba: 'File3', 0xbb: 'File4', 0xbc: 'File5', 0xbd: 'File6', 0xc2: 'AxesOn', 0xd2: 'AxesOff' } self.table_root = { 0x01: 'femto', 0x02: 'pico', 0x03: 'nano', 0x04: 'micro', 0x05: 'milli', 0x06: 'kilo', 0x07: 'mega', 0x08: 'giga', 0x09: 'tera', 0x0a: 'peta', 0x0b: 'exa', 0x0c: H(S(' [print]\n','◿\n'),'◿
\n'), 0x0d: H('\n','
\n'), 0x0e: S(H('->','->'),'→'), 0x0f: S('E', 'ᴇ'), # the *10^ variant 0x10: S(H('<=','<='),'≤'), 0x11: S(H('<>','<>'),'≠'), 0x12: S(H('>=','>='),'≥'), 0x13: S(H('=>','=>'),'⇒'), 0x14: S('f1','f₁'), 0x15: S('f2','f₂'), 0x16: S('f3','f₃'), 0x17: S('f4','f₄'), 0x18: S('f5','f₅'), 0x19: S('A','𝐀'), # hexadecimal nr 10 (bold) 0x1a: S('B','𝐁'), # hexadecimal nr 11 (bold) 0x1b: S('C','𝐂'), # hexadecimal nr 12 (bold) 0x1c: S('D','𝐃'), # hexadecimal nr 13 (bold) 0x1d: S('E','𝐄'), # hexadecimal nr 14 (bold) 0x1e: S('F','𝐅'), # hexadecimal nr 15 (bold) # 20-5b are identical (though +,-,* and / are just symbols) 0x5c: S('yen','¥'), # Displayed like a yen symbol. Probably unused. # 5d-7e are identical (^ is just a symbol I guess) 0x7f: self.table_special, 0x80: 'Pol(', 0x81: 'sin ', 0x82: 'cos ', 0x83: 'tan ', 0x84: 'h', # it's displayed like this 0x85: 'ln ', 0x86: S('sqrt ','√'), 0x87: S('(-)','‐'), # small minus 0x88: 'nPr', # displayed as a bold 'P' 0x89: '+', 0x8a: 'xnor', 0x8b: S('^2','²'), 0x8c: '\'', # degree-minutes-seconds symbol 0x8d: 'integrate(', 0x8e: 'Mod', 0x8f: S('Sum x^2','Sum x²'), 0x91: 'asin', 0x92: 'acos', 0x93: 'atan', 0x94: 'd', # it's displayed like this 0x95: 'log ', 0x96: S('cuberoot ','∛'), 0x97: 'Abs ', 0x98: 'nCr', # displayed as a bold 'C' 0x99: '-', # subtraction 0x9a: 'xor', 0x9b: H(S('^-1','⁻¹'),'-1'), 0x9c: S('degree','°'), 0x9e: 'Med', 0x9f: 'Sum x', 0xa0: 'Rec(', 0xa1: 'sinh ', 0xa2: 'cosh ', 0xa3: 'tanh ', 0xa4: 'o', # it's displayed like this 0xa5: 'e', # 2.71828... I guess 0xa6: 'Int ', 0xa7: 'Not ', 0xa8: '^', # power 0xa9: '*', # multiplication 0xaa: 'or', 0xab: '!', 0xac: H(S('^r','ʳ'),'r'), # radians 0xad: 'minY', 0xae: 'minX', 0xb1: 'asinh ', 0xb2: 'acosh ', 0xb3: 'atanh ', 0xb4: 'b', # it's displayed like this 0xb5: H('10^','10'), # it's displayed as a single character subscript 10 0xb6: 'Frac ', 0xb7: 'Neg', 0xb8: S('-th root ', '̽√'), 0xb9: '/', # Devision 0xba: 'and', 0xbb: S('_','⌟'), # small (mirrored) L 0xbc: S('^g', 'ᵍ'), # grades (something like degrees and radians) 0xbd: 'maxY', 0xbe: 'maxX', 0xbf: S('Sum y^2','Sum y²'), 0xc0: 'Ans', 0xc1: 'Ran#', 0xc2: 'x-bar', 0xc3: 'y-bar', 0xc4: 'x sigma n', 0xc5: 'x sigma n-1', 0xc6: 'y sigma n', 0xc7: 'y sigma n-1', 0xc8: 'a', # it's displayed like this 0xc9: 'b', # it's displayed like this 0xca: 'r', # it's displayed like this 0xcb: S('x','x̂'), # a x with ^ 0xcc: S('y','ŷ'), # an y with ^ 0xcd: S('rho','ρ'), 0xce: S('tau','τ'), 0xcf: 'Sum y', 0xd0: S('pi','π'), 0xd1: 'Cls', 0xd3: 'Rnd', 0xd4: 'Dec', 0xd5: 'Hex', 0xd6: 'Bin', 0xd7: 'Oct', 0xd9: 'Norm', 0xda: 'Deg', 0xdb: 'Rad', 0xdc: 'Gra', 0xdd: 'Eng', 0xde: 'Intg ', 0xdf: 'Sum xy', 0xe0: 'Plot ', 0xe1: 'Line', 0xe2: 'Lbl ', 0xe3: 'Fix ', 0xe4: 'Sci ', 0xe8: 'Dsz ', 0xe9: 'Isz ', 0xea: 'Factor ', 0xeb: 'ViewWindow ', 0xec: 'Goto ', 0xed: 'Prog ', 0xee: 'Graph Y=', 0xef: 'Graph Integrate', 0xf0: H('Graph Y>','Graph Y>'), 0xf1: H('Graph Y<','Graph Y<'), 0xf2: S(H('Graph Y>=','Graph Y>='),'Graph Y≥'), 0xf3: S(H('Graph Y<=','Graph Y<='),'Graph Y≤'), 0xf4: 'Graph r=', 0xf5: 'Graph(X,Y)=', 0xf6: ',', 0xf7: self.table_flow, 0xfb: 'P(', 0xfc: 'Q(', 0xfd: 'R(', 0xfe: 't(', 0xff: H('\n','
\n') # End of file symbol } if colors: if html: def colorwrap(c,s): return '%s'%(c, s) else: def colorwrap(c,s): return "\033[%sm%s\033[0m"%(c, s) ts = type('') def colormap(c,m): for i in m: if type(m[i]) is ts: m[i] = colorwrap(c, m[i]) colormap(H('32','special'), self.table_special) colormap(H('33','symbol'), self.table_root) colormap(H('34','flow'), self.table_flow) self.errorstyle = colorwrap(H('1;31','error'), self.errorstyle) for l in ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~': self.table_root[ord(l)]=l if colors: self.table_root[ord('"')]=colorwrap(H('35','quotes'),'"') if html: self.table_root[ord('<')]='<' self.table_root[ord('>')]='>' self.table_root[ord(' ')]=' ' self.table_root[ord('&')]='&' self.table_root[0x0d] = '
\n' # strips style tags def translate(self, bytes): table = self.table_root ret = [] if self.css: ret.append('') ret.append('\n') if self.html: ret.append('
\n') chain = [] for c in bytes: byte = ord(c) if byte in table: if type(table[byte]) is type(""): ret.append(table[byte]) else: table = table[byte] chain.append(byte) continue else: chain.append(byte) ret.append(self.errorstyle % (" ".join(["%02x"%i for i in chain]))) table = self.table_root chain = [] if self.html: ret.append('
\n') return "".join(ret) def main(): from optparse import OptionParser import sys parser = OptionParser(usage="usage: %prog [options] [input-file]") # parser.add_option("-r", dest="reverse", action="store_true", help="Convert back to binary", default=False) parser.add_option("-i", dest="inp", action="store", help="Read from FILE instead of stdin.", metavar="FILE") parser.add_option("-o", dest="out", action="store", help="Write to FILE instead of stdout.", metavar="FILE") parser.add_option("-c", dest="colors", action="store_true", help="Use terminal colors or, if '-w' is specified, wrap in span-tags.", default=False) parser.add_option("-u", dest="extended", action="store_true", help="Use unicode characters.", default=False) parser.add_option("-w", dest="html", action="store_true", help="Output in HTML format.", default=False) parser.add_option("-s", dest="css", action="store_true", help="Prepend a style section.", default=False) (opts,args) = parser.parse_args() if len(args)==1 and not opts.inp: opts.inp=args[0] inp=open(opts.inp,mode="rb") if opts.inp else sys.stdin out=open(opts.out,mode="wb") if opts.out else sys.stdout bytes = inp.read() tr = translater(colors=opts.colors, extended=opts.extended, html=opts.html, css=opts.css) out.write(tr.translate(bytes)) if __name__ == '__main__': main()