Package translate :: Package tools :: Module podebug

[hide private]
[frames] | no frames]

# Source Code for Module translate.tools.podebug

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2004-2006 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  """Insert debug messages into XLIFF and Gettex PO localization files
     23
     24  See: http://translate.sourceforge.net/wiki/toolkit/podebug for examples and
     25  usage instructions
     26  """
     27
     28  from translate.storage import factory
     29  import os
     30  import re
     31  import md5
     32
     33 -class podebug:
     34 -    def __init__(self, format=None, rewritestyle=None, hash=None, ignoreoption=None):
     35          if format is None:
     36              self.format = ""
     37          else:
     38              self.format = format
     39          self.rewritefunc = getattr(self, "rewrite_%s" % rewritestyle, None)
     40          self.ignorefunc = getattr(self, "ignore_%s" % ignoreoption, None)
     41          self.hash = hash
     42
     43 -    def rewritelist(cls):
     44          return [rewrite.replace("rewrite_", "") for rewrite in dir(cls) if rewrite.startswith("rewrite_")]
     45      rewritelist = classmethod(rewritelist)
     46
     47 -    def rewrite_xxx(self, string):
     48          return "xxx%sxxx" % string
     49
     50 -    def rewrite_en(self, string):
     51          return string
     52
     53 -    def rewrite_blank(self, string):
     54          return ""
     55
     56 -    def rewrite_chef(self, string):
     57          """Rewrite using Mock Swedish as made famous by Monty Python"""
     58          # From Dive into Python which itself got it elsewhere http://www.renderx.com/demos/examples/diveintopython.pdf
     59          subs = (
     60                 (r'a([nu])', r'u\1'),
     61                 (r'A([nu])', r'U\1'),
     62                 (r'a\B', r'e'),
     63                 (r'A\B', r'E'),
     64                 (r'en\b', r'ee'),
     65                 (r'\Bew', r'oo'),
     66                 (r'\Be\b', r'e-a'),
     67                 (r'\be', r'i'),
     68                 (r'\bE', r'I'),
     69                 (r'\Bf', r'ff'),
     70                 (r'\Bir', r'ur'),
     71                 (r'(\w*?)i(\w*?)$', r'\1ee\2'),
     72                 (r'\bow', r'oo'),
     73                 (r'\bo', r'oo'),
     74                 (r'\bO', r'Oo'),
     75                 (r'the', r'zee'),
     76                 (r'The', r'Zee'),
     77                 (r'th\b', r't'),
     78                 (r'\Btion', r'shun'),
     79                 (r'\Bu', r'oo'),
     80                 (r'\BU', r'Oo'),
     81                 (r'v', r'f'),
     82                 (r'V', r'F'),
     83                 (r'w', r'w'),
     84                 (r'W', r'W'),
     85                 (r'([a-z])[.]', r'\1. Bork Bork Bork!'))
     86          for a, b in subs:
     87              string = re.sub(a, b, string)
     88          return string
     89
     90      REWRITE_UNICODE_MAP = u"ȦƁƇḒḖƑƓĦĪĴĶĿḾȠǾƤɊŘŞŦŬṼẆẊẎẐ" + u"[\\]^_`" + u"ȧƀƈḓḗƒɠħīĵķŀḿƞǿƥɋřşŧŭṽẇẋẏẑ"
     91 -    def rewrite_unicode(self, string):
     92          """Convert to Unicode characters that look like the source string"""
     93          def transpose(char):
     94              loc = ord(char)-65
     95              if loc < 0 or loc > 56:
     96                  return char
     97              return self.REWRITE_UNICODE_MAP[loc]
     98          return "".join(map(transpose, string))
     99
    100 -    def ignorelist(cls):
    101          return [rewrite.replace("ignore_", "") for rewrite in dir(cls) if rewrite.startswith("ignore_")]
    102      ignorelist = classmethod(ignorelist)
    103
    104 -    def ignore_openoffice(self, locations):
    105          for location in locations:
    106              if location.startswith("Common.xcu#..Common.View.Localisation"):
    107                  return True
    108              elif location.startswith("profile.lng#STR_DIR_MENU_NEW_"):
    109                  return True
    110              elif location.startswith("profile.lng#STR_DIR_MENU_WIZARD_"):
    111                  return True
    112          return False
    113
    114 -    def ignore_mozilla(self, locations):
    115          if len(locations) == 1 and locations[0].lower().endswith(".accesskey"):
    116              return True
    117          for location in locations:
    118              if location.endswith(".height") or location.endswith(".width") or \
    119                      location.endswith(".macWidth") or location.endswith(".unixWidth"):
    120                  return True
    121              if location == "brandShortName" or location == "brandFullName" or location == "vendorShortName":
    122                  return True
    123              if location.lower().endswith(".commandkey") or location.endswith(".key"):
    124                  return True
    125          return False
    126
    127 -    def convertunit(self, unit, prefix):
    128          if self.ignorefunc:
    129              if self.ignorefunc(unit.getlocations()):
    130                  return unit
    131          if self.hash:
    132              if unit.getlocations():
    133                  hashable = unit.getlocations()[0]
    134              else:
    135                  hashable = unit.source
    136              prefix = md5.new(hashable).hexdigest()[:self.hash] + " "
    137          if self.rewritefunc:
    138              unit.target = self.rewritefunc(unit.source)
    139          elif not unit.istranslated():
    140              unit.target = unit.source
    141          if unit.hasplural():
    142              strings = unit.target.strings
    143              for i, string in enumerate(strings):
    144                  strings[i] = prefix + string
    145              unit.target = strings
    146          else:
    147              unit.target = prefix + unit.target
    148          return unit
    149
    150 -    def convertstore(self, store):
    151          filename = self.shrinkfilename(store.filename)
    152          prefix = self.format
    153          for formatstr in re.findall("%[0-9c]*[sfFbBd]", self.format):
    154              if formatstr.endswith("s"):
    155                  formatted = self.shrinkfilename(store.filename)
    156              elif formatstr.endswith("f"):
    157                  formatted = store.filename
    158                  formatted = os.path.splitext(formatted)[0]
    159              elif formatstr.endswith("F"):
    160                  formatted = store.filename
    161              elif formatstr.endswith("b"):
    162                  formatted = os.path.basename(store.filename)
    163                  formatted = os.path.splitext(formatted)[0]
    164              elif formatstr.endswith("B"):
    165                  formatted = os.path.basename(store.filename)
    166              elif formatstr.endswith("d"):
    167                  formatted = os.path.dirname(store.filename)
    168              else:
    169                  continue
    170              formatoptions = formatstr[1:-1]
    171              if formatoptions:
    172                  if "c" in formatoptions and formatted:
    173                      formatted = formatted[0] + filter(lambda x: x.lower() not in "aeiou", formatted[1:])
    174                  length = filter(str.isdigit, formatoptions)
    175                  if length:
    176                      formatted = formatted[:int(length)]
    177              prefix = prefix.replace(formatstr, formatted)
    178          for unit in store.units:
    179              if unit.isheader() or unit.isblank():
    180                  continue
    181              unit = self.convertunit(unit, prefix)
    182          return store
    183
    184 -    def shrinkfilename(self, filename):
    185          if filename.startswith("." + os.sep):
    186              filename = filename.replace("." + os.sep, "", 1)
    187          dirname = os.path.dirname(filename)
    188          dirparts = dirname.split(os.sep)
    189          if not dirparts:
    190              dirshrunk = ""
    191          else:
    192              dirshrunk = dirparts[0][:4] + "-"
    193              if len(dirparts) > 1:
    194                  dirshrunk += "".join([dirpart[0] for dirpart in dirparts[1:]]) + "-"
    195          baseshrunk = os.path.basename(filename)[:4]
    196          if "." in baseshrunk:
    197              baseshrunk = baseshrunk[:baseshrunk.find(".")]
    198          return dirshrunk + baseshrunk
    199
    200 -def convertpo(inputfile, outputfile, templatefile, format=None, rewritestyle=None, hash=None, ignoreoption=None):
    201      """reads in inputfile using po, changes to have debug strings, writes to outputfile"""
    202      # note that templatefile is not used, but it is required by the converter...
    203      inputstore = factory.getobject(inputfile)
    204      if inputstore.isempty():
    205          return 0
    206      convertor = podebug(format=format, rewritestyle=rewritestyle, hash=hash, ignoreoption=ignoreoption)
    207      outputstore = convertor.convertstore(inputstore)
    208      outputfile.write(str(outputstore))
    209      return 1
    210
    211 -def main():
    212      from translate.convert import convert
    213      formats = {"po":("po", convertpo), "xlf":("xlf", convertpo)}
    214      parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
    215      # TODO: add documentation on format strings...
    216      parser.add_option("-f", "--format", dest="format", default="[%s] ", help="specify format string")
    217      parser.add_option("", "--rewrite", dest="rewritestyle",
    218          type="choice", choices=podebug.rewritelist(), metavar="STYLE", help="the translation rewrite style: %s" % ", ".join(podebug.rewritelist()))
    219      parser.add_option("", "--ignore", dest="ignoreoption",
    220          type="choice", choices=podebug.ignorelist(), metavar="APPLICATION", help="apply tagging ignore rules for the given application: %s" % ", ".join(podebug.ignorelist()))
    221      parser.add_option("", "--hash", dest="hash", metavar="LENGTH", type="int", help="add an md5 hash to translations")
    222      parser.passthrough.append("format")
    223      parser.passthrough.append("rewritestyle")
    224      parser.passthrough.append("ignoreoption")
    225      parser.passthrough.append("hash")
    226      parser.run()
    227
    228
    229  if __name__ == '__main__':
    230      main()
    231