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