Permalink
Browse files

Initial push

The Localize collection allows automatic localization file creation for
your *m source and *.plist files.  The localize.py script was an
original by João Moreno (2009) modified by Steve Streeting (2010) even
more modified and broght to plists by Gerry Weißbach (2011)
  • Loading branch information...
0 parents commit a83f3e9a27b88679e697cff05a482c77de551356 @gamma committed Aug 6, 2011
Showing with 288 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +66 −0 localize-plist.py
  3. +56 −0 localize.py
  4. +144 −0 localizeUtils.py
  5. +21 −0 plist2text.sh
@@ -0,0 +1 @@
+*.pyc
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Localize.py - Incremental localization on XCode projects
+# João Moreno 2009
+# http://joaomoreno.com/
+
+# Modified by Steve Streeting 2010 http://www.stevestreeting.com
+# Changes
+# - Use .strings files encoded as UTF-8
+# This is useful because Mercurial and Git treat UTF-16 as binary and can't
+# diff/merge them. For use on iPhone you can run an iconv script during build to
+# convert back to UTF-16 (Mac OS X will happily use UTF-8 .strings files).
+# - Clean up .old and .new files once we're done
+
+# localize-plist.py
+# Extracted by Gerry Weißbach 2011 http://www.gammaproduction.de
+# Changes
+# - extract util methods
+# - add sorting of the strings files - genstrings does this, but the plist2text does not
+# - improved Error messaging
+
+from string import replace
+import os, sys
+
+from localizeUtils import *
+
+def localize(self_path, path):
+ plist2txt = self_path + os.path.sep + 'plist2text.sh'
+ files = [name for name in os.listdir(path + os.path.sep) if name.endswith('plist') and os.path.isfile(path + os.path.sep + name)]
+
+ for fileName in files:
+ fullFileName = path + os.path.sep + fileName
+ fileName = replace(fileName, '.plist', '.strings')
+
+ languages = [name for name in os.listdir(path + os.path.sep) if name.endswith('.lproj') and os.path.isdir(path + os.path.sep + name)]
+
+
+ for language in languages:
+ language = path + os.path.sep + language
+ original = merged = language + os.path.sep + fileName
+
+ old = original + '.old'
+ new = original + '.new'
+
+ if os.path.isfile(original):
+ os.rename(original, old)
+ os.system('bash "%s" "%s" "%s"' % (plist2txt, fullFileName, original))
+ os.system('iconv -f UTF-8 -t UTF-8 "%s" > "%s"' % (original, new))
+ merge(merged, old, new)
+ else:
+ os.system('bash "%s" "%s" "%s"' % (plist2txt, fullFileName, old))
+ sortLocale(old, new)
+ os.system('iconv -f UTF-8 -t UTF-8 "%s" > "%s"' % (new, original))
+
+ if os.path.isfile(old):
+ os.remove(old)
+ if os.path.isfile(new):
+ os.remove(new)
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2 or not os.path.isdir(sys.argv[1]):
+ print >>sys.stderr, 'Usage: python localize-plist.py path-to-plists'
+ sys.exit(2)
+
+ localize(os.path.dirname(sys.argv[0]), os.path.dirname(sys.argv[1]))
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Localize.py - Incremental localization on XCode projects
+# João Moreno 2009
+# http://joaomoreno.com/
+
+# Modified by Steve Streeting 2010 http://www.stevestreeting.com
+# Changes
+# - Use .strings files encoded as UTF-8
+# This is useful because Mercurial and Git treat UTF-16 as binary and can't
+# diff/merge them. For use on iPhone you can run an iconv script during build to
+# convert back to UTF-16 (Mac OS X will happily use UTF-8 .strings files).
+# - Clean up .old and .new files once we're done
+
+# localizeUtils.py
+# Extracted by Gerry Weißbach 2011 http://www.gammaproduction.de
+# Changes
+# - extract util methods
+# - add sorting of the strings files - genstrings does this, but the plist2text does not
+# - improved Error messaging
+
+from sys import argv
+from string import replace
+import os
+
+from localizeUtils import *
+
+STRINGS_FILE = 'Localizable.strings'
+
+def localize(path):
+ languages = [name for name in os.listdir(path + os.path.sep + 'i18n') if name.endswith('.lproj') and os.path.isdir(path + os.path.sep + 'i18n' + os.path.sep + name)]
+
+ for language in languages:
+ language = 'i18n' + os.path.sep + language
+ original = merged = language + os.path.sep + STRINGS_FILE
+ old = original + '.old'
+ new = original + '.new'
+
+ if os.path.isfile(original):
+ os.rename(original, old)
+ os.system('genstrings -q -o "%s" `find . -name "*.m"`' % language)
+ os.system('iconv -f UTF-16 -t UTF-8 "%s" > "%s"' % (original, new))
+ merge(merged, old, new)
+ else:
+ os.system('genstrings -q -o "%s" `find . -name "*.m"`' % language)
+ os.rename(original, old)
+ os.system('iconv -f UTF-16 -t UTF-8 "%s" > "%s"' % (old, original))
+
+ if os.path.isfile(old):
+ os.remove(old)
+ if os.path.isfile(new):
+ os.remove(new)
+
+if __name__ == '__main__':
+ localize(os.getcwd())
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Localize.py - Incremental localization on XCode projects
+# João Moreno 2009
+# http://joaomoreno.com/
+
+# Modified by Steve Streeting 2010 http://www.stevestreeting.com
+# Changes
+# - Use .strings files encoded as UTF-8
+# This is useful because Mercurial and Git treat UTF-16 as binary and can't
+# diff/merge them. For use on iPhone you can run an iconv script during build to
+# convert back to UTF-16 (Mac OS X will happily use UTF-8 .strings files).
+# - Clean up .old and .new files once we're done
+
+# localizeUtils.py
+# Extracted by Gerry Weißbach 2011 http://www.gammaproduction.de
+# Changes
+# - extract util methods
+# - add sorting of the strings files - genstrings does this, but the plist2text does not
+# - improved Error messaging
+
+from sys import argv
+from codecs import open
+from re import compile
+from copy import copy
+import os
+
+re_translation = compile(r'^"(.+)" = "(.+)";$')
+re_comment_single = compile(r'^/\*.*\*/$')
+re_comment_start = compile(r'^/\*.*$')
+re_comment_end = compile(r'^.*\*/$')
+
+class LocalizedString():
+ def __init__(self, comments, translation):
+ self.comments, self.translation = comments, translation
+ self.key, self.value = re_translation.match(self.translation).groups()
+
+ def __unicode__(self):
+ return u'%s%s\n' % (u''.join(self.comments), self.translation)
+
+ def __eq__(self, other):
+ return self.key==other.key
+
+ def __hash__(self):
+ return hash(('key', self.key))
+
+class LocalizedFile():
+ def __init__(self, fname=None, auto_read=False):
+ self.fname = fname
+ self.strings = []
+ self.strings_d = {}
+
+ if auto_read:
+ self.read_from_file(fname)
+
+ def read_from_file(self, fname=None):
+ fname = self.fname if fname == None else fname
+ try:
+ f = open(fname, encoding='utf-8', mode='r')
+ except:
+ print 'File %s does not exist.' % fname
+ exit(-1)
+
+ line = f.readline()
+ while line:
+ comments = [line]
+
+ if not re_comment_single.match(line):
+ while line and not re_comment_end.match(line):
+ line = f.readline()
+ comments.append(line)
+
+ line = f.readline()
+ if line and re_translation.match(line):
+ translation = line
+ else:
+ raise Exception('input file %s have invalid format' % fname)
+
+ line = f.readline()
+ while line and line == u'\n':
+ line = f.readline()
+
+ string = LocalizedString(comments, translation)
+ self.strings.append(string)
+ self.strings_d[string.key] = string
+
+ f.close()
+
+ def save_to_file(self, fname=None):
+ fname = self.fname if fname == None else fname
+ try:
+ f = open(fname, encoding='utf_8', mode='w')
+ except:
+ raise Exception('Couldn\'t open file %s.' % fname)
+ exit(-1)
+
+ for string in self.strings:
+ f.write(string.__unicode__())
+
+ f.close()
+
+ def merge_with(self, new):
+ merged = LocalizedFile()
+
+ for string in set(new.strings):
+ if self.strings_d.has_key(string.key):
+ new_string = copy(self.strings_d[string.key])
+ new_string.comments = string.comments
+ string = new_string
+
+ merged.strings.append(string)
+ merged.strings_d[string.key] = string
+
+ return merged
+
+ def sort(self):
+ self.strings = sorted(set(self.strings), key=lambda LocalizedString: LocalizedString.key )
+ return self
+
+def merge(merged_fname, old_fname, new_fname):
+
+ print 'Merging into file %s' % merged_fname
+ try:
+ old = LocalizedFile(old_fname, auto_read=True)
+ new = LocalizedFile(new_fname, auto_read=True)
+ try:
+ merged = old.merge_with(new)
+ merged.sort().save_to_file(merged_fname)
+ except Exception, e:
+ print 'cannot merge with Error: %s' %e
+ except Exception, e:
+ print 'Error in file: %s' % merged_fname
+ print 'Error: %s' % e
+
+def sortLocale(old_fname, new_fname):
+
+ print 'Sorting file %s' % old_fname
+ try:
+ old = LocalizedFile(old_fname, auto_read=True)
+ old.sort().save_to_file(new_fname)
+ except Exception, e:
+ print 'Error in file: %s' % old_fname
+ print 'Error: %s' % e
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+rm -f $2
+
+sed -n 'N;/<key>Title<\/key>/{N;/<string>.*<\/string>/{s/.*<string>\(.*\)<\/string>.*/\/* \1 *\/\
+"\1" = "\1";\
+/p;};}' $1 >> $2
+
+sed -n 'N;/<key>FooterText<\/key>/{N;/<string>.*<\/string>/{s/.*<string>\(.*\)<\/string>.*/\/* \1 *\/\
+\"\1" = "\1";\
+/p;}
+;}' $1 >> $2
+
+sed -n 'N;/<key>Titles<\/key>/{N;/<array>/{:a
+/<\/array>/!{
+/<string>.*<\/string>/{s/.*<string>\(.*\)<\/string>.*/\/* \1 *\/\
+\"\1" = "\1";\
+/p;}
+N;
+ba
+;};};}' $1 >> $2

0 comments on commit a83f3e9

Please sign in to comment.