Package translate :: Package storage :: Module php
[hide private]
[frames] | no frames]

Source Code for Module translate.storage.php

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2004-2008 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  """classes that hold units of php localisation files (phpunit) or entire files 
 23  (phpfile) these files are used in translating many PHP based applications 
 24   
 25  """ 
 26   
 27  from translate.storage import base 
 28  from translate.misc import quote 
 29  import re 
 30   
31 -def phpencode(text, quotechar="'"):
32 """convert Python string to PHP escaping""" 33 if not text: 34 return text 35 return text.replace("%s" % quotechar, "\\%s" % quotechar).replace("\n", "\\n")
36
37 -def phpdecode(text):
38 """convert PHP escaped string to a Python string""" 39 if not text: 40 return text 41 return text.replace("\\'", "'").replace('\\"', '"').replace("\\n", "\n")
42
43 -class phpunit(base.TranslationUnit):
44 """a unit of a PHP file i.e. a name and value, and any comments 45 associated"""
46 - def __init__(self, source=""):
47 """construct a blank phpunit""" 48 super(phpunit, self).__init__(source) 49 self.name = "" 50 self.value = "" 51 self._comments = [] 52 self.source = source
53
54 - def setsource(self, source):
55 """Sets the source AND the target to be equal""" 56 self.value = phpencode(source)
57
58 - def getsource(self):
59 return phpdecode(self.value)
60 source = property(getsource, setsource) 61
62 - def settarget(self, target):
63 """Note: this also sets the .source attribute!""" 64 # TODO: shouldn't this just call the .source property? no quoting done here... 65 self.source = target
66
67 - def gettarget(self):
68 return self.source
69 target = property(gettarget, settarget) 70
71 - def __str__(self):
72 """convert to a string. double check that unicode is handled somehow here""" 73 source = self.getoutput() 74 if isinstance(source, unicode): 75 return source.encode(getattr(self, "encoding", "UTF-8")) 76 return source
77
78 - def getoutput(self):
79 """convert the unit back into formatted lines for a php file""" 80 return "".join(self._comments + ["%s='%s';\n" % (self.name, self.value)])
81
82 - def addlocation(self, location):
83 self.name = location
84
85 - def getlocations(self):
86 return [self.name]
87
88 - def addnote(self, note, origin=None):
89 self._comments.append(note)
90
91 - def getnotes(self, origin=None):
92 return '\n'.join(self._comments)
93
94 - def removenotes(self):
95 self._comments = []
96
97 - def isblank(self):
98 """returns whether this is a blank element, containing only comments...""" 99 return not (self.name or self.value)
100
101 -class phpfile(base.TranslationStore):
102 """this class represents a php file, made up of phpunits""" 103 UnitClass = phpunit
104 - def __init__(self, inputfile=None, encoding='utf-8'):
105 """construct a phpfile, optionally reading in from inputfile""" 106 super(phpfile, self).__init__(unitclass = self.UnitClass) 107 self.filename = getattr(inputfile, 'name', '') 108 self._encoding = encoding 109 if inputfile is not None: 110 phpsrc = inputfile.read() 111 inputfile.close() 112 self.parse(phpsrc)
113
114 - def parse(self, phpsrc):
115 """read the source of a php file in and include them as units""" 116 newunit = phpunit() 117 lastvalue = "" 118 value = "" 119 comment = [] 120 invalue = False 121 incomment = False 122 valuequote = "" # either ' or " 123 for line in phpsrc.decode(self._encoding).split("\n"): 124 # Assuming /* comments */ are started and stopped on lines 125 commentstartpos = line.find("/*") 126 commentendpos = line.rfind("*/") 127 if commentstartpos != -1: 128 incomment = True 129 if commentendpos != -1: 130 newunit.addnote(line[commentstartpos+2:commentendpos].strip(), "developer") 131 incomment = False 132 if incomment: 133 newunit.addnote(line[commentstartpos+2:].strip(), "developer") 134 if commentendpos != -1 and incomment: 135 newunit.addnote(line[:commentendpos].strip(), "developer") 136 incomment = False 137 if commentstartpos == -1 and incomment: 138 newunit.addnote(line.strip(), "developer") 139 equalpos = line.find("=") 140 if equalpos != -1 and not invalue: 141 newunit.addlocation(line[:equalpos].strip().replace(" ", "")) 142 value = line[equalpos+1:].lstrip()[1:] 143 valuequote = line[equalpos+1:].lstrip()[0] 144 lastvalue = "" 145 invalue = True 146 else: 147 if invalue: 148 value = line 149 colonpos = value.rfind(";") 150 while colonpos != -1: 151 if value[colonpos-1] == valuequote: 152 newunit.value = lastvalue + value[:colonpos-1] 153 lastvalue = "" 154 invalue = False 155 if not invalue and colonpos != len(value)-1: 156 commentinlinepos = value.find("//", colonpos) 157 if commentinlinepos != -1: 158 newunit.addnote(value[commentinlinepos+2:].strip(), "developer") 159 if not invalue: 160 self.addunit(newunit) 161 value = "" 162 newunit = phpunit() 163 colonpos = value.rfind(";", 0, colonpos) 164 if invalue: 165 lastvalue = lastvalue + value
166
167 - def __str__(self):
168 """convert the units back to lines""" 169 lines = [] 170 for unit in self.units: 171 lines.append(str(unit)) 172 return "".join(lines)
173 174 if __name__ == '__main__': 175 import sys 176 pf = phpfile(sys.stdin) 177 sys.stdout.write(str(pf)) 178