[Android] Fixed chrome://history's overlapped search and clear(x) icons on RTL
[chromium-blink-merge.git] / remoting / tools / json_to_grd.py
blob36a26c9c54e0b268fd9cd55197a40563e0d424bf
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 # This script can be used to convert messages.json to grd translations.
8 import codecs
9 import json
10 import optparse
11 import os
12 import string
13 import sys
14 import xml.dom.minidom as dom
16 import sys
17 sys.path.append('../../tools/grit')
18 sys.path.append('../../tools/grit/grit')
19 import tclib
21 def camelCase2ALL_CAPS(s):
22 for c in string.ascii_uppercase:
23 s = s.replace(c, '_' + c)
24 return s.upper()
26 def load_messages(filename):
27 import collections
28 def create_ordered_dict(list):
29 return collections.OrderedDict(list)
30 messages = json.load(file(filename), object_pairs_hook=create_ordered_dict)
31 ids = messages.keys()
33 result = {}
34 for id in ids:
35 text = messages[id]['message']
36 placeholders = []
37 if messages[id].has_key('placeholders'):
38 for name, p in messages[id]['placeholders'].items():
39 index = p['content']
40 caps_name = camelCase2ALL_CAPS(name)
41 placeholders.append(tclib.Placeholder(caps_name, index, p['example']))
42 text = text.replace('$' + name + '$', caps_name)
44 msg = tclib.Message(text, placeholders,
45 messages[id]['description'])
46 result[id] = msg
48 return ids, result
50 def json_to_grd(input_dir, output_dir):
51 # load list of string IDs and placeholder names from the untranslated file
52 # because order of messages and placeholder names are not persisted in
53 # translations.
54 message_ids, messages = load_messages(
55 os.path.join(input_dir, '_locales/en', 'messages.json'))
57 grd_name = os.path.join(output_dir,
58 'string_resources.grd')
59 grd_xml = dom.parse(grd_name)
60 grd_translations = grd_xml.getElementsByTagName('translations')[0]
61 grd_outputs = grd_xml.getElementsByTagName('outputs')[0]
62 grd_messages = grd_xml.getElementsByTagName('messages')[0]
64 for id in message_ids:
65 grit_id = 'IDR_' + id
66 message = grd_xml.createElement('message')
67 grd_messages.appendChild(grd_xml.createTextNode(' '))
68 grd_messages.appendChild(message)
69 grd_messages.appendChild(grd_xml.createTextNode('\n '))
70 message.setAttribute('name', grit_id)
71 message.setAttribute('desc', messages[id].description)
72 message.appendChild(grd_xml.createTextNode('\n '))
73 for part in messages[id].parts:
74 if isinstance(part, tclib.Placeholder):
75 ph = grd_xml.createElement('ph')
76 message.appendChild(ph)
77 ph.setAttribute('name', part.presentation)
78 ph.appendChild(grd_xml.createTextNode(part.original))
79 ex = grd_xml.createElement('ex')
80 ph.appendChild(ex)
81 ex.appendChild(grd_xml.createTextNode(part.example))
82 else:
83 message.appendChild(grd_xml.createTextNode(part))
84 message.appendChild(grd_xml.createTextNode('\n '))
86 translations_dir = os.path.join(input_dir, '_locales.official')
87 lang_list = os.listdir(translations_dir)
88 lang_list.sort()
89 for lang in lang_list:
90 # Convert locale name representation to the Grit format.
91 grit_lang = lang.replace('_', '-') if lang != 'en' else 'en_US'
93 # Load translations
94 translations_file = file(
95 os.path.join(translations_dir, lang, 'messages.json'))
96 translations = json.load(translations_file)
97 translations_file.close()
99 # Uppercase all string name.
100 translations = dict(zip(map(lambda x: x.upper(), translations.iterkeys()),
101 translations.values()))
103 doc = dom.Document()
105 bundle = doc.createElement('translationbundle')
106 doc.appendChild(bundle)
107 bundle.setAttribute('lang', grit_lang)
108 written_translations = {}
109 for id in message_ids:
110 bundle.appendChild(doc.createTextNode('\n'))
112 if not translations.has_key(id):
113 # Skip not translated messages.
114 continue
115 grit_id = 'IDR_' + id
117 placeholders = messages[id].placeholders
118 text = translations[id]['message']
119 for p in placeholders:
120 text = text.replace(p.original, p.presentation)
122 msg_id = messages[id].GetId()
123 if written_translations.has_key(msg_id):
124 # We've already written translation for this message.
125 continue
126 parsed_translation = tclib.Translation(text, msg_id, placeholders)
127 written_translations[msg_id] = 1
129 translation = doc.createElement('translation')
130 bundle.appendChild(translation)
131 translation.setAttribute('id', parsed_translation.GetId())
132 for part in parsed_translation.parts:
133 if isinstance(part, tclib.Placeholder):
134 ph = doc.createElement('ph')
135 translation.appendChild(ph)
136 ph.setAttribute('name', part.presentation)
137 else:
138 translation.appendChild(doc.createTextNode(part))
139 bundle.appendChild(doc.createTextNode('\n'))
141 out_name = os.path.join(output_dir,
142 'string_resources_' + grit_lang + '.xtb')
143 out = codecs.open(out_name, mode='w', encoding = 'UTF-8')
144 out.write('<?xml version="1.0" ?>\n'
145 '<!DOCTYPE translationbundle>\n')
146 bundle.writexml(out)
147 out.close()
149 if grit_lang == 'en_US':
150 continue
152 t = grd_xml.createElement('file')
153 grd_translations.appendChild(grd_xml.createTextNode(' '))
154 grd_translations.appendChild(t)
155 grd_translations.appendChild(grd_xml.createTextNode('\n '))
156 t.setAttribute('path', 'string_resources_' + grit_lang + '.xtb')
157 t.setAttribute('lang', grit_lang)
159 t = grd_xml.createElement('output')
160 grd_outputs.appendChild(grd_xml.createTextNode(' '))
161 grd_outputs.appendChild(t)
162 grd_outputs.appendChild(grd_xml.createTextNode('\n '))
163 t.setAttribute('filename', 'remoting/resources/' + grit_lang + '.pak')
164 t.setAttribute('type', 'data_package')
165 t.setAttribute('lang', grit_lang)
167 t = grd_xml.createElement('output')
168 grd_outputs.appendChild(grd_xml.createTextNode(' '))
169 grd_outputs.appendChild(t)
170 grd_outputs.appendChild(grd_xml.createTextNode('\n '))
171 t.setAttribute('filename',
172 'remoting/webapp/_locales/' + lang + '/messages.json')
173 t.setAttribute('type', 'chrome_messages_json')
174 t.setAttribute('lang', grit_lang)
176 grd_out = codecs.open(grd_name + '_new', mode='w', encoding = 'UTF-8')
177 grd_xml.writexml(grd_out, encoding = 'UTF-8')
178 grd_out.close()
180 def main():
181 usage = 'Usage: json_to_grd <input_dir> <output_dir>'
182 parser = optparse.OptionParser(usage=usage)
183 options, args = parser.parse_args()
184 if len(args) != 2:
185 parser.error('two positional arguments expected')
187 return json_to_grd(args[0], args[1])
189 if __name__ == '__main__':
190 sys.exit(main())