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