1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 import warnings
29
30
31 labelsuffixes = (".label", ".title")
32 accesskeysuffixes = (".accesskey", ".accessKey", ".akey")
33
35 """retrieve the label from a mixed label+accesskey entity"""
36 if isinstance(unquotedstr, str):
37 unquotedstr = unquotedstr.decode("UTF-8")
38
39
40 amppos = 0
41 while amppos >= 0:
42 amppos = unquotedstr.find("&", amppos)
43 if amppos != -1:
44 amppos += 1
45 semipos = unquotedstr.find(";", amppos)
46 if semipos != -1:
47 if unquotedstr[amppos:semipos].isalnum():
48 continue
49
50
51 unquotedstr = unquotedstr[:amppos-1] + unquotedstr[amppos:]
52 break
53 return unquotedstr.encode("UTF-8")
54
56 """retrieve the access key from a mixed label+accesskey entity"""
57 if isinstance(unquotedstr, str):
58 unquotedstr = unquotedstr.decode("UTF-8")
59
60
61 amppos = 0
62 while amppos >= 0:
63 amppos = unquotedstr.find("&", amppos)
64 if amppos != -1:
65 amppos += 1
66 semipos = unquotedstr.find(";", amppos)
67 if semipos != -1:
68 if unquotedstr[amppos:semipos].isalnum():
69
70 continue
71
72 return unquotedstr[amppos].encode("UTF-8")
73
74
75
76 return ""
77
79 """find ampersands that aren't part of an entity definition..."""
80 amppos = 0
81 invalidamps = []
82 while amppos >= 0:
83 amppos = unquotedstr.find("&", amppos)
84 if amppos != -1:
85 amppos += 1
86 semipos = unquotedstr.find(";", amppos)
87 if semipos != -1:
88 checkentity = unquotedstr[amppos:semipos]
89 if checkentity.replace('.', '').isalnum():
90
91 continue
92 elif checkentity[0] == '#' and checkentity[1:].isalnum():
93
94 continue
95
96 invalidamps.append(amppos-1)
97 if len(invalidamps) > 0:
98 warnings.warn("invalid ampersands in dtd entity %s" % (entity))
99 comp = 0
100 for amppos in invalidamps:
101 unquotedstr = unquotedstr[:amppos-comp] + unquotedstr[amppos-comp+1:]
102 comp += 1
103 return unquotedstr
104
106 """returns a list of mixed .label and .accesskey entities from a list of entities"""
107 mixedentities = []
108
109 for entity in entities:
110 for labelsuffix in labelsuffixes:
111 if entity.endswith(labelsuffix):
112 entitybase = entity[:entity.rfind(labelsuffix)]
113
114 for akeytype in accesskeysuffixes:
115 if entitybase + akeytype in entities:
116
117 mixedentities += [entity, entitybase+akeytype]
118 return mixedentities
119
121 """applies the translation for entity in the po unit to the dtd unit"""
122
123 unquotedstr = inputunit.target
124
125 if len(unquotedstr.strip()) == 0:
126 return
127
128 for labelsuffix in labelsuffixes:
129 if entity.endswith(labelsuffix):
130 if entity in mixedentities:
131 unquotedstr = getlabel(unquotedstr)
132 break
133 else:
134 for akeytype in accesskeysuffixes:
135 if entity.endswith(akeytype):
136 if entity in mixedentities:
137 unquotedstr = getaccesskey(unquotedstr)
138 if not unquotedstr:
139 warnings.warn("Could not find accesskey for %s" % entity)
140 else:
141 original = dtd.unquotefromdtd(dtdunit.definition)
142 if original.isupper() and unquotedstr.islower():
143 unquotedstr = unquotedstr.upper()
144 elif original.islower() and unquotedstr.isupper():
145 unquotedstr = unquotedstr.lower()
146
147 unquotedstr = removeinvalidamps(entity, unquotedstr)
148
149 if len(unquotedstr) > 0:
150 dtdunit.definition = dtd.quotefordtd(unquotedstr)
151
153 """this is a convertor class that creates a new dtd based on a template using translations in a po"""
156
164
173
175 """this is a convertor class that creates a new dtd file based on a po file without a template"""
201
202
210
216
226
227 -def convertdtd(inputfile, outputfile, templatefile, includefuzzy=False):
228 inputstore = po.pofile(inputfile)
229 if templatefile is None:
230 convertor = po2dtd()
231 else:
232 templatestore = dtd.dtdfile(templatefile)
233 convertor = redtd(templatestore)
234 outputstore = convertor.convertstore(inputstore, includefuzzy)
235 outputfile.write(str(outputstore))
236 return 1
237
238 -def main(argv=None):
239
240 from translate.convert import convert
241 formats = {"po": ("dtd", convertdtd), ("po", "dtd"): ("dtd", convertdtd)}
242 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
243 parser.add_fuzzy_option()
244 parser.run(argv)
245
246 if __name__ == '__main__':
247 main()
248