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