| OLD | NEW |
| (Empty) |
| 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. | |
| 5 # | |
| 6 # This script can be used to convert messages.json to grd translations. | |
| 7 | |
| 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 | |
| 15 | |
| 16 import sys | |
| 17 sys.path.append('../../tools/grit') | |
| 18 sys.path.append('../../tools/grit/grit') | |
| 19 import tclib | |
| 20 | |
| 21 def camelCase2ALL_CAPS(s): | |
| 22 for c in string.ascii_uppercase: | |
| 23 s = s.replace(c, '_' + c) | |
| 24 return s.upper() | |
| 25 | |
| 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() | |
| 32 | |
| 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) | |
| 43 | |
| 44 msg = tclib.Message(text, placeholders, | |
| 45 messages[id]['description']) | |
| 46 result[id] = msg | |
| 47 | |
| 48 return ids, result | |
| 49 | |
| 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')) | |
| 56 | |
| 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] | |
| 63 | |
| 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 ')) | |
| 85 | |
| 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' | |
| 92 | |
| 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() | |
| 98 | |
| 99 # Uppercase all string name. | |
| 100 translations = dict(zip(map(lambda x: x.upper(), translations.iterkeys()), | |
| 101 translations.values())) | |
| 102 | |
| 103 doc = dom.Document() | |
| 104 | |
| 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')) | |
| 111 | |
| 112 if not translations.has_key(id): | |
| 113 # Skip not translated messages. | |
| 114 continue | |
| 115 grit_id = 'IDR_' + id | |
| 116 | |
| 117 placeholders = messages[id].placeholders | |
| 118 text = translations[id]['message'] | |
| 119 for p in placeholders: | |
| 120 text = text.replace(p.original, p.presentation) | |
| 121 | |
| 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 | |
| 128 | |
| 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')) | |
| 140 | |
| 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() | |
| 148 | |
| 149 if grit_lang == 'en_US': | |
| 150 continue | |
| 151 | |
| 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) | |
| 158 | |
| 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) | |
| 166 | |
| 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) | |
| 175 | |
| 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() | |
| 179 | |
| 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') | |
| 186 | |
| 187 return json_to_grd(args[0], args[1]) | |
| 188 | |
| 189 if __name__ == '__main__': | |
| 190 sys.exit(main()) | |
| OLD | NEW |