OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path] | 7 # Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path] |
8 # | 8 # |
9 # Extracts all the localizable strings that start with "^IDS" from the given | 9 # Extracts all the localizable strings that start with "^IDS" from the given |
10 # xib file, and then generates a localizer to process those strings. | 10 # xib file, and then generates a localizer to process those strings. |
11 | 11 |
12 import os.path | 12 import os.path |
13 import plistlib | 13 import plistlib |
14 import subprocess | 14 import subprocess |
15 import sys | 15 import sys |
16 | 16 |
17 generate_localizer = "me" | 17 generate_localizer = "me" |
18 | 18 |
19 localizer_template_h = \ | 19 localizer_template_h = \ |
20 '''// ---------- WARNING ---------- | 20 '''// ---------- WARNING ---------- |
21 // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! | 21 // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! |
22 // | 22 // |
| 23 // This header includes the table used by ui_localizer.mm. Nothing else should |
| 24 // be including this file. |
| 25 // |
23 // Generated by %(generate_localizer)s. | 26 // Generated by %(generate_localizer)s. |
24 // Generated from %(xib_file)s. | 27 // Generated from: |
| 28 // %(xib_files)s |
25 // | 29 // |
26 | 30 |
27 #ifndef %(class_name)s_LOCALIZER_H_ | 31 #ifndef UI_LOCALIZER_TABLE_H_ |
28 #define %(class_name)s_LOCALIZER_H_ | 32 #define UI_LOCALIZER_TABLE_H_ |
29 | 33 |
30 #import "chrome/browser/cocoa/ui_localizer.h" | 34 static const UILocalizerResourceMap kUIResources[] = { |
| 35 %(resource_map_list)s }; |
| 36 static const size_t kUIResourcesSize = arraysize(kUIResources); |
31 | 37 |
32 // A subclass of ChromeUILocalizer that handles localization based on resource | 38 #endif // UI_LOCALIZER_TABLE_H_ |
33 // constants. | |
34 | |
35 @interface %(class_name)sLocalizer : ChromeUILocalizer | |
36 @end | |
37 | |
38 #endif // %(class_name)s_LOCALIZER_H_ | |
39 ''' | |
40 | |
41 localizer_template_mm = \ | |
42 '''// ---------- WARNING ---------- | |
43 // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! | |
44 // | |
45 // Generated by '%(generate_localizer)s'. | |
46 // Generated from '%(xib_file)s'. | |
47 // | |
48 | |
49 #import "%(header_name)s" | |
50 | |
51 #include "grit/app_strings.h" | |
52 #include "grit/chromium_strings.h" | |
53 #include "grit/generated_resources.h" | |
54 | |
55 @implementation %(class_name)sLocalizer | |
56 | |
57 - (NSString *)localizedStringForString:(NSString *)string { | |
58 | |
59 static const ui_localizer::ResourceMap kUIResources[] = { | |
60 %(resource_map_list)s }; | |
61 static const size_t kUIResourcesSize = arraysize(kUIResources); | |
62 | |
63 return ui_localizer::LocalizedStringForKeyFromMapList(string, | |
64 kUIResources, | |
65 kUIResourcesSize); | |
66 } | |
67 | |
68 @end | |
69 ''' | 39 ''' |
70 | 40 |
71 def xib_localizable_strings(xib_path): | 41 def xib_localizable_strings(xib_path): |
72 """Runs ibtool to extract the localizable strings data from the xib.""" | 42 """Runs ibtool to extract the localizable strings data from the xib.""" |
73 ibtool_cmd = subprocess.Popen(['/usr/bin/ibtool', '--localizable-strings', | 43 ibtool_cmd = subprocess.Popen(['/usr/bin/ibtool', '--localizable-strings', |
74 xib_path], | 44 xib_path], |
75 stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 45 stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
76 (cmd_out, cmd_err) = ibtool_cmd.communicate() | 46 (cmd_out, cmd_err) = ibtool_cmd.communicate() |
77 if ibtool_cmd.returncode: | 47 if ibtool_cmd.returncode: |
78 sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' % | 48 sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' % |
79 (generate_localizer, xib_path, ibtool_cmd.returncode, | 49 (generate_localizer, xib_path, ibtool_cmd.returncode, |
80 cmd_err)) | 50 cmd_err)) |
81 return None | 51 return None |
82 return cmd_out | 52 return cmd_out |
83 | 53 |
84 def extract_resource_constants(plist_localizable_strings_dict, xib_path): | 54 def extract_resource_constants(plist_localizable_strings_dict, xib_path): |
85 """Extracts all the values that start with ^IDS from the localizable | 55 """Extracts all the values that start with ^IDS from the localizable |
86 strings plist entry.""" | 56 strings plist entry.""" |
87 constants_list = [] | 57 constants_list = [] |
88 for item_dict in plist_localizable_strings_dict.itervalues(): | 58 for item_dict in plist_localizable_strings_dict.itervalues(): |
89 for item_value in item_dict.itervalues(): | 59 for item_value in item_dict.itervalues(): |
90 if item_value.startswith('^IDS'): | 60 if item_value.startswith('^IDS'): |
91 constants_list.append(item_value) | 61 constants_list.append(item_value) |
92 elif item_value.startswith('IDS'): | 62 elif item_value.startswith('IDS'): |
93 sys.stderr.write( | 63 sys.stderr.write( |
94 '%s:0: warning: %s found a string with questionable prefix, "%s"\n' | 64 '%s:0: warning: %s found a string with questionable prefix, "%s"\n' |
95 % (xib_path, generate_localizer, item_value)); | 65 % (xib_path, generate_localizer, item_value)); |
96 return constants_list | 66 return constants_list |
97 | 67 |
98 def generate_files_contents(class_name, constants_list, header_name, xib_path): | 68 def generate_file_contents(constants_list, xib_paths): |
99 """Generates a localizer files contents from the list of constants.""" | 69 """Generates the header listing the constants.""" |
100 # Bounce through a set to uniq the strings, sort the list, then build the | 70 # Bounce through a set to uniq the strings, sort the list, then build the |
101 # values we need from it. | 71 # values we need from it. |
102 constants_list = sorted(set(constants_list)) | 72 constants_list = sorted(set(constants_list)) |
103 constant_list_str = '' | 73 constant_list_str = '' |
104 for item in constants_list: | 74 for item in constants_list: |
105 parts = item.split('$', 1) | 75 parts = item.split('$', 1) |
106 label_id = parts[0] | 76 label_id = parts[0] |
107 if len(parts) == 2: | 77 if len(parts) == 2: |
108 label_arg_id = parts[1] | 78 label_arg_id = parts[1] |
109 else: | 79 else: |
110 label_arg_id = '0' | 80 label_arg_id = '0' |
111 constant_list_str += ' { "%s", %s, %s },\n' % \ | 81 constant_list_str += ' { "%s", %s, %s },\n' % \ |
112 ( item, label_id[1:], label_arg_id) | 82 ( item, label_id[1:], label_arg_id) |
113 # Assemble the contents from the templates. | 83 # Assemble the contents from the templates. |
114 values_dict = { | 84 values_dict = { |
115 'class_name': class_name, | |
116 'header_name': header_name, | |
117 'resource_map_list': constant_list_str, | 85 'resource_map_list': constant_list_str, |
118 'generate_localizer': generate_localizer, | 86 'generate_localizer': generate_localizer, |
119 'xib_file': xib_path, | 87 'xib_files': "\n// ".join(xib_paths), |
120 } | 88 } |
121 h_file = localizer_template_h % values_dict | 89 h_file = localizer_template_h % values_dict |
122 mm_file = localizer_template_mm % values_dict | 90 return h_file |
123 return (h_file, mm_file) | |
124 | 91 |
125 | 92 |
126 def Main(argv=None): | 93 def Main(argv=None): |
127 global generate_localizer | 94 global generate_localizer |
128 generate_localizer = os.path.basename(argv[0]) | 95 generate_localizer = os.path.basename(argv[0]) |
129 | 96 |
130 # Args | 97 # Args |
131 if len(argv) != 4: | 98 if len(argv) < 4: |
132 sys.stderr.write('%s:0: error: Expected xib and output file arguments\n' % | 99 sys.stderr.write('%s:0: error: Expected output file and then xibs\n' % |
133 generate_localizer); | 100 generate_localizer); |
134 return 1 | 101 return 1 |
135 xib_path, output_h_path, output_mm_path = argv[1:] | 102 output_path = argv[1]; |
| 103 xib_paths = argv[2:] |
136 | 104 |
137 # Run ibtool and convert to something Python can deal with | 105 full_constants_list = [] |
138 plist_string = xib_localizable_strings(xib_path) | 106 for xib_path in xib_paths: |
139 if not plist_string: | 107 # Run ibtool and convert to something Python can deal with |
140 return 2 | 108 plist_string = xib_localizable_strings(xib_path) |
141 plist = plistlib.readPlistFromString(plist_string) | 109 if not plist_string: |
| 110 return 2 |
| 111 plist = plistlib.readPlistFromString(plist_string) |
142 | 112 |
143 # Extract the resource constant strings | 113 # Extract the resource constant strings |
144 localizable_strings = plist['com.apple.ibtool.document.localizable-strings'] | 114 localizable_strings = plist['com.apple.ibtool.document.localizable-strings'] |
145 constants_list = extract_resource_constants(localizable_strings, xib_path) | 115 constants_list = extract_resource_constants(localizable_strings, xib_path) |
146 if not constants_list: | 116 if not constants_list: |
147 sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" % | 117 sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" % |
148 (xib_path, generate_localizer)); | 118 (xib_path, generate_localizer)); |
149 # Seed constant_list with an entry so things will compile even though the | 119 full_constants_list.extend(constants_list) |
150 # array sould really be empty (array_size in the generated file doesn't | |
151 # like an empty array). | |
152 constants_list.append('^0'); | |
153 | |
154 # Name the class based on the output file | |
155 class_name = os.path.splitext(os.path.basename(output_h_path))[0] | |
156 suffix = '_localizer' | |
157 if class_name.endswith(suffix): | |
158 class_name = class_name[:-len(suffix)]; | |
159 class_name = class_name.replace('_', ' ').title().replace(' ', ''); | |
160 | 120 |
161 # Generate our file contents | 121 # Generate our file contents |
162 (h_file_content, mm_file_content) = \ | 122 h_file_content = \ |
163 generate_files_contents(class_name, constants_list, | 123 generate_file_contents(full_constants_list, xib_paths) |
164 os.path.basename(output_h_path), | |
165 xib_path) | |
166 | 124 |
167 # Write out the files | 125 # Write out the file |
168 file_fd = open(output_h_path, 'w') | 126 file_fd = open(output_path, 'w') |
169 file_fd.write(h_file_content) | 127 file_fd.write(h_file_content) |
170 file_fd.close() | 128 file_fd.close() |
171 file_fd = open(output_mm_path, 'w') | |
172 file_fd.write(mm_file_content) | |
173 file_fd.close() | |
174 | 129 |
175 return 0 | 130 return 0 |
176 | 131 |
177 if __name__ == '__main__': | 132 if __name__ == '__main__': |
178 sys.exit(Main(sys.argv)) | 133 sys.exit(Main(sys.argv)) |
OLD | NEW |