Package translate :: Package convert :: Module po2php

[hide private]
[frames] | no frames]

# Source Code for Module translate.convert.po2php

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2002-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
     23  """convert Gettext PO localization files to PHP localization files
     24
     25  see: http://translate.sourceforge.net/wiki/toolkit/po2php for examples and
     26  usage instructions
     27  """
     28
     29  from translate.misc import quote
     30  from translate.storage import po
     31  from translate.storage import php
     32
     33  eol = "\n"
     34
     35 -class rephp:
     36 -    def __init__(self, templatefile):
     37          self.templatefile = templatefile
     38          self.inputdict = {}
     39          self.inmultilinemsgid = False
     40          self.inecho = False
     41          self.inarray = False
     42          self.equaldel = "="
     43          self.enddel = ";"
     44          self.prename = ""
     45          self.quotechar = ""
     46
     47 -    def convertstore(self, inputstore, includefuzzy=False):
     48          self.makestoredict(inputstore, includefuzzy)
     49          outputlines = []
     50          for line in self.templatefile.readlines():
     51              outputstr = self.convertline(line)
     52              outputlines.append(outputstr)
     53          return outputlines
     54
     55 -    def makestoredict(self, store, includefuzzy=False):
     56          '''make a dictionary of the translations'''
     57          for unit in store.units:
     58              if includefuzzy or not unit.isfuzzy():
     59                  for location in unit.getlocations():
     60                      inputstring = unit.target
     61                      if len(inputstring.strip()) == 0:
     62                          inputstring = unit.source
     63                      self.inputdict[location] = inputstring
     64
     65 -    def convertline(self, line):
     66          line = unicode(line, 'utf-8')
     67          returnline = ""
     68          # handle multiline msgid if we're in one
     69          if self.inmultilinemsgid:
     70              # see if there's more
     71              endpos = line.rfind("%s%s" % (self.quotechar, self.enddel))
     72              # if there was no '; or the quote is escaped, we have to continue
     73              if endpos >= 0 and line[endpos-1] != '\\':
     74                  self.inmultilinemsgid = False
     75              # if we're echoing...
     76              if self.inecho:
     77                  returnline = line
     78          # otherwise, this could be a comment
     79          elif line.strip()[:2] == '//' or line.strip()[:2] == '/*':
     80              returnline = quote.rstripeol(line)+eol
     81          elif line.find('array(') != -1:
     82              self.inarray = True
     83              self.prename = line[:line.find('=')].strip() + "->"
     84              self.equaldel = "=>"
     85              self.enddel = ","
     86              returnline = quote.rstripeol(line)+eol
     87          elif self.inarray and line.find(');') != -1:
     88              self.inarray = False
     89              self.equaldel = "="
     90              self.enddel = ";"
     91              self.prename = ""
     92              returnline = quote.rstripeol(line)+eol
     93          else:
     94              line = quote.rstripeol(line)
     95              equalspos = line.find(self.equaldel)
     96              hashpos = line.find("#")
     97              # if no equals, just repeat it
     98              if equalspos == -1:
     99                  returnline = quote.rstripeol(line)+eol
    100              elif 0 <= hashpos < equalspos:
    101                  # Assume that this is a '#' comment line
    102                  returnline = quote.rstripeol(line)+eol
    103              # otherwise, this is a definition
    104              else:
    105                  # now deal with the current string...
    106                  key = line[:equalspos].rstrip()
    107                  lookupkey = self.prename + key.lstrip().replace(" ", "")
    108                  # Calculate space around the equal sign
    109                  prespace = line[len(line[:equalspos].rstrip()):equalspos]
    110                  postspacestart = len(line[equalspos+len(self.equaldel):])
    111                  postspaceend = len(line[equalspos+len(self.equaldel):].lstrip())
    112                  postspace = line[equalspos+len(self.equaldel):equalspos+(postspacestart-postspaceend)+len(self.equaldel)]
    113                  self.quotechar = line[equalspos+(postspacestart-postspaceend)+len(self.equaldel)]
    114                  inlinecomment_pos = line.rfind("%s%s" % (self.quotechar, self.enddel))
    115                  if inlinecomment_pos > -1:
    116                      inlinecomment = line[inlinecomment_pos+2:]
    117                  else:
    118                      inlinecomment = ""
    119                  if self.inputdict.has_key(lookupkey):
    120                      self.inecho = False
    121                      value = php.phpencode(self.inputdict[lookupkey], self.quotechar)
    122                      if isinstance(value, str):
    123                          value = value.decode('utf8')
    124                      returnline = key + prespace + self.equaldel + postspace + self.quotechar + value + self.quotechar + self.enddel + inlinecomment + eol
    125                  else:
    126                      self.inecho = True
    127                      returnline = line+eol
    128                  # no string termination means carry string on to next line
    129                  endpos = line.rfind("%s%s" % (self.quotechar, self.enddel))
    130                  # if there was no '; or the quote is escaped, we have to continue
    131                  if endpos == -1 or line[endpos-1] == '\\':
    132                      self.inmultilinemsgid = True
    133          if isinstance(returnline, unicode):
    134              returnline = returnline.encode('utf-8')
    135          return returnline
    136
    137 -def convertphp(inputfile, outputfile, templatefile, includefuzzy=False):
    138      inputstore = po.pofile(inputfile)
    139      if templatefile is None:
    140          raise ValueError("must have template file for php files")
    141          # convertor = po2php()
    142      else:
    143          convertor = rephp(templatefile)
    144      outputphplines = convertor.convertstore(inputstore, includefuzzy)
    145      outputfile.writelines(outputphplines)
    146      return 1
    147
    148 -def main(argv=None):
    149      # handle command line options
    150      from translate.convert import convert
    151      formats = {("po", "php"): ("php", convertphp)}
    152      parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
    153      parser.add_fuzzy_option()
    154      parser.run(argv)
    155
    156  if __name__ == '__main__':
    157      main()
    158