#! /usr/bin/env python3
# 
#recode.py - recode a PPD file's translation strings
#Version 0.1
#
#Copyright (C) 2004 R.A.Owen
#
#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 2
#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.
#
#The GNU General Public License can be found at:
#http://www.gnu.org/licenses/gpl.html
#
# To use do:
# recode.py source.ppd >destination.ppd
#
# ToDo:
# * translate via unicode 
# * add filters for the unicode intermediate string
#    eg-  To expand the(macintosh) "(TM)" symbol
#         to the 4 chars '('+'T'+'M'+')' 
# * autodetct input encoding - easy just look at LanguageEncoding line
#   & then output as UTF-8 encoding


import os
import sys
import re
from string import maketrans

""" recode.py - recode a ppd file from MacStandard to IsoLatin1 """

usage="Usage: "+os.path.basename(sys.argv[0])+" filename"
if len(sys.argv) !=2 :
    sys.exit(usage)
    



def ppd2str(ts):
    """ Recursive function to translate <xx> to equivilent(hex) charcode """
    if ts == None:
        return ''
    rx=re.compile("(.*)<(.*)>(.*)")
    m=rx.match(ts)
    if m == None:
        return ts
    tshex=''.join(m.group(2).split())
    tspystr=''.join([ chr(int(tshex[i:(i+2)],16)) for i in range(0,len(tshex),2) ])
    return ppd2str(m.group(1))+tspystr+ppd2str(m.group(3))

def str2ppd(ts):
    """ function to translate out of range charcodes to ppd hex equivilents"""
    #    allow dec 32-126 + 9tab 10lf 13cr 
    #    disallow 60< 62> 58: 
    ppdstr=[]
    for char in [ ts[i] for i in range(len(ts))]:
        if   ord(char)==0x3a or ord(char)==0x3c or ord(char)==0x3e:
            #hexify ":" , "<" and  ">"
            ppdstr.append('<'+hex(ord(char))[2:4]+'>')
        elif ord(char)>=0x20 and ord(char)<=0x7e:
            #any others between 32 and 126 OK as is
            ppdstr.append(char)
        elif ord(char)==0x09 or ord(char)==0x0a  or ord(char)==0x0d:
            # tab, linefeed and caragereturn OK too
            ppdstr.append(char)
        elif ord(char)>0x7e:
            #hexify all above 126
            ppdstr.append('<'+hex(ord(char))[2:4]+'>')
        else:
            #anything else is NOT allowed
            raise ValueError('Bad char value '+hex(ord(char))+' in translation string')
    return ''.join(ppdstr)







file=sys.argv[1]

realmac=maketrans('\x2D\xA5\x60\xA6\x80\xA7\x81\xA8\x82\xAA\x83\xAB\x84\xAC\x85\xAD\x86\xAE\x87\xAF\x88\xB0\x89\xB2\x8A\xB3\x8B\xB4\x8C\xB6\x8D\xB7\x8E\xB8\x8F\xB9\x90\xBA\x91\xBB\x92\xBC\x93\xBD\x94\xBE\x95\xBF\x96\xC0\x97\xC1\x98\xC2\x99\xC3\x9A\xC4\x9B\xC5\x9C\xC6\x9D\xC7\x9E\xC8\x9F\xC9\xA0\xCA\xA1\xCB\xA4\xCC\xCD\xFB\xCE\xFC\xCF\xFD\xD0\xFE\xD1\xFF\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA','\xAD\x20\x91\xB6\xC4\xDF\xC5\xAE\xC7\x20\xC9\x92\xD1\x98\xD6\x20\xDC\xC6\xE1\xD8\xE0\x20\xE2\x20\xE4\x20\xE3\xA5\xE5\x20\xE7\x20\xE9\x20\xE8\x20\xEA\x20\xEB\xAA\xED\xBA\xEC\x20\xEE\xE6\xEF\xF8\xF1\xBF\xF3\xA1\xF2\xAC\xF4\x20\xF6\x20\xF5\x20\xFA\x20\xF9\xAB\xFB\xBB\xFC\x20\x20\x20\xB0\xC0\xA7\xC3\xD5\x9A\x20\x9B\x20\x9D\x20\x9E\x20\x9F\x20\x20\x60\x27\xF7\x20\xFF\x20\x20\xA4\x20\x20\x20\x20\x20\xB7\x20\x20\x20\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\x20\xD2\xDA\xDB\xD9\x90\x93\x94\x95\x96\x97')

#Above maps hyphen to hyphen
#Below maps hyphen to minus (this is a null-op in char-code space)
#This mapping is done to make the translations more ASCII friendly 
mac=maketrans('\xA5\x60\xA6\x80\xA7\x81\xA8\x82\xAA\x83\xAB\x84\xAC\x85\xAD\x86\xAE\x87\xAF\x88\xB0\x89\xB2\x8A\xB3\x8B\xB4\x8C\xB6\x8D\xB7\x8E\xB8\x8F\xB9\x90\xBA\x91\xBB\x92\xBC\x93\xBD\x94\xBE\x95\xBF\x96\xC0\x97\xC1\x98\xC2\x99\xC3\x9A\xC4\x9B\xC5\x9C\xC6\x9D\xC7\x9E\xC8\x9F\xC9\xA0\xCA\xA1\xCB\xA4\xCC\xCD\xFB\xCE\xFC\xCF\xFD\xD0\xFE\xD1\xFF\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA','\x20\x91\xB6\xC4\xDF\xC5\xAE\xC7\x20\xC9\x92\xD1\x98\xD6\x20\xDC\xC6\xE1\xD8\xE0\x20\xE2\x20\xE4\x20\xE3\xA5\xE5\x20\xE7\x20\xE9\x20\xE8\x20\xEA\x20\xEB\xAA\xED\xBA\xEC\x20\xEE\xE6\xEF\xF8\xF1\xBF\xF3\xA1\xF2\xAC\xF4\x20\xF6\x20\xF5\x20\xFA\x20\xF9\xAB\xFB\xBB\xFC\x20\x20\x20\xB0\xC0\xA7\xC3\xD5\x9A\x20\x9B\x20\x9D\x20\x9E\x20\x9F\x20\x20\x60\x27\xF7\x20\xFF\x20\x20\xA4\x20\x20\x20\x20\x20\xB7\x20\x20\x20\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4\x20\xD2\xDA\xDB\xD9\x90\x93\x94\x95\x96\x97')

#OK so now doit!

Fin=open(file, 'r')
#Fout=open(file+'.new', 'w')
Fout=sys.stdout

#read in ppd line by line fix up and write out
for line in Fin.readlines():
    
    line=line.replace('*LanguageEncoding: MacStandard','*LanguageEncoding: ISOLatin1')
    #The recoded PPD is not for mac only
    line=line.replace('*% For Macintosh only','*%')
    
    if line[0] == '*' and line[1] != '%' :
        TSstart=line.find('/')+1
        
        if TSstart != 0 :
            TSend=line[TSstart:].find(':') + TSstart
            if TSend < TSstart :
                TSend=len(line)-1
        
            TS=ppd2str(line[TSstart:TSend])

            TS=TS.translate(mac)

            line=line[0:TSstart] + str2ppd(TS) + line[TSend:]
            Fout.write(line)
          
        else:
            Fout.write(line)
    else:
        Fout.write(line)

Fin.close()
Fout.close()


