#!/usr/bin/python # Copyright (c) 2009 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Usage: generate_localizer [xib_path] [output_dot_h_path] [output_dot_mm_path] # # Extracts all the localizable strings that start with "^IDS" from the given # xib file, and then generates a localizer to process those strings. import os.path import plistlib import subprocess import sys generate_localizer = "me" localizer_template_h = \ '''// ---------- WARNING ---------- // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! // // Generated by %(generate_localizer)s. // Generated from %(xib_file)s. // #ifndef %(class_name)s_LOCALIZER_H_ #define %(class_name)s_LOCALIZER_H_ #import "chrome/browser/cocoa/ui_localizer.h" // A subclass of ChromeUILocalizer that handles localization based on resource // constants. @interface %(class_name)sLocalizer : ChromeUILocalizer @end #endif // %(class_name)s_LOCALIZER_H_ ''' localizer_template_mm = \ '''// ---------- WARNING ---------- // THIS IS A GENERATED FILE, DO NOT EDIT IT DIRECTLY! // // Generated by '%(generate_localizer)s'. // Generated from '%(xib_file)s'. // #import "%(header_name)s" #include "grit/app_strings.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @implementation %(class_name)sLocalizer - (NSString *)localizedStringForString:(NSString *)string { static const ui_localizer::ResourceMap kUIResources[] = { %(resource_map_list)s }; static const size_t kUIResourcesSize = arraysize(kUIResources); return ui_localizer::LocalizedStringForKeyFromMapList(string, kUIResources, kUIResourcesSize); } @end ''' def xib_localizable_strings(xib_path): """Runs ibtool to extract the localizable strings data from the xib.""" ibtool_cmd = subprocess.Popen(['/usr/bin/ibtool', '--localizable-strings', xib_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (cmd_out, cmd_err) = ibtool_cmd.communicate() if ibtool_cmd.returncode: sys.stderr.write('%s:0: error: ibtool on "%s" failed (%d):\n%s\n' % (generate_localizer, xib_path, ibtool_cmd.returncode, cmd_err)) return None return cmd_out def extract_resource_constants(plist_localizable_strings_dict, xib_path): """Extracts all the values that start with ^IDS from the localizable strings plist entry.""" constants_list = [] for item_dict in plist_localizable_strings_dict.itervalues(): for item_value in item_dict.itervalues(): if item_value.startswith('^IDS'): constants_list.append(item_value) elif item_value.startswith('IDS'): sys.stderr.write( '%s:0: warning: %s found a string with questionable prefix, "%s"\n' % (xib_path, generate_localizer, item_value)); return constants_list def generate_files_contents(class_name, constants_list, header_name, xib_path): """Generates a localizer files contents from the list of constants.""" # Copy and sort the list, then build the strings we need from it. constants_list = constants_list[:] constants_list.sort() constant_list_str = '' for item in constants_list: parts = item.split('$', 1) label_id = parts[0] if len(parts) == 2: label_arg_id = parts[1] else: label_arg_id = '0' constant_list_str += ' { "%s", %s, %s },\n' % \ ( item, label_id[1:], label_arg_id) # Assemble the contents from the templates. values_dict = { 'class_name': class_name, 'header_name': header_name, 'resource_map_list': constant_list_str, 'generate_localizer': generate_localizer, 'xib_file': xib_path, } h_file = localizer_template_h % values_dict mm_file = localizer_template_mm % values_dict return (h_file, mm_file) def Main(argv=None): global generate_localizer generate_localizer = os.path.basename(argv[0]) # Args if len(argv) != 4: sys.stderr.write('%s:0: error: Expected xib and output file arguments\n' % generate_localizer); return 1 xib_path, output_h_path, output_mm_path = argv[1:] # Run ibtool and convert to something Python can deal with plist_string = xib_localizable_strings(xib_path) if not plist_string: return 2 plist = plistlib.readPlistFromString(plist_string) # Extract the resource constant strings localizable_strings = plist['com.apple.ibtool.document.localizable-strings'] constants_list = extract_resource_constants(localizable_strings, xib_path) if not constants_list: sys.stderr.write("%s:0: warning: %s didn't find any resource strings\n" % (xib_path, generate_localizer)); # Seed constant_list with an entry so things will compile even though the # array sould really be empty (array_size in the generated file doesn't # like an empty array). constants_list.append('^0'); # Name the class based on the output file class_name = os.path.splitext(os.path.basename(output_h_path))[0] suffix = '_localizer' if class_name.endswith(suffix): class_name = class_name[:-len(suffix)]; class_name = class_name.replace('_', ' ').title().replace(' ', ''); # Generate our file contents (h_file_content, mm_file_content) = \ generate_files_contents(class_name, constants_list, os.path.basename(output_h_path), xib_path) # Write out the files file_fd = open(output_h_path, 'w') file_fd.write(h_file_content) file_fd.close() file_fd = open(output_mm_path, 'w') file_fd.write(mm_file_content) file_fd.close() return 0 if __name__ == '__main__': sys.exit(Main(sys.argv))