1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
44 return [rewrite.replace("rewrite_", "") for rewrite in dir(cls) if rewrite.startswith("rewrite_")]
45 rewritelist = classmethod(rewritelist)
46
48 return "xxx%sxxx" % string
49
52
55
57 """Rewrite using Mock Swedish as made famous by Monty Python"""
58
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"ȧƀƈḓḗƒɠħīĵķŀḿƞǿƥɋřşŧŭṽẇẋẏẑ"
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
101 return [rewrite.replace("ignore_", "") for rewrite in dir(cls) if rewrite.startswith("ignore_")]
102 ignorelist = classmethod(ignorelist)
103
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
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
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
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
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
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
212 from translate.convert import convert
213 formats = {"po":("po", convertpo), "xlf":("xlf", convertpo)}
214 parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
215
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