Package translate :: Package convert :: Module po2dtd
[hide private]
[frames] | no frames]

Source Code for Module translate.convert.po2dtd

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2002-2009 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  """script that converts a .po file to a UTF-8 encoded .dtd file as used by mozilla 
 23  either done using a template or just using the .po file""" 
 24   
 25  from translate.storage import dtd 
 26  from translate.storage import po 
 27  from translate.misc import quote 
 28  from translate.convert import accesskey 
 29  import warnings 
 30   
31 -def getmixedentities(entities):
32 """returns a list of mixed .label and .accesskey entities from a list of entities""" 33 mixedentities = [] # those entities which have a .label and .accesskey combined 34 # search for mixed entities... 35 for entity in entities: 36 for labelsuffix in dtd.labelsuffixes: 37 if entity.endswith(labelsuffix): 38 entitybase = entity[:entity.rfind(labelsuffix)] 39 # see if there is a matching accesskey, making this a mixed entity 40 for akeytype in dtd.accesskeysuffixes: 41 if entitybase + akeytype in entities: 42 # add both versions to the list of mixed entities 43 mixedentities += [entity, entitybase+akeytype] 44 return mixedentities
45
46 -def applytranslation(entity, dtdunit, inputunit, mixedentities):
47 """applies the translation for entity in the po unit to the dtd unit""" 48 # this converts the po-style string to a dtd-style string 49 unquotedstr = inputunit.target 50 # check there aren't missing entities... 51 if len(unquotedstr.strip()) == 0: 52 return 53 # handle mixed entities 54 for labelsuffix in dtd.labelsuffixes: 55 if entity.endswith(labelsuffix): 56 if entity in mixedentities: 57 unquotedstr, akey = accesskey.extract(unquotedstr) 58 break 59 else: 60 for akeytype in dtd.accesskeysuffixes: 61 if entity.endswith(akeytype): 62 if entity in mixedentities: 63 label, unquotedstr = accesskey.extract(unquotedstr) 64 if not unquotedstr: 65 warnings.warn("Could not find accesskey for %s" % entity) 66 else: 67 original = dtd.unquotefromdtd(dtdunit.definition) 68 # For the sake of diffs we keep the case of the 69 # accesskey the same if we know the translation didn't 70 # change. Casing matters in XUL. 71 if unquotedstr == dtdunit.source and original.lower() == unquotedstr.lower(): 72 if original.isupper(): 73 unquotedstr = unquotedstr.upper() 74 elif original.islower(): 75 unquotedstr = unquotedstr.lower() 76 if len(unquotedstr) > 0: 77 dtdunit.definition = dtd.quotefordtd(dtd.removeinvalidamps(entity, unquotedstr))
78
79 -class redtd:
80 """this is a convertor class that creates a new dtd based on a template using translations in a po"""
81 - def __init__(self, dtdfile):
82 self.dtdfile = dtdfile
83
84 - def convertstore(self, inputstore, includefuzzy=False):
85 # translate the strings 86 for inunit in inputstore.units: 87 # there may be more than one entity due to msguniq merge 88 if includefuzzy or not inunit.isfuzzy(): 89 self.handleinunit(inunit) 90 return self.dtdfile
91
92 - def handleinunit(self, inunit):
93 entities = inunit.getlocations() 94 mixedentities = getmixedentities(entities) 95 for entity in entities: 96 if self.dtdfile.index.has_key(entity): 97 # now we need to replace the definition of entity with msgstr 98 dtdunit = self.dtdfile.index[entity] # find the dtd 99 applytranslation(entity, dtdunit, inunit, mixedentities)
100
101 -class po2dtd:
102 """this is a convertor class that creates a new dtd file based on a po file without a template"""
103 - def convertcomments(self, inputunit, dtdunit):
104 entities = inputunit.getlocations() 105 if len(entities) > 1: 106 # don't yet handle multiple entities 107 dtdunit.comments.append(("conversionnote",'<!-- CONVERSION NOTE - multiple entities -->\n')) 108 dtdunit.entity = entities[0] 109 elif len(entities) == 1: 110 dtdunit.entity = entities[0] 111 else: 112 # this produces a blank entity, which doesn't write anything out 113 dtdunit.entity = "" 114 115 if inputunit.isfuzzy(): 116 dtdunit.comments.append(("potype", "fuzzy\n")) 117 for note in inputunit.getnotes("translator").split("\n"): 118 if not note: 119 continue 120 note = quote.unstripcomment(note) 121 if (note.find('LOCALIZATION NOTE') == -1) or (note.find('GROUP') == -1): 122 dtdunit.comments.append(("comment", note)) 123 # msgidcomments are special - they're actually localization notes 124 msgidcomment = inputunit._extract_msgidcomments() 125 if msgidcomment: 126 locnote = quote.unstripcomment("LOCALIZATION NOTE ("+dtdunit.entity+"): "+msgidcomment) 127 dtdunit.comments.append(("locnote", locnote))
128 129
130 - def convertstrings(self, inputunit, dtdunit):
131 if inputunit.istranslated(): 132 unquoted = inputunit.target 133 else: 134 unquoted = inputunit.source 135 dtdunit.definition = dtd.quotefordtd(dtd.removeinvalidamps(dtdunit.entity, unquoted))
136
137 - def convertunit(self, inputunit):
138 dtdunit = dtd.dtdunit() 139 self.convertcomments(inputunit, dtdunit) 140 self.convertstrings(inputunit, dtdunit) 141 return dtdunit
142
143 - def convertstore(self, inputstore, includefuzzy=False):
144 outputstore = dtd.dtdfile() 145 self.currentgroups = [] 146 for inputunit in inputstore.units: 147 if includefuzzy or not inputunit.isfuzzy(): 148 dtdunit = self.convertunit(inputunit) 149 if dtdunit is not None: 150 outputstore.addunit(dtdunit) 151 return outputstore
152
153 -def convertdtd(inputfile, outputfile, templatefile, includefuzzy=False):
154 inputstore = po.pofile(inputfile) 155 if templatefile is None: 156 convertor = po2dtd() 157 else: 158 templatestore = dtd.dtdfile(templatefile) 159 convertor = redtd(templatestore) 160 outputstore = convertor.convertstore(inputstore, includefuzzy) 161 outputfile.write(str(outputstore)) 162 return 1
163
164 -def main(argv=None):
165 # handle command line options 166 from translate.convert import convert 167 formats = {"po": ("dtd", convertdtd), ("po", "dtd"): ("dtd", convertdtd)} 168 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__) 169 parser.add_fuzzy_option() 170 parser.run(argv)
171 172 if __name__ == '__main__': 173 main() 174