23

Localizable strings file which are used for Apple/iPhone apps localization have the following format:

/* COMMENT */
"KEY" = "VALUE"

Note that KEY is unique in a given strings file.
COMMENT is optional however it can help the translator with some additional info.

Example:

/* Menu item to make the current document plain text */
"Make Plain Text" = "Make Plain Text";
/* Menu item to make the current document rich text */
"Make Rich Text" = "Make Rich Text";

I would like to diff/merge two strings files and optionally sort that kind of files. It would be great if the comments would be kept while doing these operations.

The format is quite simple and I could write let's say a python script to do that, but if somebody has already done that, I prefer not reinventing the wheel ;)

Do you know a tool that can manipulate strings file?

mharper
  • 3,212
  • 1
  • 23
  • 23
Jean Regisser
  • 6,636
  • 4
  • 32
  • 32

6 Answers6

28

I was desperate to find a decent way to manages Localized.strings during development, when there are new strings added to the code and you don't want to manually manage all the files.

I found Localization Manager that does this quite well. It has a nonexistent documentation, but comes with a separate program for the translators. It imports your strings, keeps track of changes and exports the needed Localization.strings files back to your project.

Up till now it seems to be freeware.

chaos0815
  • 811
  • 16
  • 27
  • 1
    Localization Manager is awesome! The end of my nightmare! How can the diffstring script be the accepted solution here when this tool does it a 1000 times better!? – Martin Jan 25 '10 at 16:16
  • 2
    What I don't get is, why this site does not even mention how to use that? There's zero information on that page, and a lot of different files to download. Really strange project. – dontWatchMyProfile May 18 '10 at 11:35
  • Once you understood it, it's just great! – Sandro Meier Jun 21 '11 at 16:51
  • 3
    I couldn't get this application to run on either Lion or SL. Is there some guide that I need to/can follow? Is anyone still using this app? @Martin – Schoob Jul 20 '11 at 10:27
7

Like I said in this post, I recently found a free app called Localizable Strings Merge on the Mac App Store. It does exactly what you ask, even the sorting/beautification. And it is free. Hope it helps.

Community
  • 1
  • 1
Dev
  • 7,027
  • 6
  • 37
  • 65
2

I found this tool from the Three20 project:

http://github.com/facebook/three20/blob/master/diffstrings.py

It answers my initial need in different way of what I had imagined:
it can diff between the main locale and the other locales to see what needs translating in each other locale. And then merge back the translated strings.

Note that it outputs xml files to give to the translators.

Jean Regisser
  • 6,636
  • 4
  • 32
  • 32
  • Is there any documentation on how to use diffstrings.py? I keep on getting errors: Traceback (most recent call last): File "diffstrings.py", line 656, in main() File "diffstrings.py", line 638, in main projects = list(openProjects(projectPaths, options.locale)) ...and so on. This tool seems amazingly valuable; I just don't know enough about Python to figure out what's going wrong. (Even the arguments to be passed in as paths seem mysterious. "Source files?" Which source files?) Any help would be appreciated. – Greg Maletic Apr 14 '10 at 00:54
  • As the link in the answer appears to be 404: https://github.com/alunny/three20/blob/master/diffstrings.py – Isaac Dec 13 '16 at 15:42
0

Ugly but works

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSString* f1 = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
        NSString* f2 = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding];

        //

        NSLog(@" Comparing %@ to %@\n", f1, f2);

        //

        NSError* error;
        if ( [f1 hasPrefix:@"~"] ) {
            f1 = [f1 stringByReplacingOccurrencesOfString:@"~" withString:NSHomeDirectory()];
        }
        if ( [f2 hasPrefix:@"~"] ) {
            f2 = [f2 stringByReplacingOccurrencesOfString:@"~" withString:NSHomeDirectory()];
        }

        NSStringEncoding encoding;
        NSString* f1Content = [NSString stringWithContentsOfFile:f1 usedEncoding:&encoding error:&error];
        NSString* f2Content = [NSString stringWithContentsOfFile:f2 usedEncoding:&encoding error:&error];

        //

        NSArray* f1Strings = [f1Content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
        NSArray* f2Strings = [f2Content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

        for (NSString* keyString in f1Strings) {
            NSString* trimKey = [keyString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            if ( !trimKey || [trimKey isEqualToString:@""] )
                continue;

            NSString* key = [keyString componentsSeparatedByString:@" = "][0];

            BOOL found = NO;
            for (NSString* keyString2 in f2Strings) {
                if ( [keyString2 hasPrefix:key] ) {
                    found = YES;
                    break;
                }
            }

            if ( !found ) {
                printf("%s\n\n", [keyString UTF8String]);
            }
        }
    }
    return 0;
}
Cherpak Evgeny
  • 2,659
  • 22
  • 29
0

https://github.com/luckytianyiyan/TyStrings

$ tystrings diff diff1.strings diff2.strings

>>> Parsing File1 Reference...
>>> Parsing File2 Reference...
>>> Comparing...
+----+---------+---------+-------------+---------+
|    | File1   | File2   | Key         | Value   |
|----+---------+---------+-------------+---------|
| +  | 2       |         | diff.test.0 | Test0   |
| -  |         | 2       | diff.test.0 | Test    |
| -  |         | 5       | diff.test.4 | Test4   |
| +  | 8       |         | diff.test.2 | Test2   |
| -  |         | 11      | diff.test.3 | Test3   |
+----+---------+---------+-------------+---------+
-4

You can try /Developer/Applications/Utilities/FileMerge.app. That's always a good start. Also, you should try genstrings.

Chris Frederick
  • 5,482
  • 3
  • 36
  • 44
Alexsander Akers
  • 15,967
  • 12
  • 58
  • 83